summaryrefslogtreecommitdiffstats
path: root/eval
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2018-01-10 15:58:37 +0100
committerHenning Baldersheim <balder@yahoo-inc.com>2018-01-10 15:58:37 +0100
commitb839058fe6ae1efcd786f670e57c4c9b84a375ab (patch)
tree31e59c084b3f11a495b7b3a476921263453abd94 /eval
parente7acdd2c4fe3fbb1d0e99a64a7a1ca462886b04a (diff)
Move the right address context on the outside.
Diffstat (limited to 'eval')
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.cpp9
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_tensor_address_combiner.h108
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_tensor_apply.hpp26
3 files changed, 68 insertions, 75 deletions
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<std::pair<uint32_t, uint32_t>>;
+ 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<size_t> _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<std::pair<uint32_t, uint32_t>>;
+ using Mapping = AddressContext::Mapping;
private:
using Address = DenseTensorCellsIterator::Address;
using CellsRef = vespalib::ConstArrayRef<double>;
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<size_t> _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 <typename Func>
- 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 <typename Function>
std::unique_ptr<Tensor>
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 <typename Function>
std::unique_ptr<Tensor>
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 <typename Function>
std::unique_ptr<Tensor>
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 <typename Function>
std::unique_ptr<Tensor>
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<Tensor>
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));
}
}