From a6a23d5e1d07aad3f0c88f7a70539fcf15fa1029 Mon Sep 17 00:00:00 2001 From: Henning Baldersheim Date: Tue, 9 Jan 2018 22:37:34 +0100 Subject: Rename to indicate it refers to right side. --- .../eval/tensor/dense/dense_tensor_address_combiner.cpp | 4 ++-- .../eval/tensor/dense/dense_tensor_address_combiner.h | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'eval') diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.cpp b/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.cpp index 5ad4181bbf5..58f1d35dc48 100644 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.cpp +++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.cpp @@ -14,7 +14,7 @@ DenseTensorAddressCombiner::DenseTensorAddressCombiner(const eval::ValueType &lh _combinedAddress(), _rightCells(rhsCells), _rightAddress(rhs.dimensions().size(), 0), - _accumulatedSize(_rightAddress.size()), + _rightAccumulatedSize(_rightAddress.size()), _left(), _commonRight(), _right() @@ -43,7 +43,7 @@ DenseTensorAddressCombiner::DenseTensorAddressCombiner(const eval::ValueType &lh _combinedAddress.resize(numDimensions); size_t multiplier = 1; for (int32_t i(_rightAddress.size() - 1); i >= 0; i--) { - _accumulatedSize[i] = multiplier; + _rightAccumulatedSize[i] = multiplier; multiplier *= _rightType.dimensions()[i].size; } } diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h b/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h index fdd8da467cc..a45944ef9bf 100644 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h +++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h @@ -29,7 +29,7 @@ private: Address _combinedAddress; CellsRef _rightCells; Address _rightAddress; - std::vector _accumulatedSize; + std::vector _rightAccumulatedSize; Mapping _left; Mapping _commonRight; Mapping _right; @@ -42,7 +42,7 @@ private: size_t rightIndex(const Address &address) const { size_t cellIdx(0); for (uint32_t i(0); i < address.size(); i++) { - cellIdx += address[i]*_accumulatedSize[i]; + cellIdx += address[i]*_rightAccumulatedSize[i]; } return cellIdx; } @@ -70,26 +70,26 @@ public: void for_each(Func && func) { const int32_t lastDimension = _right.size() - 1; int32_t curDimension = lastDimension; - size_t cellIdx = rightIndex(_rightAddress); + size_t rightCellIdx = rightIndex(_rightAddress); while (curDimension >= 0) { const uint32_t rdim = _right[curDimension].second; const uint32_t cdim = _right[curDimension].first; size_type & cindex = _combinedAddress[cdim]; if (curDimension == lastDimension) { for (cindex = 0; cindex < _rightType.dimensions()[rdim].size; cindex++) { - func(_combinedAddress, rightCell(cellIdx)); - cellIdx += _accumulatedSize[rdim]; + func(_combinedAddress, rightCell(rightCellIdx)); + rightCellIdx += _rightAccumulatedSize[rdim]; } cindex = 0; - cellIdx -= _accumulatedSize[rdim] * _rightType.dimensions()[rdim].size; + rightCellIdx -= _rightAccumulatedSize[rdim] * _rightType.dimensions()[rdim].size; curDimension--; } else { if (cindex < _rightType.dimensions()[rdim].size) { cindex++; - cellIdx += _accumulatedSize[rdim]; + rightCellIdx += _rightAccumulatedSize[rdim]; curDimension++; } else { - cellIdx -= _accumulatedSize[rdim] * _rightType.dimensions()[rdim].size; + rightCellIdx -= _rightAccumulatedSize[rdim] * _rightType.dimensions()[rdim].size; cindex = 0; curDimension--; } -- cgit v1.2.3 From 0a8534171a39c00f7d1938c14eb4ec96a0c02692 Mon Sep 17 00:00:00 2001 From: Henning Baldersheim Date: Tue, 9 Jan 2018 23:05:15 +0100 Subject: Make and address context to keep code together. --- .../tensor/dense/dense_tensor_address_combiner.cpp | 20 +++++--- .../tensor/dense/dense_tensor_address_combiner.h | 57 +++++++++++++--------- 2 files changed, 47 insertions(+), 30 deletions(-) (limited to 'eval') diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.cpp b/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.cpp index 58f1d35dc48..55a5d90fd4b 100644 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.cpp +++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.cpp @@ -10,11 +10,8 @@ DenseTensorAddressCombiner::~DenseTensorAddressCombiner() = default; DenseTensorAddressCombiner::DenseTensorAddressCombiner(const eval::ValueType &lhs, const eval::ValueType &rhs, CellsRef rhsCells) - : _rightType(rhs), + : _rightAddress(rhs, rhsCells), _combinedAddress(), - _rightCells(rhsCells), - _rightAddress(rhs.dimensions().size(), 0), - _rightAccumulatedSize(_rightAddress.size()), _left(), _commonRight(), _right() @@ -41,13 +38,22 @@ DenseTensorAddressCombiner::DenseTensorAddressCombiner(const eval::ValueType &lh ++rhsItr; } _combinedAddress.resize(numDimensions); +} + +DenseTensorAddressCombiner::AddressContext::AddressContext(const eval::ValueType &type, CellsRef cells) + : _type(type), + _cells(cells), + _address(type.dimensions().size(), 0), + _accumulatedSize(_address.size()) +{ size_t multiplier = 1; - for (int32_t i(_rightAddress.size() - 1); i >= 0; i--) { - _rightAccumulatedSize[i] = multiplier; - multiplier *= _rightType.dimensions()[i].size; + for (int32_t i(_address.size() - 1); i >= 0; i--) { + _accumulatedSize[i] = multiplier; + multiplier *= type.dimensions()[i].size; } } + eval::ValueType DenseTensorAddressCombiner::combineDimensions(const eval::ValueType &lhs, const eval::ValueType &rhs) { diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h b/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h index a45944ef9bf..5b7c2cb4cb4 100644 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h +++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h @@ -25,11 +25,29 @@ private: using CellsRef = vespalib::ConstArrayRef; using size_type = eval::ValueType::Dimension::size_type; - const eval::ValueType &_rightType; + class AddressContext { + public: + AddressContext(const eval::ValueType &type, CellsRef cells); + size_type dimSize(uint32_t dim) const { return _type.dimensions()[dim].size; } + double cell() const { return cell(index()); } + double cell(size_t cellIdx) const { return _cells[cellIdx]; } + size_t index() const { + size_t cellIdx(0); + for (uint32_t i(0); i < _address.size(); i++) { + cellIdx += _address[i]*_accumulatedSize[i]; + } + return cellIdx; + } + + const eval::ValueType &_type; + CellsRef _cells; + Address _address; + std::vector _accumulatedSize; + }; + + AddressContext _rightAddress; Address _combinedAddress; - CellsRef _rightCells; - Address _rightAddress; - std::vector _rightAccumulatedSize; + Mapping _left; Mapping _commonRight; Mapping _right; @@ -38,14 +56,7 @@ private: _combinedAddress[m.first] = addr[m.second]; } } - double rightCell(size_t cellIdx) const { return _rightCells[cellIdx]; } - size_t rightIndex(const Address &address) const { - size_t cellIdx(0); - for (uint32_t i(0); i < address.size(); i++) { - cellIdx += address[i]*_rightAccumulatedSize[i]; - } - return cellIdx; - } + public: DenseTensorAddressCombiner(const eval::ValueType &lhs, const eval::ValueType &rhs, CellsRef rhsCells); ~DenseTensorAddressCombiner(); @@ -57,39 +68,39 @@ public: bool updateCommonRight() { for (const auto & m : _commonRight) { - if (_combinedAddress[m.first] >= _rightType.dimensions()[m.second].size) { + if (_combinedAddress[m.first] >= _rightAddress._type.dimensions()[m.second].size) { return false; } - _rightAddress[m.second] = _combinedAddress[m.first]; + _rightAddress._address[m.second] = _combinedAddress[m.first]; } return true; } - double rightCell() { return rightCell(rightIndex(_rightAddress)); } + double rightCell() { return _rightAddress.cell(); } template void for_each(Func && func) { const int32_t lastDimension = _right.size() - 1; int32_t curDimension = lastDimension; - size_t rightCellIdx = rightIndex(_rightAddress); + size_t rightCellIdx = _rightAddress.index(); while (curDimension >= 0) { const uint32_t rdim = _right[curDimension].second; const uint32_t cdim = _right[curDimension].first; size_type & cindex = _combinedAddress[cdim]; if (curDimension == lastDimension) { - for (cindex = 0; cindex < _rightType.dimensions()[rdim].size; cindex++) { - func(_combinedAddress, rightCell(rightCellIdx)); - rightCellIdx += _rightAccumulatedSize[rdim]; + for (cindex = 0; cindex < _rightAddress.dimSize(rdim); cindex++) { + func(_combinedAddress, _rightAddress.cell(rightCellIdx)); + rightCellIdx += _rightAddress._accumulatedSize[rdim]; } cindex = 0; - rightCellIdx -= _rightAccumulatedSize[rdim] * _rightType.dimensions()[rdim].size; + rightCellIdx -= _rightAddress._accumulatedSize[rdim] * _rightAddress.dimSize(rdim); curDimension--; } else { - if (cindex < _rightType.dimensions()[rdim].size) { + if (cindex < _rightAddress.dimSize(rdim)) { cindex++; - rightCellIdx += _rightAccumulatedSize[rdim]; + rightCellIdx += _rightAddress._accumulatedSize[rdim]; curDimension++; } else { - rightCellIdx -= _rightAccumulatedSize[rdim] * _rightType.dimensions()[rdim].size; + rightCellIdx -= _rightAddress._accumulatedSize[rdim] * _rightAddress.dimSize(rdim); cindex = 0; curDimension--; } -- cgit v1.2.3 From 1b305b6f01bd0df3fbd655d069f9b24b6a41d842 Mon Sep 17 00:00:00 2001 From: Henning Baldersheim Date: Tue, 9 Jan 2018 23:20:13 +0100 Subject: Hide the calculation inside the address context. --- eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'eval') diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h b/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h index 5b7c2cb4cb4..845ec767094 100644 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h +++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h @@ -29,6 +29,7 @@ private: public: AddressContext(const eval::ValueType &type, CellsRef cells); size_type dimSize(uint32_t dim) const { return _type.dimensions()[dim].size; } + size_type wholeDimStep(uint32_t dim) const { return _accumulatedSize[dim] * dimSize(dim); } double cell() const { return cell(index()); } double cell(size_t cellIdx) const { return _cells[cellIdx]; } size_t index() const { @@ -92,7 +93,7 @@ public: rightCellIdx += _rightAddress._accumulatedSize[rdim]; } cindex = 0; - rightCellIdx -= _rightAddress._accumulatedSize[rdim] * _rightAddress.dimSize(rdim); + rightCellIdx -= _rightAddress.wholeDimStep(rdim); curDimension--; } else { if (cindex < _rightAddress.dimSize(rdim)) { @@ -100,7 +101,7 @@ public: rightCellIdx += _rightAddress._accumulatedSize[rdim]; curDimension++; } else { - rightCellIdx -= _rightAddress._accumulatedSize[rdim] * _rightAddress.dimSize(rdim); + rightCellIdx -= _rightAddress.wholeDimStep(rdim); cindex = 0; curDimension--; } -- cgit v1.2.3 From e7acdd2c4fe3fbb1d0e99a64a7a1ca462886b04a Mon Sep 17 00:00:00 2001 From: Henning Baldersheim Date: Wed, 10 Jan 2018 00:27:13 +0100 Subject: Use the same AddressContext for the combinedAddress and compute the combinedIdx inline too. --- .../tensor/dense/dense_tensor_address_combiner.cpp | 16 +++---- .../tensor/dense/dense_tensor_address_combiner.h | 52 ++++++++++++++-------- .../vespa/eval/tensor/dense/dense_tensor_apply.hpp | 7 +-- 3 files changed, 45 insertions(+), 30 deletions(-) (limited to 'eval') diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.cpp b/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.cpp index 55a5d90fd4b..8c704c61415 100644 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.cpp +++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.cpp @@ -8,10 +8,10 @@ namespace vespalib::tensor { DenseTensorAddressCombiner::~DenseTensorAddressCombiner() = default; -DenseTensorAddressCombiner::DenseTensorAddressCombiner(const eval::ValueType &lhs, const eval::ValueType &rhs, - CellsRef rhsCells) +DenseTensorAddressCombiner::DenseTensorAddressCombiner(const eval::ValueType &combined, const eval::ValueType &lhs, + const eval::ValueType &rhs, CellsRef rhsCells) : _rightAddress(rhs, rhsCells), - _combinedAddress(), + _combinedAddress(combined), _left(), _commonRight(), _right() @@ -37,14 +37,13 @@ DenseTensorAddressCombiner::DenseTensorAddressCombiner(const eval::ValueType &lh _right.emplace_back(numDimensions++, rhsItr-rhs.dimensions().cbegin()); ++rhsItr; } - _combinedAddress.resize(numDimensions); } -DenseTensorAddressCombiner::AddressContext::AddressContext(const eval::ValueType &type, CellsRef cells) +DenseTensorAddressCombiner::AddressContext::AddressContext(const eval::ValueType &type) : _type(type), - _cells(cells), - _address(type.dimensions().size(), 0), - _accumulatedSize(_address.size()) + _accumulatedSize(_type.dimensions().size()), + _address(type.dimensions().size(), 0) + { size_t multiplier = 1; for (int32_t i(_address.size() - 1); i >= 0; i--) { @@ -53,6 +52,7 @@ DenseTensorAddressCombiner::AddressContext::AddressContext(const eval::ValueType } } +DenseTensorAddressCombiner::AddressContext::~AddressContext() = default; eval::ValueType DenseTensorAddressCombiner::combineDimensions(const eval::ValueType &lhs, const eval::ValueType &rhs) diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h b/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h index 845ec767094..0d4fa794f38 100644 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h +++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h @@ -27,11 +27,10 @@ private: class AddressContext { public: - AddressContext(const eval::ValueType &type, CellsRef cells); + AddressContext(const eval::ValueType &type); + ~AddressContext(); size_type dimSize(uint32_t dim) const { return _type.dimensions()[dim].size; } size_type wholeDimStep(uint32_t dim) const { return _accumulatedSize[dim] * dimSize(dim); } - double cell() const { return cell(index()); } - double cell(size_t cellIdx) const { return _cells[cellIdx]; } size_t index() const { size_t cellIdx(0); for (uint32_t i(0); i < _address.size(); i++) { @@ -39,40 +38,50 @@ private: } return cellIdx; } + void update(const Address & addr, const Mapping & mapping) { + for (const auto & m : mapping) { + _address[m.first] = addr[m.second]; + } + } const eval::ValueType &_type; - CellsRef _cells; - Address _address; std::vector _accumulatedSize; + Address _address; + }; + class CellAddressContext : public AddressContext { + public: + CellAddressContext(const eval::ValueType &type, CellsRef cells) : AddressContext(type), _cells(cells) { } + double cell() const { return cell(index()); } + double cell(size_t cellIdx) const { return _cells[cellIdx]; } + private: + CellsRef _cells; + }; + - AddressContext _rightAddress; - Address _combinedAddress; + CellAddressContext _rightAddress; + AddressContext _combinedAddress; Mapping _left; Mapping _commonRight; Mapping _right; - void update(const Address & addr, const Mapping & mapping) { - for (const auto & m : mapping) { - _combinedAddress[m.first] = addr[m.second]; - } - } public: - DenseTensorAddressCombiner(const eval::ValueType &lhs, const eval::ValueType &rhs, CellsRef rhsCells); + DenseTensorAddressCombiner(const eval::ValueType &combined, const eval::ValueType &lhs, + const eval::ValueType &rhs, CellsRef rhsCells); ~DenseTensorAddressCombiner(); - void updateLeftAndCommon(const Address & addr) { update(addr, _left); } + void updateLeftAndCommon(const Address & addr) { _combinedAddress.update(addr, _left); } bool hasAnyRightOnlyDimensions() const { return ! _right.empty(); } - const Address &address() const { return _combinedAddress; } + const Address &address() const { return _combinedAddress._address; } bool updateCommonRight() { for (const auto & m : _commonRight) { - if (_combinedAddress[m.first] >= _rightAddress._type.dimensions()[m.second].size) { + if (_combinedAddress._address[m.first] >= _rightAddress.dimSize(m.second)) { return false; } - _rightAddress._address[m.second] = _combinedAddress[m.first]; + _rightAddress._address[m.second] = _combinedAddress._address[m.first]; } return true; } @@ -83,25 +92,30 @@ public: const int32_t lastDimension = _right.size() - 1; int32_t curDimension = lastDimension; size_t rightCellIdx = _rightAddress.index(); + size_t combinedCellIdx = _combinedAddress.index(); while (curDimension >= 0) { const uint32_t rdim = _right[curDimension].second; const uint32_t cdim = _right[curDimension].first; - size_type & cindex = _combinedAddress[cdim]; + size_type & cindex = _combinedAddress._address[cdim]; if (curDimension == lastDimension) { for (cindex = 0; cindex < _rightAddress.dimSize(rdim); cindex++) { - func(_combinedAddress, _rightAddress.cell(rightCellIdx)); + func(combinedCellIdx, _rightAddress.cell(rightCellIdx)); rightCellIdx += _rightAddress._accumulatedSize[rdim]; + combinedCellIdx += _combinedAddress._accumulatedSize[cdim]; } cindex = 0; rightCellIdx -= _rightAddress.wholeDimStep(rdim); + combinedCellIdx -= _combinedAddress.wholeDimStep(cdim); curDimension--; } else { if (cindex < _rightAddress.dimSize(rdim)) { cindex++; rightCellIdx += _rightAddress._accumulatedSize[rdim]; + combinedCellIdx += _combinedAddress._accumulatedSize[cdim]; curDimension++; } else { rightCellIdx -= _rightAddress.wholeDimStep(rdim); + combinedCellIdx -= _combinedAddress.wholeDimStep(cdim); cindex = 0; curDimension--; } diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_apply.hpp b/eval/src/vespa/eval/tensor/dense/dense_tensor_apply.hpp index 80720bd10e1..868a49627c8 100644 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_apply.hpp +++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_apply.hpp @@ -21,7 +21,7 @@ apply(DenseTensorAddressCombiner & combiner, DirectDenseTensorBuilder & builder, for (DenseTensorCellsIterator lhsItr = lhs.cellsIterator(); lhsItr.valid(); lhsItr.next()) { combiner.updateLeftAndCommon(lhsItr.address()); if (combiner.updateCommonRight()) { - combiner.for_each([&func, &builder, &lhsItr](const DenseTensorCellsIterator::Address & combined, double rhsCell) { + combiner.for_each([&func, &builder, &lhsItr](size_t combined, double rhsCell) { builder.insertCell(combined, func(lhsItr.cell(), rhsCell)); }); } @@ -53,8 +53,9 @@ template std::unique_ptr apply(const DenseTensorView &lhs, const DenseTensorView &rhs, Function &&func) { - DenseTensorAddressCombiner combiner(lhs.fast_type(), rhs.fast_type(), rhs.cellsRef()); - DirectDenseTensorBuilder builder(DenseTensorAddressCombiner::combineDimensions(lhs.fast_type(), rhs.fast_type())); + eval::ValueType resultType = DenseTensorAddressCombiner::combineDimensions(lhs.fast_type(), rhs.fast_type()); + DenseTensorAddressCombiner combiner(resultType, lhs.fast_type(), rhs.fast_type(), rhs.cellsRef()); + DirectDenseTensorBuilder builder(resultType); if (combiner.hasAnyRightOnlyDimensions()) { return apply(combiner, builder, lhs, std::move(func)); } else { -- cgit v1.2.3 From b839058fe6ae1efcd786f670e57c4c9b84a375ab Mon Sep 17 00:00:00 2001 From: Henning Baldersheim Date: Wed, 10 Jan 2018 15:58:37 +0100 Subject: Move the right address context on the outside. --- .../tensor/dense/dense_tensor_address_combiner.cpp | 9 +- .../tensor/dense/dense_tensor_address_combiner.h | 108 ++++++++++----------- .../vespa/eval/tensor/dense/dense_tensor_apply.hpp | 26 ++--- 3 files changed, 68 insertions(+), 75 deletions(-) (limited to 'eval') diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.cpp b/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.cpp index 8c704c61415..d6d0a1abf4a 100644 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.cpp +++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.cpp @@ -9,9 +9,8 @@ namespace vespalib::tensor { DenseTensorAddressCombiner::~DenseTensorAddressCombiner() = default; DenseTensorAddressCombiner::DenseTensorAddressCombiner(const eval::ValueType &combined, const eval::ValueType &lhs, - const eval::ValueType &rhs, CellsRef rhsCells) - : _rightAddress(rhs, rhsCells), - _combinedAddress(combined), + const eval::ValueType &rhs) + : _combinedAddress(combined), _left(), _commonRight(), _right() @@ -39,7 +38,7 @@ DenseTensorAddressCombiner::DenseTensorAddressCombiner(const eval::ValueType &co } } -DenseTensorAddressCombiner::AddressContext::AddressContext(const eval::ValueType &type) +AddressContext::AddressContext(const eval::ValueType &type) : _type(type), _accumulatedSize(_type.dimensions().size()), _address(type.dimensions().size(), 0) @@ -52,7 +51,7 @@ DenseTensorAddressCombiner::AddressContext::AddressContext(const eval::ValueType } } -DenseTensorAddressCombiner::AddressContext::~AddressContext() = default; +AddressContext::~AddressContext() = default; eval::ValueType DenseTensorAddressCombiner::combineDimensions(const eval::ValueType &lhs, const eval::ValueType &rhs) diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h b/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h index 0d4fa794f38..eea523045e9 100644 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h +++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h @@ -9,6 +9,42 @@ namespace vespalib::tensor { +class AddressContext { +public: + using Address = DenseTensorCellsIterator::Address; + using size_type = eval::ValueType::Dimension::size_type; + using Mapping = std::vector>; + AddressContext(const eval::ValueType &type); + ~AddressContext(); + size_type dimSize(uint32_t dim) const { return _type.dimensions()[dim].size; } + size_type wholeDimStep(uint32_t dim) const { return _accumulatedSize[dim] * dimSize(dim); } + size_t index() const { + size_t cellIdx(0); + for (uint32_t i(0); i < _address.size(); i++) { + cellIdx += _address[i]*_accumulatedSize[i]; + } + return cellIdx; + } + void update(const Address & addr, const Mapping & mapping) { + for (const auto & m : mapping) { + _address[m.first] = addr[m.second]; + } + } + bool updateCommon(const Address & addr, const Mapping & mapping) { + for (const auto & m : mapping) { + if (addr[m.first] >= dimSize(m.second)) { + return false; + } + _address[m.second] = addr[m.first]; + } + return true; + } + + const eval::ValueType &_type; + std::vector _accumulatedSize; + Address _address; + +}; /** * Combines two dense tensor addresses to a new tensor address. @@ -18,48 +54,13 @@ namespace vespalib::tensor { class DenseTensorAddressCombiner { public: - using Mapping = std::vector>; + using Mapping = AddressContext::Mapping; private: using Address = DenseTensorCellsIterator::Address; using CellsRef = vespalib::ConstArrayRef; using size_type = eval::ValueType::Dimension::size_type; - class AddressContext { - public: - AddressContext(const eval::ValueType &type); - ~AddressContext(); - size_type dimSize(uint32_t dim) const { return _type.dimensions()[dim].size; } - size_type wholeDimStep(uint32_t dim) const { return _accumulatedSize[dim] * dimSize(dim); } - size_t index() const { - size_t cellIdx(0); - for (uint32_t i(0); i < _address.size(); i++) { - cellIdx += _address[i]*_accumulatedSize[i]; - } - return cellIdx; - } - void update(const Address & addr, const Mapping & mapping) { - for (const auto & m : mapping) { - _address[m.first] = addr[m.second]; - } - } - - const eval::ValueType &_type; - std::vector _accumulatedSize; - Address _address; - - }; - class CellAddressContext : public AddressContext { - public: - CellAddressContext(const eval::ValueType &type, CellsRef cells) : AddressContext(type), _cells(cells) { } - double cell() const { return cell(index()); } - double cell(size_t cellIdx) const { return _cells[cellIdx]; } - private: - CellsRef _cells; - }; - - - CellAddressContext _rightAddress; AddressContext _combinedAddress; Mapping _left; @@ -67,54 +68,43 @@ private: Mapping _right; public: - DenseTensorAddressCombiner(const eval::ValueType &combined, const eval::ValueType &lhs, - const eval::ValueType &rhs, CellsRef rhsCells); + DenseTensorAddressCombiner(const eval::ValueType &combined, const eval::ValueType &lhs, const eval::ValueType &rhs); ~DenseTensorAddressCombiner(); void updateLeftAndCommon(const Address & addr) { _combinedAddress.update(addr, _left); } bool hasAnyRightOnlyDimensions() const { return ! _right.empty(); } - const Address &address() const { return _combinedAddress._address; } - - bool updateCommonRight() { - for (const auto & m : _commonRight) { - if (_combinedAddress._address[m.first] >= _rightAddress.dimSize(m.second)) { - return false; - } - _rightAddress._address[m.second] = _combinedAddress._address[m.first]; - } - return true; - } - double rightCell() { return _rightAddress.cell(); } + const Address & address() const { return _combinedAddress._address; } + const Mapping & commonRight() const { return _commonRight; } template - void for_each(Func && func) { + void for_each(const AddressContext & rightAddress, const CellsRef & rhsCells, Func && func) { const int32_t lastDimension = _right.size() - 1; int32_t curDimension = lastDimension; - size_t rightCellIdx = _rightAddress.index(); + size_t rightCellIdx = rightAddress.index(); size_t combinedCellIdx = _combinedAddress.index(); while (curDimension >= 0) { const uint32_t rdim = _right[curDimension].second; const uint32_t cdim = _right[curDimension].first; size_type & cindex = _combinedAddress._address[cdim]; if (curDimension == lastDimension) { - for (cindex = 0; cindex < _rightAddress.dimSize(rdim); cindex++) { - func(combinedCellIdx, _rightAddress.cell(rightCellIdx)); - rightCellIdx += _rightAddress._accumulatedSize[rdim]; + for (cindex = 0; cindex < rightAddress.dimSize(rdim); cindex++) { + func(combinedCellIdx, rhsCells[rightCellIdx]); + rightCellIdx += rightAddress._accumulatedSize[rdim]; combinedCellIdx += _combinedAddress._accumulatedSize[cdim]; } cindex = 0; - rightCellIdx -= _rightAddress.wholeDimStep(rdim); + rightCellIdx -= rightAddress.wholeDimStep(rdim); combinedCellIdx -= _combinedAddress.wholeDimStep(cdim); curDimension--; } else { - if (cindex < _rightAddress.dimSize(rdim)) { + if (cindex < rightAddress.dimSize(rdim)) { cindex++; - rightCellIdx += _rightAddress._accumulatedSize[rdim]; + rightCellIdx += rightAddress._accumulatedSize[rdim]; combinedCellIdx += _combinedAddress._accumulatedSize[cdim]; curDimension++; } else { - rightCellIdx -= _rightAddress.wholeDimStep(rdim); + rightCellIdx -= rightAddress.wholeDimStep(rdim); combinedCellIdx -= _combinedAddress.wholeDimStep(cdim); cindex = 0; curDimension--; diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_apply.hpp b/eval/src/vespa/eval/tensor/dense/dense_tensor_apply.hpp index 868a49627c8..f61dbd05def 100644 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_apply.hpp +++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_apply.hpp @@ -11,17 +11,18 @@ namespace vespalib::tensor::dense { template std::unique_ptr apply(DenseTensorAddressCombiner & combiner, DirectDenseTensorBuilder & builder, - const DenseTensorView &lhs, Function &&func) __attribute__((noinline)); + const DenseTensorView &lhs, AddressContext & rhsAddr, const DenseTensorView::CellsRef & rhsCells, + Function &&func) __attribute__((noinline)); template std::unique_ptr apply(DenseTensorAddressCombiner & combiner, DirectDenseTensorBuilder & builder, - const DenseTensorView &lhs, Function &&func) + const DenseTensorView &lhs, AddressContext & rhsAddr, const DenseTensorView::CellsRef & rhsCells, Function &&func) { for (DenseTensorCellsIterator lhsItr = lhs.cellsIterator(); lhsItr.valid(); lhsItr.next()) { combiner.updateLeftAndCommon(lhsItr.address()); - if (combiner.updateCommonRight()) { - combiner.for_each([&func, &builder, &lhsItr](size_t combined, double rhsCell) { + if (rhsAddr.updateCommon(combiner.address(), combiner.commonRight())) { + combiner.for_each(rhsAddr, rhsCells, [&func, &builder, &lhsItr](size_t combined, double rhsCell) { builder.insertCell(combined, func(lhsItr.cell(), rhsCell)); }); } @@ -33,17 +34,19 @@ apply(DenseTensorAddressCombiner & combiner, DirectDenseTensorBuilder & builder, template std::unique_ptr apply_no_rightonly_dimensions(DenseTensorAddressCombiner & combiner, DirectDenseTensorBuilder & builder, - const DenseTensorView &lhs, Function &&func) __attribute__((noinline)); + const DenseTensorView &lhs, AddressContext & rhsAddr, + const DenseTensorView::CellsRef & rhsCells, Function &&func) __attribute__((noinline)); template std::unique_ptr apply_no_rightonly_dimensions(DenseTensorAddressCombiner & combiner, DirectDenseTensorBuilder & builder, - const DenseTensorView &lhs, Function &&func) + const DenseTensorView &lhs, AddressContext & rhsAddr, + const DenseTensorView::CellsRef & rhsCells, Function &&func) { for (DenseTensorCellsIterator lhsItr = lhs.cellsIterator(); lhsItr.valid(); lhsItr.next()) { combiner.updateLeftAndCommon(lhsItr.address()); - if (combiner.updateCommonRight()) { - builder.insertCell(combiner.address(), func(lhsItr.cell(), combiner.rightCell())); + if (rhsAddr.updateCommon(combiner.address(), combiner.commonRight())) { + builder.insertCell(combiner.address(), func(lhsItr.cell(), rhsCells[rhsAddr.index()])); } } return builder.build(); @@ -54,12 +57,13 @@ std::unique_ptr apply(const DenseTensorView &lhs, const DenseTensorView &rhs, Function &&func) { eval::ValueType resultType = DenseTensorAddressCombiner::combineDimensions(lhs.fast_type(), rhs.fast_type()); - DenseTensorAddressCombiner combiner(resultType, lhs.fast_type(), rhs.fast_type(), rhs.cellsRef()); + DenseTensorAddressCombiner combiner(resultType, lhs.fast_type(), rhs.fast_type()); DirectDenseTensorBuilder builder(resultType); + AddressContext rhsAddress(rhs.fast_type()); if (combiner.hasAnyRightOnlyDimensions()) { - return apply(combiner, builder, lhs, std::move(func)); + return apply(combiner, builder, lhs, rhsAddress, rhs.cellsRef(), std::move(func)); } else { - return apply_no_rightonly_dimensions(combiner, builder, lhs, std::move(func)); + return apply_no_rightonly_dimensions(combiner, builder, lhs, rhsAddress, rhs.cellsRef(), std::move(func)); } } -- cgit v1.2.3 From 522e31627fb1ef6948433830941d9fe99e5826c9 Mon Sep 17 00:00:00 2001 From: Henning Baldersheim Date: Wed, 10 Jan 2018 16:19:07 +0100 Subject: Add comment explaining a bit about the right address. --- eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'eval') diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h b/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h index eea523045e9..af7c545b3fd 100644 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h +++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h @@ -79,6 +79,8 @@ public: template void for_each(const AddressContext & rightAddress, const CellsRef & rhsCells, Func && func) { + // The rightAddress oly holds the starting point for iteration and what is need to efficiently maintain + // an index for addressing th ecells. const int32_t lastDimension = _right.size() - 1; int32_t curDimension = lastDimension; size_t rightCellIdx = rightAddress.index(); -- cgit v1.2.3 From 328c64a519ce00d301f1404b907afe663abbe11a Mon Sep 17 00:00:00 2001 From: Henning Baldersheim Date: Wed, 10 Jan 2018 20:41:56 +0100 Subject: Put the address back in the combiner. --- .../tensor/dense/dense_tensor_address_combiner.cpp | 3 ++- .../tensor/dense/dense_tensor_address_combiner.h | 21 +++++++++--------- .../vespa/eval/tensor/dense/dense_tensor_apply.hpp | 25 ++++++++++------------ 3 files changed, 24 insertions(+), 25 deletions(-) (limited to 'eval') diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.cpp b/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.cpp index d6d0a1abf4a..df6ac162d7f 100644 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.cpp +++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.cpp @@ -10,7 +10,8 @@ DenseTensorAddressCombiner::~DenseTensorAddressCombiner() = default; DenseTensorAddressCombiner::DenseTensorAddressCombiner(const eval::ValueType &combined, const eval::ValueType &lhs, const eval::ValueType &rhs) - : _combinedAddress(combined), + : _rightAddress(rhs), + _combinedAddress(combined), _left(), _commonRight(), _right() diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h b/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h index af7c545b3fd..325242bbd9b 100644 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h +++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h @@ -61,6 +61,7 @@ private: using CellsRef = vespalib::ConstArrayRef; using size_type = eval::ValueType::Dimension::size_type; + AddressContext _rightAddress; AddressContext _combinedAddress; Mapping _left; @@ -71,42 +72,42 @@ public: DenseTensorAddressCombiner(const eval::ValueType &combined, const eval::ValueType &lhs, const eval::ValueType &rhs); ~DenseTensorAddressCombiner(); void updateLeftAndCommon(const Address & addr) { _combinedAddress.update(addr, _left); } - + bool updateCommon() { return _rightAddress.updateCommon(_combinedAddress._address, _commonRight); } bool hasAnyRightOnlyDimensions() const { return ! _right.empty(); } const Address & address() const { return _combinedAddress._address; } - const Mapping & commonRight() const { return _commonRight; } + size_t rightCellIndex() const { return _rightAddress.index(); } template - void for_each(const AddressContext & rightAddress, const CellsRef & rhsCells, Func && func) { + void for_each_right(const CellsRef & rhsCells, Func && func) { // The rightAddress oly holds the starting point for iteration and what is need to efficiently maintain // an index for addressing th ecells. const int32_t lastDimension = _right.size() - 1; int32_t curDimension = lastDimension; - size_t rightCellIdx = rightAddress.index(); + size_t rightCellIdx = _rightAddress.index(); size_t combinedCellIdx = _combinedAddress.index(); while (curDimension >= 0) { const uint32_t rdim = _right[curDimension].second; const uint32_t cdim = _right[curDimension].first; size_type & cindex = _combinedAddress._address[cdim]; if (curDimension == lastDimension) { - for (cindex = 0; cindex < rightAddress.dimSize(rdim); cindex++) { + for (cindex = 0; cindex < _rightAddress.dimSize(rdim); cindex++) { func(combinedCellIdx, rhsCells[rightCellIdx]); - rightCellIdx += rightAddress._accumulatedSize[rdim]; + rightCellIdx += _rightAddress._accumulatedSize[rdim]; combinedCellIdx += _combinedAddress._accumulatedSize[cdim]; } cindex = 0; - rightCellIdx -= rightAddress.wholeDimStep(rdim); + rightCellIdx -= _rightAddress.wholeDimStep(rdim); combinedCellIdx -= _combinedAddress.wholeDimStep(cdim); curDimension--; } else { - if (cindex < rightAddress.dimSize(rdim)) { + if (cindex < _rightAddress.dimSize(rdim)) { cindex++; - rightCellIdx += rightAddress._accumulatedSize[rdim]; + rightCellIdx += _rightAddress._accumulatedSize[rdim]; combinedCellIdx += _combinedAddress._accumulatedSize[cdim]; curDimension++; } else { - rightCellIdx -= rightAddress.wholeDimStep(rdim); + rightCellIdx -= _rightAddress.wholeDimStep(rdim); combinedCellIdx -= _combinedAddress.wholeDimStep(cdim); cindex = 0; curDimension--; diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_apply.hpp b/eval/src/vespa/eval/tensor/dense/dense_tensor_apply.hpp index f61dbd05def..25478510587 100644 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_apply.hpp +++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_apply.hpp @@ -11,18 +11,17 @@ namespace vespalib::tensor::dense { template std::unique_ptr apply(DenseTensorAddressCombiner & combiner, DirectDenseTensorBuilder & builder, - const DenseTensorView &lhs, AddressContext & rhsAddr, const DenseTensorView::CellsRef & rhsCells, - Function &&func) __attribute__((noinline)); + const DenseTensorView &lhs, const DenseTensorView::CellsRef & rhsCells, Function &&func) __attribute__((noinline)); template std::unique_ptr apply(DenseTensorAddressCombiner & combiner, DirectDenseTensorBuilder & builder, - const DenseTensorView &lhs, AddressContext & rhsAddr, const DenseTensorView::CellsRef & rhsCells, Function &&func) + const DenseTensorView &lhs, const DenseTensorView::CellsRef & rhsCells, Function &&func) { for (DenseTensorCellsIterator lhsItr = lhs.cellsIterator(); lhsItr.valid(); lhsItr.next()) { combiner.updateLeftAndCommon(lhsItr.address()); - if (rhsAddr.updateCommon(combiner.address(), combiner.commonRight())) { - combiner.for_each(rhsAddr, rhsCells, [&func, &builder, &lhsItr](size_t combined, double rhsCell) { + if (combiner.updateCommon()) { + combiner.for_each_right(rhsCells, [&func, &builder, &lhsItr](size_t combined, double rhsCell) { builder.insertCell(combined, func(lhsItr.cell(), rhsCell)); }); } @@ -34,19 +33,18 @@ apply(DenseTensorAddressCombiner & combiner, DirectDenseTensorBuilder & builder, template std::unique_ptr apply_no_rightonly_dimensions(DenseTensorAddressCombiner & combiner, DirectDenseTensorBuilder & builder, - const DenseTensorView &lhs, AddressContext & rhsAddr, - const DenseTensorView::CellsRef & rhsCells, Function &&func) __attribute__((noinline)); + const DenseTensorView &lhs, const DenseTensorView::CellsRef & rhsCells, + Function &&func) __attribute__((noinline)); template std::unique_ptr apply_no_rightonly_dimensions(DenseTensorAddressCombiner & combiner, DirectDenseTensorBuilder & builder, - const DenseTensorView &lhs, AddressContext & rhsAddr, - const DenseTensorView::CellsRef & rhsCells, Function &&func) + const DenseTensorView &lhs, const DenseTensorView::CellsRef & rhsCells, Function &&func) { for (DenseTensorCellsIterator lhsItr = lhs.cellsIterator(); lhsItr.valid(); lhsItr.next()) { combiner.updateLeftAndCommon(lhsItr.address()); - if (rhsAddr.updateCommon(combiner.address(), combiner.commonRight())) { - builder.insertCell(combiner.address(), func(lhsItr.cell(), rhsCells[rhsAddr.index()])); + if (combiner.updateCommon()) { + builder.insertCell(combiner.address(), func(lhsItr.cell(), rhsCells[combiner.rightCellIndex()])); } } return builder.build(); @@ -59,11 +57,10 @@ apply(const DenseTensorView &lhs, const DenseTensorView &rhs, Function &&func) eval::ValueType resultType = DenseTensorAddressCombiner::combineDimensions(lhs.fast_type(), rhs.fast_type()); DenseTensorAddressCombiner combiner(resultType, lhs.fast_type(), rhs.fast_type()); DirectDenseTensorBuilder builder(resultType); - AddressContext rhsAddress(rhs.fast_type()); if (combiner.hasAnyRightOnlyDimensions()) { - return apply(combiner, builder, lhs, rhsAddress, rhs.cellsRef(), std::move(func)); + return apply(combiner, builder, lhs, rhs.cellsRef(), std::move(func)); } else { - return apply_no_rightonly_dimensions(combiner, builder, lhs, rhsAddress, rhs.cellsRef(), std::move(func)); + return apply_no_rightonly_dimensions(combiner, builder, lhs, rhs.cellsRef(), std::move(func)); } } -- cgit v1.2.3