diff options
84 files changed, 584 insertions, 552 deletions
diff --git a/document/src/tests/documentupdatetestcase.cpp b/document/src/tests/documentupdatetestcase.cpp index 9d2567e93ed..ca519a2f7d0 100644 --- a/document/src/tests/documentupdatetestcase.cpp +++ b/document/src/tests/documentupdatetestcase.cpp @@ -21,8 +21,9 @@ #include <vespa/document/update/tensor_remove_update.h> #include <vespa/document/update/valueupdate.h> #include <vespa/document/util/bytebuffer.h> -#include <vespa/eval/tensor/default_tensor_engine.h> -#include <vespa/eval/tensor/tensor.h> +#include <vespa/eval/eval/engine_or_factory.h> +#include <vespa/eval/eval/value.h> +#include <vespa/eval/eval/test/value_compare.h> #include <vespa/vespalib/objects/nbostream.h> #include <vespa/vespalib/util/exception.h> #include <vespa/vespalib/util/exceptions.h> @@ -33,10 +34,10 @@ #include <unistd.h> using namespace document::config_builder; + using vespalib::eval::TensorSpec; using vespalib::eval::ValueType; -using vespalib::tensor::DefaultTensorEngine; -using vespalib::tensor::Tensor; +using vespalib::eval::EngineOrFactory; using vespalib::nbostream; namespace document { @@ -771,11 +772,12 @@ TEST(DocumentUpdateTest, testMapValueUpdate) EXPECT_EQ(fv4->find(StringFieldValue("apple")), fv4->end()); } -std::unique_ptr<Tensor> +std::unique_ptr<vespalib::eval::Value> makeTensor(const TensorSpec &spec) { - auto result = DefaultTensorEngine::ref().from_spec(spec); - return std::unique_ptr<Tensor>(dynamic_cast<Tensor*>(result.release())); + auto result = EngineOrFactory::get().from_spec(spec); + EXPECT_TRUE(result->is_tensor()); + return result; } std::unique_ptr<TensorFieldValue> @@ -787,7 +789,7 @@ makeTensorFieldValue(const TensorSpec &spec, const TensorDataType &dataType) return result; } -const Tensor &asTensor(const FieldValue &fieldValue) { +const vespalib::eval::Value &asTensor(const FieldValue &fieldValue) { auto &tensorFieldValue = dynamic_cast<const TensorFieldValue &>(fieldValue); auto tensor = tensorFieldValue.getAsTensorPtr(); assert(tensor); diff --git a/document/src/tests/serialization/vespadocumentserializer_test.cpp b/document/src/tests/serialization/vespadocumentserializer_test.cpp index 02f170cd5f1..13d5e7d8405 100644 --- a/document/src/tests/serialization/vespadocumentserializer_test.cpp +++ b/document/src/tests/serialization/vespadocumentserializer_test.cpp @@ -36,8 +36,9 @@ #include <vespa/document/serialization/vespadocumentdeserializer.h> #include <vespa/document/serialization/vespadocumentserializer.h> #include <vespa/document/serialization/annotationserializer.h> -#include <vespa/eval/tensor/tensor.h> -#include <vespa/eval/tensor/default_tensor_engine.h> +#include <vespa/eval/eval/engine_or_factory.h> +#include <vespa/eval/eval/value.h> +#include <vespa/eval/eval/test/value_compare.h> #include <vespa/vespalib/io/fileutil.h> #include <vespa/vespalib/objects/nbostream.h> #include <vespa/vespalib/testkit/testapp.h> @@ -50,8 +51,7 @@ using vespalib::nbostream; using vespalib::nbostream_longlivedbuf; using vespalib::slime::Cursor; using vespalib::eval::TensorSpec; -using vespalib::tensor::Tensor; -using vespalib::tensor::DefaultTensorEngine; +using vespalib::eval::EngineOrFactory; using vespalib::compression::CompressionConfig; using namespace document; using std::string; @@ -771,12 +771,10 @@ TEST("Require that predicate deserialization matches Java") { namespace { -Tensor::UP createTensor(const TensorSpec &spec) { - auto value = DefaultTensorEngine::ref().from_spec(spec); - Tensor *tensor = dynamic_cast<Tensor*>(value.get()); - ASSERT_TRUE(tensor != nullptr); - value.release(); - return Tensor::UP(tensor); +vespalib::eval::Value::UP createTensor(const TensorSpec &spec) { + auto value = EngineOrFactory::get().from_spec(spec); + ASSERT_TRUE(value->is_tensor()); + return value; } } @@ -836,13 +834,13 @@ void deserializeAndCheck(const string &file_name, TensorFieldValue &value) { deserializeAndCheck(file_name, value, tensor_repo, tensor_field_name); } -void checkDeserialization(const string &name, std::unique_ptr<Tensor> tensor) { +void checkDeserialization(const string &name, std::unique_ptr<vespalib::eval::Value> tensor) { const string data_dir = TEST_PATH("../../test/resources/tensor/"); TensorDataType valueType(tensor ? tensor->type() : vespalib::eval::ValueType::error_type()); TensorFieldValue value(valueType); if (tensor) { - value = tensor->clone(); + value = EngineOrFactory::get().copy(*tensor); } serializeToFile(value, data_dir + name + "__cpp"); deserializeAndCheck(data_dir + name + "__cpp", value); @@ -851,7 +849,7 @@ void checkDeserialization(const string &name, std::unique_ptr<Tensor> tensor) { TEST("Require that tensor deserialization matches Java") { - checkDeserialization("non_existing_tensor", std::unique_ptr<Tensor>()); + checkDeserialization("non_existing_tensor", std::unique_ptr<vespalib::eval::Value>()); checkDeserialization("empty_tensor", createTensor(TensorSpec("tensor(dimX{},dimY{})"))); checkDeserialization("multi_cell_tensor", createTensor(TensorSpec("tensor(dimX{},dimY{})") @@ -863,17 +861,17 @@ TEST("Require that tensor deserialization matches Java") { struct TensorDocFixture { const DocumentTypeRepo &_docTypeRepo; const DocumentType *_docType; - std::unique_ptr<Tensor> _tensor; + std::unique_ptr<vespalib::eval::Value> _tensor; Document _doc; vespalib::nbostream _blob; TensorDocFixture(const DocumentTypeRepo &docTypeRepo, - std::unique_ptr<Tensor> tensor); + std::unique_ptr<vespalib::eval::Value> tensor); ~TensorDocFixture(); }; TensorDocFixture::TensorDocFixture(const DocumentTypeRepo &docTypeRepo, - std::unique_ptr<Tensor> tensor) + std::unique_ptr<vespalib::eval::Value> tensor) : _docTypeRepo(docTypeRepo), _docType(_docTypeRepo.getDocumentType(tensor_doc_type_id)), _tensor(std::move(tensor)), @@ -881,7 +879,7 @@ TensorDocFixture::TensorDocFixture(const DocumentTypeRepo &docTypeRepo, _blob() { auto fv = _doc.getField(tensor_field_name).createValue(); - dynamic_cast<TensorFieldValue &>(*fv) = _tensor->clone(); + dynamic_cast<TensorFieldValue &>(*fv) = EngineOrFactory::get().copy(*_tensor); _doc.setValue(tensor_field_name, *fv); _doc.serialize(_blob); } @@ -897,7 +895,7 @@ struct DeserializedTensorDoc ~DeserializedTensorDoc(); void setup(const DocumentTypeRepo &docTypeRepo, const vespalib::nbostream &blob); - const Tensor *getTensor() const; + const vespalib::eval::Value *getTensor() const; }; DeserializedTensorDoc::DeserializedTensorDoc() @@ -916,7 +914,7 @@ DeserializedTensorDoc::setup(const DocumentTypeRepo &docTypeRepo, const vespalib _fieldValue = _doc->getValue(tensor_field_name); } -const Tensor * +const vespalib::eval::Value * DeserializedTensorDoc::getTensor() const { return dynamic_cast<const TensorFieldValue &>(*_fieldValue).getAsTensorPtr(); @@ -936,14 +934,14 @@ TEST("Require that wrong tensor type hides tensor") DeserializedTensorDoc doc; doc.setup(tensor_doc_repo, f._blob); EXPECT_TRUE(doc.getTensor() != nullptr); - EXPECT_TRUE(doc.getTensor()->equals(*f._tensor)); + EXPECT_TRUE((*doc.getTensor()) == (*f._tensor)); doc.setup(tensor_doc_repo, f1._blob); EXPECT_TRUE(doc.getTensor() == nullptr); doc.setup(tensor_doc_repo1, f._blob); EXPECT_TRUE(doc.getTensor() == nullptr); doc.setup(tensor_doc_repo1, f1._blob); EXPECT_TRUE(doc.getTensor() != nullptr); - EXPECT_TRUE(doc.getTensor()->equals(*f1._tensor)); + EXPECT_TRUE((*doc.getTensor()) == (*f1._tensor)); } struct RefFixture { diff --git a/document/src/tests/tensor_fieldvalue/tensor_fieldvalue_test.cpp b/document/src/tests/tensor_fieldvalue/tensor_fieldvalue_test.cpp index 9d2da9c983a..18afdb15bb8 100644 --- a/document/src/tests/tensor_fieldvalue/tensor_fieldvalue_test.cpp +++ b/document/src/tests/tensor_fieldvalue/tensor_fieldvalue_test.cpp @@ -7,9 +7,8 @@ LOG_SETUP("fieldvalue_test"); #include <vespa/document/base/exceptions.h> #include <vespa/document/datatype/tensor_data_type.h> #include <vespa/document/fieldvalue/tensorfieldvalue.h> -#include <vespa/eval/tensor/tensor.h> -#include <vespa/eval/tensor/types.h> -#include <vespa/eval/tensor/default_tensor_engine.h> +#include <vespa/eval/eval/engine_or_factory.h> +#include <vespa/eval/eval/value.h> #include <vespa/eval/tensor/test/test_utils.h> #include <vespa/vespalib/testkit/testapp.h> @@ -18,7 +17,7 @@ using namespace document; using namespace vespalib::tensor; using vespalib::eval::TensorSpec; using vespalib::eval::ValueType; -using vespalib::tensor::DefaultTensorEngine; +using vespalib::eval::EngineOrFactory; using vespalib::tensor::test::makeTensor; namespace @@ -27,19 +26,17 @@ namespace TensorDataType xSparseTensorDataType(ValueType::from_spec("tensor(x{})")); TensorDataType xySparseTensorDataType(ValueType::from_spec("tensor(x{},y{})")); -Tensor::UP createTensor(const TensorSpec &spec) { - auto value = DefaultTensorEngine::ref().from_spec(spec); - Tensor *tensor = dynamic_cast<Tensor*>(value.get()); - ASSERT_TRUE(tensor != nullptr); - value.release(); - return Tensor::UP(tensor); +vespalib::eval::Value::UP createTensor(const TensorSpec &spec) { + auto value = EngineOrFactory::get().from_spec(spec); + ASSERT_TRUE(value->is_tensor()); + return value; } -std::unique_ptr<Tensor> +std::unique_ptr<vespalib::eval::Value> makeSimpleTensor() { - return makeTensor<Tensor>(TensorSpec("tensor(x{},y{})"). - add({{"x", "4"}, {"y", "5"}}, 7)); + return makeTensor<vespalib::eval::Value>(TensorSpec("tensor(x{},y{})"). + add({{"x", "4"}, {"y", "5"}}, 7)); } FieldValue::UP clone(FieldValue &fv) { diff --git a/document/src/vespa/document/fieldvalue/tensorfieldvalue.cpp b/document/src/vespa/document/fieldvalue/tensorfieldvalue.cpp index c3b593732b9..2a66ea61966 100644 --- a/document/src/vespa/document/fieldvalue/tensorfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/tensorfieldvalue.cpp @@ -6,16 +6,14 @@ #include <vespa/vespalib/util/xmlstream.h> #include <vespa/eval/eval/engine_or_factory.h> #include <vespa/eval/eval/tensor_spec.h> -#include <vespa/eval/tensor/tensor.h> -#include <vespa/eval/tensor/default_tensor_engine.h> +#include <vespa/eval/eval/value.h> +#include <vespa/eval/eval/engine_or_factory.h> #include <ostream> #include <cassert> -using vespalib::tensor::Tensor; using vespalib::eval::EngineOrFactory; using vespalib::eval::TensorSpec; using vespalib::eval::ValueType; -using Engine = vespalib::tensor::DefaultTensorEngine; using namespace vespalib::xml; namespace document { @@ -53,7 +51,7 @@ TensorFieldValue::TensorFieldValue(const TensorFieldValue &rhs) _altered(true) { if (rhs._tensor) { - _tensor = rhs._tensor->clone(); + _tensor = EngineOrFactory::get().copy(*rhs._tensor); } } @@ -80,7 +78,7 @@ TensorFieldValue::operator=(const TensorFieldValue &rhs) if (&_dataType == &rhs._dataType || !rhs._tensor || _dataType.isAssignableType(rhs._tensor->type())) { if (rhs._tensor) { - _tensor = rhs._tensor->clone(); + _tensor = EngineOrFactory::get().copy(*rhs._tensor); } else { _tensor.reset(); } @@ -94,7 +92,7 @@ TensorFieldValue::operator=(const TensorFieldValue &rhs) TensorFieldValue & -TensorFieldValue::operator=(std::unique_ptr<Tensor> rhs) +TensorFieldValue::operator=(std::unique_ptr<vespalib::eval::Value> rhs) { if (!rhs || _dataType.isAssignableType(rhs->type())) { _tensor = std::move(rhs); @@ -111,11 +109,7 @@ TensorFieldValue::make_empty_if_not_existing() { if (!_tensor) { TensorSpec empty_spec(_dataType.getTensorType().to_spec()); - auto empty_value = Engine::ref().from_spec(empty_spec); - auto tensor_ptr = dynamic_cast<Tensor*>(empty_value.get()); - assert(tensor_ptr != nullptr); - _tensor.reset(tensor_ptr); - empty_value.release(); + _tensor = EngineOrFactory::get().from_spec(empty_spec); } } @@ -163,7 +157,7 @@ TensorFieldValue::print(std::ostream& out, bool verbose, (void) indent; out << "{TensorFieldValue: "; if (_tensor) { - out << Engine::ref().to_spec(*_tensor).to_string(); + out << EngineOrFactory::get().to_spec(*_tensor).to_string(); } else { out << "null"; } @@ -192,7 +186,7 @@ TensorFieldValue::assign(const FieldValue &value) void -TensorFieldValue::assignDeserialized(std::unique_ptr<Tensor> rhs) +TensorFieldValue::assignDeserialized(std::unique_ptr<vespalib::eval::Value> rhs) { if (!rhs || _dataType.isAssignableType(rhs->type())) { _tensor = std::move(rhs); diff --git a/document/src/vespa/document/fieldvalue/tensorfieldvalue.h b/document/src/vespa/document/fieldvalue/tensorfieldvalue.h index 30cc10558b5..82a10e8aaa6 100644 --- a/document/src/vespa/document/fieldvalue/tensorfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/tensorfieldvalue.h @@ -5,6 +5,7 @@ #include "fieldvalue.h" namespace vespalib { namespace tensor { class Tensor; } } +namespace vespalib::eval { class Value; } namespace document { @@ -16,7 +17,7 @@ class TensorDataType; class TensorFieldValue : public FieldValue { private: const TensorDataType &_dataType; - std::unique_ptr<vespalib::tensor::Tensor> _tensor; + std::unique_ptr<vespalib::eval::Value> _tensor; bool _altered; public: TensorFieldValue(); @@ -26,7 +27,7 @@ public: ~TensorFieldValue(); TensorFieldValue &operator=(const TensorFieldValue &rhs); - TensorFieldValue &operator=(std::unique_ptr<vespalib::tensor::Tensor> rhs); + TensorFieldValue &operator=(std::unique_ptr<vespalib::eval::Value> rhs); void make_empty_if_not_existing(); @@ -39,10 +40,10 @@ public: const std::string& indent) const override; virtual void printXml(XmlOutputStream& out) const override; virtual FieldValue &assign(const FieldValue &value) override; - const vespalib::tensor::Tensor *getAsTensorPtr() const { + const vespalib::eval::Value *getAsTensorPtr() const { return _tensor.get(); } - void assignDeserialized(std::unique_ptr<vespalib::tensor::Tensor> rhs); + void assignDeserialized(std::unique_ptr<vespalib::eval::Value> rhs); virtual int compare(const FieldValue& other) const override; DECLARE_IDENTIFIABLE(TensorFieldValue); diff --git a/document/src/vespa/document/serialization/vespadocumentdeserializer.cpp b/document/src/vespa/document/serialization/vespadocumentdeserializer.cpp index 94644438f5c..6ec9c52281f 100644 --- a/document/src/vespa/document/serialization/vespadocumentdeserializer.cpp +++ b/document/src/vespa/document/serialization/vespadocumentdeserializer.cpp @@ -22,8 +22,8 @@ #include <vespa/vespalib/data/slime/slime.h> #include <vespa/vespalib/stllike/asciistream.h> #include <vespa/vespalib/util/backtrace.h> -#include <vespa/eval/tensor/tensor.h> -#include <vespa/eval/tensor/serialization/typed_binary_format.h> +#include <vespa/eval/eval/engine_or_factory.h> +#include <vespa/eval/eval/value.h> #include <vespa/document/util/serializableexceptions.h> #include <vespa/document/base/exceptions.h> #include <vespa/vespalib/objects/nbostream.h> @@ -41,6 +41,7 @@ using vespalib::nbostream; using vespalib::Memory; using vespalib::stringref; using vespalib::compression::CompressionConfig; +using vespalib::eval::EngineOrFactory; namespace document { @@ -363,10 +364,10 @@ VespaDocumentDeserializer::read(TensorFieldValue &value) throw DeserializeException(vespalib::make_string("Stream failed size(%zu), needed(%zu) to deserialize tensor field value", _stream.size(), length), VESPA_STRLOC); } - std::unique_ptr<vespalib::tensor::Tensor> tensor; + std::unique_ptr<vespalib::eval::Value> tensor; if (length != 0) { nbostream wrapStream(_stream.peek(), length); - tensor = vespalib::tensor::TypedBinaryFormat::deserialize(wrapStream); + tensor = EngineOrFactory::get().decode(wrapStream); if (wrapStream.size() != 0) { throw DeserializeException("Leftover bytes deserializing tensor field value.", VESPA_STRLOC); } diff --git a/document/src/vespa/document/serialization/vespadocumentserializer.cpp b/document/src/vespa/document/serialization/vespadocumentserializer.cpp index 6d9c08578e7..882dc4e83f3 100644 --- a/document/src/vespa/document/serialization/vespadocumentserializer.cpp +++ b/document/src/vespa/document/serialization/vespadocumentserializer.cpp @@ -26,7 +26,8 @@ #include <vespa/document/update/fieldpathupdates.h> #include <vespa/document/update/updates.h> #include <vespa/document/util/bytebuffer.h> -#include <vespa/eval/tensor/serialization/typed_binary_format.h> +#include <vespa/eval/eval/value.h> +#include <vespa/eval/eval/engine_or_factory.h> #include <vespa/vespalib/data/databuffer.h> #include <vespa/vespalib/data/slime/binary_format.h> #include <vespa/vespalib/objects/nbostream.h> @@ -370,7 +371,7 @@ VespaDocumentSerializer::write(const TensorFieldValue &value) { vespalib::nbostream tmpStream; auto tensor = value.getAsTensorPtr(); if (tensor) { - vespalib::tensor::TypedBinaryFormat::serialize(tmpStream, *tensor); + vespalib::eval::EngineOrFactory::get().encode(*tensor, tmpStream); assert( ! tmpStream.empty()); _stream.putInt1_4Bytes(tmpStream.size()); _stream.write(tmpStream.peek(), tmpStream.size()); diff --git a/document/src/vespa/document/update/tensor_add_update.cpp b/document/src/vespa/document/update/tensor_add_update.cpp index d9bec7762b6..91b72329994 100644 --- a/document/src/vespa/document/update/tensor_add_update.cpp +++ b/document/src/vespa/document/update/tensor_add_update.cpp @@ -8,6 +8,9 @@ #include <vespa/document/fieldvalue/tensorfieldvalue.h> #include <vespa/document/serialization/vespadocumentdeserializer.h> #include <vespa/document/util/serializableexceptions.h> +#include <vespa/eval/eval/value.h> +#include <vespa/eval/eval/engine_or_factory.h> +#include <vespa/eval/tensor/partial_update.h> #include <vespa/eval/tensor/tensor.h> #include <vespa/vespalib/objects/nbostream.h> #include <vespa/vespalib/stllike/asciistream.h> @@ -17,8 +20,9 @@ using vespalib::IllegalArgumentException; using vespalib::IllegalStateException; -using vespalib::tensor::Tensor; using vespalib::make_string; +using vespalib::eval::EngineOrFactory; +using vespalib::tensor::TensorPartialUpdate; namespace document { @@ -78,14 +82,34 @@ TensorAddUpdate::checkCompatibility(const Field& field) const } } -std::unique_ptr<Tensor> -TensorAddUpdate::applyTo(const Tensor &tensor) const +namespace { + +std::unique_ptr<vespalib::eval::Value> +old_add(const vespalib::eval::Value *input, + const vespalib::eval::Value *add_cells) +{ + auto a = dynamic_cast<const vespalib::tensor::Tensor *>(input); + assert(a); + auto b = dynamic_cast<const vespalib::tensor::Tensor *>(add_cells); + assert(b); + return a->add(*b); +} + +} // namespace + +std::unique_ptr<vespalib::eval::Value> +TensorAddUpdate::applyTo(const vespalib::eval::Value &tensor) const { auto addTensor = _tensor->getAsTensorPtr(); if (addTensor) { - return tensor.add(*addTensor); + auto engine = EngineOrFactory::get(); + if (engine.is_factory()) { + return TensorPartialUpdate::add(tensor, *addTensor, engine.factory()); + } else { + return old_add(&tensor, addTensor); + } } - return std::unique_ptr<Tensor>(); + return std::unique_ptr<vespalib::eval::Value>(); } bool diff --git a/document/src/vespa/document/update/tensor_add_update.h b/document/src/vespa/document/update/tensor_add_update.h index 49519ee1ddd..8687967be49 100644 --- a/document/src/vespa/document/update/tensor_add_update.h +++ b/document/src/vespa/document/update/tensor_add_update.h @@ -2,7 +2,7 @@ #include "valueupdate.h" -namespace vespalib::tensor { class Tensor; } +namespace vespalib::eval { class Value; } namespace document { @@ -27,7 +27,7 @@ public: bool operator==(const ValueUpdate &other) const override; const TensorFieldValue &getTensor() const { return *_tensor; } void checkCompatibility(const Field &field) const override; - std::unique_ptr<vespalib::tensor::Tensor> applyTo(const vespalib::tensor::Tensor &tensor) const; + std::unique_ptr<vespalib::eval::Value> applyTo(const vespalib::eval::Value &tensor) const; bool applyTo(FieldValue &value) const override; void printXml(XmlOutputStream &xos) const override; void print(std::ostream &out, bool verbose, const std::string &indent) const override; diff --git a/document/src/vespa/document/update/tensor_modify_update.cpp b/document/src/vespa/document/update/tensor_modify_update.cpp index 5fbdc2467b3..292b4165540 100644 --- a/document/src/vespa/document/update/tensor_modify_update.cpp +++ b/document/src/vespa/document/update/tensor_modify_update.cpp @@ -9,8 +9,11 @@ #include <vespa/document/serialization/vespadocumentdeserializer.h> #include <vespa/document/util/serializableexceptions.h> #include <vespa/eval/eval/operation.h> -#include <vespa/eval/tensor/cell_values.h> +#include <vespa/eval/eval/value.h> +#include <vespa/eval/eval/engine_or_factory.h> +#include <vespa/eval/tensor/partial_update.h> #include <vespa/eval/tensor/tensor.h> +#include <vespa/eval/tensor/cell_values.h> #include <vespa/vespalib/objects/nbostream.h> #include <vespa/vespalib/stllike/asciistream.h> #include <vespa/vespalib/util/stringfmt.h> @@ -19,9 +22,10 @@ using vespalib::IllegalArgumentException; using vespalib::IllegalStateException; -using vespalib::tensor::Tensor; using vespalib::make_string; using vespalib::eval::ValueType; +using vespalib::eval::EngineOrFactory; +using vespalib::tensor::TensorPartialUpdate; using join_fun_t = double (*)(double, double); @@ -156,16 +160,32 @@ TensorModifyUpdate::checkCompatibility(const Field& field) const } } -std::unique_ptr<Tensor> -TensorModifyUpdate::applyTo(const Tensor &tensor) const + +std::unique_ptr<vespalib::eval::Value> +old_modify(const vespalib::eval::Value *input, + const vespalib::eval::Value *modify_spec, + join_fun_t function) +{ + auto a = dynamic_cast<const vespalib::tensor::Tensor *>(input); + // Cells tensor being sparse was validated during deserialize(). + auto b = dynamic_cast<const vespalib::tensor::SparseTensor *>(modify_spec); + vespalib::tensor::CellValues cellValues(*b); + return a->modify(function, cellValues); +} + +std::unique_ptr<vespalib::eval::Value> +TensorModifyUpdate::applyTo(const vespalib::eval::Value &tensor) const { auto cellsTensor = _tensor->getAsTensorPtr(); if (cellsTensor) { - // Cells tensor being sparse was validated during deserialize(). - vespalib::tensor::CellValues cellValues(static_cast<const vespalib::tensor::SparseTensor &>(*cellsTensor)); - return tensor.modify(getJoinFunction(_operation), cellValues); + auto engine = EngineOrFactory::get(); + if (engine.is_factory()) { + return TensorPartialUpdate::modify(tensor, getJoinFunction(_operation), *cellsTensor, engine.factory()); + } else { + return old_modify(&tensor, cellsTensor, getJoinFunction(_operation)); + } } - return std::unique_ptr<Tensor>(); + return std::unique_ptr<vespalib::eval::Value>(); } bool @@ -207,13 +227,24 @@ TensorModifyUpdate::print(std::ostream& out, bool verbose, const std::string& in namespace { void -verifyCellsTensorIsSparse(const Tensor *cellsTensor) +verifyCellsTensorIsSparse(const vespalib::eval::Value *cellsTensor) { - if (cellsTensor && !dynamic_cast<const vespalib::tensor::SparseTensor *>(cellsTensor)) { - vespalib::string err = make_string("Expected cell values tensor to be sparse, but has type '%s'", - cellsTensor->type().to_spec().c_str()); - throw IllegalStateException(err, VESPA_STRLOC); + if (cellsTensor == nullptr) { + return; + } + auto engine = EngineOrFactory::get(); + if (engine.is_factory()) { + if (cellsTensor->type().is_sparse()) { + return; + } + } else { + if (dynamic_cast<const vespalib::tensor::SparseTensor *>(cellsTensor)) { + return; + } } + vespalib::string err = make_string("Expected cells tensor to be sparse, but has type '%s'", + cellsTensor->type().to_spec().c_str()); + throw IllegalStateException(err, VESPA_STRLOC); } } diff --git a/document/src/vespa/document/update/tensor_modify_update.h b/document/src/vespa/document/update/tensor_modify_update.h index c2d61d3e69b..528ff8c95e9 100644 --- a/document/src/vespa/document/update/tensor_modify_update.h +++ b/document/src/vespa/document/update/tensor_modify_update.h @@ -2,7 +2,7 @@ #include "valueupdate.h" -namespace vespalib::tensor { class Tensor; } +namespace vespalib::eval { class Value; } namespace document { @@ -41,7 +41,7 @@ public: Operation getOperation() const { return _operation; } const TensorFieldValue &getTensor() const { return *_tensor; } void checkCompatibility(const Field &field) const override; - std::unique_ptr<vespalib::tensor::Tensor> applyTo(const vespalib::tensor::Tensor &tensor) const; + std::unique_ptr<vespalib::eval::Value> applyTo(const vespalib::eval::Value &tensor) const; bool applyTo(FieldValue &value) const override; void printXml(XmlOutputStream &xos) const override; void print(std::ostream &out, bool verbose, const std::string &indent) const override; diff --git a/document/src/vespa/document/update/tensor_remove_update.cpp b/document/src/vespa/document/update/tensor_remove_update.cpp index 34a6223e185..178bd1bd950 100644 --- a/document/src/vespa/document/update/tensor_remove_update.cpp +++ b/document/src/vespa/document/update/tensor_remove_update.cpp @@ -6,18 +6,23 @@ #include <vespa/document/fieldvalue/document.h> #include <vespa/document/fieldvalue/tensorfieldvalue.h> #include <vespa/document/serialization/vespadocumentdeserializer.h> +#include <vespa/eval/eval/engine_or_factory.h> +#include <vespa/eval/tensor/partial_update.h> +#include <vespa/eval/tensor/tensor.h> #include <vespa/eval/tensor/cell_values.h> #include <vespa/eval/tensor/sparse/sparse_tensor.h> -#include <vespa/eval/tensor/tensor.h> +#include <vespa/eval/eval/value.h> #include <vespa/vespalib/objects/nbostream.h> #include <vespa/vespalib/util/xmlstream.h> #include <ostream> +#include <cassert> using vespalib::IllegalArgumentException; using vespalib::IllegalStateException; -using vespalib::tensor::Tensor; using vespalib::make_string; using vespalib::eval::ValueType; +using vespalib::eval::EngineOrFactory; +using vespalib::tensor::TensorPartialUpdate; namespace document { @@ -35,6 +40,16 @@ convertToCompatibleType(const TensorDataType &tensorType) return std::make_unique<const TensorDataType>(ValueType::tensor_type(std::move(list), tensorType.getTensorType().cell_type())); } +std::unique_ptr<vespalib::eval::Value> +old_remove(const vespalib::eval::Value *input, + const vespalib::eval::Value *remove_spec) +{ + auto a = dynamic_cast<const vespalib::tensor::Tensor *>(input); + auto b = dynamic_cast<const vespalib::tensor::SparseTensor *>(remove_spec); + vespalib::tensor::CellValues cellAddresses(*b); + return a->remove(cellAddresses); +} + } IMPLEMENT_IDENTIFIABLE(TensorRemoveUpdate, ValueUpdate); @@ -102,16 +117,19 @@ TensorRemoveUpdate::checkCompatibility(const Field &field) const } } -std::unique_ptr<Tensor> -TensorRemoveUpdate::applyTo(const Tensor &tensor) const +std::unique_ptr<vespalib::eval::Value> +TensorRemoveUpdate::applyTo(const vespalib::eval::Value &tensor) const { auto addressTensor = _tensor->getAsTensorPtr(); if (addressTensor) { - // Address tensor being sparse was validated during deserialize(). - vespalib::tensor::CellValues cellAddresses(static_cast<const vespalib::tensor::SparseTensor &>(*addressTensor)); - return tensor.remove(cellAddresses); + auto engine = EngineOrFactory::get(); + if (engine.is_factory()) { + return TensorPartialUpdate::remove(tensor, *addressTensor, engine.factory()); + } else { + return old_remove(&tensor, addressTensor); + } } - return std::unique_ptr<Tensor>(); + return std::unique_ptr<vespalib::eval::Value>(); } bool @@ -153,15 +171,27 @@ TensorRemoveUpdate::print(std::ostream &out, bool verbose, const std::string &in namespace { void -verifyAddressTensorIsSparse(const Tensor *addressTensor) +verifyAddressTensorIsSparse(const vespalib::eval::Value *addressTensor) { - if (addressTensor && !dynamic_cast<const vespalib::tensor::SparseTensor *>(addressTensor)) { - vespalib::string err = make_string("Expected address tensor to be sparse, but has type '%s'", - addressTensor->type().to_spec().c_str()); - throw IllegalStateException(err, VESPA_STRLOC); + if (addressTensor == nullptr) { + return; + } + auto engine = EngineOrFactory::get(); + if (engine.is_factory()) { + if (addressTensor->type().is_sparse()) { + return; + } + } else { + if (dynamic_cast<const vespalib::tensor::SparseTensor *>(addressTensor)) { + return; + } } + vespalib::string err = make_string("Expected address tensor to be sparse, but has type '%s'", + addressTensor->type().to_spec().c_str()); + throw IllegalStateException(err, VESPA_STRLOC); } + } void diff --git a/document/src/vespa/document/update/tensor_remove_update.h b/document/src/vespa/document/update/tensor_remove_update.h index e75348fa829..6ab66048dd4 100644 --- a/document/src/vespa/document/update/tensor_remove_update.h +++ b/document/src/vespa/document/update/tensor_remove_update.h @@ -2,7 +2,7 @@ #include "valueupdate.h" -namespace vespalib::tensor { class Tensor; } +namespace vespalib::eval { class Value; } namespace document { @@ -30,7 +30,7 @@ public: TensorRemoveUpdate &operator=(const TensorRemoveUpdate &rhs); TensorRemoveUpdate &operator=(TensorRemoveUpdate &&rhs); const TensorFieldValue &getTensor() const { return *_tensor; } - std::unique_ptr<vespalib::tensor::Tensor> applyTo(const vespalib::tensor::Tensor &tensor) const; + std::unique_ptr<vespalib::eval::Value> applyTo(const vespalib::eval::Value &tensor) const; bool operator==(const ValueUpdate &other) const override; void checkCompatibility(const Field &field) const override; diff --git a/searchcore/src/apps/verify_ranksetup/verify_ranksetup.cpp b/searchcore/src/apps/verify_ranksetup/verify_ranksetup.cpp index 533e8881d27..bea93f82c2d 100644 --- a/searchcore/src/apps/verify_ranksetup/verify_ranksetup.cpp +++ b/searchcore/src/apps/verify_ranksetup/verify_ranksetup.cpp @@ -11,6 +11,7 @@ #include <vespa/config/common/exceptions.h> #include <vespa/eval/eval/tensor_spec.h> #include <vespa/eval/eval/value_cache/constant_value.h> +#include <vespa/eval/eval/engine_or_factory.h> #include <vespa/eval/tensor/default_tensor_engine.h> #include <vespa/searchcommon/common/schemaconfigurer.h> #include <vespa/searchcore/config/config-ranking-constants.h> @@ -39,12 +40,13 @@ using vespa::config::search::RankProfilesConfig; using vespa::config::search::core::RankingConstantsConfig; using vespa::config::search::core::OnnxModelsConfig; using vespa::config::search::core::VerifyRanksetupConfig; +using vespalib::eval::BadConstantValue; using vespalib::eval::ConstantValue; +using vespalib::eval::EngineOrFactory; +using vespalib::eval::SimpleConstantValue; using vespalib::eval::TensorSpec; +using vespalib::eval::Value; using vespalib::eval::ValueType; -using vespalib::tensor::DefaultTensorEngine; -using vespalib::eval::SimpleConstantValue; -using vespalib::eval::BadConstantValue; std::optional<vespalib::string> get_file(const vespalib::string &ref, const VerifyRanksetupConfig &myCfg) { for (const auto &entry: myCfg.file) { @@ -94,9 +96,8 @@ struct DummyConstantValueRepo : IConstantValueRepo { virtual vespalib::eval::ConstantValue::UP getConstant(const vespalib::string &name) const override { for (const auto &entry: cfg.constant) { if (entry.name == name) { - const auto &engine = DefaultTensorEngine::ref(); try { - auto tensor = engine.from_spec(TensorSpec(entry.type)); + auto tensor = EngineOrFactory::get().from_spec(TensorSpec(entry.type)); return std::make_unique<SimpleConstantValue>(std::move(tensor)); } catch (std::exception &) { return std::make_unique<BadConstantValue>(); diff --git a/searchcore/src/tests/proton/attribute/attribute_test.cpp b/searchcore/src/tests/proton/attribute/attribute_test.cpp index a647085e3d1..00153402fc9 100644 --- a/searchcore/src/tests/proton/attribute/attribute_test.cpp +++ b/searchcore/src/tests/proton/attribute/attribute_test.cpp @@ -7,8 +7,9 @@ #include <vespa/document/update/arithmeticvalueupdate.h> #include <vespa/document/update/assignvalueupdate.h> #include <vespa/document/update/documentupdate.h> -#include <vespa/eval/tensor/default_tensor_engine.h> -#include <vespa/eval/tensor/tensor.h> +#include <vespa/eval/eval/engine_or_factory.h> +#include <vespa/eval/eval/value.h> +#include <vespa/eval/eval/test/value_compare.h> #include <vespa/searchcommon/attribute/attributecontent.h> #include <vespa/searchcommon/attribute/iattributevector.h> #include <vespa/searchcore/proton/attribute/attribute_collection_spec_factory.h> @@ -81,10 +82,10 @@ using std::string; using vespalib::ForegroundTaskExecutor; using vespalib::ForegroundThreadExecutor; using vespalib::SequencedTaskExecutorObserver; +using vespalib::eval::EngineOrFactory; using vespalib::eval::TensorSpec; +using vespalib::eval::Value; using vespalib::eval::ValueType; -using vespalib::tensor::DefaultTensorEngine; -using vespalib::tensor::Tensor; using AVBasicType = search::attribute::BasicType; using AVCollectionType = search::attribute::CollectionType; @@ -639,9 +640,9 @@ TEST_F(FilterAttributeManagerTest, readable_attribute_vector_filters_attributes) namespace { -Tensor::UP make_tensor(const TensorSpec &spec) { - auto tensor = DefaultTensorEngine::ref().from_spec(spec); - return Tensor::UP(dynamic_cast<Tensor*>(tensor.release())); +Value::UP make_tensor(const TensorSpec &spec) { + auto tensor = EngineOrFactory::get().from_spec(spec); + return tensor; } const vespalib::string sparse_tensor = "tensor(x{},y{})"; @@ -662,10 +663,10 @@ createTensorSchema(const vespalib::string& tensor_spec = sparse_tensor) { } Document::UP -createTensorPutDoc(DocBuilder &builder, const Tensor &tensor) { +createTensorPutDoc(DocBuilder &builder, const Value &tensor) { return builder.startDocument("id:ns:searchdocument::1"). startAttributeField("a1"). - addTensor(tensor.clone()).endField().endDocument(); + addTensor(EngineOrFactory::get().copy(tensor)).endField().endDocument(); } } @@ -684,7 +685,7 @@ TEST_F(AttributeWriterTest, can_write_to_tensor_attribute) EXPECT_TRUE(tensorAttribute != nullptr); auto tensor2 = tensorAttribute->getTensor(1); EXPECT_TRUE(static_cast<bool>(tensor2)); - EXPECT_TRUE(tensor->equals(*tensor2)); + EXPECT_EQ(*tensor, *tensor2); } TEST_F(AttributeWriterTest, handles_tensor_assign_update) @@ -701,7 +702,7 @@ TEST_F(AttributeWriterTest, handles_tensor_assign_update) EXPECT_TRUE(tensorAttribute != nullptr); auto tensor2 = tensorAttribute->getTensor(1); EXPECT_TRUE(static_cast<bool>(tensor2)); - EXPECT_TRUE(tensor->equals(*tensor2)); + EXPECT_EQ(*tensor, *tensor2); const document::DocumentType &dt(builder.getDocumentType()); DocumentUpdate upd(*builder.getDocumentTypeRepo(), dt, DocumentId("id:ns:searchdocument::1")); @@ -709,7 +710,7 @@ TEST_F(AttributeWriterTest, handles_tensor_assign_update) .add({{"x", "8"}, {"y", "9"}}, 11)); TensorDataType xySparseTensorDataType(vespalib::eval::ValueType::from_spec(sparse_tensor)); TensorFieldValue new_value(xySparseTensorDataType); - new_value = new_tensor->clone(); + new_value = EngineOrFactory::get().copy(*new_tensor); upd.addUpdate(FieldUpdate(upd.getType().getField("a1")) .addUpdate(AssignValueUpdate(new_value))); bool immediateCommit = true; @@ -719,8 +720,8 @@ TEST_F(AttributeWriterTest, handles_tensor_assign_update) EXPECT_TRUE(tensorAttribute != nullptr); tensor2 = tensorAttribute->getTensor(1); EXPECT_TRUE(static_cast<bool>(tensor2)); - EXPECT_TRUE(!tensor->equals(*tensor2)); - EXPECT_TRUE(new_tensor->equals(*tensor2)); + EXPECT_FALSE(*tensor == *tensor2); + EXPECT_EQ(*new_tensor, *tensor2); } namespace { @@ -792,8 +793,8 @@ TEST_F(AttributeWriterTest, spreads_write_over_3_write_contexts) struct MockPrepareResult : public PrepareResult { uint32_t docid; - const Tensor& tensor; - MockPrepareResult(uint32_t docid_in, const Tensor& tensor_in) : docid(docid_in), tensor(tensor_in) {} + const Value& tensor; + MockPrepareResult(uint32_t docid_in, const Value& tensor_in) : docid(docid_in), tensor(tensor_in) {} }; class MockDenseTensorAttribute : public DenseTensorAttribute { @@ -812,12 +813,12 @@ public: ++clear_doc_cnt; return DenseTensorAttribute::clearDoc(docid); } - std::unique_ptr<PrepareResult> prepare_set_tensor(uint32_t docid, const Tensor& tensor) const override { + std::unique_ptr<PrepareResult> prepare_set_tensor(uint32_t docid, const Value& tensor) const override { ++prepare_set_tensor_cnt; return std::make_unique<MockPrepareResult>(docid, tensor); } - void complete_set_tensor(DocId docid, const Tensor& tensor, std::unique_ptr<PrepareResult> prepare_result) override { + void complete_set_tensor(DocId docid, const Value& tensor, std::unique_ptr<PrepareResult> prepare_result) override { ++complete_set_tensor_cnt; assert(prepare_result); auto* mock_result = dynamic_cast<MockPrepareResult*>(prepare_result.get()); @@ -872,7 +873,7 @@ public: Schema schema; DocBuilder builder; std::shared_ptr<MockDenseTensorAttribute> attr; - std::unique_ptr<Tensor> tensor; + std::unique_ptr<Value> tensor; TwoPhasePutTest() : AttributeWriterTest(), @@ -904,7 +905,7 @@ public: Document::UP make_no_tensor_doc() { return builder.startDocument("id:ns:searchdocument::1"). startAttributeField("a1"). - addTensor(std::unique_ptr<vespalib::tensor::Tensor>()).endField().endDocument(); + addTensor(std::unique_ptr<vespalib::eval::Value>()).endField().endDocument(); } void expect_shared_executor_tasks(size_t exp_accepted_tasks) { auto stats = _shared.getStats(); diff --git a/searchcore/src/tests/proton/common/attribute_updater/attribute_updater_test.cpp b/searchcore/src/tests/proton/common/attribute_updater/attribute_updater_test.cpp index 59c046dee46..61b5f9cb847 100644 --- a/searchcore/src/tests/proton/common/attribute_updater/attribute_updater_test.cpp +++ b/searchcore/src/tests/proton/common/attribute_updater/attribute_updater_test.cpp @@ -22,8 +22,8 @@ #include <vespa/document/update/tensor_add_update.h> #include <vespa/document/update/tensor_modify_update.h> #include <vespa/document/update/tensor_remove_update.h> -#include <vespa/eval/tensor/default_tensor_engine.h> -#include <vespa/eval/tensor/tensor.h> +#include <vespa/eval/eval/engine_or_factory.h> +#include <vespa/eval/eval/value.h> #include <vespa/searchcore/proton/common/attribute_updater.h> #include <vespa/searchlib/attribute/attributefactory.h> #include <vespa/searchlib/attribute/reference_attribute.h> @@ -50,10 +50,10 @@ using search::tensor::ITensorAttribute; using search::tensor::DenseTensorAttribute; using search::tensor::SerializedTensorAttribute; using search::tensor::TensorAttribute; +using vespalib::eval::EngineOrFactory; +using vespalib::eval::Value; using vespalib::eval::ValueType; using vespalib::eval::TensorSpec; -using vespalib::tensor::DefaultTensorEngine; -using vespalib::tensor::Tensor; namespace search { @@ -408,11 +408,11 @@ getTensorDataType(const vespalib::string &spec) return *insres.first->second; } -std::unique_ptr<Tensor> +std::unique_ptr<Value> makeTensor(const TensorSpec &spec) { - auto result = DefaultTensorEngine::ref().from_spec(spec); - return std::unique_ptr<Tensor>(dynamic_cast<Tensor*>(result.release())); + auto result = EngineOrFactory::get().from_spec(spec); + return result; } std::unique_ptr<TensorFieldValue> @@ -442,7 +442,9 @@ struct TensorFixture : public Fixture { } void assertTensor(const TensorSpec &expSpec) { - EXPECT_EQUAL(expSpec, attribute->getTensor(1)->toSpec()); + auto engine = EngineOrFactory::get(); + auto actual = engine.to_spec(*attribute->getTensor(1)); + EXPECT_EQUAL(expSpec, actual); } }; diff --git a/searchcore/src/tests/proton/docsummary/docsummary.cpp b/searchcore/src/tests/proton/docsummary/docsummary.cpp index 07f023982c9..7e220cd0165 100644 --- a/searchcore/src/tests/proton/docsummary/docsummary.cpp +++ b/searchcore/src/tests/proton/docsummary/docsummary.cpp @@ -2,9 +2,9 @@ #include <tests/proton/common/dummydbowner.h> #include <vespa/config/helper/configgetter.hpp> -#include <vespa/eval/tensor/tensor.h> -#include <vespa/eval/tensor/default_tensor_engine.h> -#include <vespa/eval/tensor/serialization/typed_binary_format.h> +#include <vespa/eval/eval/engine_or_factory.h> +#include <vespa/eval/eval/value.h> +#include <vespa/eval/eval/test/value_compare.h> #include <vespa/document/repo/documenttyperepo.h> #include <vespa/document/test/make_bucket_space.h> #include <vespa/searchcore/proton/attribute/attribute_writer.h> @@ -59,8 +59,7 @@ using storage::spi::Timestamp; using vespa::config::search::core::ProtonConfig; using vespa::config::content::core::BucketspacesConfig; using vespalib::eval::TensorSpec; -using vespalib::tensor::Tensor; -using vespalib::tensor::DefaultTensorEngine; +using vespalib::eval::EngineOrFactory; using namespace vespalib::slime; typedef std::unique_ptr<GeneralResult> GeneralResultPtr; @@ -139,9 +138,9 @@ getDocTypeName() return "searchdocument"; } -Tensor::UP make_tensor(const TensorSpec &spec) { - auto tensor = DefaultTensorEngine::ref().from_spec(spec); - return Tensor::UP(dynamic_cast<Tensor*>(tensor.release())); +vespalib::eval::Value::UP make_tensor(const TensorSpec &spec) { + auto tensor = EngineOrFactory::get().from_spec(spec); + return tensor; } vespalib::string asVstring(vespalib::Memory str) { @@ -316,7 +315,7 @@ assertString(const std::string & exp, const std::string & fieldName, } void -assertTensor(const Tensor::UP & exp, const std::string & fieldName, +assertTensor(const vespalib::eval::Value::UP & exp, const std::string & fieldName, const DocsumReply & reply, uint32_t id, uint32_t) { const DocsumReply::Docsum & docsum = reply.docsums[id]; @@ -335,7 +334,7 @@ assertTensor(const Tensor::UP & exp, const std::string & fieldName, EXPECT_EQUAL(exp.get() == nullptr, data.size == 0u); if (exp) { vespalib::nbostream x(data.data, data.size); - Tensor::UP tensor = vespalib::tensor::TypedBinaryFormat::deserialize(x); + vespalib::eval::Value::UP tensor = EngineOrFactory::get().decode(x); EXPECT_TRUE(tensor.get() != nullptr); EXPECT_EQUAL(*exp, *tensor); } @@ -741,7 +740,7 @@ TEST("requireThatAttributesAreUsed") // empty doc EXPECT_TRUE(assertSlime("{}", *rep, 1, false)); - TEST_DO(assertTensor(Tensor::UP(), "bj", *rep, 1, rclass)); + TEST_DO(assertTensor(vespalib::eval::Value::UP(), "bj", *rep, 1, rclass)); proton::IAttributeManager::SP attributeManager = dc._ddb->getReadySubDB()->getAttributeManager(); vespalib::ISequencedTaskExecutor &attributeFieldWriter = attributeManager->getAttributeFieldWriter(); diff --git a/searchcore/src/tests/proton/docsummary/summaryfieldconverter_test.cpp b/searchcore/src/tests/proton/docsummary/summaryfieldconverter_test.cpp index 5f8f7a63dd0..6309f96b747 100644 --- a/searchcore/src/tests/proton/docsummary/summaryfieldconverter_test.cpp +++ b/searchcore/src/tests/proton/docsummary/summaryfieldconverter_test.cpp @@ -45,9 +45,10 @@ #include <vespa/vespalib/data/slime/json_format.h> #include <vespa/vespalib/data/slime/binary_format.h> #include <vespa/searchlib/util/slime_output_raw_buf_adapter.h> -#include <vespa/eval/tensor/tensor.h> +#include <vespa/eval/eval/engine_or_factory.h> +#include <vespa/eval/eval/value.h> +#include <vespa/eval/eval/test/value_compare.h> #include <vespa/eval/tensor/types.h> -#include <vespa/eval/tensor/default_tensor_engine.h> #include <vespa/vespalib/data/slime/slime.h> using document::Annotation; @@ -93,13 +94,13 @@ using search::linguistics::TERM; using vespa::config::search::SummarymapConfig; using vespa::config::search::SummarymapConfigBuilder; using vespalib::Slime; +using vespalib::eval::Value; using vespalib::eval::ValueType; using vespalib::eval::TensorSpec; +using vespalib::eval::EngineOrFactory; using vespalib::geo::ZCurve; using vespalib::slime::Cursor; using vespalib::string; -using vespalib::tensor::Tensor; -using vespalib::tensor::DefaultTensorEngine; using namespace search::docsummary; @@ -165,7 +166,7 @@ class Test : public vespalib::TestApp { void checkString(const string &str, const FieldValue *value); void checkStringForAllConversions(const string& expected, const FieldValue* fv); void checkData(const search::RawBuf &data, const FieldValue *value); - void checkTensor(const Tensor::UP &tensor, const FieldValue *value); + void checkTensor(const Value::UP &tensor, const FieldValue *value); template <unsigned int N> void checkArray(const char *(&str)[N], const FieldValue *value); void setSummaryField(const string &name); @@ -464,7 +465,7 @@ void Test::checkData(const search::RawBuf &buf, const FieldValue *value) { EXPECT_TRUE(memcmp(buf.GetDrainPos(), got.first, got.second) == 0); } -void Test::checkTensor(const Tensor::UP &tensor, const FieldValue *value) { +void Test::checkTensor(const Value::UP &tensor, const FieldValue *value) { ASSERT_TRUE(value); const TensorFieldValue *s = dynamic_cast<const TensorFieldValue *>(value); ASSERT_TRUE(s); @@ -675,9 +676,9 @@ Test::requireThatPredicateIsPrinted() SFC::convertSummaryField(false, *doc.getValue("predicate")).get()); } -Tensor::UP make_tensor(const TensorSpec &spec) { - auto tensor = DefaultTensorEngine::ref().from_spec(spec); - return Tensor::UP(dynamic_cast<Tensor*>(tensor.release())); +Value::UP make_tensor(const TensorSpec &spec) { + auto tensor = EngineOrFactory::get().from_spec(spec); + return tensor; } void @@ -697,7 +698,7 @@ Test::requireThatTensorIsNotConverted() *doc.getValue("tensor")).get())); doc.setValue("tensor", TensorFieldValue()); - TEST_CALL(checkTensor(Tensor::UP(), + TEST_CALL(checkTensor(Value::UP(), SFC::convertSummaryField(false, *doc.getValue("tensor")).get())); } diff --git a/searchcore/src/tests/proton/documentdb/feedhandler/feedhandler_test.cpp b/searchcore/src/tests/proton/documentdb/feedhandler/feedhandler_test.cpp index 72592cca681..01a35f6017e 100644 --- a/searchcore/src/tests/proton/documentdb/feedhandler/feedhandler_test.cpp +++ b/searchcore/src/tests/proton/documentdb/feedhandler/feedhandler_test.cpp @@ -5,7 +5,7 @@ #include <vespa/document/update/assignvalueupdate.h> #include <vespa/document/repo/documenttyperepo.h> #include <vespa/document/update/documentupdate.h> -#include <vespa/eval/tensor/tensor.h> +#include <vespa/eval/eval/value.h> #include <vespa/eval/tensor/test/test_utils.h> #include <vespa/searchcore/proton/bucketdb/bucketdbhandler.h> #include <vespa/searchcore/proton/test/bucketfactory.h> @@ -59,9 +59,9 @@ using vespalib::ThreadStackExecutor; using vespalib::ThreadStackExecutorBase; using vespalib::makeClosure; using vespalib::eval::TensorSpec; +using vespalib::eval::Value; using vespalib::eval::ValueType; using vespalib::tensor::test::makeTensor; -using vespalib::tensor::Tensor; using namespace proton; using namespace search::index; @@ -330,12 +330,12 @@ struct UpdateContext { auto fieldValue = field.createValue(); if (fieldName == "tensor") { dynamic_cast<TensorFieldValue &>(*fieldValue) = - makeTensor<Tensor>(TensorSpec("tensor(x{},y{})"). + makeTensor<Value>(TensorSpec("tensor(x{},y{})"). add({{"x","8"},{"y","9"}}, 11)); } else if (fieldName == "tensor2") { auto tensorFieldValue = std::make_unique<TensorFieldValue>(tensor1DType); *tensorFieldValue = - makeTensor<Tensor>(TensorSpec("tensor(x{})"). + makeTensor<Value>(TensorSpec("tensor(x{})"). add({{"x","8"}}, 11)); fieldValue = std::move(tensorFieldValue); } else { diff --git a/searchcore/src/tests/proton/matching/matching_test.cpp b/searchcore/src/tests/proton/matching/matching_test.cpp index 30f83273bd7..11ea6e87233 100644 --- a/searchcore/src/tests/proton/matching/matching_test.cpp +++ b/searchcore/src/tests/proton/matching/matching_test.cpp @@ -33,6 +33,7 @@ #include <vespa/searchcore/proton/matching/match_tools.h> #include <vespa/searchcore/proton/matching/match_context.h> #include <vespa/eval/eval/tensor_spec.h> +#include <vespa/eval/eval/engine_or_factory.h> #include <vespa/eval/tensor/default_tensor_engine.h> #include <vespa/vespalib/objects/nbostream.h> @@ -59,7 +60,7 @@ using search::fef::indexproperties::hitcollector::HeapSize; using vespalib::nbostream; using vespalib::eval::TensorSpec; -using vespalib::tensor::DefaultTensorEngine; +using vespalib::eval::EngineOrFactory; void inject_match_phase_limiting(Properties &setup, const vespalib::string &attribute, size_t max_hits, bool descending) { @@ -666,7 +667,7 @@ TEST("require that summary features are filled") { EXPECT_TRUE(!f[2].is_double()); EXPECT_TRUE(f[2].is_data()); { - auto &engine = DefaultTensorEngine::ref(); + auto engine = EngineOrFactory::get(); nbostream buf(f[2].as_data().data, f[2].as_data().size); auto actual = engine.to_spec(*engine.decode(buf)); auto expect = TensorSpec("tensor(x[3])").add({{"x", 0}}, 0).add({{"x", 1}}, 1).add({{"x", 2}}, 2); diff --git a/searchcore/src/tests/proton/matching/request_context/request_context_test.cpp b/searchcore/src/tests/proton/matching/request_context/request_context_test.cpp index 3b54768f223..90a6e173129 100644 --- a/searchcore/src/tests/proton/matching/request_context/request_context_test.cpp +++ b/searchcore/src/tests/proton/matching/request_context/request_context_test.cpp @@ -1,6 +1,7 @@ // Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include <vespa/eval/eval/tensor_spec.h> +#include <vespa/eval/eval/engine_or_factory.h> #include <vespa/eval/tensor/default_tensor_engine.h> #include <vespa/searchcore/proton/matching/requestcontext.h> #include <vespa/searchlib/attribute/attribute_blueprint_params.h> @@ -13,9 +14,9 @@ using search::attribute::IAttributeContext; using search::attribute::IAttributeFunctor; using search::attribute::IAttributeVector; using search::fef::Properties; +using vespalib::eval::EngineOrFactory; using vespalib::eval::TensorSpec; using vespalib::eval::Value; -using vespalib::tensor::DefaultTensorEngine; using namespace proton; class MyAttributeContext : public search::attribute::IAttributeContext { @@ -37,7 +38,7 @@ private: void insert_tensor_in_properties(const vespalib::string& tensor_name, const Value& tensor_value) { vespalib::nbostream stream; - DefaultTensorEngine::ref().encode(tensor_value, stream); + EngineOrFactory::get().encode(tensor_value, stream); _props.add(tensor_name, vespalib::stringref(stream.data(), stream.size())); } @@ -48,13 +49,15 @@ public: _attr_ctx(), _props(), _request_ctx(_doom, _attr_ctx, _props, AttributeBlueprintParams()), - _query_tensor(DefaultTensorEngine::ref().from_spec(TensorSpec("tensor(x[2])") + _query_tensor(EngineOrFactory::get().from_spec(TensorSpec("tensor(x[2])") .add({{"x", 0}}, 3).add({{"x", 1}}, 5))) { insert_tensor_in_properties("my_tensor", *_query_tensor); _props.add("my_string", "foo bar"); } - TensorSpec expected_query_tensor() const { return DefaultTensorEngine::ref().to_spec(*_query_tensor); } + TensorSpec expected_query_tensor() const { + return EngineOrFactory::get().to_spec(*_query_tensor); + } Value::UP get_query_tensor(const vespalib::string& tensor_name) const { return _request_ctx.get_query_tensor(tensor_name); } @@ -65,7 +68,7 @@ TEST_F(RequestContextTest, query_tensor_can_be_retrieved) auto tensor = get_query_tensor("my_tensor"); ASSERT_TRUE(tensor); EXPECT_TRUE(tensor->is_tensor()); - EXPECT_EQ(expected_query_tensor(), DefaultTensorEngine::ref().to_spec(*tensor)); + EXPECT_EQ(expected_query_tensor(), EngineOrFactory::get().to_spec(*tensor)); } TEST_F(RequestContextTest, non_existing_query_tensor_returns_nullptr) diff --git a/searchcore/src/tests/proton/server/documentretriever_test.cpp b/searchcore/src/tests/proton/server/documentretriever_test.cpp index 314e1adcc14..b4ae15be17e 100644 --- a/searchcore/src/tests/proton/server/documentretriever_test.cpp +++ b/searchcore/src/tests/proton/server/documentretriever_test.cpp @@ -20,7 +20,9 @@ #include <vespa/document/fieldset/fieldsets.h> #include <vespa/document/repo/configbuilder.h> #include <vespa/document/repo/documenttyperepo.h> -#include <vespa/eval/tensor/tensor.h> +#include <vespa/eval/eval/engine_or_factory.h> +#include <vespa/eval/eval/value.h> +#include <vespa/eval/eval/test/value_compare.h> #include <vespa/eval/tensor/test/test_utils.h> #include <vespa/persistence/spi/bucket.h> #include <vespa/persistence/spi/test.h> @@ -88,10 +90,11 @@ using storage::spi::Timestamp; using storage::spi::test::makeSpiBucket; using vespalib::make_string; using vespalib::string; +using vespalib::eval::EngineOrFactory; using vespalib::eval::TensorSpec; using vespalib::eval::ValueType; +using vespalib::eval::Value; using vespalib::tensor::test::makeTensor; -using vespalib::tensor::Tensor; using namespace document::config_builder; using namespace search::index; @@ -110,8 +113,8 @@ const char dyn_field_nas[] = "dynamic null attr string field"; // in document, n const char position_field[] = "position_field"; vespalib::string dyn_field_tensor("dynamic_tensor_field"); vespalib::string tensor_spec("tensor(x{})"); -std::unique_ptr<Tensor> static_tensor = makeTensor<Tensor>(TensorSpec(tensor_spec).add({{"x", "1"}}, 1.5)); -std::unique_ptr<Tensor> dynamic_tensor = makeTensor<Tensor>(TensorSpec(tensor_spec).add({{"x", "2"}}, 3.5)); +std::unique_ptr<Value> static_tensor = makeTensor<Value>(TensorSpec(tensor_spec).add({{"x", "1"}}, 1.5)); +std::unique_ptr<Value> dynamic_tensor = makeTensor<Value>(TensorSpec(tensor_spec).add({{"x", "2"}}, 3.5)); const char zcurve_field[] = "position_field_zcurve"; const char position_array_field[] = "position_array"; const char zcurve_array_field[] = "position_array_zcurve"; @@ -167,7 +170,7 @@ struct MyDocumentStore : proton::test::DummyDocumentStore { doc->set(zcurve_field, static_zcurve_value); doc->setValue(dyn_field_p, static_value_p); TensorFieldValue tensorFieldValue(tensorDataType); - tensorFieldValue = static_tensor->clone(); + tensorFieldValue = EngineOrFactory::get().copy(*static_tensor); doc->setValue(dyn_field_tensor, tensorFieldValue); if (_set_position_struct_field) { FieldValue::UP fv = PositionDataType::getInstance().createFieldValue(); @@ -307,7 +310,7 @@ struct Fixture { } attr->commit(); } - void addTensorAttribute(const char *name, const Tensor &val) { + void addTensorAttribute(const char *name, const Value &val) { auto * attr = addAttribute<TensorAttribute>(name, schema::DataType::TENSOR, schema::CollectionType::SINGLE); attr->setTensor(lid, val); attr->commit(); @@ -574,7 +577,7 @@ TEST_F("require that tensor attribute can be retrieved", Fixture) { FieldValue::UP value = doc->getValue(dyn_field_tensor); ASSERT_TRUE(value); auto * tensor_value = dynamic_cast<TensorFieldValue *>(value.get()); - ASSERT_TRUE(tensor_value->getAsTensorPtr()->equals(*dynamic_tensor)); + ASSERT_EQUAL(*tensor_value->getAsTensorPtr(), *dynamic_tensor); } struct Lookup : public IFieldInfo diff --git a/searchcore/src/vespa/searchcore/proton/attribute/document_field_retriever.cpp b/searchcore/src/vespa/searchcore/proton/attribute/document_field_retriever.cpp index 358556abce7..c470b7e909c 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/document_field_retriever.cpp +++ b/searchcore/src/vespa/searchcore/proton/attribute/document_field_retriever.cpp @@ -6,7 +6,7 @@ #include <vespa/document/fieldvalue/tensorfieldvalue.h> #include <vespa/searchcommon/attribute/attributecontent.h> #include <vespa/searchlib/tensor/tensor_attribute.h> -#include <vespa/eval/tensor/tensor.h> +#include <vespa/eval/eval/value.h> #include <vespa/vespalib/util/exceptions.h> #include <vespa/log/log.h> diff --git a/searchcore/src/vespa/searchcore/proton/common/attribute_updater.cpp b/searchcore/src/vespa/searchcore/proton/common/attribute_updater.cpp index d7cf6caff28..063ecffe729 100644 --- a/searchcore/src/vespa/searchcore/proton/common/attribute_updater.cpp +++ b/searchcore/src/vespa/searchcore/proton/common/attribute_updater.cpp @@ -17,7 +17,7 @@ #include <vespa/document/update/tensor_add_update.h> #include <vespa/document/update/tensor_modify_update.h> #include <vespa/document/update/tensor_remove_update.h> -#include <vespa/eval/tensor/tensor.h> +#include <vespa/eval/eval/value.h> #include <vespa/searchlib/attribute/attributevector.hpp> #include <vespa/searchlib/attribute/changevector.hpp> #include <vespa/searchlib/attribute/predicate_attribute.h> diff --git a/searchcore/src/vespa/searchcore/proton/docsummary/documentstoreadapter.cpp b/searchcore/src/vespa/searchcore/proton/docsummary/documentstoreadapter.cpp index 0e6ce5e689b..ecca993fa27 100644 --- a/searchcore/src/vespa/searchcore/proton/docsummary/documentstoreadapter.cpp +++ b/searchcore/src/vespa/searchcore/proton/docsummary/documentstoreadapter.cpp @@ -3,8 +3,7 @@ #include "documentstoreadapter.h" #include <vespa/searchsummary/docsummary/summaryfieldconverter.h> #include <vespa/document/fieldvalue/stringfieldvalue.h> -#include <vespa/eval/tensor/tensor.h> -#include <vespa/eval/tensor/serialization/typed_binary_format.h> +#include <vespa/eval/eval/engine_or_factory.h> #include <vespa/vespalib/objects/nbostream.h> #include <vespa/document/fieldvalue/tensorfieldvalue.h> @@ -13,7 +12,6 @@ LOG_SETUP(".proton.docsummary.documentstoreadapter"); using namespace document; using namespace search::docsummary; -using vespalib::tensor::Tensor; namespace proton { @@ -88,7 +86,7 @@ DocumentStoreAdapter::writeField(const FieldValue &value, ResType type) const auto &tvalue = static_cast<const TensorFieldValue &>(value); auto tensor = tvalue.getAsTensorPtr(); if (tensor) { - vespalib::tensor::TypedBinaryFormat::serialize(serialized, *tensor); + vespalib::eval::EngineOrFactory::get().encode(*tensor, serialized); } } return _resultPacker.AddSerializedTensor(serialized.peek(), serialized.size()); diff --git a/searchcore/src/vespa/searchcore/proton/matching/docsum_matcher.cpp b/searchcore/src/vespa/searchcore/proton/matching/docsum_matcher.cpp index abd4a9cfbe4..624daaf3cb8 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/docsum_matcher.cpp +++ b/searchcore/src/vespa/searchcore/proton/matching/docsum_matcher.cpp @@ -5,6 +5,7 @@ #include "search_session.h" #include <vespa/eval/eval/tensor.h> #include <vespa/eval/eval/tensor_engine.h> +#include <vespa/eval/eval/engine_or_factory.h> #include <vespa/vespalib/objects/nbostream.h> #include <vespa/searchcommon/attribute/i_search_context.h> #include <vespa/searchlib/queryeval/blueprint.h> @@ -71,9 +72,9 @@ get_feature_set(const MatchToolsFactory &mtf, for (uint32_t j = 0; j < featureNames.size(); ++j) { if (resolver.is_object(j)) { auto obj = resolver.resolve(j).as_object(docId); - if (const auto *tensor = obj.get().as_tensor()) { + if (! obj.get().is_double()) { vespalib::nbostream buf; - tensor->engine().encode(*tensor, buf); + vespalib::eval::EngineOrFactory::get().encode(obj.get(), buf); f[j].set_data(vespalib::Memory(buf.peek(), buf.size())); } else { f[j].set_double(obj.get().as_double()); diff --git a/searchcore/src/vespa/searchcore/proton/matching/requestcontext.cpp b/searchcore/src/vespa/searchcore/proton/matching/requestcontext.cpp index 86afeb5de24..cf8a8d0da06 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/requestcontext.cpp +++ b/searchcore/src/vespa/searchcore/proton/matching/requestcontext.cpp @@ -1,6 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "requestcontext.h" +#include <vespa/eval/eval/engine_or_factory.h> #include <vespa/eval/tensor/default_tensor_engine.h> #include <vespa/searchlib/attribute/attributevector.h> #include <vespa/searchlib/fef/properties.h> @@ -10,6 +11,8 @@ #include <vespa/log/log.h> LOG_SETUP(".proton.matching.requestcontext"); +using vespalib::eval::EngineOrFactory; + namespace proton { using search::attribute::IAttributeVector; @@ -50,7 +53,7 @@ RequestContext::get_query_tensor(const vespalib::string& tensor_name) const const vespalib::string& value = property.get(); vespalib::nbostream stream(value.data(), value.size()); try { - return vespalib::tensor::DefaultTensorEngine::ref().decode(stream); + return EngineOrFactory::get().decode(stream); } catch (vespalib::IllegalArgumentException& ex) { LOG(warning, "Query tensor '%s' could not be deserialized", tensor_name.c_str()); return vespalib::eval::Value::UP(); diff --git a/searchcore/src/vespa/searchcore/proton/matching/requestcontext.h b/searchcore/src/vespa/searchcore/proton/matching/requestcontext.h index ada11167983..3c48e40c33c 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/requestcontext.h +++ b/searchcore/src/vespa/searchcore/proton/matching/requestcontext.h @@ -2,7 +2,7 @@ #pragma once -#include <vespa/eval/tensor/tensor.h> +#include <vespa/eval/eval/value.h> #include <vespa/searchlib/queryeval/irequestcontext.h> #include <vespa/searchcommon/attribute/iattributecontext.h> #include <vespa/searchlib/attribute/attribute_blueprint_params.h> diff --git a/searchcore/src/vespa/searchcore/proton/server/searchabledocsubdb.cpp b/searchcore/src/vespa/searchcore/proton/server/searchabledocsubdb.cpp index 23ab568c767..481fe799f8f 100644 --- a/searchcore/src/vespa/searchcore/proton/server/searchabledocsubdb.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/searchabledocsubdb.cpp @@ -29,6 +29,7 @@ using search::TuneFileDocumentDB; using search::index::Schema; using search::SerialNum; using vespalib::ThreadStackExecutorBase; +using vespalib::eval::EngineOrFactory; using namespace searchcorespi; namespace proton { @@ -40,7 +41,7 @@ SearchableDocSubDB::SearchableDocSubDB(const Config &cfg, const Context &ctx) _indexWriter(), _rSearchView(), _rFeedView(), - _tensorLoader(vespalib::tensor::DefaultTensorEngine::ref()), + _tensorLoader(EngineOrFactory::get()), _constantValueCache(_tensorLoader), _constantValueRepo(_constantValueCache), _configurer(_iSummaryMgr, _rSearchView, _rFeedView, ctx._queryLimiter, _constantValueRepo, ctx._clock, diff --git a/searchlib/src/apps/vespa-ranking-expression-analyzer/vespa-ranking-expression-analyzer.cpp b/searchlib/src/apps/vespa-ranking-expression-analyzer/vespa-ranking-expression-analyzer.cpp index ae4b55948dc..51f243e1c37 100644 --- a/searchlib/src/apps/vespa-ranking-expression-analyzer/vespa-ranking-expression-analyzer.cpp +++ b/searchlib/src/apps/vespa-ranking-expression-analyzer/vespa-ranking-expression-analyzer.cpp @@ -9,6 +9,7 @@ #include <vespa/eval/eval/vm_forest.h> #include <vespa/eval/eval/fast_forest.h> #include <vespa/eval/eval/llvm/deinline_forest.h> +#include <vespa/eval/eval/engine_or_factory.h> #include <vespa/eval/tensor/default_tensor_engine.h> #include <vespa/vespalib/io/mapped_file_input.h> #include <vespa/eval/eval/param_usage.h> @@ -17,7 +18,6 @@ //----------------------------------------------------------------------------- using vespalib::BenchmarkTimer; -using vespalib::tensor::DefaultTensorEngine; using namespace vespalib::eval; using namespace vespalib::eval::nodes; using namespace vespalib::eval::gbdt; @@ -154,7 +154,7 @@ struct FunctionInfo { size_t get_path_len(const TreeList &trees) const { size_t path = 0; for (const Node *tree: trees) { - InterpretedFunction ifun(DefaultTensorEngine::ref(), *tree, NodeTypes()); + InterpretedFunction ifun(EngineOrFactory::get(), *tree, NodeTypes()); InterpretedFunction::Context ctx(ifun); SimpleParams fun_params(params); ifun.eval(ctx, fun_params); diff --git a/searchlib/src/tests/attribute/imported_attribute_vector/imported_attribute_vector_test.cpp b/searchlib/src/tests/attribute/imported_attribute_vector/imported_attribute_vector_test.cpp index 48a06bec9e8..387378659e9 100644 --- a/searchlib/src/tests/attribute/imported_attribute_vector/imported_attribute_vector_test.cpp +++ b/searchlib/src/tests/attribute/imported_attribute_vector/imported_attribute_vector_test.cpp @@ -1,6 +1,8 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/eval/tensor/tensor.h> +#include <vespa/eval/eval/engine_or_factory.h> +#include <vespa/eval/eval/value.h> +#include <vespa/eval/eval/test/value_compare.h> #include <vespa/eval/tensor/default_tensor_engine.h> #include <vespa/searchcommon/attribute/search_context_params.h> #include <vespa/searchlib/fef/termfieldmatchdata.h> @@ -11,17 +13,15 @@ using search::attribute::IAttributeVector; using search::tensor::ITensorAttribute; using search::tensor::TensorAttribute; +using vespalib::eval::Value; using vespalib::eval::ValueType; using vespalib::eval::TensorSpec; -using vespalib::tensor::Tensor; -using vespalib::tensor::DefaultTensorEngine; +using vespalib::eval::EngineOrFactory; -Tensor::UP createTensor(const TensorSpec &spec) { - auto value = DefaultTensorEngine::ref().from_spec(spec); - Tensor *tensor = dynamic_cast<Tensor*>(value.get()); - ASSERT_TRUE(tensor != nullptr); - value.release(); - return Tensor::UP(tensor); +Value::UP createTensor(const TensorSpec &spec) { + auto value = EngineOrFactory::get().from_spec(spec); + ASSERT_TRUE(value->is_tensor()); + return value; } namespace search::attribute { @@ -501,8 +501,8 @@ TEST("onSerializeForDescendingSort() is forwarded with remapped LID to target ve } struct TensorAttrFixture : Fixture { - std::shared_ptr<Tensor> tensor1; - std::shared_ptr<Tensor> tensor2; + std::shared_ptr<Value> tensor1; + std::shared_ptr<Value> tensor2; TensorAttrFixture(bool dense) : Fixture(), @@ -519,14 +519,14 @@ struct TensorAttrFixture : Fixture { tensor1 = createTensor(TensorSpec("tensor(x{})").add({{"x", "1"}}, 11)); tensor2 = createTensor(TensorSpec("tensor(x{})").add({{"x", "0"}}, 12)); } - const std::vector<ImportedAttributeFixture::LidToLidMapping<std::shared_ptr<Tensor>>> mappings = + const std::vector<ImportedAttributeFixture::LidToLidMapping<std::shared_ptr<Value>>> mappings = { {DocId(2), dummy_gid(3), DocId(3), tensor1 }, {DocId(4), dummy_gid(7), DocId(7), tensor2 } }; - this->template reset_with_tensor_reference_mappings<TensorAttribute, std::shared_ptr<Tensor>>( + this->template reset_with_tensor_reference_mappings<TensorAttribute, std::shared_ptr<Value>>( ValueType::from_spec(dense ? "tensor(x[2])" : "tensor(x{})"), mappings); } - Tensor::UP getTensor(DocId docId) { + Value::UP getTensor(DocId docId) { auto imp_attr = this->get_imported_attr(); const ITensorAttribute *tensorAttr = imp_attr->asTensorAttribute(); ASSERT_TRUE(tensorAttr != nullptr); @@ -536,7 +536,7 @@ struct TensorAttrFixture : Fixture { auto tensor = getTensor(docId); EXPECT_TRUE(!tensor); } - void assertTensor(DocId docId, const Tensor &expTensor) { + void assertTensor(DocId docId, const Value &expTensor) { auto tensor = getTensor(docId); ASSERT_TRUE(!!tensor); EXPECT_EQUAL(expTensor, *tensor); diff --git a/searchlib/src/tests/attribute/searchable/attributeblueprint_test.cpp b/searchlib/src/tests/attribute/searchable/attributeblueprint_test.cpp index 3098232b443..82e1d5c2b48 100644 --- a/searchlib/src/tests/attribute/searchable/attributeblueprint_test.cpp +++ b/searchlib/src/tests/attribute/searchable/attributeblueprint_test.cpp @@ -1,5 +1,6 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#include <vespa/eval/eval/engine_or_factory.h> #include <vespa/eval/tensor/default_tensor_engine.h> #include <vespa/eval/tensor/dense/dense_tensor_view.h> #include <vespa/searchcommon/attribute/iattributecontext.h> @@ -50,8 +51,9 @@ using search::queryeval::SearchIterator; using std::string; using std::vector; using vespalib::eval::TensorSpec; +using vespalib::eval::EngineOrFactory; +using vespalib::eval::Value; using vespalib::eval::ValueType; -using vespalib::tensor::DefaultTensorEngine; using namespace search::attribute; using namespace search; @@ -356,7 +358,7 @@ expect_nearest_neighbor_blueprint(const vespalib::string& attribute_tensor_type_ auto result = f.create_blueprint(); const auto& nearest = downcast<const NearestNeighborBlueprint>(*result); EXPECT_EQ(attribute_tensor_type_spec, nearest.get_attribute_tensor().getTensorType().to_spec()); - EXPECT_EQ(converted_query_tensor, DefaultTensorEngine::ref().to_spec(nearest.get_query_tensor())); + EXPECT_EQ(converted_query_tensor, EngineOrFactory::get().to_spec(nearest.get_query_tensor())); EXPECT_EQ(7u, nearest.get_target_num_hits()); } diff --git a/searchlib/src/tests/attribute/tensorattribute/tensorattribute_test.cpp b/searchlib/src/tests/attribute/tensorattribute/tensorattribute_test.cpp index b4bf571c756..2de95e89da5 100644 --- a/searchlib/src/tests/attribute/tensorattribute/tensorattribute_test.cpp +++ b/searchlib/src/tests/attribute/tensorattribute/tensorattribute_test.cpp @@ -1,9 +1,9 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include <vespa/document/base/exceptions.h> -#include <vespa/eval/tensor/default_tensor_engine.h> -#include <vespa/eval/tensor/dense/dense_tensor.h> -#include <vespa/eval/tensor/tensor.h> +#include <vespa/eval/eval/engine_or_factory.h> +#include <vespa/eval/eval/value.h> +#include <vespa/eval/eval/test/value_compare.h> #include <vespa/fastos/file.h> #include <vespa/searchlib/attribute/attribute_read_guard.h> #include <vespa/searchlib/attribute/attributeguard.h> @@ -50,36 +50,19 @@ using search::tensor::PrepareResult; using search::tensor::TensorAttribute; using vespalib::eval::TensorSpec; using vespalib::eval::ValueType; -using vespalib::tensor::DefaultTensorEngine; -using vespalib::tensor::DenseTensor; -using vespalib::tensor::DenseTensorView; -using vespalib::tensor::Tensor; +using vespalib::eval::Value; +using vespalib::eval::EngineOrFactory; using DoubleVector = std::vector<double>; using generation_t = vespalib::GenerationHandler::generation_t; -namespace vespalib::tensor { - -static bool operator==(const Tensor &lhs, const Tensor &rhs) -{ - return lhs.equals(rhs); -} - -} - vespalib::string sparseSpec("tensor(x{},y{})"); vespalib::string denseSpec("tensor(x[2],y[3])"); vespalib::string vec_2d_spec("tensor(x[2])"); -Tensor::UP createTensor(const TensorSpec &spec) { - auto value = DefaultTensorEngine::ref().from_spec(spec); - if (value->is_double()) { - return Tensor::UP(new DenseTensor<double>(ValueType::double_type(), {value->as_double()})); - } - Tensor *tensor = dynamic_cast<Tensor*>(value.get()); - ASSERT_TRUE(tensor != nullptr); - value.release(); - return Tensor::UP(tensor); +Value::UP createTensor(const TensorSpec &spec) { + auto value = EngineOrFactory::get().from_spec(spec); + return value; } TensorSpec @@ -418,7 +401,7 @@ struct Fixture { set_tensor_internal(docid, *_tensorAttr->getEmptyTensor()); } - void set_tensor_internal(uint32_t docId, const Tensor &tensor) { + void set_tensor_internal(uint32_t docId, const Value &tensor) { ensureSpace(docId); _tensorAttr->setTensor(docId, tensor); _attr->commit(); @@ -435,14 +418,14 @@ struct Fixture { void assertGetNoTensor(uint32_t docId) { AttributeGuard guard(_attr); - Tensor::UP actTensor = _tensorAttr->getTensor(docId); + Value::UP actTensor = _tensorAttr->getTensor(docId); EXPECT_FALSE(actTensor); } void assertGetTensor(const TensorSpec &expSpec, uint32_t docId) { - Tensor::UP expTensor = createTensor(expSpec); + Value::UP expTensor = createTensor(expSpec); AttributeGuard guard(_attr); - Tensor::UP actTensor = _tensorAttr->getTensor(docId); + Value::UP actTensor = _tensorAttr->getTensor(docId); EXPECT_TRUE(static_cast<bool>(actTensor)); EXPECT_EQUAL(*expTensor, *actTensor); } @@ -655,7 +638,7 @@ void Fixture::testEmptyTensor() { const TensorAttribute &tensorAttr = *_tensorAttr; - Tensor::UP emptyTensor = tensorAttr.getEmptyTensor(); + Value::UP emptyTensor = tensorAttr.getEmptyTensor(); if (_denseTensors) { vespalib::string expSpec = expEmptyDenseTensorSpec(); EXPECT_EQUAL(emptyTensor->type(), ValueType::from_spec(expSpec)); @@ -907,8 +890,6 @@ TEST_F("Nearest neighbor index type is added to attribute file header", DenseTen class NearestNeighborBlueprintFixture : public DenseTensorAttributeMockIndex { public: - using QueryTensor = DenseTensor<double>; - NearestNeighborBlueprintFixture() { set_tensor(1, vec_2d(1, 1)); set_tensor(2, vec_2d(2, 2)); @@ -922,12 +903,9 @@ public: set_tensor(10, vec_2d(0, 0)); } - std::unique_ptr<QueryTensor> createDenseTensor(const TensorSpec &spec) { - auto value = DefaultTensorEngine::ref().from_spec(spec); - QueryTensor *tensor = dynamic_cast<QueryTensor *>(value.get()); - ASSERT_TRUE(tensor != nullptr); - value.release(); - return std::unique_ptr<QueryTensor>(tensor); + std::unique_ptr<Value> createDenseTensor(const TensorSpec &spec) { + auto value = EngineOrFactory::get().from_spec(spec); + return value; } std::unique_ptr<NearestNeighborBlueprint> make_blueprint(double brute_force_limit = 0.05) { diff --git a/searchlib/src/tests/features/constant/constant_test.cpp b/searchlib/src/tests/features/constant/constant_test.cpp index e558839d2cf..e513e20a35c 100644 --- a/searchlib/src/tests/features/constant/constant_test.cpp +++ b/searchlib/src/tests/features/constant/constant_test.cpp @@ -1,14 +1,15 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include <vespa/vespalib/testkit/test_kit.h> - +#include <iostream> #include <vespa/searchlib/features/setup.h> #include <vespa/searchlib/fef/fef.h> #include <vespa/searchlib/fef/test/ftlib.h> #include <vespa/searchlib/fef/test/indexenvironment.h> #include <vespa/eval/eval/function.h> #include <vespa/eval/eval/tensor_spec.h> -#include <vespa/eval/tensor/tensor.h> -#include <vespa/eval/tensor/default_tensor_engine.h> +#include <vespa/eval/eval/engine_or_factory.h> +#include <vespa/eval/eval/value.h> +#include <vespa/eval/eval/test/value_compare.h> using search::feature_t; using namespace search::fef; @@ -20,15 +21,13 @@ using vespalib::eval::Value; using vespalib::eval::DoubleValue; using vespalib::eval::TensorSpec; using vespalib::eval::ValueType; -using vespalib::tensor::DefaultTensorEngine; -using vespalib::tensor::Tensor; +using vespalib::eval::EngineOrFactory; namespace { -Tensor::UP make_tensor(const TensorSpec &spec) { - auto tensor = DefaultTensorEngine::ref().from_spec(spec); - return Tensor::UP(dynamic_cast<Tensor*>(tensor.release())); +Value::UP make_tensor(const TensorSpec &spec) { + return EngineOrFactory::get().from_spec(spec); } } @@ -44,12 +43,12 @@ struct ExecFixture setup_search_features(factory); } bool setup() { return test.setup(); } - const Tensor &extractTensor(uint32_t docid) { + const Value &extractTensor(uint32_t docid) { Value::CREF value = test.resolveObjectFeature(docid); ASSERT_TRUE(value.get().is_tensor()); - return static_cast<const Tensor &>(*value.get().as_tensor()); + return value.get(); } - const Tensor &executeTensor(uint32_t docId = 1) { + const Value &executeTensor(uint32_t docId = 1) { return extractTensor(docId); } double extractDouble(uint32_t docid) { @@ -63,7 +62,7 @@ struct ExecFixture void addTensor(const vespalib::string &name, const TensorSpec &spec) { - Tensor::UP tensor = make_tensor(spec); + Value::UP tensor = make_tensor(spec); ValueType type(tensor->type()); test.getIndexEnv().addConstantValue(name, std::move(type), 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 2f710c5d6e1..3a755704c0d 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 @@ -6,8 +6,7 @@ #include <vespa/searchlib/fef/test/ftlib.h> #include <vespa/searchlib/fef/test/rankresult.h> #include <vespa/searchlib/fef/test/dummy_dependency_handler.h> -#include <vespa/eval/tensor/tensor.h> -#include <vespa/eval/tensor/serialization/typed_binary_format.h> +#include <vespa/eval/eval/engine_or_factory.h> #include <vespa/vespalib/objects/nbostream.h> #include <vespa/eval/tensor/dense/dense_tensor.h> @@ -108,9 +107,9 @@ struct ArrayFixture : FixtureBase { } template <typename ExpectedType> - void check_prepare_state_output(const vespalib::tensor::Tensor & tensor, const ExpectedType & expected) { + void check_prepare_state_output(const vespalib::eval::Value & tensor, const ExpectedType & expected) { vespalib::nbostream os; - vespalib::tensor::TypedBinaryFormat::serialize(os, tensor); + vespalib::eval::EngineOrFactory::get().encode(tensor, os); vespalib::string input_vector(os.data(), os.size()); check_prepare_state_output(".tensor", input_vector, expected); } diff --git a/searchlib/src/tests/features/tensor/tensor_test.cpp b/searchlib/src/tests/features/tensor/tensor_test.cpp index 18efd69d0b9..116b4ed2bb5 100644 --- a/searchlib/src/tests/features/tensor/tensor_test.cpp +++ b/searchlib/src/tests/features/tensor/tensor_test.cpp @@ -11,11 +11,11 @@ #include <vespa/searchlib/fef/test/queryenvironment.h> #include <vespa/searchlib/tensor/tensor_attribute.h> #include <vespa/searchlib/tensor/direct_tensor_attribute.h> +#include <vespa/eval/eval/engine_or_factory.h> #include <vespa/eval/eval/function.h> #include <vespa/eval/eval/tensor_spec.h> -#include <vespa/eval/tensor/tensor.h> -#include <vespa/eval/tensor/default_tensor_engine.h> -#include <vespa/eval/tensor/serialization/typed_binary_format.h> +#include <vespa/eval/eval/value.h> +#include <vespa/eval/eval/test/value_compare.h> #include <vespa/eval/tensor/test/test_utils.h> #include <vespa/vespalib/objects/nbostream.h> @@ -28,12 +28,11 @@ using search::AttributeFactory; using search::tensor::TensorAttribute; using search::tensor::DirectTensorAttribute; using search::AttributeVector; +using vespalib::eval::EngineOrFactory; using vespalib::eval::Function; using vespalib::eval::Value; using vespalib::eval::ValueType; using vespalib::eval::TensorSpec; -using vespalib::tensor::DefaultTensorEngine; -using vespalib::tensor::Tensor; using vespalib::tensor::test::makeTensor; using AVC = search::attribute::Config; @@ -46,8 +45,8 @@ using CollectionType = FieldInfo::CollectionType; namespace { -Tensor::UP make_empty(const vespalib::string &type) { - return makeTensor<Tensor>(TensorSpec(type)); +Value::UP make_empty(const vespalib::string &type) { + return EngineOrFactory::get().from_spec(TensorSpec(type)); } } @@ -114,7 +113,7 @@ struct ExecFixture DirectTensorAttribute *directAttr = dynamic_cast<DirectTensorAttribute *>(attrs[1].get()); - auto doc_tensor = makeTensor<Tensor>(TensorSpec("tensor(x{})") + auto doc_tensor = makeTensor<Value>(TensorSpec("tensor(x{})") .add({{"x", "a"}}, 3) .add({{"x", "b"}}, 5) .add({{"x", "c"}}, 7)); @@ -127,10 +126,10 @@ struct ExecFixture } void setQueryTensor(const vespalib::string &tensorName, const vespalib::string &tensorTypeSpec, - std::unique_ptr<Tensor> tensor) + std::unique_ptr<Value> tensor) { vespalib::nbostream stream; - vespalib::tensor::TypedBinaryFormat::serialize(stream, *tensor); + EngineOrFactory::get().encode(*tensor, stream); test.getQueryEnv().getProperties().add(tensorName, vespalib::stringref(stream.peek(), stream.size())); setQueryTensorType(tensorName, tensorTypeSpec); @@ -139,24 +138,24 @@ struct ExecFixture void setupQueryEnvironment() { setQueryTensor("tensorquery", "tensor(q{})", - makeTensor<Tensor>(TensorSpec("tensor(q{})") + makeTensor<Value>(TensorSpec("tensor(q{})") .add({{"q", "d"}}, 11 ) .add({{"q", "e"}}, 13 ) .add({{"q", "f"}}, 17 ))); setQueryTensor("mappedtensorquery", "tensor(x[2])", - makeTensor<Tensor>(TensorSpec("tensor(x{},y{})") + makeTensor<Value>(TensorSpec("tensor(x{},y{})") .add({{"x", "0"},{"y", "0"}}, 11 ) .add({{"x", "0"},{"y", "1"}}, 13 ) .add({{"x", "1"},{"y", "0"}}, 17 ))); setQueryTensorType("null", "tensor(q{})"); } - const Tensor &extractTensor(uint32_t docid) { + const Value &extractTensor(uint32_t docid) { Value::CREF value = test.resolveObjectFeature(docid); ASSERT_TRUE(value.get().is_tensor()); - return static_cast<const Tensor &>(*value.get().as_tensor()); + return value.get(); } - const Tensor &execute(uint32_t docId = 1) { + const Value &execute(uint32_t docId = 1) { return extractTensor(docId); } }; @@ -164,7 +163,7 @@ struct ExecFixture TEST_F("require that tensor attribute can be extracted as tensor in attribute feature", ExecFixture("attribute(tensorattr)")) { - EXPECT_EQUAL(*makeTensor<Tensor>(TensorSpec("tensor(x{})") + EXPECT_EQUAL(*makeTensor<Value>(TensorSpec("tensor(x{})") .add({{"x", "b"}}, 5) .add({{"x", "c"}}, 7) .add({{"x", "a"}}, 3)), f.execute()); @@ -173,7 +172,7 @@ TEST_F("require that tensor attribute can be extracted as tensor in attribute fe TEST_F("require that direct tensor attribute can be extracted in attribute feature", ExecFixture("attribute(directattr)")) { - EXPECT_EQUAL(*makeTensor<Tensor>(TensorSpec("tensor(x{})") + EXPECT_EQUAL(*makeTensor<Value>(TensorSpec("tensor(x{})") .add({{"x", "b"}}, 5) .add({{"x", "c"}}, 7) .add({{"x", "a"}}, 3)), f.execute()); @@ -182,7 +181,7 @@ TEST_F("require that direct tensor attribute can be extracted in attribute featu TEST_F("require that tensor from query can be extracted as tensor in query feature", ExecFixture("query(tensorquery)")) { - EXPECT_EQUAL(*makeTensor<Tensor>(TensorSpec("tensor(q{})") + EXPECT_EQUAL(*makeTensor<Value>(TensorSpec("tensor(q{})") .add({{"q", "f"}}, 17) .add({{"q", "d"}}, 11) .add({{"q", "e"}}, 13)), f.execute()); @@ -218,7 +217,7 @@ TEST_F("require that empty tensor with correct type is returned by direct tensor TEST_F("require that wrong tensor type from query tensor gives empty tensor", ExecFixture("query(mappedtensorquery)")) { - EXPECT_EQUAL(*makeTensor<Tensor>(TensorSpec("tensor(x[2])") + EXPECT_EQUAL(*makeTensor<Value>(TensorSpec("tensor(x[2])") .add({{"x", 0}}, 0) .add({{"x", 1}}, 0)), f.execute()); } diff --git a/searchlib/src/tests/features/tensor_from_labels/tensor_from_labels_test.cpp b/searchlib/src/tests/features/tensor_from_labels/tensor_from_labels_test.cpp index d2fc79f8fa2..6b43f97354f 100644 --- a/searchlib/src/tests/features/tensor_from_labels/tensor_from_labels_test.cpp +++ b/searchlib/src/tests/features/tensor_from_labels/tensor_from_labels_test.cpp @@ -12,9 +12,10 @@ #include <vespa/searchlib/fef/test/indexenvironment.h> #include <vespa/searchlib/fef/test/indexenvironmentbuilder.h> #include <vespa/searchlib/fef/test/queryenvironment.h> +#include <vespa/eval/eval/engine_or_factory.h> #include <vespa/eval/eval/function.h> -#include <vespa/eval/tensor/tensor.h> -#include <vespa/eval/tensor/default_tensor_engine.h> +#include <vespa/eval/eval/value.h> +#include <vespa/eval/eval/test/value_compare.h> using search::feature_t; using namespace search::fef; @@ -26,8 +27,7 @@ using search::StringAttribute; using vespalib::eval::Value; using vespalib::eval::Function; using vespalib::eval::TensorSpec; -using vespalib::tensor::DefaultTensorEngine; -using vespalib::tensor::Tensor; +using vespalib::eval::EngineOrFactory; typedef search::attribute::Config AVC; typedef search::attribute::BasicType AVBT; @@ -35,12 +35,12 @@ typedef search::attribute::CollectionType AVCT; typedef search::AttributeVector::SP AttributePtr; typedef FtTestApp FTA; -Tensor::UP make_tensor(const TensorSpec &spec) { - auto tensor = DefaultTensorEngine::ref().from_spec(spec); - return Tensor::UP(dynamic_cast<Tensor*>(tensor.release())); +Value::UP make_tensor(const TensorSpec &spec) { + auto tensor = EngineOrFactory::get().from_spec(spec); + return tensor; } -Tensor::UP make_empty(const vespalib::string &type) { +Value::UP make_empty(const vespalib::string &type) { return make_tensor(TensorSpec(type)); } @@ -121,12 +121,12 @@ struct ExecFixture test.getQueryEnv().getProperties().add("astr_query", "[d e f e]"); test.getQueryEnv().getProperties().add("aint_query", "[11 13 17]"); } - const Tensor &extractTensor(uint32_t docid) { + const Value &extractTensor(uint32_t docid) { Value::CREF value = test.resolveObjectFeature(docid); ASSERT_TRUE(value.get().is_tensor()); - return static_cast<const Tensor &>(*value.get().as_tensor()); + return value.get(); } - const Tensor &execute() { + const Value &execute() { return extractTensor(1); } }; diff --git a/searchlib/src/tests/features/tensor_from_weighted_set/tensor_from_weighted_set_test.cpp b/searchlib/src/tests/features/tensor_from_weighted_set/tensor_from_weighted_set_test.cpp index e0eee954a53..40a5b8a8cc7 100644 --- a/searchlib/src/tests/features/tensor_from_weighted_set/tensor_from_weighted_set_test.cpp +++ b/searchlib/src/tests/features/tensor_from_weighted_set/tensor_from_weighted_set_test.cpp @@ -12,10 +12,11 @@ #include <vespa/searchlib/fef/test/indexenvironment.h> #include <vespa/searchlib/fef/test/indexenvironmentbuilder.h> #include <vespa/searchlib/fef/test/queryenvironment.h> +#include <vespa/eval/eval/engine_or_factory.h> #include <vespa/eval/eval/function.h> #include <vespa/eval/eval/tensor_spec.h> -#include <vespa/eval/tensor/default_tensor_engine.h> -#include <vespa/eval/tensor/tensor.h> +#include <vespa/eval/eval/value.h> +#include <vespa/eval/eval/test/value_compare.h> using search::feature_t; using namespace search::fef; @@ -27,8 +28,7 @@ using search::StringAttribute; using vespalib::eval::Value; using vespalib::eval::Function; using vespalib::eval::TensorSpec; -using vespalib::tensor::Tensor; -using vespalib::tensor::DefaultTensorEngine; +using vespalib::eval::EngineOrFactory; typedef search::attribute::Config AVC; typedef search::attribute::BasicType AVBT; @@ -36,12 +36,12 @@ typedef search::attribute::CollectionType AVCT; typedef search::AttributeVector::SP AttributePtr; typedef FtTestApp FTA; -Tensor::UP make_tensor(const TensorSpec &spec) { - auto tensor = DefaultTensorEngine::ref().from_spec(spec); - return Tensor::UP(dynamic_cast<Tensor*>(tensor.release())); +Value::UP make_tensor(const TensorSpec &spec) { + auto tensor = EngineOrFactory::get().from_spec(spec); + return tensor; } -Tensor::UP make_empty(const vespalib::string &type) { +Value::UP make_empty(const vespalib::string &type) { return make_tensor(TensorSpec(type)); } @@ -120,12 +120,12 @@ struct ExecFixture void setupQueryEnvironment() { test.getQueryEnv().getProperties().add("wsquery", "{d:11,e:13,f:17}"); } - const Tensor &extractTensor(uint32_t docid) { + const Value &extractTensor(uint32_t docid) { Value::CREF value = test.resolveObjectFeature(docid); ASSERT_TRUE(value.get().is_tensor()); - return static_cast<const Tensor &>(*value.get().as_tensor()); + return value.get(); } - const Tensor &execute() { + const Value &execute() { return extractTensor(1); } }; diff --git a/searchlib/src/tests/queryeval/nearest_neighbor/nearest_neighbor_test.cpp b/searchlib/src/tests/queryeval/nearest_neighbor/nearest_neighbor_test.cpp index e8c83b8548a..0a28f0a4c17 100644 --- a/searchlib/src/tests/queryeval/nearest_neighbor/nearest_neighbor_test.cpp +++ b/searchlib/src/tests/queryeval/nearest_neighbor/nearest_neighbor_test.cpp @@ -3,9 +3,7 @@ #include <vespa/vespalib/testkit/test_kit.h> #include <vespa/vespalib/util/stringfmt.h> -#include <vespa/eval/tensor/default_tensor_engine.h> -#include <vespa/eval/tensor/dense/dense_tensor.h> -#include <vespa/eval/tensor/tensor.h> +#include <vespa/eval/eval/engine_or_factory.h> #include <vespa/searchlib/common/bitvector.h> #include <vespa/searchlib/common/feature.h> #include <vespa/searchlib/fef/matchdata.h> @@ -25,12 +23,11 @@ using search::feature_t; using search::tensor::DenseTensorAttribute; using search::AttributeVector; using search::BitVector; +using vespalib::eval::Value; using vespalib::eval::ValueType; using CellType = vespalib::eval::ValueType::CellType; using vespalib::eval::TensorSpec; -using vespalib::tensor::Tensor; -using vespalib::tensor::DenseTensorView; -using vespalib::tensor::DefaultTensorEngine; +using vespalib::eval::EngineOrFactory; using search::tensor::DistanceFunction; using search::attribute::DistanceMetric; @@ -43,15 +40,13 @@ vespalib::string denseSpecFloat("tensor<float>(x[2])"); DistanceFunction::UP euclid_d = search::tensor::make_distance_function(DistanceMetric::Euclidean, CellType::DOUBLE); DistanceFunction::UP euclid_f = search::tensor::make_distance_function(DistanceMetric::Euclidean, CellType::FLOAT); -std::unique_ptr<DenseTensorView> createTensor(const TensorSpec &spec) { - auto value = DefaultTensorEngine::ref().from_spec(spec); - DenseTensorView *tensor = dynamic_cast<DenseTensorView*>(value.get()); - ASSERT_TRUE(tensor != nullptr); - value.release(); - return std::unique_ptr<DenseTensorView>(tensor); +std::unique_ptr<Value> createTensor(const TensorSpec &spec) { + auto value = EngineOrFactory::get().from_spec(spec); + ASSERT_TRUE(value->is_tensor()); + return value; } -std::unique_ptr<DenseTensorView> createTensor(const vespalib::string& type_spec, double v1, double v2) { +std::unique_ptr<Value> createTensor(const vespalib::string& type_spec, double v1, double v2) { return createTensor(TensorSpec(type_spec).add({{"x", 0}}, v1) .add({{"x", 1}}, v2)); } @@ -106,7 +101,7 @@ struct Fixture } } - void setTensor(uint32_t docId, const Tensor &tensor) { + void setTensor(uint32_t docId, const Value &tensor) { ensureSpace(docId); _tensorAttr->setTensor(docId, tensor); _attr->commit(); @@ -127,7 +122,7 @@ struct Fixture }; template <bool strict> -SimpleResult find_matches(Fixture &env, const DenseTensorView &qtv) { +SimpleResult find_matches(Fixture &env, const Value &qtv) { auto md = MatchData::makeTestInstance(2, 2); auto &tfmd = *(md->resolveTermField(0)); auto &attr = *(env._tensorAttr); @@ -205,7 +200,7 @@ TEST("require that NearestNeighborIterator returns filtered results") { } template <bool strict> -std::vector<feature_t> get_rawscores(Fixture &env, const DenseTensorView &qtv) { +std::vector<feature_t> get_rawscores(Fixture &env, const Value &qtv) { auto md = MatchData::makeTestInstance(2, 2); auto &tfmd = *(md->resolveTermField(0)); auto &attr = *(env._tensorAttr); diff --git a/searchlib/src/tests/tensor/dense_tensor_store/dense_tensor_store_test.cpp b/searchlib/src/tests/tensor/dense_tensor_store/dense_tensor_store_test.cpp index 1d80fec720a..f2470fd0319 100644 --- a/searchlib/src/tests/tensor/dense_tensor_store/dense_tensor_store_test.cpp +++ b/searchlib/src/tests/tensor/dense_tensor_store/dense_tensor_store_test.cpp @@ -3,26 +3,28 @@ LOG_SETUP("dense_tensor_store_test"); #include <vespa/vespalib/testkit/test_kit.h> #include <vespa/searchlib/tensor/dense_tensor_store.h> +#include <vespa/eval/eval/engine_or_factory.h> #include <vespa/eval/eval/tensor_spec.h> +#include <vespa/eval/eval/test/value_compare.h> +#include <vespa/eval/eval/value.h> #include <vespa/eval/eval/value_type.h> #include <vespa/eval/tensor/default_tensor_engine.h> -#include <vespa/eval/tensor/tensor.h> #include <vespa/eval/tensor/dense/mutable_dense_tensor_view.h> using search::tensor::DenseTensorStore; using vespalib::eval::TensorSpec; +using vespalib::eval::Value; using vespalib::eval::ValueType; +using vespalib::eval::EngineOrFactory; using vespalib::tensor::MutableDenseTensorView; -using vespalib::tensor::Tensor; -using vespalib::tensor::DefaultTensorEngine; using EntryRef = DenseTensorStore::EntryRef; -Tensor::UP +Value::UP makeTensor(const TensorSpec &spec) { - auto tensor = DefaultTensorEngine::ref().from_spec(spec); - return Tensor::UP(dynamic_cast<Tensor *>(tensor.release())); + auto tensor = EngineOrFactory::get().from_spec(spec); + return tensor; } struct Fixture @@ -32,23 +34,23 @@ struct Fixture : store(ValueType::from_spec(tensorType)) {} void assertSetAndGetTensor(const TensorSpec &tensorSpec) { - Tensor::UP expTensor = makeTensor(tensorSpec); + Value::UP expTensor = makeTensor(tensorSpec); EntryRef ref = store.setTensor(*expTensor); - Tensor::UP actTensor = store.getTensor(ref); - EXPECT_EQUAL(expTensor->toSpec(), actTensor->toSpec()); + Value::UP actTensor = store.getTensor(ref); + EXPECT_EQUAL(*expTensor, *actTensor); assertTensorView(ref, *expTensor); } void assertEmptyTensor(const TensorSpec &tensorSpec) { - Tensor::UP expTensor = makeTensor(tensorSpec); + Value::UP expTensor = makeTensor(tensorSpec); EntryRef ref; - Tensor::UP actTensor = store.getTensor(ref); + Value::UP actTensor = store.getTensor(ref); EXPECT_TRUE(actTensor.get() == nullptr); assertTensorView(ref, *expTensor); } - void assertTensorView(EntryRef ref, const Tensor &expTensor) { + void assertTensorView(EntryRef ref, const Value &expTensor) { MutableDenseTensorView actTensor(store.type()); store.getTensor(ref, actTensor); - EXPECT_EQUAL(expTensor.toSpec(), actTensor.toSpec()); + EXPECT_EQUAL(expTensor, actTensor); } }; diff --git a/searchlib/src/tests/tensor/direct_tensor_store/direct_tensor_store_test.cpp b/searchlib/src/tests/tensor/direct_tensor_store/direct_tensor_store_test.cpp index 5a815a96dfb..4eb2c935234 100644 --- a/searchlib/src/tests/tensor/direct_tensor_store/direct_tensor_store_test.cpp +++ b/searchlib/src/tests/tensor/direct_tensor_store/direct_tensor_store_test.cpp @@ -2,30 +2,28 @@ #include <vespa/searchlib/tensor/direct_tensor_store.h> #include <vespa/vespalib/gtest/gtest.h> -#include <vespa/eval/tensor/default_tensor_engine.h> -#include <vespa/eval/tensor/tensor.h> +#include <vespa/eval/eval/engine_or_factory.h> +#include <vespa/eval/eval/value.h> #include <vespa/vespalib/datastore/datastore.hpp> using namespace search::tensor; using vespalib::datastore::EntryRef; +using vespalib::eval::EngineOrFactory; using vespalib::eval::TensorSpec; -using vespalib::tensor::DefaultTensorEngine; -using vespalib::tensor::Tensor; +using vespalib::eval::Value; vespalib::string tensor_spec("tensor(x{})"); -Tensor::UP +Value::UP make_tensor(const TensorSpec& spec) { - auto value = DefaultTensorEngine::ref().from_spec(spec); - auto* tensor = dynamic_cast<Tensor*>(value.get()); - assert(tensor != nullptr); - value.release(); - return Tensor::UP(tensor); + auto value = EngineOrFactory::get().from_spec(spec); + assert(value->is_tensor()); + return value; } -Tensor::UP +Value::UP make_tensor(double value) { return make_tensor(TensorSpec(tensor_spec).add({{"x", "a"}}, value)); @@ -41,7 +39,7 @@ public: store.clearHoldLists(); } - void expect_tensor(const Tensor* exp, EntryRef ref) { + void expect_tensor(const Value* exp, EntryRef ref) { const auto* act = store.get_tensor(ref); ASSERT_TRUE(act); EXPECT_EQ(exp, act); diff --git a/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp b/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp index bc0b5366fac..b8110b4556d 100644 --- a/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp +++ b/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp @@ -82,7 +82,6 @@ using search::tensor::DenseTensorAttribute; using vespalib::geo::ZCurve; using vespalib::make_string; using vespalib::string; -using vespalib::tensor::DenseTensorView; namespace search { namespace { @@ -724,19 +723,17 @@ public: if (query_tensor.get() == nullptr) { return fail_nearest_neighbor_term(n, "Query tensor was not found in request context"); } - auto* dense_query_tensor = dynamic_cast<DenseTensorView*>(query_tensor.get()); - if (dense_query_tensor == nullptr) { + const auto & qt_type = query_tensor->type(); + if (! qt_type.is_dense()) { return fail_nearest_neighbor_term(n, make_string("Query tensor is not a dense tensor (type=%s)", query_tensor->type().to_spec().c_str())); } - if (!is_compatible_for_nearest_neighbor(dense_attr_tensor->getTensorType(), dense_query_tensor->type())) { + if (!is_compatible_for_nearest_neighbor(dense_attr_tensor->getTensorType(), qt_type)) { return fail_nearest_neighbor_term(n, make_string("Attribute tensor type (%s) and query tensor type (%s) are not compatible", - dense_attr_tensor->getTensorType().to_spec().c_str(), dense_query_tensor->type().to_spec().c_str())); + dense_attr_tensor->getTensorType().to_spec().c_str(), query_tensor->type().to_spec().c_str())); } - std::unique_ptr<DenseTensorView> dense_query_tensor_up(dense_query_tensor); - query_tensor.release(); setResult(std::make_unique<queryeval::NearestNeighborBlueprint>(_field, *dense_attr_tensor, - std::move(dense_query_tensor_up), + std::move(query_tensor), n.get_target_num_hits(), n.get_allow_approximate(), n.get_explore_additional_hits(), diff --git a/searchlib/src/vespa/searchlib/features/constant_tensor_executor.h b/searchlib/src/vespa/searchlib/features/constant_tensor_executor.h index 785eb357795..44e530821a2 100644 --- a/searchlib/src/vespa/searchlib/features/constant_tensor_executor.h +++ b/searchlib/src/vespa/searchlib/features/constant_tensor_executor.h @@ -6,6 +6,7 @@ #include <vespa/eval/eval/tensor_spec.h> #include <vespa/eval/eval/value.h> #include <vespa/eval/eval/value_type.h> +#include <vespa/eval/eval/engine_or_factory.h> #include <vespa/eval/tensor/default_tensor_engine.h> #include <vespa/vespalib/util/stash.h> @@ -27,11 +28,11 @@ public: void execute(uint32_t) override { outputs().set_object(0, *_tensor); } - static fef::FeatureExecutor &create(std::unique_ptr<vespalib::eval::Tensor> tensor, vespalib::Stash &stash) { + static fef::FeatureExecutor &create(std::unique_ptr<vespalib::eval::Value> tensor, vespalib::Stash &stash) { return stash.create<ConstantTensorExecutor>(std::move(tensor)); } static fef::FeatureExecutor &createEmpty(const vespalib::eval::ValueType &valueType, vespalib::Stash &stash) { - const auto &engine = vespalib::tensor::DefaultTensorEngine::ref(); + const auto engine = vespalib::eval::EngineOrFactory::get(); auto spec = vespalib::eval::TensorSpec(valueType.to_spec()); return stash.create<ConstantTensorExecutor>(engine.from_spec(spec)); } diff --git a/searchlib/src/vespa/searchlib/features/dense_tensor_attribute_executor.cpp b/searchlib/src/vespa/searchlib/features/dense_tensor_attribute_executor.cpp index 3dfba3092cd..8f7d82adadd 100644 --- a/searchlib/src/vespa/searchlib/features/dense_tensor_attribute_executor.cpp +++ b/searchlib/src/vespa/searchlib/features/dense_tensor_attribute_executor.cpp @@ -4,7 +4,6 @@ #include <vespa/searchlib/tensor/i_tensor_attribute.h> using search::tensor::ITensorAttribute; -using vespalib::eval::Tensor; using vespalib::tensor::MutableDenseTensorView; namespace search::features { diff --git a/searchlib/src/vespa/searchlib/features/direct_tensor_attribute_executor.cpp b/searchlib/src/vespa/searchlib/features/direct_tensor_attribute_executor.cpp index 56765bd168f..0463b253740 100644 --- a/searchlib/src/vespa/searchlib/features/direct_tensor_attribute_executor.cpp +++ b/searchlib/src/vespa/searchlib/features/direct_tensor_attribute_executor.cpp @@ -1,7 +1,6 @@ // Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "direct_tensor_attribute_executor.h" -#include <vespa/eval/tensor/tensor.h> #include <vespa/searchlib/tensor/i_tensor_attribute.h> namespace search::features { diff --git a/searchlib/src/vespa/searchlib/features/onnx_feature.cpp b/searchlib/src/vespa/searchlib/features/onnx_feature.cpp index fca8988ba36..e40b6ebf3e4 100644 --- a/searchlib/src/vespa/searchlib/features/onnx_feature.cpp +++ b/searchlib/src/vespa/searchlib/features/onnx_feature.cpp @@ -21,7 +21,6 @@ using search::fef::ParameterList; using vespalib::Stash; using vespalib::eval::ValueType; using vespalib::make_string_short::fmt; -using vespalib::tensor::DenseTensorView; using vespalib::tensor::MutableDenseTensorView; using vespalib::tensor::Onnx; diff --git a/searchlib/src/vespa/searchlib/features/queryfeature.cpp b/searchlib/src/vespa/searchlib/features/queryfeature.cpp index 12cad613a80..9cded69d5de 100644 --- a/searchlib/src/vespa/searchlib/features/queryfeature.cpp +++ b/searchlib/src/vespa/searchlib/features/queryfeature.cpp @@ -11,8 +11,6 @@ #include <vespa/searchlib/fef/properties.h> #include <vespa/searchlib/fef/feature_type.h> #include <vespa/vespalib/objects/nbostream.h> -#include <vespa/eval/tensor/serialization/typed_binary_format.h> -#include <vespa/eval/tensor/tensor.h> #include <vespa/eval/eval/value_type.h> #include <vespa/vespalib/locale/c.h> #include <cerrno> @@ -121,7 +119,7 @@ createTensorExecutor(const IQueryEnvironment &env, if (prop.found() && !prop.get().empty()) { const vespalib::string &value = prop.get(); vespalib::nbostream stream(value.data(), value.size()); - auto tensor = vespalib::tensor::TypedBinaryFormat::deserialize(stream); + auto tensor = vespalib::eval::EngineOrFactory::get().decode(stream); if (!TensorDataType::isAssignableType(valueType, tensor->type())) { LOG(warning, "Query feature type is '%s' but other tensor type is '%s'", valueType.to_spec().c_str(), tensor->type().to_spec().c_str()); diff --git a/searchlib/src/vespa/searchlib/features/rankingexpressionfeature.cpp b/searchlib/src/vespa/searchlib/features/rankingexpressionfeature.cpp index bf0a731eaef..c8cc573c0d2 100644 --- a/searchlib/src/vespa/searchlib/features/rankingexpressionfeature.cpp +++ b/searchlib/src/vespa/searchlib/features/rankingexpressionfeature.cpp @@ -5,6 +5,7 @@ #include <vespa/searchlib/fef/properties.h> #include <vespa/searchlib/fef/indexproperties.h> #include <vespa/searchlib/features/rankingexpression/feature_name_extractor.h> +#include <vespa/eval/eval/engine_or_factory.h> #include <vespa/eval/tensor/default_tensor_engine.h> #include <vespa/eval/eval/param_usage.h> @@ -17,6 +18,7 @@ using vespalib::ConstArrayRef; using vespalib::eval::CompileCache; using vespalib::eval::CompiledFunction; using vespalib::eval::DoubleValue; +using vespalib::eval::EngineOrFactory; using vespalib::eval::Function; using vespalib::eval::InterpretedFunction; using vespalib::eval::LazyParams; @@ -25,7 +27,6 @@ using vespalib::eval::PassParams; using vespalib::eval::Value; using vespalib::eval::ValueType; using vespalib::eval::gbdt::FastForest; -using vespalib::tensor::DefaultTensorEngine; namespace search::features { @@ -325,7 +326,8 @@ RankingExpressionBlueprint::setup(const fef::IIndexEnvironment &env, } } } else { - _interpreted_function.reset(new InterpretedFunction(DefaultTensorEngine::ref(), *rank_function, node_types)); + _interpreted_function.reset(new InterpretedFunction(EngineOrFactory::get(), + *rank_function, node_types)); } } FeatureType output_type = do_compile diff --git a/searchlib/src/vespa/searchlib/features/tensor_attribute_executor.h b/searchlib/src/vespa/searchlib/features/tensor_attribute_executor.h index be900e8a3e7..f22922e4d12 100644 --- a/searchlib/src/vespa/searchlib/features/tensor_attribute_executor.h +++ b/searchlib/src/vespa/searchlib/features/tensor_attribute_executor.h @@ -5,8 +5,6 @@ #include <vespa/searchcommon/attribute/iattributevector.h> #include <vespa/searchlib/fef/featureexecutor.h> #include <vespa/eval/eval/value.h> -#include <vespa/eval/eval/tensor.h> -#include <vespa/eval/tensor/tensor.h> #include <vespa/vespalib/stllike/string.h> namespace search::tensor { class ITensorAttribute; } @@ -16,8 +14,8 @@ class TensorAttributeExecutor : public fef::FeatureExecutor { private: const search::tensor::ITensorAttribute& _attribute; - std::unique_ptr<vespalib::eval::Tensor> _emptyTensor; - std::unique_ptr<vespalib::eval::Tensor> _tensor; + std::unique_ptr<vespalib::eval::Value> _emptyTensor; + std::unique_ptr<vespalib::eval::Value> _tensor; public: TensorAttributeExecutor(const search::tensor::ITensorAttribute& attribute); diff --git a/searchlib/src/vespa/searchlib/features/tensor_from_attribute_executor.h b/searchlib/src/vespa/searchlib/features/tensor_from_attribute_executor.h index aae3d773820..a6d3de54d00 100644 --- a/searchlib/src/vespa/searchlib/features/tensor_from_attribute_executor.h +++ b/searchlib/src/vespa/searchlib/features/tensor_from_attribute_executor.h @@ -5,7 +5,6 @@ #include <vespa/searchcommon/attribute/iattributevector.h> #include <vespa/eval/eval/value.h> #include <vespa/vespalib/stllike/string.h> -#include <vespa/eval/tensor/tensor.h> #include <vespa/eval/tensor/sparse/direct_sparse_tensor_builder.h> namespace search::features { @@ -21,7 +20,7 @@ private: const search::attribute::IAttributeVector *_attribute; vespalib::eval::ValueType _type; WeightedBufferType _attrBuffer; - std::unique_ptr<vespalib::tensor::Tensor> _tensor; + std::unique_ptr<vespalib::eval::Value> _tensor; public: TensorFromAttributeExecutor(const search::attribute::IAttributeVector *attribute, diff --git a/searchlib/src/vespa/searchlib/features/tensor_from_weighted_set_feature.cpp b/searchlib/src/vespa/searchlib/features/tensor_from_weighted_set_feature.cpp index 5926c91c7c5..8c290e1f2b0 100644 --- a/searchlib/src/vespa/searchlib/features/tensor_from_weighted_set_feature.cpp +++ b/searchlib/src/vespa/searchlib/features/tensor_from_weighted_set_feature.cpp @@ -12,8 +12,8 @@ #include <vespa/searchcommon/attribute/attributecontent.h> #include <vespa/searchcommon/attribute/iattributevector.h> #include <vespa/eval/eval/function.h> -#include <vespa/eval/tensor/tensor.h> #include <vespa/eval/eval/value_type.h> +#include <vespa/eval/tensor/sparse/direct_sparse_tensor_builder.h> #include <vespa/log/log.h> LOG_SETUP(".features.tensor_from_weighted_set_feature"); diff --git a/searchlib/src/vespa/searchlib/index/docbuilder.cpp b/searchlib/src/vespa/searchlib/index/docbuilder.cpp index b79aa423413..a5557a59464 100644 --- a/searchlib/src/vespa/searchlib/index/docbuilder.cpp +++ b/searchlib/src/vespa/searchlib/index/docbuilder.cpp @@ -6,7 +6,7 @@ #include <vespa/fastlib/text/unicodeutil.h> #include <vespa/vespalib/geo/zcurve.h> #include <vespa/vespalib/text/utf8.h> -#include <vespa/eval/tensor/tensor.h> +#include <vespa/eval/eval/value.h> #include <vespa/vespalib/data/slime/slime.h> using namespace document; @@ -74,7 +74,7 @@ void insertPredicate(const Schema::Field &sfield, void insertTensor(const Schema::Field &schemaField, document::FieldValue *fvalue, - std::unique_ptr<vespalib::tensor::Tensor> val) { + std::unique_ptr<vespalib::eval::Value> val) { if (schemaField.getDataType() == schema::DataType::TENSOR) { *(dynamic_cast<TensorFieldValue *>(fvalue)) = std::move(val); } else { @@ -539,7 +539,7 @@ DocBuilder::AttributeFieldHandle::addPredicate( void DocBuilder::AttributeFieldHandle::addTensor( - std::unique_ptr<vespalib::tensor::Tensor> val) + std::unique_ptr<vespalib::eval::Value> val) { if (_element) { insertTensor(_sfield, _element.get(), std::move(val)); @@ -773,7 +773,7 @@ DocBuilder::addPredicate(std::unique_ptr<vespalib::Slime> val) } DocBuilder & -DocBuilder::addTensor(std::unique_ptr<vespalib::tensor::Tensor> val) +DocBuilder::addTensor(std::unique_ptr<vespalib::eval::Value> val) { assert(_currDoc != nullptr); _currDoc->getFieldHandle()->addTensor(std::move(val)); diff --git a/searchlib/src/vespa/searchlib/index/docbuilder.h b/searchlib/src/vespa/searchlib/index/docbuilder.h index 3aaeb26146b..4b22e35e5c9 100644 --- a/searchlib/src/vespa/searchlib/index/docbuilder.h +++ b/searchlib/src/vespa/searchlib/index/docbuilder.h @@ -13,7 +13,7 @@ #include <vespa/vespalib/util/exception.h> #include <vespa/vespalib/util/stringfmt.h> -namespace vespalib::tensor { class Tensor; } +namespace vespalib::eval { class Value; } namespace search::index { @@ -96,7 +96,7 @@ private: virtual void addPredicate(std::unique_ptr<vespalib::Slime>) { throw Error("Function not supported"); } - virtual void addTensor(std::unique_ptr<vespalib::tensor::Tensor>) { + virtual void addTensor(std::unique_ptr<vespalib::eval::Value>) { throw Error("Function not supported"); } const document::FieldValue::UP & getValue() const { return _value; } @@ -203,7 +203,7 @@ private: void addInt(int64_t val) override; void addFloat(double val) override; void addPredicate(std::unique_ptr<vespalib::Slime> val) override; - void addTensor(std::unique_ptr<vespalib::tensor::Tensor> val) override; + void addTensor(std::unique_ptr<vespalib::eval::Value> val) override; void addPosition(int32_t xpos, int32_t ypos) override; }; @@ -280,7 +280,7 @@ public: DocBuilder & addInt(int64_t val); DocBuilder & addFloat(double val); DocBuilder & addPredicate(std::unique_ptr<vespalib::Slime> val); - DocBuilder & addTensor(std::unique_ptr<vespalib::tensor::Tensor> val); + DocBuilder & addTensor(std::unique_ptr<vespalib::eval::Value> val); DocBuilder &addTokenizedString(const vespalib::string &val); DocBuilder &addUrlTokenizedString(const vespalib::string &val); DocBuilder &addSpan(size_t start, size_t len); diff --git a/searchlib/src/vespa/searchlib/queryeval/fake_requestcontext.h b/searchlib/src/vespa/searchlib/queryeval/fake_requestcontext.h index 94257363c60..96fb2968188 100644 --- a/searchlib/src/vespa/searchlib/queryeval/fake_requestcontext.h +++ b/searchlib/src/vespa/searchlib/queryeval/fake_requestcontext.h @@ -4,6 +4,7 @@ #include <vespa/eval/eval/tensor_spec.h> #include <vespa/eval/eval/value.h> +#include <vespa/eval/eval/engine_or_factory.h> #include <vespa/eval/tensor/default_tensor_engine.h> #include <vespa/searchcommon/attribute/iattributecontext.h> #include <vespa/searchlib/attribute/attributevector.h> @@ -34,7 +35,7 @@ public: } vespalib::eval::Value::UP get_query_tensor(const vespalib::string& tensor_name) const override { if (_query_tensor && (tensor_name == _query_tensor_name)) { - return vespalib::tensor::DefaultTensorEngine::ref().from_spec(*_query_tensor); + return vespalib::eval::EngineOrFactory::get().from_spec(*_query_tensor); } return vespalib::eval::Value::UP(); } diff --git a/searchlib/src/vespa/searchlib/queryeval/nearest_neighbor_blueprint.cpp b/searchlib/src/vespa/searchlib/queryeval/nearest_neighbor_blueprint.cpp index e99e14c8d6b..d75cda2e513 100644 --- a/searchlib/src/vespa/searchlib/queryeval/nearest_neighbor_blueprint.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/nearest_neighbor_blueprint.cpp @@ -5,7 +5,6 @@ #include "nearest_neighbor_iterator.h" #include "nns_index_iterator.h" #include <vespa/searchlib/fef/termfieldmatchdataarray.h> -#include <vespa/eval/tensor/dense/dense_tensor_view.h> #include <vespa/eval/tensor/dense/dense_tensor.h> #include <vespa/searchlib/tensor/dense_tensor_attribute.h> #include <vespa/searchlib/tensor/distance_function_factory.h> @@ -13,7 +12,7 @@ LOG_SETUP(".searchlib.queryeval.nearest_neighbor_blueprint"); -using vespalib::tensor::DenseTensorView; +using vespalib::eval::Value; using vespalib::tensor::DenseTensor; namespace search::queryeval { @@ -22,7 +21,7 @@ namespace { template<typename LCT, typename RCT> void -convert_cells(std::unique_ptr<DenseTensorView> &original, vespalib::eval::ValueType want_type) +convert_cells(std::unique_ptr<Value> &original, vespalib::eval::ValueType want_type) { auto old_cells = original->cells().typify<LCT>(); std::vector<RCT> new_cells; @@ -36,11 +35,11 @@ convert_cells(std::unique_ptr<DenseTensorView> &original, vespalib::eval::ValueT template<> void -convert_cells<float,float>(std::unique_ptr<DenseTensorView> &, vespalib::eval::ValueType) {} +convert_cells<float,float>(std::unique_ptr<Value> &, vespalib::eval::ValueType) {} template<> void -convert_cells<double,double>(std::unique_ptr<DenseTensorView> &, vespalib::eval::ValueType) {} +convert_cells<double,double>(std::unique_ptr<Value> &, vespalib::eval::ValueType) {} struct ConvertCellsSelector { @@ -52,7 +51,7 @@ struct ConvertCellsSelector NearestNeighborBlueprint::NearestNeighborBlueprint(const queryeval::FieldSpec& field, const tensor::DenseTensorAttribute& attr_tensor, - std::unique_ptr<vespalib::tensor::DenseTensorView> query_tensor, + std::unique_ptr<Value> query_tensor, uint32_t target_num_hits, bool approximate, uint32_t explore_additional_hits, double brute_force_limit) : ComplexLeafBlueprint(field), _attr_tensor(attr_tensor), @@ -120,7 +119,7 @@ NearestNeighborBlueprint::perform_top_k() { auto nns_index = _attr_tensor.nearest_neighbor_index(); if (_approximate && nns_index) { - auto lhs_type = _query_tensor->fast_type(); + auto lhs_type = _query_tensor->type(); auto rhs_type = _attr_tensor.getTensorType(); // different cell types should be converted already if (lhs_type == rhs_type) { @@ -144,7 +143,7 @@ NearestNeighborBlueprint::createLeafSearch(const search::fef::TermFieldMatchData if (! _found_hits.empty()) { return NnsIndexIterator::create(tfmd, _found_hits, _dist_fun); } - const vespalib::tensor::DenseTensorView &qT = *_query_tensor; + const Value &qT = *_query_tensor; return NearestNeighborIterator::create(strict, tfmd, qT, _attr_tensor, _distance_heap, _global_filter->filter(), _dist_fun); } diff --git a/searchlib/src/vespa/searchlib/queryeval/nearest_neighbor_blueprint.h b/searchlib/src/vespa/searchlib/queryeval/nearest_neighbor_blueprint.h index 8656e5b4bf2..ebabf3a95eb 100644 --- a/searchlib/src/vespa/searchlib/queryeval/nearest_neighbor_blueprint.h +++ b/searchlib/src/vespa/searchlib/queryeval/nearest_neighbor_blueprint.h @@ -6,8 +6,8 @@ #include <vespa/searchlib/tensor/distance_function.h> #include <vespa/searchlib/tensor/nearest_neighbor_index.h> -namespace vespalib::tensor { class DenseTensorView; } namespace search::tensor { class DenseTensorAttribute; } +namespace vespalib::eval { class Value; } namespace search::queryeval { @@ -20,7 +20,7 @@ namespace search::queryeval { class NearestNeighborBlueprint : public ComplexLeafBlueprint { private: const tensor::DenseTensorAttribute& _attr_tensor; - std::unique_ptr<vespalib::tensor::DenseTensorView> _query_tensor; + std::unique_ptr<vespalib::eval::Value> _query_tensor; uint32_t _target_num_hits; bool _approximate; uint32_t _explore_additional_hits; @@ -35,13 +35,13 @@ private: public: NearestNeighborBlueprint(const queryeval::FieldSpec& field, const tensor::DenseTensorAttribute& attr_tensor, - std::unique_ptr<vespalib::tensor::DenseTensorView> query_tensor, + std::unique_ptr<vespalib::eval::Value> query_tensor, uint32_t target_num_hits, bool approximate, uint32_t explore_additional_hits, double brute_force_limit); NearestNeighborBlueprint(const NearestNeighborBlueprint&) = delete; NearestNeighborBlueprint& operator=(const NearestNeighborBlueprint&) = delete; ~NearestNeighborBlueprint(); const tensor::DenseTensorAttribute& get_attribute_tensor() const { return _attr_tensor; } - const vespalib::tensor::DenseTensorView& get_query_tensor() const { return *_query_tensor; } + const vespalib::eval::Value& get_query_tensor() const { return *_query_tensor; } uint32_t get_target_num_hits() const { return _target_num_hits; } void set_global_filter(const GlobalFilter &global_filter) override; bool may_approximate() const { return _approximate; } diff --git a/searchlib/src/vespa/searchlib/queryeval/nearest_neighbor_iterator.cpp b/searchlib/src/vespa/searchlib/queryeval/nearest_neighbor_iterator.cpp index 3012de7563b..dd685ce5c43 100644 --- a/searchlib/src/vespa/searchlib/queryeval/nearest_neighbor_iterator.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/nearest_neighbor_iterator.cpp @@ -5,7 +5,6 @@ using search::tensor::DenseTensorAttribute; using vespalib::ConstArrayRef; -using vespalib::tensor::DenseTensorView; using vespalib::tensor::MutableDenseTensorView; using vespalib::eval::TypedCells; @@ -41,7 +40,7 @@ public: _fieldTensor(params().tensorAttribute.getTensorType()), _lastScore(0.0) { - assert(is_compatible(_fieldTensor.fast_type(), params().queryTensor.fast_type())); + assert(is_compatible(_fieldTensor.fast_type(), params().queryTensor.type())); } ~NearestNeighborImpl(); @@ -95,7 +94,7 @@ template <bool has_filter> std::unique_ptr<NearestNeighborIterator> resolve_strict(bool strict, const NearestNeighborIterator::Params ¶ms) { - CellType lct = params.queryTensor.fast_type().cell_type(); + CellType lct = params.queryTensor.type().cell_type(); CellType rct = params.tensorAttribute.getTensorType().cell_type(); if (lct != rct) abort(); if (strict) { @@ -113,7 +112,7 @@ std::unique_ptr<NearestNeighborIterator> NearestNeighborIterator::create( bool strict, fef::TermFieldMatchData &tfmd, - const vespalib::tensor::DenseTensorView &queryTensor, + const vespalib::eval::Value &queryTensor, const search::tensor::DenseTensorAttribute &tensorAttribute, NearestNeighborDistanceHeap &distanceHeap, const search::BitVector *filter, diff --git a/searchlib/src/vespa/searchlib/queryeval/nearest_neighbor_iterator.h b/searchlib/src/vespa/searchlib/queryeval/nearest_neighbor_iterator.h index 9cbb1d39a91..9b8ad6295b3 100644 --- a/searchlib/src/vespa/searchlib/queryeval/nearest_neighbor_iterator.h +++ b/searchlib/src/vespa/searchlib/queryeval/nearest_neighbor_iterator.h @@ -4,7 +4,7 @@ #include "searchiterator.h" #include "nearest_neighbor_distance_heap.h" -#include <vespa/eval/tensor/dense/dense_tensor_view.h> +#include <vespa/eval/eval/value.h> #include <vespa/eval/tensor/dense/mutable_dense_tensor_view.h> #include <vespa/searchlib/fef/termfieldmatchdata.h> #include <vespa/searchlib/tensor/dense_tensor_attribute.h> @@ -18,18 +18,18 @@ class NearestNeighborIterator : public SearchIterator { public: using DenseTensorAttribute = search::tensor::DenseTensorAttribute; - using DenseTensorView = vespalib::tensor::DenseTensorView; + using Value = vespalib::eval::Value; struct Params { fef::TermFieldMatchData &tfmd; - const DenseTensorView &queryTensor; + const Value &queryTensor; const DenseTensorAttribute &tensorAttribute; NearestNeighborDistanceHeap &distanceHeap; const search::BitVector *filter; const search::tensor::DistanceFunction *distanceFunction; Params(fef::TermFieldMatchData &tfmd_in, - const DenseTensorView &queryTensor_in, + const Value &queryTensor_in, const DenseTensorAttribute &tensorAttribute_in, NearestNeighborDistanceHeap &distanceHeap_in, const search::BitVector *filter_in, @@ -50,7 +50,7 @@ public: static std::unique_ptr<NearestNeighborIterator> create( bool strict, fef::TermFieldMatchData &tfmd, - const vespalib::tensor::DenseTensorView &queryTensor, + const Value &queryTensor, const search::tensor::DenseTensorAttribute &tensorAttribute, NearestNeighborDistanceHeap &distanceHeap, const search::BitVector *filter, diff --git a/searchlib/src/vespa/searchlib/tensor/dense_tensor_attribute.cpp b/searchlib/src/vespa/searchlib/tensor/dense_tensor_attribute.cpp index 81c8df982b1..8bd276e7dd9 100644 --- a/searchlib/src/vespa/searchlib/tensor/dense_tensor_attribute.cpp +++ b/searchlib/src/vespa/searchlib/tensor/dense_tensor_attribute.cpp @@ -7,7 +7,6 @@ #include "tensor_attribute.hpp" #include <vespa/eval/tensor/dense/dense_tensor_view.h> #include <vespa/eval/tensor/dense/mutable_dense_tensor_view.h> -#include <vespa/eval/tensor/tensor.h> #include <vespa/fastlib/io/bufferedfile.h> #include <vespa/searchlib/attribute/load_utils.h> #include <vespa/searchlib/attribute/readerbase.h> @@ -17,11 +16,10 @@ LOG_SETUP(".searchlib.tensor.dense_tensor_attribute"); using search::attribute::LoadUtils; +using vespalib::eval::Value; using vespalib::eval::ValueType; using vespalib::slime::ObjectInserter; -using vespalib::tensor::DenseTensorView; using vespalib::tensor::MutableDenseTensorView; -using vespalib::tensor::Tensor; namespace search::tensor { @@ -79,7 +77,7 @@ can_use_index_save_file(const search::attribute::Config &config, const search::a } void -DenseTensorAttribute::internal_set_tensor(DocId docid, const Tensor& tensor) +DenseTensorAttribute::internal_set_tensor(DocId docid, const vespalib::eval::Value& tensor) { checkTensorType(tensor); consider_remove_from_index(docid); @@ -135,7 +133,7 @@ DenseTensorAttribute::clearDoc(DocId docId) } void -DenseTensorAttribute::setTensor(DocId docId, const Tensor &tensor) +DenseTensorAttribute::setTensor(DocId docId, const vespalib::eval::Value &tensor) { internal_set_tensor(docId, tensor); if (_index) { @@ -144,18 +142,16 @@ DenseTensorAttribute::setTensor(DocId docId, const Tensor &tensor) } std::unique_ptr<PrepareResult> -DenseTensorAttribute::prepare_set_tensor(DocId docid, const Tensor& tensor) const +DenseTensorAttribute::prepare_set_tensor(DocId docid, const vespalib::eval::Value& tensor) const { if (_index) { - const auto* view = dynamic_cast<const DenseTensorView*>(&tensor); - assert(view); - return _index->prepare_add_document(docid, view->cells(), getGenerationHandler().takeGuard()); + return _index->prepare_add_document(docid, tensor.cells(), getGenerationHandler().takeGuard()); } return std::unique_ptr<PrepareResult>(); } void -DenseTensorAttribute::complete_set_tensor(DocId docid, const Tensor& tensor, +DenseTensorAttribute::complete_set_tensor(DocId docid, const vespalib::eval::Value& tensor, std::unique_ptr<PrepareResult> prepare_result) { internal_set_tensor(docid, tensor); @@ -164,7 +160,7 @@ DenseTensorAttribute::complete_set_tensor(DocId docid, const Tensor& tensor, } } -std::unique_ptr<Tensor> +std::unique_ptr<vespalib::eval::Value> DenseTensorAttribute::getTensor(DocId docId) const { EntryRef ref; @@ -172,7 +168,7 @@ DenseTensorAttribute::getTensor(DocId docId) const ref = _refVector[docId]; } if (!ref.valid()) { - return std::unique_ptr<Tensor>(); + return std::unique_ptr<vespalib::eval::Value>(); } return _denseTensorStore.getTensor(ref); } diff --git a/searchlib/src/vespa/searchlib/tensor/dense_tensor_attribute.h b/searchlib/src/vespa/searchlib/tensor/dense_tensor_attribute.h index 859ea82cee6..e06bbf331ac 100644 --- a/searchlib/src/vespa/searchlib/tensor/dense_tensor_attribute.h +++ b/searchlib/src/vespa/searchlib/tensor/dense_tensor_attribute.h @@ -23,7 +23,7 @@ private: DenseTensorStore _denseTensorStore; std::unique_ptr<NearestNeighborIndex> _index; - void internal_set_tensor(DocId docid, const Tensor& tensor); + void internal_set_tensor(DocId docid, const vespalib::eval::Value& tensor); void consider_remove_from_index(DocId docid); vespalib::MemoryUsage memory_usage() const override; @@ -33,10 +33,10 @@ public: virtual ~DenseTensorAttribute(); // Implements AttributeVector and ITensorAttribute uint32_t clearDoc(DocId docId) override; - void setTensor(DocId docId, const Tensor &tensor) override; - std::unique_ptr<PrepareResult> prepare_set_tensor(DocId docid, const Tensor& tensor) const override; - void complete_set_tensor(DocId docid, const Tensor& tensor, std::unique_ptr<PrepareResult> prepare_result) override; - std::unique_ptr<Tensor> getTensor(DocId docId) const override; + void setTensor(DocId docId, const vespalib::eval::Value &tensor) override; + std::unique_ptr<PrepareResult> prepare_set_tensor(DocId docid, const vespalib::eval::Value& tensor) const override; + void complete_set_tensor(DocId docid, const vespalib::eval::Value& tensor, std::unique_ptr<PrepareResult> prepare_result) override; + std::unique_ptr<vespalib::eval::Value> getTensor(DocId docId) const override; void extract_dense_view(DocId docId, vespalib::tensor::MutableDenseTensorView &tensor) const override; bool supports_extract_dense_view() const override { return true; } bool onLoad() override; diff --git a/searchlib/src/vespa/searchlib/tensor/dense_tensor_store.cpp b/searchlib/src/vespa/searchlib/tensor/dense_tensor_store.cpp index e250a19214c..e76cea53c12 100644 --- a/searchlib/src/vespa/searchlib/tensor/dense_tensor_store.cpp +++ b/searchlib/src/vespa/searchlib/tensor/dense_tensor_store.cpp @@ -1,17 +1,13 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "dense_tensor_store.h" -#include <vespa/eval/tensor/tensor.h> #include <vespa/eval/tensor/dense/dense_tensor_view.h> #include <vespa/eval/tensor/dense/mutable_dense_tensor_view.h> -#include <vespa/eval/tensor/dense/dense_tensor.h> -#include <vespa/eval/tensor/serialization/typed_binary_format.h> #include <vespa/vespalib/datastore/datastore.hpp> using vespalib::datastore::Handle; -using vespalib::tensor::Tensor; -using vespalib::tensor::DenseTensorView; using vespalib::tensor::MutableDenseTensorView; +using vespalib::eval::Value; using vespalib::eval::ValueType; using CellType = vespalib::eval::ValueType::CellType; @@ -131,14 +127,14 @@ DenseTensorStore::move(EntryRef ref) return newraw.ref; } -std::unique_ptr<Tensor> +std::unique_ptr<Value> DenseTensorStore::getTensor(EntryRef ref) const { if (!ref.valid()) { - return std::unique_ptr<Tensor>(); + return std::unique_ptr<Value>(); } vespalib::eval::TypedCells cells_ref(getRawBuffer(ref), _type.cell_type(), getNumCells()); - return std::make_unique<DenseTensorView>(_type, cells_ref); + return std::make_unique<vespalib::tensor::DenseTensorView>(_type, cells_ref); } void @@ -166,19 +162,19 @@ template <class TensorType> TensorStore::EntryRef DenseTensorStore::setDenseTensor(const TensorType &tensor) { - size_t numCells = tensor.cells().size; - assert(numCells == getNumCells()); assert(tensor.type() == _type); + auto cells = tensor.cells(); + assert(cells.size == getNumCells()); + assert(cells.type == _type.cell_type()); auto raw = allocRawBuffer(); - memcpy(raw.data, tensor.cells().data, getBufSize()); + memcpy(raw.data, cells.data, getBufSize()); return raw.ref; } TensorStore::EntryRef -DenseTensorStore::setTensor(const Tensor &tensor) +DenseTensorStore::setTensor(const vespalib::eval::Value &tensor) { - const DenseTensorView &view(dynamic_cast<const DenseTensorView &>(tensor)); - return setDenseTensor(view); + return setDenseTensor(tensor); } } diff --git a/searchlib/src/vespa/searchlib/tensor/dense_tensor_store.h b/searchlib/src/vespa/searchlib/tensor/dense_tensor_store.h index 979df1a9a4e..bae2aa9c3a4 100644 --- a/searchlib/src/vespa/searchlib/tensor/dense_tensor_store.h +++ b/searchlib/src/vespa/searchlib/tensor/dense_tensor_store.h @@ -7,6 +7,7 @@ #include <vespa/eval/eval/typed_cells.h> namespace vespalib { namespace tensor { class MutableDenseTensorView; }} +namespace vespalib::eval { class Value; } namespace search::tensor { @@ -64,10 +65,10 @@ public: vespalib::datastore::Handle<char> allocRawBuffer(); void holdTensor(EntryRef ref) override; EntryRef move(EntryRef ref) override; - std::unique_ptr<Tensor> getTensor(EntryRef ref) const; + std::unique_ptr<vespalib::eval::Value> getTensor(EntryRef ref) const; void getTensor(EntryRef ref, vespalib::tensor::MutableDenseTensorView &tensor) const; vespalib::eval::TypedCells get_typed_cells(EntryRef ref) const; - EntryRef setTensor(const Tensor &tensor); + EntryRef setTensor(const vespalib::eval::Value &tensor); // The following method is meant to be used only for unit tests. uint32_t getArraySize() const { return _bufferType.getArraySize(); } }; diff --git a/searchlib/src/vespa/searchlib/tensor/direct_tensor_attribute.cpp b/searchlib/src/vespa/searchlib/tensor/direct_tensor_attribute.cpp index 570be586e88..62beb25be22 100644 --- a/searchlib/src/vespa/searchlib/tensor/direct_tensor_attribute.cpp +++ b/searchlib/src/vespa/searchlib/tensor/direct_tensor_attribute.cpp @@ -3,7 +3,8 @@ #include "direct_tensor_attribute.h" #include "direct_tensor_saver.h" -#include <vespa/eval/tensor/tensor.h> +#include <vespa/eval/eval/engine_or_factory.h> +#include <vespa/eval/eval/value.h> #include <vespa/fastlib/io/bufferedfile.h> #include <vespa/searchlib/attribute/readerbase.h> #include <vespa/searchlib/util/fileutil.h> @@ -13,7 +14,7 @@ #include "tensor_deserialize.h" #include "tensor_attribute.hpp" -using vespalib::tensor::Tensor; +using vespalib::eval::EngineOrFactory; namespace search::tensor { @@ -62,7 +63,7 @@ DirectTensorAttribute::onLoad() } void -DirectTensorAttribute::set_tensor(DocId lid, std::unique_ptr<Tensor> tensor) +DirectTensorAttribute::set_tensor(DocId lid, std::unique_ptr<vespalib::eval::Value> tensor) { checkTensorType(*tensor); EntryRef ref = _direct_store.store_tensor(std::move(tensor)); @@ -70,12 +71,12 @@ DirectTensorAttribute::set_tensor(DocId lid, std::unique_ptr<Tensor> tensor) } void -DirectTensorAttribute::setTensor(DocId lid, const Tensor &tensor) +DirectTensorAttribute::setTensor(DocId lid, const vespalib::eval::Value &tensor) { - set_tensor(lid, tensor.clone()); + set_tensor(lid, EngineOrFactory::get().copy(tensor)); } -std::unique_ptr<Tensor> +std::unique_ptr<vespalib::eval::Value> DirectTensorAttribute::getTensor(DocId docId) const { EntryRef ref; @@ -85,14 +86,14 @@ DirectTensorAttribute::getTensor(DocId docId) const if (ref.valid()) { auto ptr = _direct_store.get_tensor(ref); if (ptr) { - return ptr->clone(); + return EngineOrFactory::get().copy(*ptr); } } - std::unique_ptr<Tensor> empty; + std::unique_ptr<vespalib::eval::Value> empty; return empty; } -const Tensor & +const vespalib::eval::Value & DirectTensorAttribute::get_tensor_ref(DocId docId) const { EntryRef ref; diff --git a/searchlib/src/vespa/searchlib/tensor/direct_tensor_attribute.h b/searchlib/src/vespa/searchlib/tensor/direct_tensor_attribute.h index 1429a8b4d5d..ce2bc0de386 100644 --- a/searchlib/src/vespa/searchlib/tensor/direct_tensor_attribute.h +++ b/searchlib/src/vespa/searchlib/tensor/direct_tensor_attribute.h @@ -5,22 +5,25 @@ #include "tensor_attribute.h" #include "direct_tensor_store.h" +namespace vespalib::eval { class Value; } + namespace search::tensor { class DirectTensorAttribute : public TensorAttribute { DirectTensorStore _direct_store; + public: DirectTensorAttribute(vespalib::stringref baseFileName, const Config &cfg); virtual ~DirectTensorAttribute(); - virtual void setTensor(DocId docId, const Tensor &tensor) override; - virtual std::unique_ptr<Tensor> getTensor(DocId docId) const override; + virtual void setTensor(DocId docId, const vespalib::eval::Value &tensor) override; + virtual std::unique_ptr<vespalib::eval::Value> getTensor(DocId docId) const override; virtual bool onLoad() override; virtual std::unique_ptr<AttributeSaver> onInitSave(vespalib::stringref fileName) override; virtual void compactWorst() override; - void set_tensor(DocId docId, std::unique_ptr<Tensor> tensor); - const Tensor &get_tensor_ref(DocId docId) const override; + void set_tensor(DocId docId, std::unique_ptr<vespalib::eval::Value> tensor); + const vespalib::eval::Value &get_tensor_ref(DocId docId) const override; virtual bool supports_get_tensor_ref() const override { return true; } }; diff --git a/searchlib/src/vespa/searchlib/tensor/direct_tensor_saver.cpp b/searchlib/src/vespa/searchlib/tensor/direct_tensor_saver.cpp index 9ab2978722e..e67d5d8202b 100644 --- a/searchlib/src/vespa/searchlib/tensor/direct_tensor_saver.cpp +++ b/searchlib/src/vespa/searchlib/tensor/direct_tensor_saver.cpp @@ -3,15 +3,13 @@ #include "direct_tensor_saver.h" #include "direct_tensor_store.h" +#include <vespa/eval/eval/engine_or_factory.h> #include <vespa/eval/tensor/serialization/typed_binary_format.h> #include <vespa/searchlib/attribute/iattributesavetarget.h> #include <vespa/searchlib/util/bufferwriter.h> #include <vespa/vespalib/objects/nbostream.h> using vespalib::GenerationHandler; -using vespalib::tensor::Tensor; -using vespalib::tensor::TypedBinaryFormat; - namespace search::tensor { @@ -38,10 +36,10 @@ DirectTensorAttributeSaver::onSave(IAttributeSaveTarget &saveTarget) const uint32_t docIdLimit(_refs.size()); vespalib::nbostream stream; for (uint32_t lid = 0; lid < docIdLimit; ++lid) { - const Tensor *tensor = _tensorStore.get_tensor(_refs[lid]); + const vespalib::eval::Value *tensor = _tensorStore.get_tensor(_refs[lid]); if (tensor) { stream.clear(); - TypedBinaryFormat::serialize(stream, *tensor); + vespalib::eval::EngineOrFactory::get().encode(*tensor, stream); uint32_t sz = stream.size(); datWriter->write(&sz, sizeof(sz)); datWriter->write(stream.peek(), stream.size()); diff --git a/searchlib/src/vespa/searchlib/tensor/direct_tensor_store.cpp b/searchlib/src/vespa/searchlib/tensor/direct_tensor_store.cpp index 90be394227c..a74da056d00 100644 --- a/searchlib/src/vespa/searchlib/tensor/direct_tensor_store.cpp +++ b/searchlib/src/vespa/searchlib/tensor/direct_tensor_store.cpp @@ -1,7 +1,7 @@ // Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "direct_tensor_store.h" -#include <vespa/eval/tensor/tensor.h> +#include <vespa/eval/eval/value.h> #include <vespa/vespalib/datastore/datastore.hpp> using vespalib::datastore::EntryRef; @@ -44,7 +44,7 @@ DirectTensorStore::DirectTensorStore() DirectTensorStore::~DirectTensorStore() = default; -const vespalib::tensor::Tensor* +const vespalib::eval::Value * DirectTensorStore::get_tensor(EntryRef ref) const { if (!ref.valid()) { @@ -56,7 +56,7 @@ DirectTensorStore::get_tensor(EntryRef ref) const } EntryRef -DirectTensorStore::store_tensor(std::unique_ptr<Tensor> tensor) +DirectTensorStore::store_tensor(std::unique_ptr<vespalib::eval::Value> tensor) { assert(tensor); return add_entry(TensorSP(std::move(tensor))); diff --git a/searchlib/src/vespa/searchlib/tensor/direct_tensor_store.h b/searchlib/src/vespa/searchlib/tensor/direct_tensor_store.h index 881506adb48..3955551f0f5 100644 --- a/searchlib/src/vespa/searchlib/tensor/direct_tensor_store.h +++ b/searchlib/src/vespa/searchlib/tensor/direct_tensor_store.h @@ -5,6 +5,8 @@ #include "tensor_store.h" #include <memory> +namespace vespalib::eval { class Value; } + namespace search::tensor { /** @@ -16,7 +18,7 @@ class DirectTensorStore : public TensorStore { private: // Note: Must use SP (instead of UP) because of fallbackCopy() and initializeReservedElements() in BufferType, // and implementation of move(). - using TensorSP = std::shared_ptr<Tensor>; + using TensorSP = std::shared_ptr<vespalib::eval::Value>; using TensorStoreType = vespalib::datastore::DataStore<TensorSP>; class TensorBufferType : public vespalib::datastore::BufferType<TensorSP> { @@ -38,8 +40,8 @@ public: ~DirectTensorStore() override; using RefType = TensorStoreType::RefType; - const Tensor* get_tensor(EntryRef ref) const; - EntryRef store_tensor(std::unique_ptr<Tensor> tensor); + const vespalib::eval::Value * get_tensor(EntryRef ref) const; + EntryRef store_tensor(std::unique_ptr<vespalib::eval::Value> tensor); void holdTensor(EntryRef ref) override; EntryRef move(EntryRef ref) override; diff --git a/searchlib/src/vespa/searchlib/tensor/i_tensor_attribute.h b/searchlib/src/vespa/searchlib/tensor/i_tensor_attribute.h index 12b6857d122..f107f6bd781 100644 --- a/searchlib/src/vespa/searchlib/tensor/i_tensor_attribute.h +++ b/searchlib/src/vespa/searchlib/tensor/i_tensor_attribute.h @@ -6,9 +6,8 @@ namespace vespalib::tensor { class MutableDenseTensorView; -class Tensor; } -namespace vespalib::eval { class ValueType; } +namespace vespalib::eval { class ValueType; class Value; } namespace vespalib::slime { struct Inserter; } namespace search::tensor { @@ -19,13 +18,11 @@ namespace search::tensor { class ITensorAttribute { public: - using Tensor = vespalib::tensor::Tensor; - virtual ~ITensorAttribute() {} - virtual std::unique_ptr<Tensor> getTensor(uint32_t docId) const = 0; - virtual std::unique_ptr<Tensor> getEmptyTensor() const = 0; + virtual std::unique_ptr<vespalib::eval::Value> getTensor(uint32_t docId) const = 0; + virtual std::unique_ptr<vespalib::eval::Value> getEmptyTensor() const = 0; virtual void extract_dense_view(uint32_t docid, vespalib::tensor::MutableDenseTensorView& tensor) const = 0; - virtual const Tensor& get_tensor_ref(uint32_t docid) const = 0; + virtual const vespalib::eval::Value& get_tensor_ref(uint32_t docid) const = 0; virtual bool supports_extract_dense_view() const = 0; virtual bool supports_get_tensor_ref() const = 0; diff --git a/searchlib/src/vespa/searchlib/tensor/imported_tensor_attribute_vector.cpp b/searchlib/src/vespa/searchlib/tensor/imported_tensor_attribute_vector.cpp index 0b13c999984..6d724d254b8 100644 --- a/searchlib/src/vespa/searchlib/tensor/imported_tensor_attribute_vector.cpp +++ b/searchlib/src/vespa/searchlib/tensor/imported_tensor_attribute_vector.cpp @@ -2,12 +2,10 @@ #include "imported_tensor_attribute_vector.h" #include "imported_tensor_attribute_vector_read_guard.h" -#include <vespa/eval/tensor/tensor.h> +#include <vespa/eval/eval/value.h> namespace search::tensor { -using vespalib::tensor::Tensor; - ImportedTensorAttributeVector::ImportedTensorAttributeVector(vespalib::stringref name, std::shared_ptr<ReferenceAttribute> reference_attribute, std::shared_ptr<IDocumentMetaStoreContext> document_meta_store, diff --git a/searchlib/src/vespa/searchlib/tensor/imported_tensor_attribute_vector_read_guard.cpp b/searchlib/src/vespa/searchlib/tensor/imported_tensor_attribute_vector_read_guard.cpp index 2e396145138..1e376faa4d3 100644 --- a/searchlib/src/vespa/searchlib/tensor/imported_tensor_attribute_vector_read_guard.cpp +++ b/searchlib/src/vespa/searchlib/tensor/imported_tensor_attribute_vector_read_guard.cpp @@ -2,12 +2,10 @@ #include "imported_tensor_attribute_vector_read_guard.h" #include <vespa/searchlib/attribute/attributevector.h> -#include <vespa/eval/tensor/tensor.h> +#include <vespa/eval/eval/value.h> namespace search::tensor { -using vespalib::tensor::Tensor; - namespace { const ITensorAttribute & @@ -38,13 +36,13 @@ ImportedTensorAttributeVectorReadGuard::asTensorAttribute() const return this; } -std::unique_ptr<Tensor> +std::unique_ptr<vespalib::eval::Value> ImportedTensorAttributeVectorReadGuard::getTensor(uint32_t docId) const { return _target_tensor_attribute.getTensor(getTargetLid(docId)); } -std::unique_ptr<Tensor> +std::unique_ptr<vespalib::eval::Value> ImportedTensorAttributeVectorReadGuard::getEmptyTensor() const { return _target_tensor_attribute.getEmptyTensor(); @@ -56,7 +54,7 @@ ImportedTensorAttributeVectorReadGuard::extract_dense_view(uint32_t docid, vespa _target_tensor_attribute.extract_dense_view(getTargetLid(docid), tensor); } -const Tensor& +const vespalib::eval::Value& ImportedTensorAttributeVectorReadGuard::get_tensor_ref(uint32_t docid) const { return _target_tensor_attribute.get_tensor_ref(getTargetLid(docid)); diff --git a/searchlib/src/vespa/searchlib/tensor/imported_tensor_attribute_vector_read_guard.h b/searchlib/src/vespa/searchlib/tensor/imported_tensor_attribute_vector_read_guard.h index e873da510d9..3abac4e532e 100644 --- a/searchlib/src/vespa/searchlib/tensor/imported_tensor_attribute_vector_read_guard.h +++ b/searchlib/src/vespa/searchlib/tensor/imported_tensor_attribute_vector_read_guard.h @@ -30,10 +30,10 @@ public: const ITensorAttribute *asTensorAttribute() const override; - std::unique_ptr<Tensor> getTensor(uint32_t docId) const override; - std::unique_ptr<Tensor> getEmptyTensor() const override; + std::unique_ptr<vespalib::eval::Value> getTensor(uint32_t docId) const override; + std::unique_ptr<vespalib::eval::Value> getEmptyTensor() const override; void extract_dense_view(uint32_t docid, vespalib::tensor::MutableDenseTensorView& tensor) const override; - const Tensor& get_tensor_ref(uint32_t docid) const override; + const vespalib::eval::Value& get_tensor_ref(uint32_t docid) const override; bool supports_extract_dense_view() const override { return _target_tensor_attribute.supports_extract_dense_view(); } bool supports_get_tensor_ref() const override { return _target_tensor_attribute.supports_get_tensor_ref(); } vespalib::eval::ValueType getTensorType() const override; diff --git a/searchlib/src/vespa/searchlib/tensor/serialized_tensor_attribute.cpp b/searchlib/src/vespa/searchlib/tensor/serialized_tensor_attribute.cpp index 3c0e9b38687..fc63969e548 100644 --- a/searchlib/src/vespa/searchlib/tensor/serialized_tensor_attribute.cpp +++ b/searchlib/src/vespa/searchlib/tensor/serialized_tensor_attribute.cpp @@ -4,14 +4,14 @@ #include "serialized_tensor_attribute.h" #include "serialized_tensor_attribute_saver.h" #include "tensor_attribute.hpp" -#include <vespa/eval/tensor/tensor.h> +#include <vespa/eval/eval/value.h> #include <vespa/fastlib/io/bufferedfile.h> #include <vespa/searchlib/attribute/readerbase.h> #include <vespa/searchlib/util/fileutil.h> #include <vespa/vespalib/util/rcuvector.hpp> +using vespalib::eval::Value; using vespalib::eval::ValueType; -using vespalib::tensor::Tensor; namespace search::tensor { @@ -34,7 +34,7 @@ SerializedTensorAttribute::~SerializedTensorAttribute() } void -SerializedTensorAttribute::setTensor(DocId docId, const Tensor &tensor) +SerializedTensorAttribute::setTensor(DocId docId, const vespalib::eval::Value &tensor) { checkTensorType(tensor); EntryRef ref = _serializedTensorStore.setTensor(tensor); @@ -42,7 +42,7 @@ SerializedTensorAttribute::setTensor(DocId docId, const Tensor &tensor) } -std::unique_ptr<Tensor> +std::unique_ptr<Value> SerializedTensorAttribute::getTensor(DocId docId) const { EntryRef ref; @@ -50,7 +50,7 @@ SerializedTensorAttribute::getTensor(DocId docId) const ref = _refVector[docId]; } if (!ref.valid()) { - return std::unique_ptr<Tensor>(); + return std::unique_ptr<Value>(); } return _serializedTensorStore.getTensor(ref); } diff --git a/searchlib/src/vespa/searchlib/tensor/serialized_tensor_attribute.h b/searchlib/src/vespa/searchlib/tensor/serialized_tensor_attribute.h index 7b385359337..fea11e3b0c4 100644 --- a/searchlib/src/vespa/searchlib/tensor/serialized_tensor_attribute.h +++ b/searchlib/src/vespa/searchlib/tensor/serialized_tensor_attribute.h @@ -15,8 +15,8 @@ class SerializedTensorAttribute : public TensorAttribute { public: SerializedTensorAttribute(vespalib::stringref baseFileName, const Config &cfg); virtual ~SerializedTensorAttribute(); - virtual void setTensor(DocId docId, const Tensor &tensor) override; - virtual std::unique_ptr<Tensor> getTensor(DocId docId) const override; + virtual void setTensor(DocId docId, const vespalib::eval::Value &tensor) override; + virtual std::unique_ptr<vespalib::eval::Value> getTensor(DocId docId) const override; virtual bool onLoad() override; virtual std::unique_ptr<AttributeSaver> onInitSave(vespalib::stringref fileName) override; virtual void compactWorst() override; diff --git a/searchlib/src/vespa/searchlib/tensor/serialized_tensor_store.cpp b/searchlib/src/vespa/searchlib/tensor/serialized_tensor_store.cpp index 77903291e13..4215df9e270 100644 --- a/searchlib/src/vespa/searchlib/tensor/serialized_tensor_store.cpp +++ b/searchlib/src/vespa/searchlib/tensor/serialized_tensor_store.cpp @@ -2,16 +2,15 @@ #include "serialized_tensor_store.h" #include "tensor_deserialize.h" -#include <vespa/eval/tensor/tensor.h> -#include <vespa/eval/tensor/serialization/typed_binary_format.h> +#include <vespa/eval/eval/engine_or_factory.h> +#include <vespa/eval/eval/value.h> #include <vespa/vespalib/datastore/datastore.hpp> #include <vespa/vespalib/objects/nbostream.h> #include <vespa/vespalib/util/stringfmt.h> #include <vespa/vespalib/util/macro.h> using vespalib::datastore::Handle; -using vespalib::tensor::Tensor; -using vespalib::tensor::TypedBinaryFormat; +using vespalib::eval::Value; namespace search::tensor { @@ -87,21 +86,21 @@ SerializedTensorStore::move(EntryRef ref) return newraw.ref; } -std::unique_ptr<Tensor> +std::unique_ptr<Value> SerializedTensorStore::getTensor(EntryRef ref) const { auto raw = getRawBuffer(ref); if (raw.second == 0u) { - return std::unique_ptr<Tensor>(); + return std::unique_ptr<Value>(); } return deserialize_tensor(raw.first, raw.second); } TensorStore::EntryRef -SerializedTensorStore::setTensor(const Tensor &tensor) +SerializedTensorStore::setTensor(const vespalib::eval::Value &tensor) { vespalib::nbostream stream; - TypedBinaryFormat::serialize(stream, tensor); + vespalib::eval::EngineOrFactory::get().encode(tensor, stream); auto raw = allocRawBuffer(stream.size()); memcpy(raw.data, stream.peek(), stream.size()); return raw.ref; diff --git a/searchlib/src/vespa/searchlib/tensor/serialized_tensor_store.h b/searchlib/src/vespa/searchlib/tensor/serialized_tensor_store.h index 7c0a8e5ed16..ce2bbdde18d 100644 --- a/searchlib/src/vespa/searchlib/tensor/serialized_tensor_store.h +++ b/searchlib/src/vespa/searchlib/tensor/serialized_tensor_store.h @@ -4,6 +4,8 @@ #include "tensor_store.h" +namespace vespalib::eval { class Value; } + namespace search::tensor { /** @@ -33,9 +35,9 @@ public: virtual EntryRef move(EntryRef ref) override; - std::unique_ptr<Tensor> getTensor(EntryRef ref) const; + std::unique_ptr<vespalib::eval::Value> getTensor(EntryRef ref) const; - EntryRef setTensor(const Tensor &tensor); + EntryRef setTensor(const vespalib::eval::Value &tensor); }; } diff --git a/searchlib/src/vespa/searchlib/tensor/tensor_attribute.cpp b/searchlib/src/vespa/searchlib/tensor/tensor_attribute.cpp index a0185b7f7c1..39e35af3174 100644 --- a/searchlib/src/vespa/searchlib/tensor/tensor_attribute.cpp +++ b/searchlib/src/vespa/searchlib/tensor/tensor_attribute.cpp @@ -3,23 +3,20 @@ #include "tensor_attribute.h" #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/typed_dense_tensor_builder.h> -#include <vespa/eval/tensor/sparse/direct_sparse_tensor_builder.h> -#include <vespa/eval/tensor/wrapped_simple_tensor.h> #include <vespa/searchlib/util/state_explorer_utils.h> #include <vespa/vespalib/data/slime/cursor.h> #include <vespa/vespalib/data/slime/inserter.h> #include <vespa/vespalib/util/rcuvector.hpp> +#include <vespa/eval/eval/engine_or_factory.h> +#include <vespa/eval/eval/tensor_spec.h> +#include <vespa/eval/eval/value.h> using document::TensorDataType; using document::WrongTensorTypeException; -using vespalib::eval::SimpleTensor; +using vespalib::eval::EngineOrFactory; +using vespalib::eval::TensorSpec; +using vespalib::eval::Value; using vespalib::eval::ValueType; -using vespalib::tensor::DirectSparseTensorBuilder; -using vespalib::tensor::Tensor; -using vespalib::tensor::TypedDenseTensorBuilder; -using vespalib::tensor::WrappedSimpleTensor; using search::StateExplorerUtils; namespace search::tensor { @@ -31,26 +28,12 @@ constexpr uint32_t TENSOR_ATTRIBUTE_VERSION = 0; // minimum dead bytes in tensor attribute before consider compaction constexpr size_t DEAD_SLACK = 0x10000u; -struct CallMakeEmptyTensor { - template <typename CT> - static Tensor::UP invoke(const ValueType &type) { - if (type.is_dense()) { - TypedDenseTensorBuilder<CT> builder(type); - return builder.build(); - } - if (type.is_sparse()) { - DirectSparseTensorBuilder<CT> builder(type); - return builder.build(); - } - return std::make_unique<WrappedSimpleTensor>(std::make_unique<SimpleTensor>(type, SimpleTensor::Cells())); - } -}; - -Tensor::UP +Value::UP createEmptyTensor(const ValueType &type) { - using MyTypify = vespalib::eval::TypifyCellType; - return vespalib::typify_invoke<1,MyTypify,CallMakeEmptyTensor>(type.cell_type(), type); + auto engine = EngineOrFactory::get(); + TensorSpec empty_spec(type.to_spec()); + return engine.from_spec(empty_spec); } vespalib::string makeWrongTensorTypeMsg(const ValueType &fieldTensorType, const ValueType &tensorType) @@ -154,7 +137,7 @@ TensorAttribute::addDoc(DocId &docId) } void -TensorAttribute::checkTensorType(const Tensor &tensor) +TensorAttribute::checkTensorType(const vespalib::eval::Value &tensor) { const ValueType &fieldTensorType = getConfig().tensorType(); const ValueType &tensorType = tensor.type(); @@ -197,10 +180,10 @@ TensorAttribute::populate_state(vespalib::slime::Cursor& object) const object.setObject("tensor_store").setObject("memory_usage")); } -Tensor::UP +vespalib::eval::Value::UP TensorAttribute::getEmptyTensor() const { - return _emptyTensor->clone(); + return EngineOrFactory::get().copy(*_emptyTensor); } void @@ -211,7 +194,7 @@ TensorAttribute::extract_dense_view(uint32_t docid, vespalib::tensor::MutableDen notImplemented(); } -const Tensor& +const vespalib::eval::Value& TensorAttribute::get_tensor_ref(uint32_t docid) const { (void) docid; @@ -271,7 +254,7 @@ TensorAttribute::getRefCopy() const } std::unique_ptr<PrepareResult> -TensorAttribute::prepare_set_tensor(DocId docid, const Tensor& tensor) const +TensorAttribute::prepare_set_tensor(DocId docid, const vespalib::eval::Value& tensor) const { (void) docid; (void) tensor; @@ -279,7 +262,7 @@ TensorAttribute::prepare_set_tensor(DocId docid, const Tensor& tensor) const } void -TensorAttribute::complete_set_tensor(DocId docid, const Tensor& tensor, +TensorAttribute::complete_set_tensor(DocId docid, const vespalib::eval::Value& tensor, std::unique_ptr<PrepareResult> prepare_result) { (void) docid; diff --git a/searchlib/src/vespa/searchlib/tensor/tensor_attribute.h b/searchlib/src/vespa/searchlib/tensor/tensor_attribute.h index 9627ea5b4aa..24b88e3a7e0 100644 --- a/searchlib/src/vespa/searchlib/tensor/tensor_attribute.h +++ b/searchlib/src/vespa/searchlib/tensor/tensor_attribute.h @@ -8,6 +8,8 @@ #include <vespa/searchlib/attribute/not_implemented_attribute.h> #include <vespa/vespalib/util/rcuvector.h> +namespace vespalib::eval { class Value; } + namespace search::tensor { /** @@ -21,12 +23,12 @@ protected: RefVector _refVector; // docId -> ref in data store for serialized tensor TensorStore &_tensorStore; // data store for serialized tensors - std::unique_ptr<Tensor> _emptyTensor; + std::unique_ptr<vespalib::eval::Value> _emptyTensor; uint64_t _compactGeneration; // Generation when last compact occurred template <typename RefType> void doCompactWorst(); - void checkTensorType(const Tensor &tensor); + void checkTensorType(const vespalib::eval::Value &tensor); void setTensorRef(DocId docId, EntryRef ref); virtual vespalib::MemoryUsage memory_usage() const; void populate_state(vespalib::slime::Cursor& object) const; @@ -44,9 +46,9 @@ public: void removeOldGenerations(generation_t firstUsed) override; void onGenerationChange(generation_t generation) override; bool addDoc(DocId &docId) override; - std::unique_ptr<Tensor> getEmptyTensor() const override; + std::unique_ptr<vespalib::eval::Value> getEmptyTensor() const override; void extract_dense_view(uint32_t docid, vespalib::tensor::MutableDenseTensorView& tensor) const override; - const Tensor& get_tensor_ref(uint32_t docid) const override; + const vespalib::eval::Value& get_tensor_ref(uint32_t docid) const override; bool supports_extract_dense_view() const override { return false; } bool supports_get_tensor_ref() const override { return false; } vespalib::eval::ValueType getTensorType() const override; @@ -55,7 +57,7 @@ public: void onShrinkLidSpace() override; uint32_t getVersion() const override; RefCopyVector getRefCopy() const; - virtual void setTensor(DocId docId, const Tensor &tensor) = 0; + virtual void setTensor(DocId docId, const vespalib::eval::Value &tensor) = 0; /** * Performs the prepare step in a two-phase operation to set a tensor for a document. @@ -63,7 +65,7 @@ public: * This function can be called by any thread. * It should return the result of the costly and non-modifying part of such operation. */ - virtual std::unique_ptr<PrepareResult> prepare_set_tensor(DocId docid, const Tensor& tensor) const; + virtual std::unique_ptr<PrepareResult> prepare_set_tensor(DocId docid, const vespalib::eval::Value& tensor) const; /** * Performs the complete step in a two-phase operation to set a tensor for a document. @@ -71,7 +73,7 @@ public: * This function is only called by the attribute writer thread. * It uses the result from the prepare step to do the modifying changes. */ - virtual void complete_set_tensor(DocId docid, const Tensor& tensor, std::unique_ptr<PrepareResult> prepare_result); + virtual void complete_set_tensor(DocId docid, const vespalib::eval::Value& tensor, std::unique_ptr<PrepareResult> prepare_result); virtual void compactWorst() = 0; }; diff --git a/searchlib/src/vespa/searchlib/tensor/tensor_deserialize.cpp b/searchlib/src/vespa/searchlib/tensor/tensor_deserialize.cpp index 7998fba5941..83988a3af11 100644 --- a/searchlib/src/vespa/searchlib/tensor/tensor_deserialize.cpp +++ b/searchlib/src/vespa/searchlib/tensor/tensor_deserialize.cpp @@ -1,20 +1,20 @@ // Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include <vespa/document/util/serializableexceptions.h> -#include <vespa/eval/tensor/serialization/typed_binary_format.h> -#include <vespa/eval/tensor/tensor.h> +#include <vespa/eval/eval/engine_or_factory.h> +#include <vespa/eval/eval/value.h> #include <vespa/vespalib/objects/nbostream.h> using document::DeserializeException; -using vespalib::tensor::Tensor; -using vespalib::tensor::TypedBinaryFormat; +using vespalib::eval::EngineOrFactory; +using vespalib::eval::Value; namespace search::tensor { -std::unique_ptr<Tensor> deserialize_tensor(const void *data, size_t size) +std::unique_ptr<Value> deserialize_tensor(const void *data, size_t size) { vespalib::nbostream wrapStream(data, size); - auto tensor = TypedBinaryFormat::deserialize(wrapStream); + auto tensor = EngineOrFactory::get().decode(wrapStream); if (wrapStream.size() != 0) { throw DeserializeException("Leftover bytes deserializing tensor attribute value.", VESPA_STRLOC); } diff --git a/searchlib/src/vespa/searchlib/tensor/tensor_deserialize.h b/searchlib/src/vespa/searchlib/tensor/tensor_deserialize.h index f1dfa1ca173..18e166543d6 100644 --- a/searchlib/src/vespa/searchlib/tensor/tensor_deserialize.h +++ b/searchlib/src/vespa/searchlib/tensor/tensor_deserialize.h @@ -1,10 +1,10 @@ // Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/eval/tensor/tensor.h> +#include <vespa/eval/eval/value.h> namespace search::tensor { -extern std::unique_ptr<vespalib::tensor::Tensor> +extern std::unique_ptr<vespalib::eval::Value> deserialize_tensor(const void *data, size_t size); } // namespace diff --git a/searchlib/src/vespa/searchlib/tensor/tensor_store.h b/searchlib/src/vespa/searchlib/tensor/tensor_store.h index 88946086bea..967b6fd62e2 100644 --- a/searchlib/src/vespa/searchlib/tensor/tensor_store.h +++ b/searchlib/src/vespa/searchlib/tensor/tensor_store.h @@ -6,7 +6,7 @@ #include <vespa/vespalib/datastore/datastore.h> #include <vespa/vespalib/util/generationhandler.h> -namespace vespalib { namespace tensor { class Tensor; } } +namespace vespalib::eval { class Value; } namespace search { @@ -24,7 +24,6 @@ class TensorStore public: using EntryRef = vespalib::datastore::EntryRef; typedef vespalib::GenerationHandler::generation_t generation_t; - using Tensor = vespalib::tensor::Tensor; protected: vespalib::datastore::DataStoreBase &_store; diff --git a/searchsummary/src/vespa/searchsummary/docsummary/attributedfw.cpp b/searchsummary/src/vespa/searchsummary/docsummary/attributedfw.cpp index 05ba12ddff9..dd1b6f95618 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/attributedfw.cpp +++ b/searchsummary/src/vespa/searchsummary/docsummary/attributedfw.cpp @@ -3,8 +3,8 @@ #include "attributedfw.h" #include "docsumstate.h" #include "docsumwriter.h" -#include <vespa/eval/tensor/serialization/typed_binary_format.h> -#include <vespa/eval/tensor/tensor.h> +#include <vespa/eval/eval/engine_or_factory.h> +#include <vespa/eval/eval/value.h> #include <vespa/searchcommon/attribute/iattributecontext.h> #include <vespa/searchlib/attribute/iattributemanager.h> #include <vespa/searchlib/attribute/integerbase.h> @@ -25,6 +25,8 @@ using search::attribute::IAttributeVector; using vespalib::Memory; using vespalib::slime::Cursor; using vespalib::slime::Inserter; +using vespalib::eval::EngineOrFactory; +using vespalib::eval::Value; namespace search::docsummary { @@ -104,7 +106,7 @@ SingleAttrDFW::insertField(uint32_t docid, GetDocsumsState * state, ResType type const auto tensor = tv->getTensor(docid); if (tensor) { vespalib::nbostream str; - vespalib::tensor::TypedBinaryFormat::serialize(str, *tensor); + EngineOrFactory::get().encode(*tensor, str); target.insertData(vespalib::Memory(str.peek(), str.size())); } } diff --git a/searchsummary/src/vespa/searchsummary/docsummary/summaryfieldconverter.cpp b/searchsummary/src/vespa/searchsummary/docsummary/summaryfieldconverter.cpp index ada14bf17f5..604e1b4c413 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/summaryfieldconverter.cpp +++ b/searchsummary/src/vespa/searchsummary/docsummary/summaryfieldconverter.cpp @@ -31,7 +31,7 @@ #include <vespa/vespalib/stllike/asciistream.h> #include <vespa/vespalib/util/stringfmt.h> #include <vespa/vespalib/data/slime/slime.h> -#include <vespa/eval/tensor/serialization/typed_binary_format.h> +#include <vespa/eval/eval/engine_or_factory.h> #include <vespa/vespalib/objects/nbostream.h> #include <vespa/searchlib/util/slime_output_raw_buf_adapter.h> #include <vespa/vespalib/util/exceptions.h> @@ -510,7 +510,7 @@ private: const auto &tensor = value.getAsTensorPtr(); vespalib::nbostream s; if (tensor) { - vespalib::tensor::TypedBinaryFormat::serialize(s, *tensor); + vespalib::eval::EngineOrFactory::get().encode(*tensor, s); } _inserter.insertData(vespalib::Memory(s.peek(), s.size())); } diff --git a/streamingvisitors/src/tests/hitcollector/hitcollector_test.cpp b/streamingvisitors/src/tests/hitcollector/hitcollector_test.cpp index bd567964e8d..d770a4d759b 100644 --- a/streamingvisitors/src/tests/hitcollector/hitcollector_test.cpp +++ b/streamingvisitors/src/tests/hitcollector/hitcollector_test.cpp @@ -8,6 +8,7 @@ #include <vespa/searchvisitor/hitcollector.h> #include <vespa/eval/eval/value.h> #include <vespa/eval/eval/tensor_spec.h> +#include <vespa/eval/eval/engine_or_factory.h> #include <vespa/eval/tensor/default_tensor_engine.h> #include <vespa/vespalib/objects/nbostream.h> @@ -17,11 +18,10 @@ using namespace vespalib; using namespace vdslib; using namespace vsm; using vespalib::nbostream; +using vespalib::eval::EngineOrFactory; using vespalib::eval::Value; using vespalib::eval::DoubleValue; using vespalib::eval::TensorSpec; -using vespalib::tensor::DefaultTensorEngine; - namespace streaming { @@ -253,7 +253,7 @@ public: ~MyRankProgram(); virtual void run(uint32_t docid, const std::vector<search::fef::TermFieldMatchData> &) override { _boxed_double = std::make_unique<DoubleValue>(docid + 30); - _tensor = DefaultTensorEngine::ref().from_spec(TensorSpec("tensor(x{})").add({{"x", "a"}}, docid + 20)); + _tensor = EngineOrFactory::get().from_spec(TensorSpec("tensor(x{})").add({{"x", "a"}}, docid + 20)); _fooValue.as_number = docid + 10; _barValue.as_object = *_boxed_double; _bazValue.as_object = *_tensor; @@ -308,7 +308,7 @@ HitCollectorTest::testFeatureSet() EXPECT_TRUE(!f[2].is_double()); EXPECT_TRUE(f[2].is_data()); { - auto &engine = DefaultTensorEngine::ref(); + auto engine = EngineOrFactory::get(); nbostream buf(f[2].as_data().data, f[2].as_data().size); auto actual = engine.to_spec(*engine.decode(buf)); auto expect = TensorSpec("tensor(x{})").add({{"x", "a"}}, 23); diff --git a/streamingvisitors/src/vespa/searchvisitor/hitcollector.cpp b/streamingvisitors/src/vespa/searchvisitor/hitcollector.cpp index f3850154505..12dce7d376c 100644 --- a/streamingvisitors/src/vespa/searchvisitor/hitcollector.cpp +++ b/streamingvisitors/src/vespa/searchvisitor/hitcollector.cpp @@ -4,8 +4,7 @@ #include <vespa/searchlib/fef/feature_resolver.h> #include <vespa/vespalib/util/stringfmt.h> #include <algorithm> -#include <vespa/eval/eval/tensor.h> -#include <vespa/eval/eval/tensor_engine.h> +#include <vespa/eval/eval/engine_or_factory.h> #include <vespa/vespalib/objects/nbostream.h> #include <vespa/log/log.h> @@ -163,9 +162,9 @@ HitCollector::getFeatureSet(IRankProgram &rankProgram, for (uint32_t j = 0; j < names.size(); ++j) { if (resolver.is_object(j)) { auto obj = resolver.resolve(j).as_object(docId); - if (const auto *tensor = obj.get().as_tensor()) { + if (! obj.get().is_double()) { vespalib::nbostream buf; - tensor->engine().encode(*tensor, buf); + vespalib::eval::EngineOrFactory::get().encode(obj.get(), buf); f[j].set_data(vespalib::Memory(buf.peek(), buf.size())); } else { f[j].set_double(obj.get().as_double()); |