diff options
4 files changed, 70 insertions, 49 deletions
diff --git a/eval/src/vespa/eval/tensor/dense/CMakeLists.txt b/eval/src/vespa/eval/tensor/dense/CMakeLists.txt index 54698371f4e..97343ffd380 100644 --- a/eval/src/vespa/eval/tensor/dense/CMakeLists.txt +++ b/eval/src/vespa/eval/tensor/dense/CMakeLists.txt @@ -10,5 +10,6 @@ vespa_add_library(eval_tensor_dense OBJECT dense_tensor_cells_iterator.cpp dense_tensor_function_compiler.cpp dense_tensor_view.cpp + dense_tensor_reduce.cpp mutable_dense_tensor_view.cpp ) diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_reduce.cpp b/eval/src/vespa/eval/tensor/dense/dense_tensor_reduce.cpp new file mode 100644 index 00000000000..e178a4c77dd --- /dev/null +++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_reduce.cpp @@ -0,0 +1,54 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "dense_tensor_reduce.hpp" + +namespace vespalib::tensor::dense { + +namespace { + +size_t +calcCellsSize(const eval::ValueType &type) +{ + size_t cellsSize = 1; + for (const auto &dim : type.dimensions()) { + cellsSize *= dim.size; + } + return cellsSize; +} + +} +DimensionReducer::DimensionReducer(const eval::ValueType &oldType, + const string &dimensionToRemove) + : _type(oldType.reduce({ dimensionToRemove })), + _cellsResult(calcCellsSize(_type)), + _innerDimSize(1), + _sumDimSize(1), + _outerDimSize(1) +{ + setup(oldType, dimensionToRemove); +} + +DimensionReducer::~DimensionReducer() = default; + +void +DimensionReducer::setup(const eval::ValueType &oldType, const vespalib::string &dimensionToRemove) +{ + auto itr = std::lower_bound(oldType.dimensions().cbegin(), + oldType.dimensions().cend(), + dimensionToRemove, + [](const auto &dim, const auto &dimension) + { return dim.name < dimension; }); + if ((itr != oldType.dimensions().end()) && (itr->name == dimensionToRemove)) { + for (auto outerItr = oldType.dimensions().cbegin(); outerItr != itr; ++outerItr) { + _outerDimSize *= outerItr->size; + } + _sumDimSize = itr->size; + for (++itr; itr != oldType.dimensions().cend(); ++itr) { + _innerDimSize *= itr->size; + } + } else { + _outerDimSize = calcCellsSize(oldType); + } +} + +}
\ No newline at end of file diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_reduce.hpp b/eval/src/vespa/eval/tensor/dense/dense_tensor_reduce.hpp index 9f608921c05..8480e7418e1 100644 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_reduce.hpp +++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_reduce.hpp @@ -9,19 +9,6 @@ namespace vespalib::tensor::dense { using Cells = DenseTensorView::Cells; using CellsRef = DenseTensorView::CellsRef; -namespace { - -size_t -calcCellsSize(const eval::ValueType &type) -{ - size_t cellsSize = 1; - for (const auto &dim : type.dimensions()) { - cellsSize *= dim.size; - } - return cellsSize; -} - - class DimensionReducer { private: @@ -31,37 +18,11 @@ private: size_t _sumDimSize; size_t _outerDimSize; - void setup(const eval::ValueType &oldType, - const vespalib::string &dimensionToRemove) { - auto itr = std::lower_bound(oldType.dimensions().cbegin(), - oldType.dimensions().cend(), - dimensionToRemove, - [](const auto &dim, const auto &dimension) - { return dim.name < dimension; }); - if ((itr != oldType.dimensions().end()) && (itr->name == dimensionToRemove)) { - for (auto outerItr = oldType.dimensions().cbegin(); outerItr != itr; ++outerItr) { - _outerDimSize *= outerItr->size; - } - _sumDimSize = itr->size; - for (++itr; itr != oldType.dimensions().cend(); ++itr) { - _innerDimSize *= itr->size; - } - } else { - _outerDimSize = calcCellsSize(oldType); - } - } + void setup(const eval::ValueType &oldType, const vespalib::string &dimensionToRemove); public: - DimensionReducer(const eval::ValueType &oldType, - const string &dimensionToRemove) - : _type(oldType.reduce({ dimensionToRemove })), - _cellsResult(calcCellsSize(_type)), - _innerDimSize(1), - _sumDimSize(1), - _outerDimSize(1) - { - setup(oldType, dimensionToRemove); - } + DimensionReducer(const eval::ValueType &oldType, const string &dimensionToRemove); + ~DimensionReducer(); template <typename Function> DenseTensor::UP @@ -90,6 +51,8 @@ public: } }; +namespace { + template <typename Function> DenseTensor::UP reduce(const DenseTensorView &tensor, const vespalib::string &dimensionToRemove, Function &&func) @@ -109,8 +72,7 @@ reduce(const DenseTensorView &tensor, const std::vector<vespalib::string> &dimen } else if (dimensions.size() > 0) { DenseTensor::UP result = reduce(tensor, dimensions[0], func); for (size_t i = 1; i < dimensions.size(); ++i) { - DenseTensor::UP tmpResult = reduce(DenseTensorView(*result), - dimensions[i], func); + DenseTensor::UP tmpResult = reduce(DenseTensorView(*result), dimensions[i], func); result = std::move(tmpResult); } return result; diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_view.cpp b/eval/src/vespa/eval/tensor/dense/dense_tensor_view.cpp index 749dc3dea7d..80e24e6e2bb 100644 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_view.cpp +++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_view.cpp @@ -261,12 +261,16 @@ DenseTensorView::join(join_fun_t function, const Tensor &arg) const } Tensor::UP -DenseTensorView::reduce(join_fun_t op, - const std::vector<vespalib::string> &dimensions) const +DenseTensorView::reduce(join_fun_t op, const std::vector<vespalib::string> &dimensions) const { - return dense::reduce(*this, - (dimensions.empty() ? _typeRef.dimension_names() : dimensions), - op); + const std::vector<vespalib::string> & dims = (dimensions.empty() ? _typeRef.dimension_names() : dimensions); + if (op == eval::operation::Mul::f) { + return dense::reduce(*this, dims, [](double a, double b) { return (a * b);}); + } + if (op == eval::operation::Add::f) { + return dense::reduce(*this, dims, [](double a, double b) { return (a + b);}); + } + return dense::reduce(*this, dims, op); } } |