diff options
9 files changed, 0 insertions, 481 deletions
diff --git a/eval/CMakeLists.txt b/eval/CMakeLists.txt index d6e6b1211b6..f01faa1362f 100644 --- a/eval/CMakeLists.txt +++ b/eval/CMakeLists.txt @@ -33,7 +33,6 @@ vespa_define_module( src/tests/tensor/dense_remove_dimension_optimizer src/tests/tensor/dense_replace_type_function src/tests/tensor/dense_tensor_address_combiner - src/tests/tensor/dense_tensor_builder src/tests/tensor/dense_xw_product_function src/tests/tensor/direct_dense_tensor_builder src/tests/tensor/sparse_tensor_builder diff --git a/eval/src/tests/tensor/dense_dot_product_function/dense_dot_product_function_test.cpp b/eval/src/tests/tensor/dense_dot_product_function/dense_dot_product_function_test.cpp index b5a1cac6d0f..d970b9dad30 100644 --- a/eval/src/tests/tensor/dense_dot_product_function/dense_dot_product_function_test.cpp +++ b/eval/src/tests/tensor/dense_dot_product_function/dense_dot_product_function_test.cpp @@ -5,7 +5,6 @@ #include <vespa/eval/tensor/default_tensor_engine.h> #include <vespa/eval/tensor/dense/dense_dot_product_function.h> #include <vespa/eval/tensor/dense/dense_tensor.h> -#include <vespa/eval/tensor/dense/dense_tensor_builder.h> #include <vespa/eval/tensor/dense/dense_tensor_view.h> #include <vespa/eval/eval/test/tensor_model.hpp> #include <vespa/eval/eval/test/eval_fixture.h> diff --git a/eval/src/tests/tensor/dense_tensor_builder/.gitignore b/eval/src/tests/tensor/dense_tensor_builder/.gitignore deleted file mode 100644 index 5b3598a205d..00000000000 --- a/eval/src/tests/tensor/dense_tensor_builder/.gitignore +++ /dev/null @@ -1 +0,0 @@ -vespalib_dense_tensor_builder_test_app diff --git a/eval/src/tests/tensor/dense_tensor_builder/CMakeLists.txt b/eval/src/tests/tensor/dense_tensor_builder/CMakeLists.txt deleted file mode 100644 index 7a746aa8345..00000000000 --- a/eval/src/tests/tensor/dense_tensor_builder/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -vespa_add_executable(eval_dense_tensor_builder_test_app TEST - SOURCES - dense_tensor_builder_test.cpp - DEPENDS - vespaeval -) -vespa_add_test(NAME eval_dense_tensor_builder_test_app COMMAND eval_dense_tensor_builder_test_app) diff --git a/eval/src/tests/tensor/dense_tensor_builder/dense_tensor_builder_test.cpp b/eval/src/tests/tensor/dense_tensor_builder/dense_tensor_builder_test.cpp deleted file mode 100644 index a0aeb6b63c9..00000000000 --- a/eval/src/tests/tensor/dense_tensor_builder/dense_tensor_builder_test.cpp +++ /dev/null @@ -1,261 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include <vespa/vespalib/test/insertion_operators.h> -#include <vespa/vespalib/testkit/test_kit.h> -#include <vespa/eval/tensor/dense/dense_tensor_builder.h> -#include <vespa/vespalib/util/exceptions.h> - -using namespace vespalib::tensor; -using vespalib::IllegalArgumentException; -using Builder = DenseTensorBuilder; -using vespalib::eval::TensorSpec; -using vespalib::eval::ValueType; -using vespalib::ConstArrayRef; - -template <typename T> std::vector<T> make_vector(const ConstArrayRef<T> &ref) { - std::vector<T> vec; - for (const T &t: ref) { - vec.push_back(t); - } - return vec; -} - -void -assertTensor(const std::vector<ValueType::Dimension> &expDims, - const DenseTensor::Cells &expCells, - const Tensor &tensor) -{ - const DenseTensor &realTensor = dynamic_cast<const DenseTensor &>(tensor); - EXPECT_EQUAL(ValueType::tensor_type(expDims), realTensor.type()); - EXPECT_EQUAL(expCells, make_vector(realTensor.cellsRef())); -} - -void -assertTensorSpec(const TensorSpec &expSpec, const Tensor &tensor) -{ - TensorSpec actSpec = tensor.toSpec(); - EXPECT_EQUAL(expSpec, actSpec); -} - -struct Fixture -{ - Builder builder; - Fixture() : builder() {} -}; - -Tensor::UP -build1DTensor(Builder &builder) -{ - Builder::Dimension dimX = builder.defineDimension("x", 3); - builder.addLabel(dimX, 0).addCell(10). - addLabel(dimX, 1).addCell(11). - addLabel(dimX, 2).addCell(12); - return builder.build(); -} - -TEST_F("require that 1d tensor can be constructed", Fixture) -{ - assertTensor({{"x",3}}, {10,11,12}, *build1DTensor(f.builder)); -} - -TEST_F("require that 1d tensor can be converted to tensor spec", Fixture) -{ - assertTensorSpec(TensorSpec("tensor(x[3])"). - add({{"x", 0}}, 10). - add({{"x", 1}}, 11). - add({{"x", 2}}, 12), - *build1DTensor(f.builder)); -} - -Tensor::UP -build2DTensor(Builder &builder) -{ - Builder::Dimension dimX = builder.defineDimension("x", 3); - Builder::Dimension dimY = builder.defineDimension("y", 2); - builder.addLabel(dimX, 0).addLabel(dimY, 0).addCell(10). - addLabel(dimX, 0).addLabel(dimY, 1).addCell(11). - addLabel(dimX, 1).addLabel(dimY, 0).addCell(12). - addLabel(dimX, 1).addLabel(dimY, 1).addCell(13). - addLabel(dimX, 2).addLabel(dimY, 0).addCell(14). - addLabel(dimX, 2).addLabel(dimY, 1).addCell(15); - return builder.build(); -} - -TEST_F("require that 2d tensor can be constructed", Fixture) -{ - assertTensor({{"x",3},{"y",2}}, {10,11,12,13,14,15}, *build2DTensor(f.builder)); -} - -TEST_F("require that 2d tensor can be converted to tensor spec", Fixture) -{ - assertTensorSpec(TensorSpec("tensor(x[3],y[2])"). - add({{"x", 0},{"y", 0}}, 10). - add({{"x", 0},{"y", 1}}, 11). - add({{"x", 1},{"y", 0}}, 12). - add({{"x", 1},{"y", 1}}, 13). - add({{"x", 2},{"y", 0}}, 14). - add({{"x", 2},{"y", 1}}, 15), - *build2DTensor(f.builder)); -} - -TEST_F("require that 3d tensor can be constructed", Fixture) -{ - Builder::Dimension dimX = f.builder.defineDimension("x", 3); - Builder::Dimension dimY = f.builder.defineDimension("y", 2); - Builder::Dimension dimZ = f.builder.defineDimension("z", 2); - f.builder.addLabel(dimX, 0).addLabel(dimY, 0).addLabel(dimZ, 0).addCell(10). - addLabel(dimX, 0).addLabel(dimY, 0).addLabel(dimZ, 1).addCell(11). - addLabel(dimX, 0).addLabel(dimY, 1).addLabel(dimZ, 0).addCell(12). - addLabel(dimX, 0).addLabel(dimY, 1).addLabel(dimZ, 1).addCell(13). - addLabel(dimX, 1).addLabel(dimY, 0).addLabel(dimZ, 0).addCell(14). - addLabel(dimX, 1).addLabel(dimY, 0).addLabel(dimZ, 1).addCell(15). - addLabel(dimX, 1).addLabel(dimY, 1).addLabel(dimZ, 0).addCell(16). - addLabel(dimX, 1).addLabel(dimY, 1).addLabel(dimZ, 1).addCell(17). - addLabel(dimX, 2).addLabel(dimY, 0).addLabel(dimZ, 0).addCell(18). - addLabel(dimX, 2).addLabel(dimY, 0).addLabel(dimZ, 1).addCell(19). - addLabel(dimX, 2).addLabel(dimY, 1).addLabel(dimZ, 0).addCell(20). - addLabel(dimX, 2).addLabel(dimY, 1).addLabel(dimZ, 1).addCell(21); - assertTensor({{"x",3},{"y",2},{"z",2}}, - {10,11,12,13,14,15,16,17,18,19,20,21}, - *f.builder.build()); -} - -TEST_F("require that cells get default value 0 if not specified", Fixture) -{ - Builder::Dimension dimX = f.builder.defineDimension("x", 3); - f.builder.addLabel(dimX, 1).addCell(11); - assertTensor({{"x",3}}, {0,11,0}, - *f.builder.build()); -} - -TEST_F("require that labels can be added in arbitrarily order", Fixture) -{ - Builder::Dimension dimX = f.builder.defineDimension("x", 2); - Builder::Dimension dimY = f.builder.defineDimension("y", 3); - f.builder.addLabel(dimY, 0).addLabel(dimX, 1).addCell(10); - assertTensor({{"x",2},{"y",3}}, {0,0,0,10,0,0}, - *f.builder.build()); -} - -TEST_F("require that builder can be re-used", Fixture) -{ - { - Builder::Dimension dimX = f.builder.defineDimension("x", 2); - f.builder.addLabel(dimX, 0).addCell(10). - addLabel(dimX, 1).addCell(11); - assertTensor({{"x",2}}, {10,11}, - *f.builder.build()); - } - { - Builder::Dimension dimY = f.builder.defineDimension("y", 3); - f.builder.addLabel(dimY, 0).addCell(20). - addLabel(dimY, 1).addCell(21). - addLabel(dimY, 2).addCell(22); - assertTensor({{"y",3}}, {20,21,22}, - *f.builder.build()); - } -} - -void -assertTensorCell(const DenseTensor::Address &expAddress, - double expCell, - const DenseTensor::CellsIterator &itr) -{ - EXPECT_TRUE(itr.valid()); - EXPECT_EQUAL(expAddress, itr.address()); - EXPECT_EQUAL(expCell, itr.cell()); -} - -TEST_F("require that dense tensor cells iterator works for 1d tensor", Fixture) -{ - Tensor::UP tensor; - { - Builder::Dimension dimX = f.builder.defineDimension("x", 2); - f.builder.addLabel(dimX, 0).addCell(2). - addLabel(dimX, 1).addCell(3); - tensor = f.builder.build(); - } - - const DenseTensor &denseTensor = dynamic_cast<const DenseTensor &>(*tensor); - DenseTensor::CellsIterator itr = denseTensor.cellsIterator(); - - assertTensorCell({0}, 2, itr); - itr.next(); - assertTensorCell({1}, 3, itr); - itr.next(); - EXPECT_FALSE(itr.valid()); -} - -TEST_F("require that dense tensor cells iterator works for 2d tensor", Fixture) -{ - Tensor::UP tensor; - { - Builder::Dimension dimX = f.builder.defineDimension("x", 2); - Builder::Dimension dimY = f.builder.defineDimension("y", 2); - f.builder.addLabel(dimX, 0).addLabel(dimY, 0).addCell(2). - addLabel(dimX, 0).addLabel(dimY, 1).addCell(3). - addLabel(dimX, 1).addLabel(dimY, 0).addCell(5). - addLabel(dimX, 1).addLabel(dimY, 1).addCell(7); - tensor = f.builder.build(); - } - - const DenseTensor &denseTensor = dynamic_cast<const DenseTensor &>(*tensor); - DenseTensor::CellsIterator itr = denseTensor.cellsIterator(); - - assertTensorCell({0,0}, 2, itr); - itr.next(); - assertTensorCell({0,1}, 3, itr); - itr.next(); - assertTensorCell({1,0}, 5, itr); - itr.next(); - assertTensorCell({1,1}, 7, itr); - itr.next(); - EXPECT_FALSE(itr.valid()); -} - -TEST_F("require that undefined label for a dimension throws exception", Fixture) -{ - Builder::Dimension dimX = f.builder.defineDimension("x", 2); - f.builder.defineDimension("y", 3); - EXPECT_EXCEPTION(f.builder.addLabel(dimX, 0).addCell(10), - IllegalArgumentException, - "Label for dimension 'y' is undefined. Expected a value in the range [0, 3>"); -} - -TEST_F("require that label outside range throws exception", Fixture) -{ - Builder::Dimension dimX = f.builder.defineDimension("x", 2); - EXPECT_EXCEPTION(f.builder.addLabel(dimX, 2).addCell(10), - IllegalArgumentException, - "Label '2' for dimension 'x' is outside range [0, 2>"); -} - -TEST_F("require that already specified label throws exception", Fixture) -{ - Builder::Dimension dimX = f.builder.defineDimension("x", 2); - EXPECT_EXCEPTION(f.builder.addLabel(dimX, 0).addLabel(dimX, 1).addCell(10), - IllegalArgumentException, - "Label for dimension 'x' is already specified with value '0'"); -} - -TEST_F("require that dimensions are sorted", Fixture) -{ - Builder::Dimension dimY = f.builder.defineDimension("y", 3); - Builder::Dimension dimX = f.builder.defineDimension("x", 5); - f.builder.addLabel(dimX, 0).addLabel(dimY, 0).addCell(10); - f.builder.addLabel(dimX, 0).addLabel(dimY, 1).addCell(11); - f.builder.addLabel(dimX, 1).addLabel(dimY, 0).addCell(12); - std::unique_ptr<Tensor> tensor = f.builder.build(); - const DenseTensor &denseTensor = dynamic_cast<const DenseTensor &>(*tensor); - assertTensor({{"x", 5}, {"y", 3}}, - {10, 11, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - denseTensor); - EXPECT_EQUAL("tensor(x[5],y[3])", denseTensor.type().to_spec()); -} - - - - - - -TEST_MAIN() { TEST_RUN_ALL(); } diff --git a/eval/src/tests/tensor/dense_xw_product_function/dense_xw_product_function_test.cpp b/eval/src/tests/tensor/dense_xw_product_function/dense_xw_product_function_test.cpp index 5c976073732..8045958d9ba 100644 --- a/eval/src/tests/tensor/dense_xw_product_function/dense_xw_product_function_test.cpp +++ b/eval/src/tests/tensor/dense_xw_product_function/dense_xw_product_function_test.cpp @@ -11,7 +11,6 @@ LOG_SETUP("dense_dot_product_function_test"); #include <vespa/eval/tensor/default_tensor_engine.h> #include <vespa/eval/tensor/dense/dense_xw_product_function.h> #include <vespa/eval/tensor/dense/dense_tensor.h> -#include <vespa/eval/tensor/dense/dense_tensor_builder.h> #include <vespa/eval/tensor/dense/dense_tensor_view.h> #include <vespa/eval/eval/test/tensor_model.hpp> #include <vespa/eval/eval/test/eval_fixture.h> diff --git a/eval/src/vespa/eval/tensor/dense/CMakeLists.txt b/eval/src/vespa/eval/tensor/dense/CMakeLists.txt index 9d54dd26763..c2638466de6 100644 --- a/eval/src/vespa/eval/tensor/dense/CMakeLists.txt +++ b/eval/src/vespa/eval/tensor/dense/CMakeLists.txt @@ -11,7 +11,6 @@ vespa_add_library(eval_tensor_dense OBJECT dense_tensor.cpp dense_tensor_address_combiner.cpp dense_tensor_address_mapper.cpp - dense_tensor_builder.cpp dense_tensor_cells_iterator.cpp dense_tensor_modify.cpp dense_tensor_reduce.cpp diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_builder.cpp b/eval/src/vespa/eval/tensor/dense/dense_tensor_builder.cpp deleted file mode 100644 index cd4738cf1ee..00000000000 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_builder.cpp +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "dense_tensor_builder.h" -#include <vespa/vespalib/util/exceptions.h> -#include <cassert> -#include <limits> -#include <algorithm> - -using vespalib::IllegalArgumentException; -using vespalib::make_string; - -namespace vespalib::tensor { - -namespace { - -constexpr size_t UNDEFINED_LABEL = std::numeric_limits<size_t>::max(); - -void -validateLabelInRange(size_t label, size_t dimensionSize, const vespalib::string &dimension) -{ - if (label >= dimensionSize) { - throw IllegalArgumentException(make_string( - "Label '%zu' for dimension '%s' is outside range [0, %zu>", - label, dimension.c_str(), dimensionSize)); - } -} - -void -validateLabelNotSpecified(size_t oldLabel, const vespalib::string &dimension) -{ - if (oldLabel != UNDEFINED_LABEL) { - throw IllegalArgumentException(make_string( - "Label for dimension '%s' is already specified with value '%zu'", - dimension.c_str(), oldLabel)); - } -} - -eval::ValueType -makeValueType(std::vector<eval::ValueType::Dimension> &&dimensions) { - return (dimensions.empty() ? - eval::ValueType::double_type() : - eval::ValueType::tensor_type(std::move(dimensions))); -} - -} - -void -DenseTensorBuilder::allocateCellsStorage() -{ - size_t cellsSize = 1; - for (const auto &dimension : _dimensions) { - cellsSize *= dimension.size; - } - _cells.resize(cellsSize, 0); -} - - -void -DenseTensorBuilder::sortDimensions() -{ - std::sort(_dimensions.begin(), _dimensions.end(), - [](const eval::ValueType::Dimension &lhs, - const eval::ValueType::Dimension &rhs) - { return lhs.name < rhs.name; }); - _dimensionsMapping.resize(_dimensions.size()); - Dimension dim = 0; - for (const auto &dimension : _dimensions) { - auto itr = _dimensionsEnum.find(dimension.name); - assert(itr != _dimensionsEnum.end()); - _dimensionsMapping[itr->second] = dim; - ++dim; - } -} - -size_t -DenseTensorBuilder::calculateCellAddress() -{ - size_t result = 0; - size_t multiplier = 1; - for (int64_t i = (_addressBuilder.size() - 1); i >= 0; --i) { - const size_t label = _addressBuilder[i]; - const auto &dim = _dimensions[i]; - if (label == UNDEFINED_LABEL) { - throw IllegalArgumentException(make_string("Label for dimension '%s' is undefined. " - "Expected a value in the range [0, %u>", dim.name.c_str(), dim.size)); - } - result += (label * multiplier); - multiplier *= dim.size; - _addressBuilder[i] = UNDEFINED_LABEL; - } - return result; -} - -DenseTensorBuilder::DenseTensorBuilder() - : _dimensionsEnum(), - _dimensions(), - _cells(), - _addressBuilder(), - _dimensionsMapping() -{ -} - -DenseTensorBuilder::~DenseTensorBuilder() = default; - -DenseTensorBuilder::Dimension -DenseTensorBuilder::defineDimension(const vespalib::string &dimension, size_t dimensionSize) -{ - auto itr = _dimensionsEnum.find(dimension); - if (itr != _dimensionsEnum.end()) { - return itr->second; - } - assert(_cells.empty()); - Dimension result = _dimensionsEnum.size(); - _dimensionsEnum.insert(std::make_pair(dimension, result)); - _dimensions.emplace_back(dimension, dimensionSize); - _addressBuilder.push_back(UNDEFINED_LABEL); - assert(_dimensions.size() == (result + 1)); - assert(_addressBuilder.size() == (result + 1)); - return result; -} - -DenseTensorBuilder & -DenseTensorBuilder::addLabel(Dimension dimension, size_t label) -{ - if (_cells.empty()) { - sortDimensions(); - allocateCellsStorage(); - } - assert(dimension < _dimensions.size()); - assert(dimension < _addressBuilder.size()); - Dimension mappedDimension = _dimensionsMapping[dimension]; - const auto &dim = _dimensions[mappedDimension]; - validateLabelInRange(label, dim.size, dim.name); - validateLabelNotSpecified(_addressBuilder[mappedDimension], dim.name); - _addressBuilder[mappedDimension] = label; - return *this; -} - -DenseTensorBuilder & -DenseTensorBuilder::addCell(double value) -{ - if (_cells.empty()) { - sortDimensions(); - allocateCellsStorage(); - } - size_t cellAddress = calculateCellAddress(); - assert(cellAddress < _cells.size()); - _cells[cellAddress] = value; - return *this; -} - -std::unique_ptr<DenseTensor> -DenseTensorBuilder::build() -{ - if (_cells.empty()) { - allocateCellsStorage(); - } - auto result = std::make_unique<DenseTensor>(makeValueType(std::move(_dimensions)), std::move(_cells)); - _dimensionsEnum.clear(); - _dimensions.clear(); - DenseTensor::Cells().swap(_cells); - _addressBuilder.clear(); - _dimensionsMapping.clear(); - return result; -} - -} diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_builder.h b/eval/src/vespa/eval/tensor/dense/dense_tensor_builder.h deleted file mode 100644 index 377cf7bbb8e..00000000000 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_builder.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include "dense_tensor.h" -#include <vespa/vespalib/stllike/hash_map.h> -#include <vespa/eval/tensor/sparse/sparse_tensor_builder.h> - -namespace vespalib::tensor { - -/** - * A builder of for dense tensors. - */ -class DenseTensorBuilder -{ -public: - using Dimension = SparseTensorBuilder::Dimension; -private: - vespalib::hash_map<vespalib::string, size_t> _dimensionsEnum; - std::vector<eval::ValueType::Dimension> _dimensions; - DenseTensor::Cells _cells; - std::vector<size_t> _addressBuilder; - std::vector<Dimension> _dimensionsMapping; - - void allocateCellsStorage(); - void sortDimensions(); - size_t calculateCellAddress(); - -public: - DenseTensorBuilder(); - ~DenseTensorBuilder(); - - Dimension defineDimension(const vespalib::string &dimension, size_t dimensionSize); - DenseTensorBuilder &addLabel(Dimension dimension, size_t label); - DenseTensorBuilder &addCell(double value); - std::unique_ptr<DenseTensor> build(); -}; - -} - |