summaryrefslogtreecommitdiffstats
path: root/searchlib
diff options
context:
space:
mode:
authorArne Juul <arnej@yahoo-inc.com>2019-06-27 08:48:33 +0000
committerArne Juul <arnej@yahoo-inc.com>2019-07-04 11:49:32 +0000
commit5a993bc1a9272281e41ca220ee117d0f8d3081d8 (patch)
treef466bc6ec9e203a12973cfcb66cef49171f0fb75 /searchlib
parenteb95248e0f4e89e59e8af64efdcfc0388529b832 (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')
-rw-r--r--searchlib/src/tests/attribute/tensorattribute/tensorattribute_test.cpp2
-rw-r--r--searchlib/src/tests/features/imported_dot_product/imported_dot_product_test.cpp8
-rw-r--r--searchlib/src/vespa/searchlib/tensor/dense_tensor_store.cpp20
-rw-r--r--searchlib/src/vespa/searchlib/tensor/tensor_attribute.cpp19
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()));
}