summaryrefslogtreecommitdiffstats
path: root/eval
diff options
context:
space:
mode:
authorHåvard Pettersen <havardpe@oath.com>2020-10-12 12:29:21 +0000
committerHåvard Pettersen <havardpe@oath.com>2020-10-12 19:05:54 +0000
commite72235763076cad111f53043578b25d88c585255 (patch)
tree0f41fc53578aa258c29607ad8910fbbcb09ad5f5 /eval
parent9886120a1bddd1016466cec317a445cd37650bff (diff)
allow interpreted function to use new generic operations
update conformance test to also test with SimpleValue and FastValue
Diffstat (limited to 'eval')
-rw-r--r--eval/src/apps/tensor_conformance/tensor_conformance.cpp2
-rw-r--r--eval/src/tests/eval/interpreted_function/interpreted_function_test.cpp2
-rw-r--r--eval/src/tests/eval/simple_value/simple_value_test.cpp2
-rw-r--r--eval/src/tests/eval/tensor_function/tensor_function_test.cpp4
-rw-r--r--eval/src/tests/instruction/generic_concat/generic_concat_test.cpp2
-rw-r--r--eval/src/tests/instruction/generic_join/generic_join_test.cpp4
-rw-r--r--eval/src/tests/instruction/generic_merge/generic_merge_test.cpp2
-rw-r--r--eval/src/tests/instruction/generic_reduce/generic_reduce_test.cpp2
-rw-r--r--eval/src/tests/instruction/generic_rename/generic_rename_test.cpp2
-rw-r--r--eval/src/tests/tensor/dense_replace_type_function/dense_replace_type_function_test.cpp2
-rw-r--r--eval/src/tests/tensor/instruction_benchmark/instruction_benchmark.cpp84
-rw-r--r--eval/src/tests/tensor/tensor_conformance/tensor_conformance_test.cpp12
-rw-r--r--eval/src/vespa/eval/eval/CMakeLists.txt1
-rw-r--r--eval/src/vespa/eval/eval/compile_tensor_function.cpp6
-rw-r--r--eval/src/vespa/eval/eval/compile_tensor_function.h4
-rw-r--r--eval/src/vespa/eval/eval/engine_or_factory.cpp91
-rw-r--r--eval/src/vespa/eval/eval/engine_or_factory.h57
-rw-r--r--eval/src/vespa/eval/eval/fast_value.hpp4
-rw-r--r--eval/src/vespa/eval/eval/interpreted_function.cpp14
-rw-r--r--eval/src/vespa/eval/eval/interpreted_function.h20
-rw-r--r--eval/src/vespa/eval/eval/make_tensor_function.cpp6
-rw-r--r--eval/src/vespa/eval/eval/make_tensor_function.h5
-rw-r--r--eval/src/vespa/eval/eval/simple_value.cpp1
-rw-r--r--eval/src/vespa/eval/eval/simple_value.h5
-rw-r--r--eval/src/vespa/eval/eval/tensor_function.cpp60
-rw-r--r--eval/src/vespa/eval/eval/tensor_function.h26
-rw-r--r--eval/src/vespa/eval/eval/test/eval_fixture.cpp4
-rw-r--r--eval/src/vespa/eval/eval/test/eval_fixture.h4
-rw-r--r--eval/src/vespa/eval/eval/test/tensor_conformance.cpp72
-rw-r--r--eval/src/vespa/eval/eval/test/tensor_conformance.h4
-rw-r--r--eval/src/vespa/eval/eval/value.cpp17
-rw-r--r--eval/src/vespa/eval/eval/value.h6
-rw-r--r--eval/src/vespa/eval/eval/value_cache/constant_tensor_loader.h6
-rw-r--r--eval/src/vespa/eval/eval/value_codec.cpp12
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_cell_range_function.cpp2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_cell_range_function.h2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_dot_product_function.cpp2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_dot_product_function.h2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_lambda_function.cpp11
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_lambda_function.h2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_lambda_peek_function.cpp2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_lambda_peek_function.h2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_matmul_function.cpp2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_matmul_function.h2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_multi_matmul_function.cpp2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_multi_matmul_function.h2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_number_join_function.cpp2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_number_join_function.h2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_replace_type_function.cpp2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_replace_type_function.h2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_simple_expand_function.cpp2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_simple_expand_function.h2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_simple_join_function.cpp2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_simple_join_function.h2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_simple_map_function.cpp2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_simple_map_function.h2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_single_reduce_function.cpp2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_single_reduce_function.h2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_tensor_create_function.cpp2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_tensor_create_function.h2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_tensor_peek_function.cpp2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_tensor_peek_function.h2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_xw_product_function.cpp2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_xw_product_function.h2
-rw-r--r--eval/src/vespa/eval/tensor/dense/vector_from_doubles_function.cpp2
-rw-r--r--eval/src/vespa/eval/tensor/dense/vector_from_doubles_function.h2
66 files changed, 405 insertions, 213 deletions
diff --git a/eval/src/apps/tensor_conformance/tensor_conformance.cpp b/eval/src/apps/tensor_conformance/tensor_conformance.cpp
index 6099e543922..1f8069db06d 100644
--- a/eval/src/apps/tensor_conformance/tensor_conformance.cpp
+++ b/eval/src/apps/tensor_conformance/tensor_conformance.cpp
@@ -88,7 +88,7 @@ std::vector<ValueType> get_types(const std::vector<Value::UP> &param_values) {
return param_types;
}
-TensorSpec eval_expr(const Inspector &test, const TensorEngine &engine, bool typed) {
+TensorSpec eval_expr(const Inspector &test, EngineOrFactory engine, bool typed) {
auto fun = Function::parse(test["expression"].asString().make_string());
std::vector<Value::UP> param_values;
std::vector<Value::CREF> param_refs;
diff --git a/eval/src/tests/eval/interpreted_function/interpreted_function_test.cpp b/eval/src/tests/eval/interpreted_function/interpreted_function_test.cpp
index 60700817266..ee595606c14 100644
--- a/eval/src/tests/eval/interpreted_function/interpreted_function_test.cpp
+++ b/eval/src/tests/eval/interpreted_function/interpreted_function_test.cpp
@@ -72,7 +72,7 @@ struct MyEvalTest : test::EvalSpec::EvalTest {
}
}
- void verify_result(const TensorEngine &engine,
+ void verify_result(EngineOrFactory engine,
const Function &function,
bool typed,
const vespalib::string &description,
diff --git a/eval/src/tests/eval/simple_value/simple_value_test.cpp b/eval/src/tests/eval/simple_value/simple_value_test.cpp
index e989b567e20..cac1a93dbf9 100644
--- a/eval/src/tests/eval/simple_value/simple_value_test.cpp
+++ b/eval/src/tests/eval/simple_value/simple_value_test.cpp
@@ -74,7 +74,7 @@ TensorSpec simple_value_new_join(const TensorSpec &a, const TensorSpec &b, join_
auto lhs = value_from_spec(a, factory);
auto rhs = value_from_spec(b, factory);
auto my_op = GenericJoin::make_instruction(lhs->type(), rhs->type(), function, factory, stash);
- InterpretedFunction::EvalSingle single(my_op);
+ InterpretedFunction::EvalSingle single(factory, my_op);
return spec_from_value(single.eval(std::vector<Value::CREF>({*lhs,*rhs})));
}
diff --git a/eval/src/tests/eval/tensor_function/tensor_function_test.cpp b/eval/src/tests/eval/tensor_function/tensor_function_test.cpp
index b205205f52e..ca446c6162f 100644
--- a/eval/src/tests/eval/tensor_function/tensor_function_test.cpp
+++ b/eval/src/tests/eval/tensor_function/tensor_function_test.cpp
@@ -14,13 +14,13 @@ using namespace vespalib::eval;
using namespace vespalib::eval::tensor_function;
struct EvalCtx {
- const TensorEngine &engine;
+ EngineOrFactory engine;
Stash stash;
std::vector<Value::UP> tensors;
std::vector<Value::CREF> params;
InterpretedFunction::UP ifun;
std::unique_ptr<InterpretedFunction::Context> ictx;
- EvalCtx(const TensorEngine &engine_in)
+ EvalCtx(EngineOrFactory engine_in)
: engine(engine_in), stash(), tensors(), params(), ifun(), ictx() {}
~EvalCtx() {}
size_t add_tensor(Value::UP tensor) {
diff --git a/eval/src/tests/instruction/generic_concat/generic_concat_test.cpp b/eval/src/tests/instruction/generic_concat/generic_concat_test.cpp
index dc69bce30f6..b48c1e2253c 100644
--- a/eval/src/tests/instruction/generic_concat/generic_concat_test.cpp
+++ b/eval/src/tests/instruction/generic_concat/generic_concat_test.cpp
@@ -126,7 +126,7 @@ TensorSpec perform_generic_concat(const TensorSpec &a, const TensorSpec &b, cons
auto lhs = value_from_spec(a, factory);
auto rhs = value_from_spec(b, factory);
auto my_op = GenericConcat::make_instruction(lhs->type(), rhs->type(), concat_dim, factory, stash);
- InterpretedFunction::EvalSingle single(my_op);
+ InterpretedFunction::EvalSingle single(factory, my_op);
return spec_from_value(single.eval(std::vector<Value::CREF>({*lhs,*rhs})));
}
diff --git a/eval/src/tests/instruction/generic_join/generic_join_test.cpp b/eval/src/tests/instruction/generic_join/generic_join_test.cpp
index 25715f07bea..82696bbbd5e 100644
--- a/eval/src/tests/instruction/generic_join/generic_join_test.cpp
+++ b/eval/src/tests/instruction/generic_join/generic_join_test.cpp
@@ -76,7 +76,7 @@ TensorSpec perform_generic_join(const TensorSpec &a, const TensorSpec &b, join_f
auto lhs = value_from_spec(a, factory);
auto rhs = value_from_spec(b, factory);
auto my_op = GenericJoin::make_instruction(lhs->type(), rhs->type(), function, factory, stash);
- InterpretedFunction::EvalSingle single(my_op);
+ InterpretedFunction::EvalSingle single(factory, my_op);
return spec_from_value(single.eval(std::vector<Value::CREF>({*lhs,*rhs})));
}
@@ -86,7 +86,7 @@ TensorSpec perform_generic_join_fast(const TensorSpec &a, const TensorSpec &b, j
auto lhs = value_from_spec(a, factory);
auto rhs = value_from_spec(b, factory);
auto my_op = GenericJoin::make_instruction(lhs->type(), rhs->type(), function, factory, stash);
- InterpretedFunction::EvalSingle single(my_op);
+ InterpretedFunction::EvalSingle single(factory, my_op);
return spec_from_value(single.eval(std::vector<Value::CREF>({*lhs,*rhs})));
}
diff --git a/eval/src/tests/instruction/generic_merge/generic_merge_test.cpp b/eval/src/tests/instruction/generic_merge/generic_merge_test.cpp
index 501d5410b87..ae2e100176b 100644
--- a/eval/src/tests/instruction/generic_merge/generic_merge_test.cpp
+++ b/eval/src/tests/instruction/generic_merge/generic_merge_test.cpp
@@ -61,7 +61,7 @@ TensorSpec perform_generic_merge(const TensorSpec &a, const TensorSpec &b, join_
auto lhs = value_from_spec(a, factory);
auto rhs = value_from_spec(b, factory);
auto my_op = GenericMerge::make_instruction(lhs->type(), rhs->type(), fun, factory, stash);
- InterpretedFunction::EvalSingle single(my_op);
+ InterpretedFunction::EvalSingle single(factory, my_op);
return spec_from_value(single.eval(std::vector<Value::CREF>({*lhs, *rhs})));
}
diff --git a/eval/src/tests/instruction/generic_reduce/generic_reduce_test.cpp b/eval/src/tests/instruction/generic_reduce/generic_reduce_test.cpp
index 7e9a059967a..335e4e46642 100644
--- a/eval/src/tests/instruction/generic_reduce/generic_reduce_test.cpp
+++ b/eval/src/tests/instruction/generic_reduce/generic_reduce_test.cpp
@@ -63,7 +63,7 @@ TensorSpec perform_generic_reduce(const TensorSpec &a, const std::vector<vespali
const auto &factory = SimpleValueBuilderFactory::get();
auto lhs = value_from_spec(a, factory);
auto my_op = GenericReduce::make_instruction(lhs->type(), aggr, dims, factory, stash);
- InterpretedFunction::EvalSingle single(my_op);
+ InterpretedFunction::EvalSingle single(factory, my_op);
return spec_from_value(single.eval(std::vector<Value::CREF>({*lhs})));
}
diff --git a/eval/src/tests/instruction/generic_rename/generic_rename_test.cpp b/eval/src/tests/instruction/generic_rename/generic_rename_test.cpp
index d5c7f58fc1f..3f151af1fd6 100644
--- a/eval/src/tests/instruction/generic_rename/generic_rename_test.cpp
+++ b/eval/src/tests/instruction/generic_rename/generic_rename_test.cpp
@@ -117,7 +117,7 @@ TensorSpec perform_generic_rename(const TensorSpec &a,
Stash stash;
auto lhs = value_from_spec(a, factory);
auto my_op = GenericRename::make_instruction(lhs->type(), ft.from, ft.to, factory, stash);
- InterpretedFunction::EvalSingle single(my_op);
+ InterpretedFunction::EvalSingle single(factory, my_op);
return spec_from_value(single.eval(std::vector<Value::CREF>({*lhs})));
}
diff --git a/eval/src/tests/tensor/dense_replace_type_function/dense_replace_type_function_test.cpp b/eval/src/tests/tensor/dense_replace_type_function/dense_replace_type_function_test.cpp
index 9ebcb0ec77c..84e79ff85e8 100644
--- a/eval/src/tests/tensor/dense_replace_type_function/dense_replace_type_function_test.cpp
+++ b/eval/src/tests/tensor/dense_replace_type_function/dense_replace_type_function_test.cpp
@@ -23,7 +23,7 @@ struct ChildMock : Leaf {
bool is_mutable;
ChildMock(const ValueType &type) : Leaf(type), is_mutable(true) {}
bool result_is_mutable() const override { return is_mutable; }
- InterpretedFunction::Instruction compile_self(const TensorEngine &, Stash &) const override { abort(); }
+ InterpretedFunction::Instruction compile_self(EngineOrFactory, Stash &) const override { abort(); }
};
struct Fixture {
diff --git a/eval/src/tests/tensor/instruction_benchmark/instruction_benchmark.cpp b/eval/src/tests/tensor/instruction_benchmark/instruction_benchmark.cpp
index 953415f9f71..e340b5d75b3 100644
--- a/eval/src/tests/tensor/instruction_benchmark/instruction_benchmark.cpp
+++ b/eval/src/tests/tensor/instruction_benchmark/instruction_benchmark.cpp
@@ -60,93 +60,55 @@ struct Impl {
size_t order;
vespalib::string name;
vespalib::string short_name;
- Impl(size_t order_in, const vespalib::string &name_in, const vespalib::string &short_name_in)
- : order(order_in), name(name_in), short_name(short_name_in) {}
- virtual Value::UP create_value(const TensorSpec &spec) const = 0;
- virtual TensorSpec create_spec(const Value &value) const = 0;
- virtual Instruction create_join(const ValueType &lhs, const ValueType &rhs, operation::op2_t function, Stash &stash) const = 0;
- virtual Instruction create_reduce(const ValueType &lhs, Aggr aggr, const std::vector<vespalib::string> &dims, Stash &stash) const = 0;
- virtual Instruction create_rename(const ValueType &lhs, const std::vector<vespalib::string> &from, const std::vector<vespalib::string> &to, Stash &stash) const = 0;
- virtual Instruction create_merge(const ValueType &lhs, const ValueType &rhs, operation::op2_t function, Stash &stash) const = 0;
- virtual Instruction create_concat(const ValueType &lhs, const ValueType &rhs, const std::string &dimension, Stash &stash) const = 0;
- virtual const TensorEngine &engine() const { return SimpleTensorEngine::ref(); } // engine used by EvalSingle
- virtual ~Impl() {}
-};
-
-struct ValueImpl : Impl {
- const ValueBuilderFactory &my_factory;
- ValueImpl(size_t order_in, const vespalib::string &name_in, const vespalib::string &short_name_in, const ValueBuilderFactory &factory)
- : Impl(order_in, name_in, short_name_in), my_factory(factory) {}
- Value::UP create_value(const TensorSpec &spec) const override { return value_from_spec(spec, my_factory); }
- TensorSpec create_spec(const Value &value) const override { return spec_from_value(value); }
- Instruction create_join(const ValueType &lhs, const ValueType &rhs, operation::op2_t function, Stash &stash) const override {
- return GenericJoin::make_instruction(lhs, rhs, function, my_factory, stash);
- }
- Instruction create_reduce(const ValueType &lhs, Aggr aggr, const std::vector<vespalib::string> &dims, Stash &stash) const override {
- return GenericReduce::make_instruction(lhs, aggr, dims, my_factory, stash);
- }
- Instruction create_rename(const ValueType &lhs, const std::vector<vespalib::string> &from, const std::vector<vespalib::string> &to, Stash &stash) const override {
- return GenericRename::make_instruction(lhs, from, to, my_factory, stash);
- }
- Instruction create_merge(const ValueType &lhs, const ValueType &rhs, operation::op2_t function, Stash &stash) const override {
- return GenericMerge::make_instruction(lhs, rhs, function, my_factory, stash);
- }
- Instruction create_concat(const ValueType &lhs, const ValueType &rhs, const std::string &dimension, Stash &stash) const override {
- return GenericConcat::make_instruction(lhs, rhs, dimension, my_factory, stash);
- }
-};
-
-struct EngineImpl : Impl {
- const TensorEngine &my_engine;
- EngineImpl(size_t order_in, const vespalib::string &name_in, const vespalib::string &short_name_in, const TensorEngine &engine_in)
- : Impl(order_in, name_in, short_name_in), my_engine(engine_in) {}
- Value::UP create_value(const TensorSpec &spec) const override { return my_engine.from_spec(spec); }
- TensorSpec create_spec(const Value &value) const override { return my_engine.to_spec(value); }
- Instruction create_join(const ValueType &lhs, const ValueType &rhs, operation::op2_t function, Stash &stash) const override {
+ EngineOrFactory engine;
+ Impl(size_t order_in, const vespalib::string &name_in, const vespalib::string &short_name_in, EngineOrFactory engine_in)
+ : order(order_in), name(name_in), short_name(short_name_in), engine(engine_in) {}
+ Value::UP create_value(const TensorSpec &spec) const { return engine.from_spec(spec); }
+ TensorSpec create_spec(const Value &value) const { return engine.to_spec(value); }
+ Instruction create_join(const ValueType &lhs, const ValueType &rhs, operation::op2_t function, Stash &stash) const {
// create a complete tensor function, but only compile the relevant instruction
const auto &lhs_node = tensor_function::inject(lhs, 0, stash);
const auto &rhs_node = tensor_function::inject(rhs, 1, stash);
const auto &join_node = tensor_function::join(lhs_node, rhs_node, function, stash);
- return join_node.compile_self(my_engine, stash);
+ return join_node.compile_self(engine, stash);
}
- Instruction create_reduce(const ValueType &lhs, Aggr aggr, const std::vector<vespalib::string> &dims, Stash &stash) const override {
+ Instruction create_reduce(const ValueType &lhs, Aggr aggr, const std::vector<vespalib::string> &dims, Stash &stash) const {
// create a complete tensor function, but only compile the relevant instruction
const auto &lhs_node = tensor_function::inject(lhs, 0, stash);
const auto &reduce_node = tensor_function::reduce(lhs_node, aggr, dims, stash);
- return reduce_node.compile_self(my_engine, stash);
+ return reduce_node.compile_self(engine, stash);
}
- Instruction create_rename(const ValueType &lhs, const std::vector<vespalib::string> &from, const std::vector<vespalib::string> &to, Stash &stash) const override {
+ Instruction create_rename(const ValueType &lhs, const std::vector<vespalib::string> &from, const std::vector<vespalib::string> &to, Stash &stash) const {
// create a complete tensor function, but only compile the relevant instruction
const auto &lhs_node = tensor_function::inject(lhs, 0, stash);
const auto &rename_node = tensor_function::rename(lhs_node, from, to, stash);
- return rename_node.compile_self(my_engine, stash);
+ return rename_node.compile_self(engine, stash);
}
- Instruction create_merge(const ValueType &lhs, const ValueType &rhs, operation::op2_t function, Stash &stash) const override {
+ Instruction create_merge(const ValueType &lhs, const ValueType &rhs, operation::op2_t function, Stash &stash) const {
// create a complete tensor function, but only compile the relevant instruction
const auto &lhs_node = tensor_function::inject(lhs, 0, stash);
const auto &rhs_node = tensor_function::inject(rhs, 1, stash);
const auto &merge_node = tensor_function::merge(lhs_node, rhs_node, function, stash);
- return merge_node.compile_self(my_engine, stash);
+ return merge_node.compile_self(engine, stash);
}
- Instruction create_concat(const ValueType &lhs, const ValueType &rhs, const std::string &dimension, Stash &stash) const override {
+ Instruction create_concat(const ValueType &lhs, const ValueType &rhs, const std::string &dimension, Stash &stash) const {
// create a complete tensor function, but only compile the relevant instruction
const auto &lhs_node = tensor_function::inject(lhs, 0, stash);
const auto &rhs_node = tensor_function::inject(rhs, 1, stash);
const auto &concat_node = tensor_function::concat(lhs_node, rhs_node, dimension, stash);
- return concat_node.compile_self(my_engine, stash);
+ return concat_node.compile_self(engine, stash);
}
- const TensorEngine &engine() const override { return my_engine; }
};
//-----------------------------------------------------------------------------
-EngineImpl simple_tensor_engine_impl(5, " SimpleTensorEngine", " SimpleT", SimpleTensorEngine::ref());
-EngineImpl default_tensor_engine_impl(1, "DefaultTensorEngine", "OLD PROD", DefaultTensorEngine::ref());
-ValueImpl simple_value_impl(2, " SimpleValue", " SimpleV", SimpleValueBuilderFactory::get());
-ValueImpl fast_value_impl(0, " FastValue", "NEW PROD", FastValueBuilderFactory::get());
-ValueImpl packed_mixed_tensor_impl(4, " PackedMixedTensor", " Packed", PackedMixedTensorBuilderFactory::get());
-ValueImpl default_tensor_value_impl(3, " DefaultValue", "DefaultV", DefaultValueBuilderFactory::get());
-vespalib::string short_header("--------");
+Impl simple_tensor_engine_impl(5, " SimpleTensorEngine", " SimpleT", SimpleTensorEngine::ref());
+Impl default_tensor_engine_impl(1, "DefaultTensorEngine", "OLD PROD", DefaultTensorEngine::ref());
+Impl simple_value_impl(2, " SimpleValue", " SimpleV", SimpleValueBuilderFactory::get());
+Impl fast_value_impl(0, " FastValue", "NEW PROD", FastValueBuilderFactory::get());
+Impl packed_mixed_tensor_impl(4, " PackedMixedTensor", " Packed", PackedMixedTensorBuilderFactory::get());
+Impl default_tensor_value_impl(3, " DefaultValue", "DefaultV", DefaultValueBuilderFactory::get());
+vespalib::string short_header("--------");
constexpr double budget = 5.0;
constexpr double best_limit = 0.95; // everything within 95% of best performance gets a star
@@ -236,7 +198,7 @@ struct EvalOp {
EvalOp(const EvalOp &) = delete;
EvalOp &operator=(const EvalOp &) = delete;
EvalOp(Instruction op, const std::vector<CREF<TensorSpec>> &stack_spec, const Impl &impl_in)
- : impl(impl_in), values(), stack(), single(impl.engine(), op)
+ : impl(impl_in), values(), stack(), single(impl.engine, op)
{
for (const TensorSpec &spec: stack_spec) {
values.push_back(impl.create_value(spec));
diff --git a/eval/src/tests/tensor/tensor_conformance/tensor_conformance_test.cpp b/eval/src/tests/tensor/tensor_conformance/tensor_conformance_test.cpp
index df415e39134..a9681cd85c9 100644
--- a/eval/src/tests/tensor/tensor_conformance/tensor_conformance_test.cpp
+++ b/eval/src/tests/tensor/tensor_conformance/tensor_conformance_test.cpp
@@ -2,9 +2,13 @@
#include <vespa/vespalib/testkit/test_kit.h>
#include <vespa/eval/eval/test/tensor_conformance.h>
#include <vespa/eval/eval/simple_tensor_engine.h>
+#include <vespa/eval/eval/simple_value.h>
+#include <vespa/eval/eval/fast_value.h>
#include <vespa/eval/tensor/default_tensor_engine.h>
#include <vespa/vespalib/util/stringfmt.h>
+using vespalib::eval::SimpleValueBuilderFactory;
+using vespalib::eval::FastValueBuilderFactory;
using vespalib::eval::SimpleTensorEngine;
using vespalib::eval::test::TensorConformance;
using vespalib::tensor::DefaultTensorEngine;
@@ -21,6 +25,14 @@ TEST("require that production tensor implementation passes all conformance tests
TEST_DO(TensorConformance::run_tests(module_src_path, DefaultTensorEngine::ref()));
}
+TEST("require that SimpleValue implementation passes all conformance tests (except ImmediateAPI tests)") {
+ TEST_DO(TensorConformance::run_tests(module_src_path, SimpleValueBuilderFactory::get()));
+}
+
+TEST("require that FastValue implementation passes all conformance tests (except ImmediateAPI tests)") {
+ TEST_DO(TensorConformance::run_tests(module_src_path, FastValueBuilderFactory::get()));
+}
+
TEST("require that tensor serialization test spec can be generated") {
vespalib::string spec = module_src_path + "src/apps/make_tensor_binary_format_test_spec/test_spec.json";
vespalib::string binary = module_build_path + "src/apps/make_tensor_binary_format_test_spec/eval_make_tensor_binary_format_test_spec_app";
diff --git a/eval/src/vespa/eval/eval/CMakeLists.txt b/eval/src/vespa/eval/eval/CMakeLists.txt
index 244966fc992..5a60adfb58b 100644
--- a/eval/src/vespa/eval/eval/CMakeLists.txt
+++ b/eval/src/vespa/eval/eval/CMakeLists.txt
@@ -7,6 +7,7 @@ vespa_add_library(eval_eval OBJECT
compile_tensor_function.cpp
delete_node.cpp
double_value_builder.cpp
+ engine_or_factory.cpp
fast_forest.cpp
fast_sparse_map.cpp
fast_value.cpp
diff --git a/eval/src/vespa/eval/eval/compile_tensor_function.cpp b/eval/src/vespa/eval/eval/compile_tensor_function.cpp
index 18ef59507d8..6fd754b9cc8 100644
--- a/eval/src/vespa/eval/eval/compile_tensor_function.cpp
+++ b/eval/src/vespa/eval/eval/compile_tensor_function.cpp
@@ -32,11 +32,11 @@ struct Frame {
};
struct ProgramCompiler {
- const TensorEngine &engine;
+ EngineOrFactory engine;
Stash &stash;
std::vector<Frame> stack;
std::vector<Instruction> prog;
- ProgramCompiler(const TensorEngine &engine_in, Stash &stash_in) : engine(engine_in), stash(stash_in), stack(), prog() {}
+ ProgramCompiler(EngineOrFactory engine_in, Stash &stash_in) : engine(engine_in), stash(stash_in), stack(), prog() {}
void append(const std::vector<Instruction> &other_prog) {
prog.insert(prog.end(), other_prog.begin(), other_prog.end());
@@ -76,7 +76,7 @@ struct ProgramCompiler {
} // namespace vespalib::eval::<unnamed>
-std::vector<Instruction> compile_tensor_function(const TensorEngine &engine, const TensorFunction &function, Stash &stash) {
+std::vector<Instruction> compile_tensor_function(EngineOrFactory engine, const TensorFunction &function, Stash &stash) {
ProgramCompiler compiler(engine, stash);
return compiler.compile(function);
}
diff --git a/eval/src/vespa/eval/eval/compile_tensor_function.h b/eval/src/vespa/eval/eval/compile_tensor_function.h
index 63f00fde053..b12705e8bb5 100644
--- a/eval/src/vespa/eval/eval/compile_tensor_function.h
+++ b/eval/src/vespa/eval/eval/compile_tensor_function.h
@@ -2,6 +2,7 @@
#pragma once
+#include "engine_or_factory.h"
#include "interpreted_function.h"
#include <vector>
@@ -10,8 +11,7 @@ namespace vespalib { class Stash; }
namespace vespalib::eval {
struct TensorFunction;
-struct TensorEngine;
-std::vector<InterpretedFunction::Instruction> compile_tensor_function(const TensorEngine &engine, const TensorFunction &function, Stash &stash);
+std::vector<InterpretedFunction::Instruction> compile_tensor_function(EngineOrFactory engine, const TensorFunction &function, Stash &stash);
} // namespace vespalib::eval
diff --git a/eval/src/vespa/eval/eval/engine_or_factory.cpp b/eval/src/vespa/eval/eval/engine_or_factory.cpp
new file mode 100644
index 00000000000..d297cc91f6f
--- /dev/null
+++ b/eval/src/vespa/eval/eval/engine_or_factory.cpp
@@ -0,0 +1,91 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "engine_or_factory.h"
+#include "fast_value.h"
+#include <vespa/eval/tensor/default_tensor_engine.h>
+#include "value_codec.h"
+
+namespace vespalib::eval {
+
+const TensorFunction &
+EngineOrFactory::optimize(const TensorFunction &expr, Stash &stash) const {
+ if (is_engine()) {
+ return engine().optimize(expr, stash);
+ } else if (&factory() == &FastValueBuilderFactory::get()) {
+ return tensor::DefaultTensorEngine::ref().optimize(expr, stash);
+ } else {
+ return expr;
+ }
+}
+
+TensorSpec
+EngineOrFactory::to_spec(const Value &value) const
+{
+ if (is_engine()) {
+ return engine().to_spec(value);
+ } else {
+ return factory(), spec_from_value(value);
+ }
+}
+
+std::unique_ptr<Value>
+EngineOrFactory::from_spec(const TensorSpec &spec) const
+{
+ if (is_engine()) {
+ return engine().from_spec(spec);
+ } else {
+ return value_from_spec(spec, factory());
+ }
+}
+
+void
+EngineOrFactory::encode(const Value &value, nbostream &output) const
+{
+ if (is_engine()) {
+ return engine().encode(value, output);
+ } else {
+ return factory(), encode_value(value, output);
+ }
+}
+
+std::unique_ptr<Value>
+EngineOrFactory::decode(nbostream &input) const
+{
+ if (is_engine()) {
+ return engine().decode(input);
+ } else {
+ return decode_value(input, factory());
+ }
+}
+
+const Value &
+EngineOrFactory::map(const Value &a, operation::op1_t function, Stash &stash) const {
+ return engine().map(a, function, stash);
+}
+
+const Value &
+EngineOrFactory::join(const Value &a, const Value &b, operation::op2_t function, Stash &stash) const {
+ return engine().join(a, b, function, stash);
+}
+
+const Value &
+EngineOrFactory::merge(const Value &a, const Value &b, operation::op2_t function, Stash &stash) const {
+ return engine().merge(a, b, function, stash);
+}
+
+const Value &
+EngineOrFactory::reduce(const Value &a, Aggr aggr, const std::vector<vespalib::string> &dimensions, Stash &stash) const {
+ return engine().reduce(a, aggr, dimensions, stash);
+}
+
+const Value &
+EngineOrFactory::concat(const Value &a, const Value &b, const vespalib::string &dimension, Stash &stash) const {
+ return engine().concat(a, b, dimension, stash);
+}
+
+const Value &
+EngineOrFactory::rename(const Value &a, const std::vector<vespalib::string> &from, const std::vector<vespalib::string> &to, Stash &stash) const {
+ return engine().rename(a, from, to, stash);
+}
+
+}
diff --git a/eval/src/vespa/eval/eval/engine_or_factory.h b/eval/src/vespa/eval/eval/engine_or_factory.h
new file mode 100644
index 00000000000..a95bfda6bd5
--- /dev/null
+++ b/eval/src/vespa/eval/eval/engine_or_factory.h
@@ -0,0 +1,57 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#pragma once
+
+#include "aggr.h"
+#include "tensor_spec.h"
+#include "operation.h"
+#include <variant>
+
+namespace vespalib {
+class Stash;
+class nbostream;
+}
+
+namespace vespalib::eval {
+
+class TensorEngine;
+class ValueBuilderFactory;
+class TensorFunction;
+
+/**
+ * This utility class contains a reference to either a TensorEngine or
+ * a ValueBuilderFactory. This is needed during a transition period to
+ * support both evaluation models. We want to get rid of the
+ * TensorEngine concept since using the Value API directly removes the
+ * need to constrain operations to only calculate on tensors belonging
+ * to the same tensor engine. The factory is a hint to the preferred
+ * Value implementation.
+ **/
+class EngineOrFactory {
+private:
+ using engine_t = const TensorEngine *;
+ using factory_t = const ValueBuilderFactory *;
+ std::variant<engine_t,factory_t> _value;
+public:
+ EngineOrFactory(const TensorEngine &engine_in) : _value(&engine_in) {}
+ EngineOrFactory(const ValueBuilderFactory &factory_in) : _value(&factory_in) {}
+ bool is_engine() const { return std::holds_alternative<engine_t>(_value); }
+ bool is_factory() const { return std::holds_alternative<factory_t>(_value); }
+ const TensorEngine &engine() const { return *std::get<engine_t>(_value); }
+ const ValueBuilderFactory &factory() const { return *std::get<factory_t>(_value); }
+ // functions that can be called with either engine or factory
+ const TensorFunction &optimize(const TensorFunction &expr, Stash &stash) const;
+ TensorSpec to_spec(const Value &value) const;
+ std::unique_ptr<Value> from_spec(const TensorSpec &spec) const;
+ void encode(const Value &value, nbostream &output) const;
+ std::unique_ptr<Value> decode(nbostream &input) const;
+ // engine-only forwarding functions
+ const Value &map(const Value &a, operation::op1_t function, Stash &stash) const;
+ const Value &join(const Value &a, const Value &b, operation::op2_t function, Stash &stash) const;
+ const Value &merge(const Value &a, const Value &b, operation::op2_t function, Stash &stash) const;
+ const Value &reduce(const Value &a, Aggr aggr, const std::vector<vespalib::string> &dimensions, Stash &stash) const;
+ const Value &concat(const Value &a, const Value &b, const vespalib::string &dimension, Stash &stash) const;
+ const Value &rename(const Value &a, const std::vector<vespalib::string> &from, const std::vector<vespalib::string> &to, Stash &stash) const;
+};
+
+}
diff --git a/eval/src/vespa/eval/eval/fast_value.hpp b/eval/src/vespa/eval/eval/fast_value.hpp
index 4efb56ee0c4..e0b401b800c 100644
--- a/eval/src/vespa/eval/eval/fast_value.hpp
+++ b/eval/src/vespa/eval/eval/fast_value.hpp
@@ -182,6 +182,10 @@ struct FastValue final : Value, ValueBuilder<T> {
return ArrayRef<T>(&my_cells[old_size], my_subspace_size);
}
std::unique_ptr<Value> build(std::unique_ptr<ValueBuilder<T>> self) override {
+ if (my_index.map.num_dims() == 0) {
+ assert(my_index.map.size() == 1);
+ }
+ assert(my_cells.size() == (my_index.map.size() * my_subspace_size));
ValueBuilder<T>* me = this;
assert(me == self.get());
self.release();
diff --git a/eval/src/vespa/eval/eval/interpreted_function.cpp b/eval/src/vespa/eval/eval/interpreted_function.cpp
index e9c82789991..3460bc5923b 100644
--- a/eval/src/vespa/eval/eval/interpreted_function.cpp
+++ b/eval/src/vespa/eval/eval/interpreted_function.cpp
@@ -33,7 +33,7 @@ const Function *get_lambda(const nodes::Node &node) {
} // namespace vespalib::<unnamed>
-InterpretedFunction::State::State(const TensorEngine &engine_in)
+InterpretedFunction::State::State(EngineOrFactory engine_in)
: engine(engine_in),
params(nullptr),
stash(),
@@ -59,7 +59,7 @@ InterpretedFunction::Context::Context(const InterpretedFunction &ifun)
{
}
-InterpretedFunction::InterpretedFunction(const TensorEngine &engine, const TensorFunction &function)
+InterpretedFunction::InterpretedFunction(EngineOrFactory engine, const TensorFunction &function)
: _program(),
_stash(),
_tensor_engine(engine)
@@ -67,7 +67,7 @@ InterpretedFunction::InterpretedFunction(const TensorEngine &engine, const Tenso
_program = compile_tensor_function(engine, function, _stash);
}
-InterpretedFunction::InterpretedFunction(const TensorEngine &engine, const nodes::Node &root, const NodeTypes &types)
+InterpretedFunction::InterpretedFunction(EngineOrFactory engine, const nodes::Node &root, const NodeTypes &types)
: _program(),
_stash(),
_tensor_engine(engine)
@@ -118,13 +118,7 @@ InterpretedFunction::detect_issues(const Function &function)
return Function::Issues(std::move(checker.issues));
}
-InterpretedFunction::EvalSingle::EvalSingle(Instruction op)
- : _state(SimpleTensorEngine::ref()),
- _op(op)
-{
-}
-
-InterpretedFunction::EvalSingle::EvalSingle(const TensorEngine &engine, Instruction op)
+InterpretedFunction::EvalSingle::EvalSingle(EngineOrFactory engine, Instruction op)
: _state(engine),
_op(op)
{
diff --git a/eval/src/vespa/eval/eval/interpreted_function.h b/eval/src/vespa/eval/eval/interpreted_function.h
index e5ec86d8a91..c1b86649606 100644
--- a/eval/src/vespa/eval/eval/interpreted_function.h
+++ b/eval/src/vespa/eval/eval/interpreted_function.h
@@ -2,6 +2,7 @@
#pragma once
+#include "engine_or_factory.h"
#include "function.h"
#include "node_types.h"
#include "lazy_params.h"
@@ -10,7 +11,6 @@
namespace vespalib::eval {
namespace nodes { struct Node; }
-struct TensorEngine;
struct TensorFunction;
class TensorSpec;
@@ -28,14 +28,14 @@ class InterpretedFunction
{
public:
struct State {
- const TensorEngine &engine;
+ EngineOrFactory engine;
const LazyParams *params;
Stash stash;
std::vector<Value::CREF> stack;
uint32_t program_offset;
uint32_t if_cnt;
- State(const TensorEngine &engine_in);
+ State(EngineOrFactory engine_in);
~State();
void init(const LazyParams &params_in);
@@ -87,14 +87,14 @@ public:
private:
std::vector<Instruction> _program;
Stash _stash;
- const TensorEngine &_tensor_engine;
+ EngineOrFactory _tensor_engine;
public:
typedef std::unique_ptr<InterpretedFunction> UP;
// for testing; use with care; the tensor function must be kept alive
- InterpretedFunction(const TensorEngine &engine, const TensorFunction &function);
- InterpretedFunction(const TensorEngine &engine, const nodes::Node &root, const NodeTypes &types);
- InterpretedFunction(const TensorEngine &engine, const Function &function, const NodeTypes &types)
+ InterpretedFunction(EngineOrFactory engine, const TensorFunction &function);
+ InterpretedFunction(EngineOrFactory engine, const nodes::Node &root, const NodeTypes &types);
+ InterpretedFunction(EngineOrFactory engine, const Function &function, const NodeTypes &types)
: InterpretedFunction(engine, function.root(), types) {}
InterpretedFunction(InterpretedFunction &&rhs) = default;
~InterpretedFunction();
@@ -109,16 +109,14 @@ public:
* instructions manipulating the program counter or resolving
* parameters may not be run in this way. Also note that the stack
* must contain exactly one value after the instruction is
- * executed. If no tensor engine is specified, SimpleTensorEngine
- * is used (typically for instructions ignoring the engine).
+ * executed.
**/
class EvalSingle {
private:
State _state;
Instruction _op;
public:
- EvalSingle(Instruction op);
- EvalSingle(const TensorEngine &engine, Instruction op);
+ EvalSingle(EngineOrFactory engine, Instruction op);
const Value &eval(const std::vector<Value::CREF> &stack);
};
};
diff --git a/eval/src/vespa/eval/eval/make_tensor_function.cpp b/eval/src/vespa/eval/eval/make_tensor_function.cpp
index c5b5ca59401..dc76c914c06 100644
--- a/eval/src/vespa/eval/eval/make_tensor_function.cpp
+++ b/eval/src/vespa/eval/eval/make_tensor_function.cpp
@@ -20,11 +20,11 @@ using namespace nodes;
struct TensorFunctionBuilder : public NodeVisitor, public NodeTraverser {
Stash &stash;
- const TensorEngine &tensor_engine;
+ EngineOrFactory tensor_engine;
const NodeTypes &types;
std::vector<TensorFunction::CREF> stack;
- TensorFunctionBuilder(Stash &stash_in, const TensorEngine &tensor_engine_in, const NodeTypes &types_in)
+ TensorFunctionBuilder(Stash &stash_in, EngineOrFactory tensor_engine_in, const NodeTypes &types_in)
: stash(stash_in), tensor_engine(tensor_engine_in), types(types_in), stack() {}
//-------------------------------------------------------------------------
@@ -356,7 +356,7 @@ struct TensorFunctionBuilder : public NodeVisitor, public NodeTraverser {
} // namespace vespalib::eval::<unnamed>
-const TensorFunction &make_tensor_function(const TensorEngine &engine, const nodes::Node &root, const NodeTypes &types, Stash &stash) {
+const TensorFunction &make_tensor_function(EngineOrFactory engine, const nodes::Node &root, const NodeTypes &types, Stash &stash) {
TensorFunctionBuilder builder(stash, engine, types);
root.traverse(builder);
assert(builder.stack.size() == 1);
diff --git a/eval/src/vespa/eval/eval/make_tensor_function.h b/eval/src/vespa/eval/eval/make_tensor_function.h
index bf6a9a44f4a..7cf9515e243 100644
--- a/eval/src/vespa/eval/eval/make_tensor_function.h
+++ b/eval/src/vespa/eval/eval/make_tensor_function.h
@@ -2,16 +2,17 @@
#pragma once
+#include "engine_or_factory.h"
+
namespace vespalib { class Stash; }
namespace vespalib::eval {
-struct TensorEngine;
class NodeTypes;
struct TensorFunction;
namespace nodes { struct Node; }
-const TensorFunction &make_tensor_function(const TensorEngine &engine, const nodes::Node &root, const NodeTypes &types, Stash &stash);
+const TensorFunction &make_tensor_function(EngineOrFactory engine, const nodes::Node &root, const NodeTypes &types, Stash &stash);
} // namespace vespalib::eval
diff --git a/eval/src/vespa/eval/eval/simple_value.cpp b/eval/src/vespa/eval/eval/simple_value.cpp
index cca4c6c7d51..2c0d08e9e86 100644
--- a/eval/src/vespa/eval/eval/simple_value.cpp
+++ b/eval/src/vespa/eval/eval/simple_value.cpp
@@ -214,7 +214,6 @@ SimpleValueT<T>::add_subspace(ConstArrayRef<vespalib::stringref> addr)
size_t old_size = _cells.size();
add_mapping(addr);
_cells.resize(old_size + subspace_size());
- assert(_cells.size() == (size() * subspace_size()));
return ArrayRef<T>(&_cells[old_size], subspace_size());
}
diff --git a/eval/src/vespa/eval/eval/simple_value.h b/eval/src/vespa/eval/eval/simple_value.h
index 81f65eee061..c838161bbde 100644
--- a/eval/src/vespa/eval/eval/simple_value.h
+++ b/eval/src/vespa/eval/eval/simple_value.h
@@ -28,6 +28,7 @@ private:
size_t _subspace_size;
std::map<Labels,size_t> _index;
protected:
+ size_t num_mapped_dims() const { return _num_mapped_dims; }
size_t subspace_size() const { return _subspace_size; }
void add_mapping(ConstArrayRef<vespalib::stringref> addr);
public:
@@ -53,6 +54,10 @@ public:
TypedCells cells() const override { return TypedCells(ConstArrayRef<T>(_cells)); }
ArrayRef<T> add_subspace(ConstArrayRef<vespalib::stringref> addr) override;
std::unique_ptr<Value> build(std::unique_ptr<ValueBuilder<T>> self) override {
+ if (num_mapped_dims() == 0) {
+ assert(size() == 1);
+ }
+ assert(_cells.size() == (size() * subspace_size()));
ValueBuilder<T>* me = this;
assert(me == self.get());
self.release();
diff --git a/eval/src/vespa/eval/eval/tensor_function.cpp b/eval/src/vespa/eval/eval/tensor_function.cpp
index ed7e173a400..33bf2ce9c0e 100644
--- a/eval/src/vespa/eval/eval/tensor_function.cpp
+++ b/eval/src/vespa/eval/eval/tensor_function.cpp
@@ -8,6 +8,11 @@
#include "simple_tensor_engine.h"
#include "visit_stuff.h"
#include "string_stuff.h"
+#include <vespa/eval/instruction/generic_concat.h>
+#include <vespa/eval/instruction/generic_join.h>
+#include <vespa/eval/instruction/generic_merge.h>
+#include <vespa/eval/instruction/generic_reduce.h>
+#include <vespa/eval/instruction/generic_rename.h>
#include <vespa/vespalib/objects/objectdumper.h>
#include <vespa/vespalib/objects/visit.hpp>
@@ -87,6 +92,18 @@ void op_tensor_map(State &state, uint64_t param) {
state.pop_push(state.engine.map(state.peek(0), to_map_fun(param), state.stash));
}
+// replace with GenericMap when ready
+void op_tensor_spec_map(State &state, uint64_t param) {
+ auto fun = to_map_fun(param);
+ auto old_spec = state.engine.to_spec(state.peek(0));
+ TensorSpec new_spec(old_spec.type());
+ for (auto &cell: old_spec.cells()) {
+ new_spec.add(cell.first, fun(cell.second));
+ }
+ const Value &result = *state.stash.create<Value::UP>(state.engine.from_spec(new_spec));
+ state.pop_push(result);
+}
+
void op_tensor_join(State &state, uint64_t param) {
state.pop_pop_push(state.engine.join(state.peek(1), state.peek(0), to_join_fun(param), state.stash));
}
@@ -239,7 +256,7 @@ Op2::visit_children(vespalib::ObjectVisitor &visitor) const
//-----------------------------------------------------------------------------
Instruction
-ConstValue::compile_self(const TensorEngine &, Stash &) const
+ConstValue::compile_self(EngineOrFactory, Stash &) const
{
return Instruction(op_load_const, wrap_param<Value>(_value));
}
@@ -258,7 +275,7 @@ ConstValue::visit_self(vespalib::ObjectVisitor &visitor) const
//-----------------------------------------------------------------------------
Instruction
-Inject::compile_self(const TensorEngine &, Stash &) const
+Inject::compile_self(EngineOrFactory, Stash &) const
{
return Instruction::fetch_param(_param_idx);
}
@@ -273,8 +290,11 @@ Inject::visit_self(vespalib::ObjectVisitor &visitor) const
//-----------------------------------------------------------------------------
Instruction
-Reduce::compile_self(const TensorEngine &, Stash &stash) const
+Reduce::compile_self(EngineOrFactory engine, Stash &stash) const
{
+ if (engine.is_factory()) {
+ return instruction::GenericReduce::make_instruction(child().result_type(), aggr(), dimensions(), engine.factory(), stash);
+ }
ReduceParams &params = stash.create<ReduceParams>(_aggr, _dimensions);
return Instruction(op_tensor_reduce, wrap_param<ReduceParams>(params));
}
@@ -290,8 +310,12 @@ Reduce::visit_self(vespalib::ObjectVisitor &visitor) const
//-----------------------------------------------------------------------------
Instruction
-Map::compile_self(const TensorEngine &, Stash &) const
+Map::compile_self(EngineOrFactory engine, Stash &) const
{
+ if (engine.is_factory()) {
+ // replace with GenericMap when ready
+ return Instruction(op_tensor_spec_map, to_param(_function));
+ }
if (result_type().is_double()) {
return Instruction(op_double_map, to_param(_function));
}
@@ -308,8 +332,11 @@ Map::visit_self(vespalib::ObjectVisitor &visitor) const
//-----------------------------------------------------------------------------
Instruction
-Join::compile_self(const TensorEngine &, Stash &) const
+Join::compile_self(EngineOrFactory engine, Stash &stash) const
{
+ if (engine.is_factory()) {
+ return instruction::GenericJoin::make_instruction(lhs().result_type(), rhs().result_type(), function(), engine.factory(), stash);
+ }
if (result_type().is_double()) {
if (_function == operation::Mul::f) {
return Instruction(op_double_mul);
@@ -332,8 +359,11 @@ Join::visit_self(vespalib::ObjectVisitor &visitor) const
//-----------------------------------------------------------------------------
Instruction
-Merge::compile_self(const TensorEngine &, Stash &) const
+Merge::compile_self(EngineOrFactory engine, Stash &stash) const
{
+ if (engine.is_factory()) {
+ return instruction::GenericMerge::make_instruction(lhs().result_type(), rhs().result_type(), function(), engine.factory(), stash);
+ }
return Instruction(op_tensor_merge, to_param(_function));
}
@@ -347,8 +377,11 @@ Merge::visit_self(vespalib::ObjectVisitor &visitor) const
//-----------------------------------------------------------------------------
Instruction
-Concat::compile_self(const TensorEngine &, Stash &) const
+Concat::compile_self(EngineOrFactory engine, Stash &stash) const
{
+ if (engine.is_factory()) {
+ return instruction::GenericConcat::make_instruction(lhs().result_type(), rhs().result_type(), dimension(), engine.factory(), stash);
+ }
return Instruction(op_tensor_concat, wrap_param<vespalib::string>(_dimension));
}
@@ -370,7 +403,7 @@ Create::push_children(std::vector<Child::CREF> &children) const
}
Instruction
-Create::compile_self(const TensorEngine &, Stash &) const
+Create::compile_self(EngineOrFactory, Stash &) const
{
return Instruction(op_tensor_create, wrap_param<Create>(*this));
}
@@ -432,7 +465,7 @@ Lambda::create_spec_impl(const ValueType &type, const LazyParams &params, const
}
InterpretedFunction::Instruction
-Lambda::compile_self(const TensorEngine &engine, Stash &stash) const
+Lambda::compile_self(EngineOrFactory engine, Stash &stash) const
{
InterpretedFunction fun(engine, _lambda->root(), _lambda_types);
LambdaParams &params = stash.create<LambdaParams>(*this, std::move(fun));
@@ -464,7 +497,7 @@ Peek::push_children(std::vector<Child::CREF> &children) const
}
Instruction
-Peek::compile_self(const TensorEngine &, Stash &) const
+Peek::compile_self(EngineOrFactory, Stash &) const
{
return Instruction(op_tensor_peek, wrap_param<Peek>(*this));
}
@@ -493,8 +526,11 @@ Peek::visit_children(vespalib::ObjectVisitor &visitor) const
//-----------------------------------------------------------------------------
Instruction
-Rename::compile_self(const TensorEngine &, Stash &stash) const
+Rename::compile_self(EngineOrFactory engine, Stash &stash) const
{
+ if (engine.is_factory()) {
+ return instruction::GenericRename::make_instruction(child().result_type(), from(), to(), engine.factory(), stash);
+ }
RenameParams &params = stash.create<RenameParams>(_from, _to);
return Instruction(op_tensor_rename, wrap_param<RenameParams>(params));
}
@@ -517,7 +553,7 @@ If::push_children(std::vector<Child::CREF> &children) const
}
Instruction
-If::compile_self(const TensorEngine &, Stash &) const
+If::compile_self(EngineOrFactory, Stash &) const
{
// 'if' is handled directly by compile_tensor_function to enable
// lazy-evaluation of true/false sub-expressions.
diff --git a/eval/src/vespa/eval/eval/tensor_function.h b/eval/src/vespa/eval/eval/tensor_function.h
index c7733147e48..d6158f8eb4a 100644
--- a/eval/src/vespa/eval/eval/tensor_function.h
+++ b/eval/src/vespa/eval/eval/tensor_function.h
@@ -107,7 +107,7 @@ struct TensorFunction
* @param engine the tensor engine used for evaluation
* @param stash heterogeneous object store
**/
- virtual InterpretedFunction::Instruction compile_self(const TensorEngine &engine, Stash &stash) const = 0;
+ virtual InterpretedFunction::Instruction compile_self(EngineOrFactory engine, Stash &stash) const = 0;
// for debug dumping
vespalib::string as_string() const;
@@ -188,7 +188,7 @@ public:
ConstValue(const Value &value_in) : Super(value_in.type()), _value(value_in) {}
const Value &value() const { return _value; }
bool result_is_mutable() const override { return false; }
- InterpretedFunction::Instruction compile_self(const TensorEngine &engine, Stash &stash) const final override;
+ InterpretedFunction::Instruction compile_self(EngineOrFactory engine, Stash &stash) const final override;
void visit_self(vespalib::ObjectVisitor &visitor) const override;
};
@@ -204,7 +204,7 @@ public:
: Super(result_type_in), _param_idx(param_idx_in) {}
size_t param_idx() const { return _param_idx; }
bool result_is_mutable() const override { return false; }
- InterpretedFunction::Instruction compile_self(const TensorEngine &engine, Stash &stash) const final override;
+ InterpretedFunction::Instruction compile_self(EngineOrFactory engine, Stash &stash) const final override;
void visit_self(vespalib::ObjectVisitor &visitor) const override;
};
@@ -225,7 +225,7 @@ public:
Aggr aggr() const { return _aggr; }
const std::vector<vespalib::string> &dimensions() const { return _dimensions; }
bool result_is_mutable() const override { return true; }
- InterpretedFunction::Instruction compile_self(const TensorEngine &engine, Stash &stash) const final override;
+ InterpretedFunction::Instruction compile_self(EngineOrFactory engine, Stash &stash) const final override;
void visit_self(vespalib::ObjectVisitor &visitor) const override;
};
@@ -243,7 +243,7 @@ public:
: Super(result_type_in, child_in), _function(function_in) {}
map_fun_t function() const { return _function; }
bool result_is_mutable() const override { return true; }
- InterpretedFunction::Instruction compile_self(const TensorEngine &engine, Stash &stash) const override;
+ InterpretedFunction::Instruction compile_self(EngineOrFactory engine, Stash &stash) const override;
void visit_self(vespalib::ObjectVisitor &visitor) const override;
};
@@ -262,7 +262,7 @@ public:
: Super(result_type_in, lhs_in, rhs_in), _function(function_in) {}
join_fun_t function() const { return _function; }
bool result_is_mutable() const override { return true; }
- InterpretedFunction::Instruction compile_self(const TensorEngine &engine, Stash &stash) const override;
+ InterpretedFunction::Instruction compile_self(EngineOrFactory engine, Stash &stash) const override;
void visit_self(vespalib::ObjectVisitor &visitor) const override;
};
@@ -281,7 +281,7 @@ public:
: Super(result_type_in, lhs_in, rhs_in), _function(function_in) {}
join_fun_t function() const { return _function; }
bool result_is_mutable() const override { return true; }
- InterpretedFunction::Instruction compile_self(const TensorEngine &engine, Stash &stash) const override;
+ InterpretedFunction::Instruction compile_self(EngineOrFactory engine, Stash &stash) const override;
void visit_self(vespalib::ObjectVisitor &visitor) const override;
};
@@ -300,7 +300,7 @@ public:
: Super(result_type_in, lhs_in, rhs_in), _dimension(dimension_in) {}
const vespalib::string &dimension() const { return _dimension; }
bool result_is_mutable() const override { return true; }
- InterpretedFunction::Instruction compile_self(const TensorEngine &engine, Stash &stash) const final override;
+ InterpretedFunction::Instruction compile_self(EngineOrFactory engine, Stash &stash) const final override;
void visit_self(vespalib::ObjectVisitor &visitor) const override;
};
@@ -321,7 +321,7 @@ public:
}
const std::map<TensorSpec::Address, Child> &spec() const { return _spec; }
bool result_is_mutable() const override { return true; }
- InterpretedFunction::Instruction compile_self(const TensorEngine &engine, Stash &stash) const final override;
+ InterpretedFunction::Instruction compile_self(EngineOrFactory engine, Stash &stash) const final override;
void push_children(std::vector<Child::CREF> &children) const final override;
void visit_children(vespalib::ObjectVisitor &visitor) const final override;
};
@@ -346,7 +346,7 @@ public:
return create_spec_impl(result_type(), params, _bindings, fun);
}
bool result_is_mutable() const override { return true; }
- InterpretedFunction::Instruction compile_self(const TensorEngine &engine, Stash &stash) const final override;
+ InterpretedFunction::Instruction compile_self(EngineOrFactory engine, Stash &stash) const final override;
void visit_self(vespalib::ObjectVisitor &visitor) const override;
};
@@ -380,7 +380,7 @@ public:
const std::map<vespalib::string, MyLabel> &spec() const { return _spec; }
const ValueType &param_type() const { return _param.get().result_type(); }
bool result_is_mutable() const override { return true; }
- InterpretedFunction::Instruction compile_self(const TensorEngine &engine, Stash &stash) const final override;
+ InterpretedFunction::Instruction compile_self(EngineOrFactory engine, Stash &stash) const final override;
void push_children(std::vector<Child::CREF> &children) const final override;
void visit_children(vespalib::ObjectVisitor &visitor) const final override;
};
@@ -402,7 +402,7 @@ public:
const std::vector<vespalib::string> &from() const { return _from; }
const std::vector<vespalib::string> &to() const { return _to; }
bool result_is_mutable() const override { return true; }
- InterpretedFunction::Instruction compile_self(const TensorEngine &engine, Stash &stash) const final override;
+ InterpretedFunction::Instruction compile_self(EngineOrFactory engine, Stash &stash) const final override;
void visit_self(vespalib::ObjectVisitor &visitor) const override;
};
@@ -428,7 +428,7 @@ public:
return (true_child().result_is_mutable() &&
false_child().result_is_mutable());
}
- InterpretedFunction::Instruction compile_self(const TensorEngine &engine, Stash &stash) const final override;
+ InterpretedFunction::Instruction compile_self(EngineOrFactory engine, Stash &stash) const final override;
void visit_children(vespalib::ObjectVisitor &visitor) const final override;
};
diff --git a/eval/src/vespa/eval/eval/test/eval_fixture.cpp b/eval/src/vespa/eval/eval/test/eval_fixture.cpp
index 0b27ba1f2df..a353f3a9ae2 100644
--- a/eval/src/vespa/eval/eval/test/eval_fixture.cpp
+++ b/eval/src/vespa/eval/eval/test/eval_fixture.cpp
@@ -79,7 +79,7 @@ const TensorFunction &maybe_patch(bool allow_mutable, const TensorFunction &plai
return root.get();
}
-std::vector<Value::UP> make_params(const TensorEngine &engine, const Function &function,
+std::vector<Value::UP> make_params(EngineOrFactory engine, const Function &function,
const ParamRepo &param_repo)
{
std::vector<Value::UP> result;
@@ -191,7 +191,7 @@ EvalFixture::detect_param_tampering(const ParamRepo &param_repo, bool allow_muta
}
}
-EvalFixture::EvalFixture(const TensorEngine &engine,
+EvalFixture::EvalFixture(EngineOrFactory engine,
const vespalib::string &expr,
const ParamRepo &param_repo,
bool optimized,
diff --git a/eval/src/vespa/eval/eval/test/eval_fixture.h b/eval/src/vespa/eval/eval/test/eval_fixture.h
index 31fcee49782..54693cbc1bb 100644
--- a/eval/src/vespa/eval/eval/test/eval_fixture.h
+++ b/eval/src/vespa/eval/eval/test/eval_fixture.h
@@ -45,7 +45,7 @@ public:
};
private:
- const TensorEngine &_engine;
+ EngineOrFactory _engine;
Stash _stash;
std::shared_ptr<Function const> _function;
NodeTypes _node_types;
@@ -74,7 +74,7 @@ private:
void detect_param_tampering(const ParamRepo &param_repo, bool allow_mutable) const;
public:
- EvalFixture(const TensorEngine &engine, const vespalib::string &expr, const ParamRepo &param_repo,
+ EvalFixture(EngineOrFactory engine, const vespalib::string &expr, const ParamRepo &param_repo,
bool optimized = true, bool allow_mutable = false);
~EvalFixture() {}
template <typename T>
diff --git a/eval/src/vespa/eval/eval/test/tensor_conformance.cpp b/eval/src/vespa/eval/eval/test/tensor_conformance.cpp
index 95e720cd1a2..c6f73d611cc 100644
--- a/eval/src/vespa/eval/eval/test/tensor_conformance.cpp
+++ b/eval/src/vespa/eval/eval/test/tensor_conformance.cpp
@@ -39,7 +39,7 @@ struct Eval {
TensorSpec _tensor;
public:
Result() : _type(Type::ERROR), _number(0.0), _tensor("error") {}
- Result(const TensorEngine &engine, const Value &value) : _type(Type::ERROR), _number(0.0), _tensor("error") {
+ Result(EngineOrFactory engine, const Value &value) : _type(Type::ERROR), _number(0.0), _tensor("error") {
if (value.is_double()) {
_type = Type::NUMBER;
}
@@ -62,15 +62,15 @@ struct Eval {
return _tensor;
}
};
- virtual Result eval(const TensorEngine &) const {
+ virtual Result eval(EngineOrFactory) const {
TEST_ERROR("wrong signature");
return Result();
}
- virtual Result eval(const TensorEngine &, const TensorSpec &) const {
+ virtual Result eval(EngineOrFactory, const TensorSpec &) const {
TEST_ERROR("wrong signature");
return Result();
}
- virtual Result eval(const TensorEngine &, const TensorSpec &, const TensorSpec &) const {
+ virtual Result eval(EngineOrFactory, const TensorSpec &, const TensorSpec &) const {
TEST_ERROR("wrong signature");
return Result();
}
@@ -81,7 +81,7 @@ struct Eval {
struct SafeEval : Eval {
const Eval &unsafe;
SafeEval(const Eval &unsafe_in) : unsafe(unsafe_in) {}
- Result eval(const TensorEngine &engine) const override {
+ Result eval(EngineOrFactory engine) const override {
try {
return unsafe.eval(engine);
} catch (std::exception &e) {
@@ -89,7 +89,7 @@ struct SafeEval : Eval {
return Result();
}
}
- Result eval(const TensorEngine &engine, const TensorSpec &a) const override {
+ Result eval(EngineOrFactory engine, const TensorSpec &a) const override {
try {
return unsafe.eval(engine, a);
} catch (std::exception &e) {
@@ -98,7 +98,7 @@ struct SafeEval : Eval {
}
}
- Result eval(const TensorEngine &engine, const TensorSpec &a, const TensorSpec &b) const override {
+ Result eval(EngineOrFactory engine, const TensorSpec &a, const TensorSpec &b) const override {
try {
return unsafe.eval(engine, a, b);
} catch (std::exception &e) {
@@ -118,7 +118,7 @@ const Value &check_type(const Value &value, const ValueType &expect_type) {
struct Expr_V : Eval {
const vespalib::string &expr;
Expr_V(const vespalib::string &expr_in) : expr(expr_in) {}
- Result eval(const TensorEngine &engine) const override {
+ Result eval(EngineOrFactory engine) const override {
auto fun = Function::parse(expr);
NodeTypes types(*fun, {});
InterpretedFunction ifun(engine, *fun, types);
@@ -132,7 +132,7 @@ struct Expr_V : Eval {
struct Expr_T : Eval {
const vespalib::string &expr;
Expr_T(const vespalib::string &expr_in) : expr(expr_in) {}
- Result eval(const TensorEngine &engine, const TensorSpec &a) const override {
+ Result eval(EngineOrFactory engine, const TensorSpec &a) const override {
auto fun = Function::parse(expr);
auto a_type = ValueType::from_spec(a.type());
NodeTypes types(*fun, {a_type});
@@ -148,7 +148,7 @@ struct Expr_T : Eval {
struct Expr_TT : Eval {
vespalib::string expr;
Expr_TT(const vespalib::string &expr_in) : expr(expr_in) {}
- Result eval(const TensorEngine &engine, const TensorSpec &a, const TensorSpec &b) const override {
+ Result eval(EngineOrFactory engine, const TensorSpec &a, const TensorSpec &b) const override {
auto fun = Function::parse(expr);
auto a_type = ValueType::from_spec(a.type());
auto b_type = ValueType::from_spec(b.type());
@@ -162,7 +162,7 @@ struct Expr_TT : Eval {
}
};
-const Value &make_value(const TensorEngine &engine, const TensorSpec &spec, Stash &stash) {
+const Value &make_value(EngineOrFactory engine, const TensorSpec &spec, Stash &stash) {
return *stash.create<Value::UP>(engine.from_spec(spec));
}
@@ -175,7 +175,7 @@ struct ImmediateReduce : Eval {
ImmediateReduce(Aggr aggr_in) : aggr(aggr_in), dimensions() {}
ImmediateReduce(Aggr aggr_in, const vespalib::string &dimension)
: aggr(aggr_in), dimensions({dimension}) {}
- Result eval(const TensorEngine &engine, const TensorSpec &a) const override {
+ Result eval(EngineOrFactory engine, const TensorSpec &a) const override {
Stash stash;
const auto &lhs = make_value(engine, a, stash);
return Result(engine, engine.reduce(lhs, aggr, dimensions, stash));
@@ -187,7 +187,7 @@ struct ImmediateMap : Eval {
using fun_t = double (*)(double);
fun_t function;
ImmediateMap(fun_t function_in) : function(function_in) {}
- Result eval(const TensorEngine &engine, const TensorSpec &a) const override {
+ Result eval(EngineOrFactory engine, const TensorSpec &a) const override {
Stash stash;
const auto &lhs = make_value(engine, a, stash);
return Result(engine, engine.map(lhs, function, stash));
@@ -199,7 +199,7 @@ struct ImmediateJoin : Eval {
using fun_t = double (*)(double, double);
fun_t function;
ImmediateJoin(fun_t function_in) : function(function_in) {}
- Result eval(const TensorEngine &engine, const TensorSpec &a, const TensorSpec &b) const override {
+ Result eval(EngineOrFactory engine, const TensorSpec &a, const TensorSpec &b) const override {
Stash stash;
const auto &lhs = make_value(engine, a, stash);
const auto &rhs = make_value(engine, b, stash);
@@ -211,7 +211,7 @@ struct ImmediateJoin : Eval {
struct ImmediateConcat : Eval {
vespalib::string dimension;
ImmediateConcat(const vespalib::string &dimension_in) : dimension(dimension_in) {}
- Result eval(const TensorEngine &engine, const TensorSpec &a, const TensorSpec &b) const override {
+ Result eval(EngineOrFactory engine, const TensorSpec &a, const TensorSpec &b) const override {
Stash stash;
const auto &lhs = make_value(engine, a, stash);
const auto &rhs = make_value(engine, b, stash);
@@ -225,7 +225,7 @@ struct ImmediateRename : Eval {
std::vector<vespalib::string> to;
ImmediateRename(const std::vector<vespalib::string> &from_in, const std::vector<vespalib::string> &to_in)
: from(from_in), to(to_in) {}
- Result eval(const TensorEngine &engine, const TensorSpec &a) const override {
+ Result eval(EngineOrFactory engine, const TensorSpec &a) const override {
Stash stash;
const auto &lhs = make_value(engine, a, stash);
return Result(engine, engine.rename(lhs, from, to, stash));
@@ -284,10 +284,10 @@ bool is_same(const nbostream &a, const nbostream &b) {
struct TestContext {
vespalib::string module_path;
- const TensorEngine &ref_engine;
- const TensorEngine &engine;
+ EngineOrFactory ref_engine;
+ EngineOrFactory engine;
- TestContext(const vespalib::string &module_path_in, const TensorEngine &engine_in)
+ TestContext(const vespalib::string &module_path_in, EngineOrFactory engine_in)
: module_path(module_path_in), ref_engine(SimpleTensorEngine::ref()), engine(engine_in) {}
//-------------------------------------------------------------------------
@@ -339,7 +339,9 @@ struct TestContext {
vespalib::string expr = make_string("reduce(a,%s,%s)",
AggrNames::name_of(aggr)->c_str(), domain.dimension.c_str());
TEST_DO(verify_reduce_result(Expr_T(expr), input, expect));
- TEST_DO(verify_reduce_result(ImmediateReduce(aggr, domain.dimension), input, expect));
+ if (engine.is_engine()) {
+ TEST_DO(verify_reduce_result(ImmediateReduce(aggr, domain.dimension), input, expect));
+ }
}
{
Eval::Result expect = ImmediateReduce(aggr).eval(ref_engine, input);
@@ -347,7 +349,9 @@ struct TestContext {
infer_type(layout).c_str()).c_str());
vespalib::string expr = make_string("reduce(a,%s)", AggrNames::name_of(aggr)->c_str());
TEST_DO(verify_reduce_result(Expr_T(expr), input, expect));
- TEST_DO(verify_reduce_result(ImmediateReduce(aggr), input, expect));
+ if (engine.is_engine()) {
+ TEST_DO(verify_reduce_result(ImmediateReduce(aggr), input, expect));
+ }
}
}
}
@@ -384,7 +388,9 @@ struct TestContext {
}
void test_map_op(const vespalib::string &expr, map_fun_t op, const Sequence &seq) {
- TEST_DO(test_map_op(ImmediateMap(op), op, seq));
+ if (engine.is_engine()) {
+ TEST_DO(test_map_op(ImmediateMap(op), op, seq));
+ }
TEST_DO(test_map_op(Expr_T(expr), op, seq));
TEST_DO(test_map_op(Expr_T(make_string("map(x,f(a)(%s))", expr.c_str())), op, seq));
}
@@ -661,7 +667,9 @@ struct TestContext {
}
void test_apply_op(const vespalib::string &expr, join_fun_t op, const Sequence &seq) {
- TEST_DO(test_apply_op(ImmediateJoin(op), op, seq));
+ if (engine.is_engine()) {
+ TEST_DO(test_apply_op(ImmediateJoin(op), op, seq));
+ }
TEST_DO(test_apply_op(Expr_TT(expr), op, seq));
TEST_DO(test_apply_op(Expr_TT(make_string("join(x,y,f(a,b)(%s))", expr.c_str())), op, seq));
}
@@ -723,9 +731,11 @@ struct TestContext {
const vespalib::string &dimension,
const TensorSpec &expect)
{
- ImmediateConcat eval(dimension);
vespalib::string expr = make_string("concat(a,b,%s)", dimension.c_str());
- TEST_DO(verify_result(eval.eval(engine, a, b), expect));
+ if (engine.is_engine()) {
+ ImmediateConcat eval(dimension);
+ TEST_DO(verify_result(eval.eval(engine, a, b), expect));
+ }
TEST_DO(verify_result(Expr_TT(expr).eval(engine, a, b), expect));
}
@@ -763,8 +773,10 @@ struct TestContext {
const std::vector<vespalib::string> &to,
const TensorSpec &expect)
{
- ImmediateRename eval(from, to);
- TEST_DO(verify_result(eval.eval(engine, input), expect));
+ if (engine.is_engine()) {
+ ImmediateRename eval(from, to);
+ TEST_DO(verify_result(eval.eval(engine, input), expect));
+ }
TEST_DO(verify_result(Expr_T(expr).eval(engine, input), expect));
}
@@ -857,8 +869,8 @@ struct TestContext {
//-------------------------------------------------------------------------
void verify_encode_decode(const TensorSpec &spec,
- const TensorEngine &encode_engine,
- const TensorEngine &decode_engine)
+ EngineOrFactory encode_engine,
+ EngineOrFactory decode_engine)
{
Stash stash;
nbostream data;
@@ -948,7 +960,7 @@ struct TestContext {
} // namespace vespalib::eval::test::<unnamed>
void
-TensorConformance::run_tests(const vespalib::string &module_path, const TensorEngine &engine)
+TensorConformance::run_tests(const vespalib::string &module_path, EngineOrFactory engine)
{
TestContext ctx(module_path, engine);
fprintf(stderr, "module path: '%s'\n", ctx.module_path.c_str());
diff --git a/eval/src/vespa/eval/eval/test/tensor_conformance.h b/eval/src/vespa/eval/eval/test/tensor_conformance.h
index e7f0560c71f..9aed3840191 100644
--- a/eval/src/vespa/eval/eval/test/tensor_conformance.h
+++ b/eval/src/vespa/eval/eval/test/tensor_conformance.h
@@ -2,7 +2,7 @@
#pragma once
-#include <vespa/eval/eval/tensor_engine.h>
+#include <vespa/eval/eval/engine_or_factory.h>
#include <vespa/vespalib/stllike/string.h>
namespace vespalib {
@@ -14,7 +14,7 @@ namespace test {
* implementations of the TensorEngine interface.
**/
struct TensorConformance {
- static void run_tests(const vespalib::string &module_path, const TensorEngine &engine);
+ static void run_tests(const vespalib::string &module_path, EngineOrFactory engine);
};
} // namespace vespalib::eval::test
diff --git a/eval/src/vespa/eval/eval/value.cpp b/eval/src/vespa/eval/eval/value.cpp
index 7bf2d587904..1e9aca9e079 100644
--- a/eval/src/vespa/eval/eval/value.cpp
+++ b/eval/src/vespa/eval/eval/value.cpp
@@ -2,6 +2,7 @@
#include "value.h"
#include "tensor_engine.h"
+#include <vespa/vespalib/util/typify.h>
namespace vespalib {
namespace eval {
@@ -22,6 +23,16 @@ struct TrivialView : Value::Index::View {
}
};
+struct MySum {
+ template <typename CT> static double invoke(TypedCells cells) {
+ double res = 0.0;
+ for (CT cell: cells.typify<CT>()) {
+ res += cell;
+ }
+ return res;
+ }
+};
+
} // <unnamed>
@@ -40,6 +51,12 @@ TrivialIndex::create_view(const std::vector<size_t> &) const
return std::make_unique<TrivialView>();
}
+double
+Value::as_double() const
+{
+ return typify_invoke<1,TypifyCellType,MySum>(type().cell_type(), cells());
+}
+
ValueType DoubleValue::_type = ValueType::double_type();
} // namespace vespalib::eval
diff --git a/eval/src/vespa/eval/eval/value.h b/eval/src/vespa/eval/eval/value.h
index da4fc47f29b..daa6678dab2 100644
--- a/eval/src/vespa/eval/eval/value.h
+++ b/eval/src/vespa/eval/eval/value.h
@@ -62,9 +62,9 @@ struct Value {
// --- end of new interface
// --- old interface that may be (partially) removed in the future
- virtual bool is_double() const { return false; }
- virtual bool is_tensor() const { return false; }
- virtual double as_double() const { return 0.0; }
+ virtual bool is_double() const { return type().is_double(); }
+ virtual bool is_tensor() const { return type().is_tensor(); }
+ virtual double as_double() const;
bool as_bool() const { return (as_double() != 0.0); }
virtual const Tensor *as_tensor() const { return nullptr; }
// --- end of old interface
diff --git a/eval/src/vespa/eval/eval/value_cache/constant_tensor_loader.h b/eval/src/vespa/eval/eval/value_cache/constant_tensor_loader.h
index 6f998232488..8fb6460efcf 100644
--- a/eval/src/vespa/eval/eval/value_cache/constant_tensor_loader.h
+++ b/eval/src/vespa/eval/eval/value_cache/constant_tensor_loader.h
@@ -3,7 +3,7 @@
#pragma once
#include "constant_value.h"
-#include <vespa/eval/eval/tensor_engine.h>
+#include <vespa/eval/eval/engine_or_factory.h>
#include <vespa/vespalib/stllike/string.h>
namespace vespalib {
@@ -19,9 +19,9 @@ namespace eval {
class ConstantTensorLoader : public ConstantValueFactory
{
private:
- const TensorEngine &_engine;
+ EngineOrFactory _engine;
public:
- ConstantTensorLoader(const TensorEngine &engine) : _engine(engine) {}
+ ConstantTensorLoader(EngineOrFactory engine) : _engine(engine) {}
ConstantValue::UP create(const vespalib::string &path, const vespalib::string &type) const override;
};
diff --git a/eval/src/vespa/eval/eval/value_codec.cpp b/eval/src/vespa/eval/eval/value_codec.cpp
index 762cecea1c3..c6456a7b723 100644
--- a/eval/src/vespa/eval/eval/value_codec.cpp
+++ b/eval/src/vespa/eval/eval/value_codec.cpp
@@ -111,6 +111,9 @@ ValueType decode_type(nbostream &input, const Format &format) {
dim_list.emplace_back(name, input.getInt1_4Bytes());
}
}
+ if (dim_list.empty()) {
+ assert(cell_type == ValueType::CellType::DOUBLE);
+ }
return ValueType::tensor_type(std::move(dim_list), cell_type);
}
@@ -138,10 +141,9 @@ void decode_mapped_labels(nbostream &input, size_t num_mapped_dims, std::vector<
template<typename T>
void decode_cells(nbostream &input, size_t num_cells, ArrayRef<T> dst)
{
- T value;
+ assert(num_cells == dst.size());
for (size_t i = 0; i < num_cells; ++i) {
- input >> value;
- dst[i] = value;
+ dst[i] = input.readValue<T>();
}
}
@@ -167,6 +169,10 @@ struct ContentDecoder {
auto block_cells = builder->add_subspace(address);
decode_cells(input, state.subspace_size, block_cells);
}
+ // add implicit empty subspace
+ if ((state.num_mapped_dims == 0) && (state.num_blocks == 0)) {
+ builder->add_subspace({});
+ }
return builder->build(std::move(builder));
}
};
diff --git a/eval/src/vespa/eval/tensor/dense/dense_cell_range_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_cell_range_function.cpp
index cdeca1653a6..a9ef5a89a1c 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_cell_range_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_cell_range_function.cpp
@@ -42,7 +42,7 @@ DenseCellRangeFunction::DenseCellRangeFunction(const eval::ValueType &result_typ
DenseCellRangeFunction::~DenseCellRangeFunction() = default;
eval::InterpretedFunction::Instruction
-DenseCellRangeFunction::compile_self(const TensorEngine &, Stash &) const
+DenseCellRangeFunction::compile_self(eval::EngineOrFactory, Stash &) const
{
assert(result_type().cell_type() == child().result_type().cell_type());
diff --git a/eval/src/vespa/eval/tensor/dense/dense_cell_range_function.h b/eval/src/vespa/eval/tensor/dense/dense_cell_range_function.h
index 3f220826324..adc1047f8f3 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_cell_range_function.h
+++ b/eval/src/vespa/eval/tensor/dense/dense_cell_range_function.h
@@ -24,7 +24,7 @@ public:
~DenseCellRangeFunction() override;
size_t offset() const { return _offset; }
size_t length() const { return _length; }
- eval::InterpretedFunction::Instruction compile_self(const eval::TensorEngine &engine, Stash &stash) const override;
+ eval::InterpretedFunction::Instruction compile_self(eval::EngineOrFactory engine, Stash &stash) const override;
bool result_is_mutable() const override { return child().result_is_mutable(); }
};
diff --git a/eval/src/vespa/eval/tensor/dense/dense_dot_product_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_dot_product_function.cpp
index 09530beb0b1..7b68bb52e3a 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_dot_product_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_dot_product_function.cpp
@@ -73,7 +73,7 @@ DenseDotProductFunction::DenseDotProductFunction(const eval::TensorFunction &lhs
}
eval::InterpretedFunction::Instruction
-DenseDotProductFunction::compile_self(const TensorEngine &, Stash &) const
+DenseDotProductFunction::compile_self(eval::EngineOrFactory, Stash &) const
{
auto op = my_select(lhs().result_type().cell_type(), rhs().result_type().cell_type());
return eval::InterpretedFunction::Instruction(op);
diff --git a/eval/src/vespa/eval/tensor/dense/dense_dot_product_function.h b/eval/src/vespa/eval/tensor/dense/dense_dot_product_function.h
index 1ee6baff2a5..28f49035860 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_dot_product_function.h
+++ b/eval/src/vespa/eval/tensor/dense/dense_dot_product_function.h
@@ -16,7 +16,7 @@ private:
public:
DenseDotProductFunction(const eval::TensorFunction &lhs_in,
const eval::TensorFunction &rhs_in);
- eval::InterpretedFunction::Instruction compile_self(const eval::TensorEngine &engine, Stash &stash) const override;
+ eval::InterpretedFunction::Instruction compile_self(eval::EngineOrFactory engine, Stash &stash) const override;
bool result_is_mutable() const override { return true; }
static bool compatible_types(const ValueType &res, const ValueType &lhs, const ValueType &rhs);
static const eval::TensorFunction &optimize(const eval::TensorFunction &expr, Stash &stash);
diff --git a/eval/src/vespa/eval/tensor/dense/dense_lambda_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_lambda_function.cpp
index 81c91c8377e..0005a56736d 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_lambda_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_lambda_function.cpp
@@ -28,8 +28,6 @@ using State = InterpretedFunction::State;
using namespace eval::tensor_function;
-const TensorEngine &prod_engine = DefaultTensorEngine::ref();
-
namespace {
//-----------------------------------------------------------------------------
@@ -105,11 +103,11 @@ struct InterpretedParams {
const std::vector<size_t> &bindings;
size_t num_cells;
InterpretedFunction fun;
- InterpretedParams(const Lambda &lambda)
+ InterpretedParams(const Lambda &lambda, eval::EngineOrFactory engine)
: result_type(lambda.result_type()),
bindings(lambda.bindings()),
num_cells(result_type.dense_subspace_size()),
- fun(prod_engine, lambda.lambda().root(), lambda.types())
+ fun(engine, lambda.lambda().root(), lambda.types())
{
assert(lambda.lambda().num_params() == (result_type.dimensions().size() + bindings.size()));
}
@@ -159,9 +157,8 @@ DenseLambdaFunction::eval_mode() const
}
Instruction
-DenseLambdaFunction::compile_self(const TensorEngine &engine, Stash &stash) const
+DenseLambdaFunction::compile_self(eval::EngineOrFactory engine, Stash &stash) const
{
- assert(&engine == &prod_engine);
auto mode = eval_mode();
using MyTypify = eval::TypifyCellType;
if (mode == EvalMode::COMPILED) {
@@ -170,7 +167,7 @@ DenseLambdaFunction::compile_self(const TensorEngine &engine, Stash &stash) cons
return Instruction(op, wrap_param<CompiledParams>(params));
} else {
assert(mode == EvalMode::INTERPRETED);
- InterpretedParams &params = stash.create<InterpretedParams>(_lambda);
+ InterpretedParams &params = stash.create<InterpretedParams>(_lambda, engine);
auto op = typify_invoke<1,MyTypify,MyInterpretedLambdaOp>(result_type().cell_type());
return Instruction(op, wrap_param<InterpretedParams>(params));
}
diff --git a/eval/src/vespa/eval/tensor/dense/dense_lambda_function.h b/eval/src/vespa/eval/tensor/dense/dense_lambda_function.h
index a1b6e5a1551..e82c022d781 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_lambda_function.h
+++ b/eval/src/vespa/eval/tensor/dense/dense_lambda_function.h
@@ -23,7 +23,7 @@ public:
~DenseLambdaFunction() override;
bool result_is_mutable() const override { return true; }
EvalMode eval_mode() const;
- eval::InterpretedFunction::Instruction compile_self(const eval::TensorEngine &engine, Stash &stash) const override;
+ eval::InterpretedFunction::Instruction compile_self(eval::EngineOrFactory engine, Stash &stash) const override;
static const eval::TensorFunction &optimize(const eval::TensorFunction &expr, Stash &stash);
};
diff --git a/eval/src/vespa/eval/tensor/dense/dense_lambda_peek_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_lambda_peek_function.cpp
index 50f58526f7c..cae17e5ebe2 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_lambda_peek_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_lambda_peek_function.cpp
@@ -61,7 +61,7 @@ DenseLambdaPeekFunction::DenseLambdaPeekFunction(const ValueType &result_type,
DenseLambdaPeekFunction::~DenseLambdaPeekFunction() = default;
InterpretedFunction::Instruction
-DenseLambdaPeekFunction::compile_self(const TensorEngine &, Stash &stash) const
+DenseLambdaPeekFunction::compile_self(eval::EngineOrFactory, Stash &stash) const
{
const Self &self = stash.create<Self>(result_type(), *_idx_fun);
using MyTypify = eval::TypifyCellType;
diff --git a/eval/src/vespa/eval/tensor/dense/dense_lambda_peek_function.h b/eval/src/vespa/eval/tensor/dense/dense_lambda_peek_function.h
index a4146787bfa..7358ef1427c 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_lambda_peek_function.h
+++ b/eval/src/vespa/eval/tensor/dense/dense_lambda_peek_function.h
@@ -23,7 +23,7 @@ public:
const eval::TensorFunction &child,
std::shared_ptr<eval::Function const> idx_fun);
~DenseLambdaPeekFunction() override;
- eval::InterpretedFunction::Instruction compile_self(const eval::TensorEngine &engine, Stash &stash) const override;
+ eval::InterpretedFunction::Instruction compile_self(eval::EngineOrFactory engine, Stash &stash) const override;
vespalib::string idx_fun_dump() const;
bool result_is_mutable() const override { return true; }
};
diff --git a/eval/src/vespa/eval/tensor/dense/dense_matmul_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_matmul_function.cpp
index 36010fb30ca..23bddc36bb1 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_matmul_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_matmul_function.cpp
@@ -166,7 +166,7 @@ DenseMatMulFunction::DenseMatMulFunction(const eval::ValueType &result_type,
DenseMatMulFunction::~DenseMatMulFunction() = default;
eval::InterpretedFunction::Instruction
-DenseMatMulFunction::compile_self(const TensorEngine &, Stash &stash) const
+DenseMatMulFunction::compile_self(eval::EngineOrFactory, Stash &stash) const
{
using MyTypify = TypifyValue<eval::TypifyCellType,TypifyBool>;
Self &self = stash.create<Self>(result_type(), _lhs_size, _common_size, _rhs_size);
diff --git a/eval/src/vespa/eval/tensor/dense/dense_matmul_function.h b/eval/src/vespa/eval/tensor/dense/dense_matmul_function.h
index 88d7b9f37e0..bf9779177bb 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_matmul_function.h
+++ b/eval/src/vespa/eval/tensor/dense/dense_matmul_function.h
@@ -50,7 +50,7 @@ public:
bool lhs_common_inner() const { return _lhs_common_inner; }
bool rhs_common_inner() const { return _rhs_common_inner; }
- eval::InterpretedFunction::Instruction compile_self(const eval::TensorEngine &engine, Stash &stash) const override;
+ eval::InterpretedFunction::Instruction compile_self(eval::EngineOrFactory engine, Stash &stash) const override;
void visit_self(vespalib::ObjectVisitor &visitor) const override;
static const eval::TensorFunction &optimize(const eval::TensorFunction &expr, Stash &stash);
};
diff --git a/eval/src/vespa/eval/tensor/dense/dense_multi_matmul_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_multi_matmul_function.cpp
index 4f228947624..8788d621693 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_multi_matmul_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_multi_matmul_function.cpp
@@ -184,7 +184,7 @@ DenseMultiMatMulFunction::DenseMultiMatMulFunction(const ValueType &result_type,
DenseMultiMatMulFunction::~DenseMultiMatMulFunction() = default;
InterpretedFunction::Instruction
-DenseMultiMatMulFunction::compile_self(const TensorEngine &, Stash &) const
+DenseMultiMatMulFunction::compile_self(eval::EngineOrFactory, Stash &) const
{
auto op = my_select(lhs().result_type().cell_type());
return InterpretedFunction::Instruction(op, wrap_param<DenseMultiMatMulFunction>(*this));
diff --git a/eval/src/vespa/eval/tensor/dense/dense_multi_matmul_function.h b/eval/src/vespa/eval/tensor/dense/dense_multi_matmul_function.h
index 6df323d6358..17ad6438593 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_multi_matmul_function.h
+++ b/eval/src/vespa/eval/tensor/dense/dense_multi_matmul_function.h
@@ -44,7 +44,7 @@ public:
bool lhs_common_inner() const { return _lhs_common_inner; }
bool rhs_common_inner() const { return _rhs_common_inner; }
- eval::InterpretedFunction::Instruction compile_self(const eval::TensorEngine &engine, Stash &stash) const override;
+ eval::InterpretedFunction::Instruction compile_self(eval::EngineOrFactory engine, Stash &stash) const override;
void visit_self(vespalib::ObjectVisitor &visitor) const override;
static const eval::TensorFunction &optimize(const eval::TensorFunction &expr, Stash &stash);
};
diff --git a/eval/src/vespa/eval/tensor/dense/dense_number_join_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_number_join_function.cpp
index c6636a6a583..d6995256411 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_number_join_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_number_join_function.cpp
@@ -95,7 +95,7 @@ DenseNumberJoinFunction::inplace() const
}
Instruction
-DenseNumberJoinFunction::compile_self(const TensorEngine &, Stash &) const
+DenseNumberJoinFunction::compile_self(eval::EngineOrFactory, Stash &) const
{
auto op = typify_invoke<4,MyTypify,MyGetFun>(result_type().cell_type(), function(),
inplace(), (_primary == Primary::RHS));
diff --git a/eval/src/vespa/eval/tensor/dense/dense_number_join_function.h b/eval/src/vespa/eval/tensor/dense/dense_number_join_function.h
index a4036a7ec34..c4478ce43b6 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_number_join_function.h
+++ b/eval/src/vespa/eval/tensor/dense/dense_number_join_function.h
@@ -27,7 +27,7 @@ public:
~DenseNumberJoinFunction() override;
Primary primary() const { return _primary; }
bool inplace() const;
- eval::InterpretedFunction::Instruction compile_self(const eval::TensorEngine &engine, Stash &stash) const override;
+ eval::InterpretedFunction::Instruction compile_self(eval::EngineOrFactory engine, Stash &stash) const override;
static const eval::TensorFunction &optimize(const eval::TensorFunction &expr, Stash &stash);
};
diff --git a/eval/src/vespa/eval/tensor/dense/dense_replace_type_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_replace_type_function.cpp
index 8880a78529d..004edf06d92 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_replace_type_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_replace_type_function.cpp
@@ -34,7 +34,7 @@ DenseReplaceTypeFunction::~DenseReplaceTypeFunction()
}
eval::InterpretedFunction::Instruction
-DenseReplaceTypeFunction::compile_self(const TensorEngine &, Stash &) const
+DenseReplaceTypeFunction::compile_self(eval::EngineOrFactory, Stash &) const
{
return eval::InterpretedFunction::Instruction(my_replace_type_op, wrap_param<ValueType>(result_type()));
}
diff --git a/eval/src/vespa/eval/tensor/dense/dense_replace_type_function.h b/eval/src/vespa/eval/tensor/dense/dense_replace_type_function.h
index 22c3886022d..504d3f1649b 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_replace_type_function.h
+++ b/eval/src/vespa/eval/tensor/dense/dense_replace_type_function.h
@@ -16,7 +16,7 @@ public:
DenseReplaceTypeFunction(const eval::ValueType &result_type,
const eval::TensorFunction &child);
~DenseReplaceTypeFunction();
- eval::InterpretedFunction::Instruction compile_self(const eval::TensorEngine &engine, Stash &stash) const override;
+ eval::InterpretedFunction::Instruction compile_self(eval::EngineOrFactory engine, Stash &stash) const override;
bool result_is_mutable() const override { return child().result_is_mutable(); }
static const DenseReplaceTypeFunction &create_compact(const eval::ValueType &result_type,
const eval::TensorFunction &child,
diff --git a/eval/src/vespa/eval/tensor/dense/dense_simple_expand_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_simple_expand_function.cpp
index e61e843e801..b2cf390dc11 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_simple_expand_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_simple_expand_function.cpp
@@ -102,7 +102,7 @@ DenseSimpleExpandFunction::DenseSimpleExpandFunction(const ValueType &result_typ
DenseSimpleExpandFunction::~DenseSimpleExpandFunction() = default;
Instruction
-DenseSimpleExpandFunction::compile_self(const TensorEngine &, Stash &stash) const
+DenseSimpleExpandFunction::compile_self(eval::EngineOrFactory, Stash &stash) const
{
size_t result_size = result_type().dense_subspace_size();
const ExpandParams &params = stash.create<ExpandParams>(result_type(), result_size, function());
diff --git a/eval/src/vespa/eval/tensor/dense/dense_simple_expand_function.h b/eval/src/vespa/eval/tensor/dense/dense_simple_expand_function.h
index 4d7c639e3d1..c5c40559c1b 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_simple_expand_function.h
+++ b/eval/src/vespa/eval/tensor/dense/dense_simple_expand_function.h
@@ -32,7 +32,7 @@ public:
Inner inner_in);
~DenseSimpleExpandFunction() override;
Inner inner() const { return _inner; }
- eval::InterpretedFunction::Instruction compile_self(const eval::TensorEngine &engine, Stash &stash) const override;
+ eval::InterpretedFunction::Instruction compile_self(eval::EngineOrFactory engine, Stash &stash) const override;
static const eval::TensorFunction &optimize(const eval::TensorFunction &expr, Stash &stash);
};
diff --git a/eval/src/vespa/eval/tensor/dense/dense_simple_join_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_simple_join_function.cpp
index 7ba043f6510..5aca3799258 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_simple_join_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_simple_join_function.cpp
@@ -190,7 +190,7 @@ DenseSimpleJoinFunction::factor() const
}
Instruction
-DenseSimpleJoinFunction::compile_self(const TensorEngine &, Stash &stash) const
+DenseSimpleJoinFunction::compile_self(eval::EngineOrFactory, Stash &stash) const
{
const JoinParams &params = stash.create<JoinParams>(result_type(), factor(), function());
auto op = typify_invoke<6,MyTypify,MyGetFun>(lhs().result_type().cell_type(),
diff --git a/eval/src/vespa/eval/tensor/dense/dense_simple_join_function.h b/eval/src/vespa/eval/tensor/dense/dense_simple_join_function.h
index ef09b2a4880..2cd918e1b06 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_simple_join_function.h
+++ b/eval/src/vespa/eval/tensor/dense/dense_simple_join_function.h
@@ -32,7 +32,7 @@ public:
Overlap overlap() const { return _overlap; }
bool primary_is_mutable() const;
size_t factor() const;
- eval::InterpretedFunction::Instruction compile_self(const eval::TensorEngine &engine, Stash &stash) const override;
+ eval::InterpretedFunction::Instruction compile_self(eval::EngineOrFactory engine, Stash &stash) const override;
static const eval::TensorFunction &optimize(const eval::TensorFunction &expr, Stash &stash);
};
diff --git a/eval/src/vespa/eval/tensor/dense/dense_simple_map_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_simple_map_function.cpp
index da9b681019e..1086af91ec4 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_simple_map_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_simple_map_function.cpp
@@ -72,7 +72,7 @@ DenseSimpleMapFunction::DenseSimpleMapFunction(const ValueType &result_type,
DenseSimpleMapFunction::~DenseSimpleMapFunction() = default;
Instruction
-DenseSimpleMapFunction::compile_self(const TensorEngine &, Stash &) const
+DenseSimpleMapFunction::compile_self(eval::EngineOrFactory, Stash &) const
{
auto op = typify_invoke<3,MyTypify,MyGetFun>(result_type().cell_type(), function(), inplace());
static_assert(sizeof(uint64_t) == sizeof(function()));
diff --git a/eval/src/vespa/eval/tensor/dense/dense_simple_map_function.h b/eval/src/vespa/eval/tensor/dense/dense_simple_map_function.h
index 6497e5aa445..ce0498c9ab7 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_simple_map_function.h
+++ b/eval/src/vespa/eval/tensor/dense/dense_simple_map_function.h
@@ -18,7 +18,7 @@ public:
map_fun_t function_in);
~DenseSimpleMapFunction() override;
bool inplace() const { return child().result_is_mutable(); }
- eval::InterpretedFunction::Instruction compile_self(const eval::TensorEngine &engine, Stash &stash) const override;
+ eval::InterpretedFunction::Instruction compile_self(eval::EngineOrFactory engine, Stash &stash) const override;
static const eval::TensorFunction &optimize(const eval::TensorFunction &expr, Stash &stash);
};
diff --git a/eval/src/vespa/eval/tensor/dense/dense_single_reduce_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_single_reduce_function.cpp
index d18d8035e0a..c0bc3f26fe9 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_single_reduce_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_single_reduce_function.cpp
@@ -95,7 +95,7 @@ DenseSingleReduceFunction::DenseSingleReduceFunction(const ValueType &result_typ
DenseSingleReduceFunction::~DenseSingleReduceFunction() = default;
InterpretedFunction::Instruction
-DenseSingleReduceFunction::compile_self(const TensorEngine &, Stash &stash) const
+DenseSingleReduceFunction::compile_self(eval::EngineOrFactory, Stash &stash) const
{
auto op = typify_invoke<2,MyTypify,MyGetFun>(result_type().cell_type(), _aggr);
auto &params = stash.create<Params>(result_type(), child().result_type(), _dim_idx);
diff --git a/eval/src/vespa/eval/tensor/dense/dense_single_reduce_function.h b/eval/src/vespa/eval/tensor/dense/dense_single_reduce_function.h
index 037994727fc..7f9313df600 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_single_reduce_function.h
+++ b/eval/src/vespa/eval/tensor/dense/dense_single_reduce_function.h
@@ -24,7 +24,7 @@ public:
size_t dim_idx() const { return _dim_idx; }
eval::Aggr aggr() const { return _aggr; }
bool result_is_mutable() const override { return true; }
- eval::InterpretedFunction::Instruction compile_self(const eval::TensorEngine &engine, Stash &stash) const override;
+ eval::InterpretedFunction::Instruction compile_self(eval::EngineOrFactory engine, Stash &stash) const override;
static const eval::TensorFunction &optimize(const eval::TensorFunction &expr, Stash &stash);
};
diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_create_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_tensor_create_function.cpp
index 57eb1fe4a74..1ad6e00f279 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_tensor_create_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_create_function.cpp
@@ -69,7 +69,7 @@ DenseTensorCreateFunction::push_children(std::vector<Child::CREF> &target) const
}
eval::InterpretedFunction::Instruction
-DenseTensorCreateFunction::compile_self(const TensorEngine &, Stash &) const
+DenseTensorCreateFunction::compile_self(eval::EngineOrFactory, Stash &) const
{
using MyTypify = eval::TypifyCellType;
auto op = typify_invoke<1,MyTypify,MyTensorCreateOp>(result_type().cell_type());
diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_create_function.h b/eval/src/vespa/eval/tensor/dense/dense_tensor_create_function.h
index d471658fba0..a2ca71ce894 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_tensor_create_function.h
+++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_create_function.h
@@ -25,7 +25,7 @@ public:
~DenseTensorCreateFunction();
const eval::ValueType &result_type() const override { return _self.result_type; }
void push_children(std::vector<Child::CREF> &children) const override;
- eval::InterpretedFunction::Instruction compile_self(const eval::TensorEngine &engine, Stash &stash) const override;
+ eval::InterpretedFunction::Instruction compile_self(eval::EngineOrFactory engine, Stash &stash) const override;
bool result_is_mutable() const override { return true; }
static const eval::TensorFunction &optimize(const eval::TensorFunction &expr, Stash &stash);
};
diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_peek_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_tensor_peek_function.cpp
index bea95a1207d..f4725cae803 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_tensor_peek_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_peek_function.cpp
@@ -70,7 +70,7 @@ DenseTensorPeekFunction::push_children(std::vector<Child::CREF> &target) const
}
eval::InterpretedFunction::Instruction
-DenseTensorPeekFunction::compile_self(const TensorEngine &, Stash &) const
+DenseTensorPeekFunction::compile_self(eval::EngineOrFactory, Stash &) const
{
using MyTypify = eval::TypifyCellType;
auto op = typify_invoke<1,MyTypify,MyTensorPeekOp>(_children[0].get().result_type().cell_type());
diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_peek_function.h b/eval/src/vespa/eval/tensor/dense/dense_tensor_peek_function.h
index 8ed672f95b0..1d834c3901a 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_tensor_peek_function.h
+++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_peek_function.h
@@ -26,7 +26,7 @@ public:
~DenseTensorPeekFunction();
const eval::ValueType &result_type() const override { return eval::DoubleValue::double_type(); }
void push_children(std::vector<Child::CREF> &children) const override;
- eval::InterpretedFunction::Instruction compile_self(const eval::TensorEngine &engine, Stash &stash) const override;
+ eval::InterpretedFunction::Instruction compile_self(eval::EngineOrFactory engine, Stash &stash) const override;
bool result_is_mutable() const override { return true; }
static const eval::TensorFunction &optimize(const eval::TensorFunction &expr, Stash &stash);
};
diff --git a/eval/src/vespa/eval/tensor/dense/dense_xw_product_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_xw_product_function.cpp
index 1b0068f7824..3e60109bbe6 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_xw_product_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_xw_product_function.cpp
@@ -142,7 +142,7 @@ DenseXWProductFunction::DenseXWProductFunction(const eval::ValueType &result_typ
}
eval::InterpretedFunction::Instruction
-DenseXWProductFunction::compile_self(const TensorEngine &, Stash &stash) const
+DenseXWProductFunction::compile_self(eval::EngineOrFactory, Stash &stash) const
{
Self &self = stash.create<Self>(result_type(), _vector_size, _result_size);
using MyTypify = TypifyValue<eval::TypifyCellType,vespalib::TypifyBool>;
diff --git a/eval/src/vespa/eval/tensor/dense/dense_xw_product_function.h b/eval/src/vespa/eval/tensor/dense/dense_xw_product_function.h
index 9f05222fff6..fa0f8724aeb 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_xw_product_function.h
+++ b/eval/src/vespa/eval/tensor/dense/dense_xw_product_function.h
@@ -44,7 +44,7 @@ public:
size_t result_size() const { return _result_size; }
bool common_inner() const { return _common_inner; }
- eval::InterpretedFunction::Instruction compile_self(const eval::TensorEngine &engine, Stash &stash) const override;
+ eval::InterpretedFunction::Instruction compile_self(eval::EngineOrFactory engine, Stash &stash) const override;
void visit_self(vespalib::ObjectVisitor &visitor) const override;
static const eval::TensorFunction &optimize(const eval::TensorFunction &expr, Stash &stash);
};
diff --git a/eval/src/vespa/eval/tensor/dense/vector_from_doubles_function.cpp b/eval/src/vespa/eval/tensor/dense/vector_from_doubles_function.cpp
index 9e4a0e3d61b..3c006fe64a0 100644
--- a/eval/src/vespa/eval/tensor/dense/vector_from_doubles_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/vector_from_doubles_function.cpp
@@ -92,7 +92,7 @@ VectorFromDoublesFunction::push_children(std::vector<Child::CREF> &target) const
}
eval::InterpretedFunction::Instruction
-VectorFromDoublesFunction::compile_self(const TensorEngine &, Stash &) const
+VectorFromDoublesFunction::compile_self(eval::EngineOrFactory, Stash &) const
{
return eval::InterpretedFunction::Instruction(my_vector_from_doubles_op, wrap_param<VectorFromDoublesFunction::Self>(_self));
}
diff --git a/eval/src/vespa/eval/tensor/dense/vector_from_doubles_function.h b/eval/src/vespa/eval/tensor/dense/vector_from_doubles_function.h
index 28346c4cb3b..e2bd0386331 100644
--- a/eval/src/vespa/eval/tensor/dense/vector_from_doubles_function.h
+++ b/eval/src/vespa/eval/tensor/dense/vector_from_doubles_function.h
@@ -30,7 +30,7 @@ public:
return _self.resultType.dimensions()[0].name;
}
size_t size() const { return _self.resultSize; }
- eval::InterpretedFunction::Instruction compile_self(const eval::TensorEngine &engine, Stash &stash) const override;
+ eval::InterpretedFunction::Instruction compile_self(eval::EngineOrFactory engine, Stash &stash) const override;
bool result_is_mutable() const override { return true; }
static const eval::TensorFunction &optimize(const eval::TensorFunction &expr, Stash &stash);
};