diff options
author | Arne Juul <arnej@yahoo-inc.com> | 2019-06-27 08:48:33 +0000 |
---|---|---|
committer | Arne Juul <arnej@yahoo-inc.com> | 2019-07-04 11:49:32 +0000 |
commit | 5a993bc1a9272281e41ca220ee117d0f8d3081d8 (patch) | |
tree | f466bc6ec9e203a12973cfcb66cef49171f0fb75 /searchlib | |
parent | eb95248e0f4e89e59e8af64efdcfc0388529b832 (diff) |
add TypedCells and related functionality
* templated DenseTensor
* templated DenseTensorModify
* add templated TypedDenseTensorBuilder
* remove DirectDenseTensorBuilder
* remove unused TensorMapper
* add dispatch structs
* add unit test for generic dense join
* add special handling of reducing all dimensions
Diffstat (limited to 'searchlib')
4 files changed, 27 insertions, 22 deletions
diff --git a/searchlib/src/tests/attribute/tensorattribute/tensorattribute_test.cpp b/searchlib/src/tests/attribute/tensorattribute/tensorattribute_test.cpp index e0ec4a6fd06..7e0fcdc0ccc 100644 --- a/searchlib/src/tests/attribute/tensorattribute/tensorattribute_test.cpp +++ b/searchlib/src/tests/attribute/tensorattribute/tensorattribute_test.cpp @@ -44,7 +44,7 @@ vespalib::string denseSpec("tensor(x[2],y[3])"); Tensor::UP createTensor(const TensorSpec &spec) { auto value = DefaultTensorEngine::ref().from_spec(spec); if (value->is_double()) { - return Tensor::UP(new DenseTensor(ValueType::double_type(), {value->as_double()})); + return Tensor::UP(new DenseTensor<double>(ValueType::double_type(), {value->as_double()})); } Tensor *tensor = dynamic_cast<Tensor*>(value.get()); ASSERT_TRUE(tensor != nullptr); diff --git a/searchlib/src/tests/features/imported_dot_product/imported_dot_product_test.cpp b/searchlib/src/tests/features/imported_dot_product/imported_dot_product_test.cpp index 6ef680e0505..b7fb3d2b6a1 100644 --- a/searchlib/src/tests/features/imported_dot_product/imported_dot_product_test.cpp +++ b/searchlib/src/tests/features/imported_dot_product/imported_dot_product_test.cpp @@ -197,25 +197,25 @@ TEST_F("prepareSharedState emits double vector for double imported attribute", A TEST_F("prepareSharedState handles tensor as float from tensor for double imported attribute", ArrayFixture) { f.setup_float_mappings(BasicType::DOUBLE); - vespalib::tensor::DenseTensor tensor(vespalib::eval::ValueType::from_spec("tensor<float>(x[3])"), {10.1, 20.2, 30.3}); + vespalib::tensor::DenseTensor<float> tensor(vespalib::eval::ValueType::from_spec("tensor<float>(x[3])"), {10.1, 20.2, 30.3}); f.template check_prepare_state_output(tensor, dotproduct::ArrayParam<double>({10.1, 20.2, 30.3})); } TEST_F("prepareSharedState handles tensor as double from tensor for double imported attribute", ArrayFixture) { f.setup_float_mappings(BasicType::DOUBLE); - vespalib::tensor::DenseTensor tensor(vespalib::eval::ValueType::from_spec("tensor(x[3])"), {10.1, 20.2, 30.3}); + vespalib::tensor::DenseTensor<double> tensor(vespalib::eval::ValueType::from_spec("tensor(x[3])"), {10.1, 20.2, 30.3}); f.template check_prepare_state_output(tensor, dotproduct::ArrayParam<double>({10.1, 20.2, 30.3})); } TEST_F("prepareSharedState handles tensor as float from tensor for float imported attribute", ArrayFixture) { f.setup_float_mappings(BasicType::FLOAT); - vespalib::tensor::DenseTensor tensor(vespalib::eval::ValueType::from_spec("tensor<float>(x[3])"), {10.1, 20.2, 30.3}); + vespalib::tensor::DenseTensor<float> tensor(vespalib::eval::ValueType::from_spec("tensor<float>(x[3])"), {10.1, 20.2, 30.3}); f.template check_prepare_state_output(tensor, dotproduct::ArrayParam<float>({10.1, 20.2, 30.3})); } TEST_F("prepareSharedState handles tensor as double from tensor for float imported attribute", ArrayFixture) { f.setup_float_mappings(BasicType::FLOAT); - vespalib::tensor::DenseTensor tensor(vespalib::eval::ValueType::from_spec("tensor(x[3])"), {10.1, 20.2, 30.3}); + vespalib::tensor::DenseTensor<double> tensor(vespalib::eval::ValueType::from_spec("tensor(x[3])"), {10.1, 20.2, 30.3}); f.template check_prepare_state_output(tensor, dotproduct::ArrayParam<float>({10.1, 20.2, 30.3})); } diff --git a/searchlib/src/vespa/searchlib/tensor/dense_tensor_store.cpp b/searchlib/src/vespa/searchlib/tensor/dense_tensor_store.cpp index 205c686df81..f741002ea5e 100644 --- a/searchlib/src/vespa/searchlib/tensor/dense_tensor_store.cpp +++ b/searchlib/src/vespa/searchlib/tensor/dense_tensor_store.cpp @@ -10,7 +10,6 @@ using search::datastore::Handle; using vespalib::tensor::Tensor; -using vespalib::tensor::DenseTensor; using vespalib::tensor::DenseTensorView; using vespalib::tensor::MutableDenseTensorView; using vespalib::eval::ValueType; @@ -41,8 +40,7 @@ DenseTensorStore::TensorSizeCalc::TensorSizeCalc(const ValueType &type) size_t DenseTensorStore::TensorSizeCalc::arraySize() const { - size_t tensorSize = _numBoundCells * _cellSize + - _numUnboundDims * sizeof(uint32_t); + size_t tensorSize = (_numBoundCells * _cellSize) + (_numUnboundDims * sizeof(uint32_t)); return DenseTensorStore::BufferType::align(tensorSize, DENSE_TENSOR_ALIGNMENT); } @@ -185,16 +183,16 @@ void makeConcreteType(MutableDenseTensorView &tensor, std::unique_ptr<Tensor> DenseTensorStore::getTensor(EntryRef ref) const { - using CellsRef = DenseTensorView::CellsRef; if (!ref.valid()) { return std::unique_ptr<Tensor>(); } auto raw = getRawBuffer(ref); size_t numCells = getNumCells(raw); + vespalib::tensor::TypedCells cells_ref(raw, _type.cell_type(), numCells); if (_tensorSizeCalc._numUnboundDims == 0) { - return std::make_unique<DenseTensorView>(_type, CellsRef(static_cast<const double *>(raw), numCells)); + return std::make_unique<DenseTensorView>(_type, cells_ref); } else { - auto result = std::make_unique<MutableDenseTensorView>(_type, CellsRef(static_cast<const double *>(raw), numCells)); + auto result = std::make_unique<MutableDenseTensorView>(_type, cells_ref); makeConcreteType(*result, raw, _tensorSizeCalc._numUnboundDims); return result; } @@ -204,14 +202,16 @@ void DenseTensorStore::getTensor(EntryRef ref, MutableDenseTensorView &tensor) const { if (!ref.valid()) { - tensor.setCells(DenseTensorView::CellsRef(&_emptyCells[0], _emptyCells.size())); + vespalib::tensor::TypedCells cells_ref(&_emptyCells[0], _type.cell_type(), _emptyCells.size()); + tensor.setCells(cells_ref); if (_tensorSizeCalc._numUnboundDims > 0) { tensor.setUnboundDimensionsForEmptyTensor(); } } else { auto raw = getRawBuffer(ref); size_t numCells = getNumCells(raw); - tensor.setCells(DenseTensorView::CellsRef(static_cast<const double *>(raw), numCells)); + vespalib::tensor::TypedCells cells_ref(raw, _type.cell_type(), numCells); + tensor.setCells(cells_ref); if (_tensorSizeCalc._numUnboundDims > 0) { makeConcreteType(tensor, raw, _tensorSizeCalc._numUnboundDims); } @@ -268,11 +268,11 @@ template <class TensorType> TensorStore::EntryRef DenseTensorStore::setDenseTensor(const TensorType &tensor) { - size_t numCells = tensor.cellsRef().size(); + size_t numCells = tensor.cellsRef().size; checkMatchingType(_type, tensor.type(), numCells); auto raw = allocRawBuffer(numCells); setDenseTensorUnboundDimSizes(raw.data, _type, _tensorSizeCalc._numUnboundDims, tensor.type()); - memcpy(raw.data, &tensor.cellsRef()[0], numCells * _tensorSizeCalc._cellSize); + memcpy(raw.data, tensor.cellsRef().data, numCells * _tensorSizeCalc._cellSize); return raw.ref; } diff --git a/searchlib/src/vespa/searchlib/tensor/tensor_attribute.cpp b/searchlib/src/vespa/searchlib/tensor/tensor_attribute.cpp index 79b02b09cba..7dd666ac74f 100644 --- a/searchlib/src/vespa/searchlib/tensor/tensor_attribute.cpp +++ b/searchlib/src/vespa/searchlib/tensor/tensor_attribute.cpp @@ -4,7 +4,7 @@ #include <vespa/document/base/exceptions.h> #include <vespa/document/datatype/tensor_data_type.h> #include <vespa/eval/eval/simple_tensor.h> -#include <vespa/eval/tensor/dense/dense_tensor.h> +#include <vespa/eval/tensor/dense/typed_dense_tensor_builder.h> #include <vespa/eval/tensor/sparse/sparse_tensor.h> #include <vespa/eval/tensor/wrapped_simple_tensor.h> #include <vespa/vespalib/util/rcuvector.hpp> @@ -12,7 +12,8 @@ using vespalib::eval::SimpleTensor; using vespalib::eval::ValueType; using vespalib::tensor::Tensor; -using vespalib::tensor::DenseTensor; +using vespalib::tensor::TypedDenseTensorBuilder; +using vespalib::tensor::dispatch_0; using vespalib::tensor::SparseTensor; using vespalib::tensor::WrappedSimpleTensor; using document::TensorDataType; @@ -44,17 +45,21 @@ createEmptyTensorType(const ValueType &type) return ValueType::tensor_type(std::move(list)); } +struct CallMakeEmptyTensor { + template <typename CT> + static Tensor::UP call(const ValueType &type) { + TypedDenseTensorBuilder<CT> builder(type); + return builder.build(); + } +}; + Tensor::UP createEmptyTensor(const ValueType &type) { if (type.is_sparse()) { return std::make_unique<SparseTensor>(type, SparseTensor::Cells()); } else if (type.is_dense()) { - size_t size = 1; - for (const auto &dimension : type.dimensions()) { - size *= dimension.size; - } - return std::make_unique<DenseTensor>(type, DenseTensor::Cells(size)); + return dispatch_0<CallMakeEmptyTensor>(type.cell_type(), type); } else { return std::make_unique<WrappedSimpleTensor>(std::make_unique<SimpleTensor>(type, SimpleTensor::Cells())); } |