summaryrefslogtreecommitdiffstats
path: root/eval
diff options
context:
space:
mode:
authorHåvard Pettersen <havardpe@oath.com>2018-01-16 10:53:41 +0000
committerHåvard Pettersen <havardpe@oath.com>2018-01-16 10:53:41 +0000
commit8852988ac1f0c391d9a3b603bd9f0e5af6c5e310 (patch)
tree3decf47e4e4971e8570dd51900d2c0cabcdd199b /eval
parent772fc30ac5acc00dd8122969ceb0dff0770e23f5 (diff)
Use lazy parameters in tensor functions.
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/tensor_function/tensor_function_test.cpp2
-rw-r--r--eval/src/tests/tensor/dense_dot_product_function/dense_dot_product_function_test.cpp7
-rw-r--r--eval/src/tests/tensor/dense_xw_product_function/dense_xw_product_function_test.cpp4
-rw-r--r--eval/src/tests/tensor/tensor_performance/tensor_performance_test.cpp4
-rw-r--r--eval/src/vespa/eval/eval/interpreted_function.cpp40
-rw-r--r--eval/src/vespa/eval/eval/interpreted_function.h10
-rw-r--r--eval/src/vespa/eval/eval/lazy_params.cpp12
-rw-r--r--eval/src/vespa/eval/eval/lazy_params.h16
-rw-r--r--eval/src/vespa/eval/eval/tensor_function.cpp10
-rw-r--r--eval/src/vespa/eval/eval/tensor_function.h11
-rw-r--r--eval/src/vespa/eval/eval/test/tensor_conformance.cpp10
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_dot_product_function.cpp6
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_dot_product_function.h2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_xw_product_function.cpp6
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_xw_product_function.h2
17 files changed, 67 insertions, 79 deletions
diff --git a/eval/src/apps/tensor_conformance/tensor_conformance.cpp b/eval/src/apps/tensor_conformance/tensor_conformance.cpp
index 616b98f0809..72fe61d7107 100644
--- a/eval/src/apps/tensor_conformance/tensor_conformance.cpp
+++ b/eval/src/apps/tensor_conformance/tensor_conformance.cpp
@@ -94,7 +94,7 @@ TensorSpec eval_expr(const Inspector &test, const TensorEngine &engine, bool typ
NodeTypes types = typed ? NodeTypes(fun, get_types(param_values)) : NodeTypes();
InterpretedFunction ifun(engine, fun, types);
InterpretedFunction::Context ctx(ifun);
- InterpretedFunction::SimpleObjectParams params(param_refs);
+ SimpleObjectParams params(param_refs);
return engine.to_spec(ifun.eval(ctx, params));
}
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 29bff7fbd69..5b7fb9af910 100644
--- a/eval/src/tests/eval/interpreted_function/interpreted_function_test.cpp
+++ b/eval/src/tests/eval/interpreted_function/interpreted_function_test.cpp
@@ -180,7 +180,7 @@ struct InnerProduct {
InterpretedFunction::Context ctx(interpreted);
Value::UP va = engine.from_spec(a);
Value::UP vb = engine.from_spec(b);
- InterpretedFunction::SimpleObjectParams params({*va,*vb});
+ SimpleObjectParams params({*va,*vb});
const Value &result = interpreted.eval(ctx, params);
EXPECT_EQUAL(engine.to_spec(result), expect);
}
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 641ebddfec2..9f4889ee5be 100644
--- a/eval/src/tests/eval/tensor_function/tensor_function_test.cpp
+++ b/eval/src/tests/eval/tensor_function/tensor_function_test.cpp
@@ -28,7 +28,7 @@ struct EvalCtx {
return id;
}
const Value &eval(const TensorFunction &fun) {
- return fun.eval(params, stash);
+ return fun.eval(SimpleObjectParams(params), stash);
}
const TensorFunction &compile(const tensor_function::Node &expr) {
return engine.compile(expr, stash);
diff --git a/eval/src/tests/tensor/dense_dot_product_function/dense_dot_product_function_test.cpp b/eval/src/tests/tensor/dense_dot_product_function/dense_dot_product_function_test.cpp
index 0b8b98fc617..3463bee3447 100644
--- a/eval/src/tests/tensor/dense_dot_product_function/dense_dot_product_function_test.cpp
+++ b/eval/src/tests/tensor/dense_dot_product_function/dense_dot_product_function_test.cpp
@@ -63,7 +63,8 @@ public:
_params.emplace_back(_lhsDenseTensor);
_params.emplace_back(_rhsDenseTensor);
}
- ConstArrayRef<Value::CREF> get() const { return _params; }
+ SimpleObjectParams get() const { return SimpleObjectParams(_params); }
+ const Value &param(size_t idx) const { return _params[idx]; }
double expectedDotProduct() const {
return calcDotProduct(_lhsDenseTensor, _rhsDenseTensor);
}
@@ -80,8 +81,8 @@ struct Fixture
const Value &result = function.eval(input.get(), stash);
ASSERT_TRUE(result.is_double());
LOG(info, "eval(): (%s) * (%s) = %f",
- input.get()[0].get().type().to_spec().c_str(),
- input.get()[1].get().type().to_spec().c_str(),
+ input.param(0).type().to_spec().c_str(),
+ input.param(1).type().to_spec().c_str(),
result.as_double());
return result.as_double();
}
diff --git a/eval/src/tests/tensor/dense_xw_product_function/dense_xw_product_function_test.cpp b/eval/src/tests/tensor/dense_xw_product_function/dense_xw_product_function_test.cpp
index 5c62d319dc3..f27a2073159 100644
--- a/eval/src/tests/tensor/dense_xw_product_function/dense_xw_product_function_test.cpp
+++ b/eval/src/tests/tensor/dense_xw_product_function/dense_xw_product_function_test.cpp
@@ -34,8 +34,8 @@ void verify_equal(const Value &expect, const Value &value) {
EXPECT_EQUAL(expect_spec, value_spec);
}
-std::vector<eval::Value::CREF> wrap(std::vector<eval::Value::CREF> params) {
- return std::move(params);
+SimpleObjectParams wrap(std::vector<eval::Value::CREF> params) {
+ return SimpleObjectParams(params);
}
void verify_result(const TensorSpec &v, const TensorSpec &m, bool happy) {
diff --git a/eval/src/tests/tensor/tensor_performance/tensor_performance_test.cpp b/eval/src/tests/tensor/tensor_performance/tensor_performance_test.cpp
index 2ed0021b5c7..1472fd3497c 100644
--- a/eval/src/tests/tensor/tensor_performance/tensor_performance_test.cpp
+++ b/eval/src/tests/tensor/tensor_performance/tensor_performance_test.cpp
@@ -33,9 +33,9 @@ struct Params {
}
};
-InterpretedFunction::SimpleObjectParams make_params(const Function &function, const Params &params)
+SimpleObjectParams make_params(const Function &function, const Params &params)
{
- InterpretedFunction::SimpleObjectParams fun_params({});
+ SimpleObjectParams fun_params({});
EXPECT_EQUAL(params.map.size(), function.num_params());
for (size_t i = 0; i < function.num_params(); ++i) {
auto param = params.map.find(function.param_name(i));
diff --git a/eval/src/vespa/eval/eval/interpreted_function.cpp b/eval/src/vespa/eval/eval/interpreted_function.cpp
index 81309956e58..89d850c2dd3 100644
--- a/eval/src/vespa/eval/eval/interpreted_function.cpp
+++ b/eval/src/vespa/eval/eval/interpreted_function.cpp
@@ -111,27 +111,9 @@ void op_tensor_concat(State &state, uint64_t param) {
//-----------------------------------------------------------------------------
-template <typename T>
-const T &undef_cref() {
- const T *undef = nullptr;
- assert(undef);
- return *undef;
-}
-
-struct TensorFunctionArgArgMeta {
- const TensorFunction &function;
- size_t param1;
- size_t param2;
- TensorFunctionArgArgMeta(const TensorFunction &function_in, size_t param1_in, size_t param2_in)
- : function(function_in), param1(param1_in), param2(param2_in) {}
-};
-
-void op_tensor_function_arg_arg(State &state, uint64_t param) {
- const TensorFunctionArgArgMeta &meta = unwrap_param<TensorFunctionArgArgMeta>(param);
- Value::CREF params[2] =
- {state.params->resolve(meta.param1, state.stash),
- state.params->resolve(meta.param2, state.stash)};
- state.stack.push_back(meta.function.eval(ConstArrayRef<Value::CREF>(params, 2), state.stash));
+void op_tensor_function(State &state, uint64_t param) {
+ const TensorFunction &fun = unwrap_param<TensorFunction>(param);
+ state.stack.push_back(fun.eval(*state.params, state.stash));
}
//-----------------------------------------------------------------------------
@@ -279,12 +261,11 @@ struct ProgramBuilder : public NodeVisitor, public NodeTraverser {
auto a = as<Symbol>(node.get_child(0).get_child(0));
auto b = as<Symbol>(node.get_child(0).get_child(1));
const auto &ir = tensor_function::reduce(tensor_function::join(
- tensor_function::inject(types.get_type(*a), 0, stash),
- tensor_function::inject(types.get_type(*b), 1, stash),
+ tensor_function::inject(types.get_type(*a), a->id(), stash),
+ tensor_function::inject(types.get_type(*b), b->id(), stash),
operation::Mul::f, stash), node.aggr(), node.dimensions(), stash);
const auto &fun = tensor_engine.compile(ir, stash);
- const auto &meta = stash.create<TensorFunctionArgArgMeta>(fun, a->id(), b->id());
- program.emplace_back(op_tensor_function_arg_arg, wrap_param<TensorFunctionArgArgMeta>(meta));
+ program.emplace_back(op_tensor_function, wrap_param<TensorFunction>(fun));
} else {
ReduceParams &params = stash.create<ReduceParams>(node.aggr(), node.dimensions());
program.emplace_back(op_tensor_reduce, wrap_param<ReduceParams>(params));
@@ -475,8 +456,6 @@ InterpretedFunction::SimpleParams::SimpleParams(const std::vector<double> &param
InterpretedFunction::SimpleParams::~SimpleParams() { }
-InterpretedFunction::SimpleObjectParams::~SimpleObjectParams() {}
-
const Value &
InterpretedFunction::SimpleParams::resolve(size_t idx, Stash &stash) const
{
@@ -484,13 +463,6 @@ InterpretedFunction::SimpleParams::resolve(size_t idx, Stash &stash) const
return stash.create<DoubleValue>(params[idx]);
}
-const Value &
-InterpretedFunction::SimpleObjectParams::resolve(size_t idx, Stash &) const
-{
- assert(idx < params.size());
- return params[idx];
-}
-
InterpretedFunction::State::State(const TensorEngine &engine_in)
: engine(engine_in),
params(nullptr),
diff --git a/eval/src/vespa/eval/eval/interpreted_function.h b/eval/src/vespa/eval/eval/interpreted_function.h
index 0741e7e4191..ea8fcbc3a42 100644
--- a/eval/src/vespa/eval/eval/interpreted_function.h
+++ b/eval/src/vespa/eval/eval/interpreted_function.h
@@ -39,16 +39,6 @@ public:
~SimpleParams();
const Value &resolve(size_t idx, Stash &stash) const override;
};
- /**
- * Simple wrapper for object parameters that are known up
- * front. Intended for convenience (testing), not performance.
- **/
- struct SimpleObjectParams : LazyParams {
- std::vector<Value::CREF> params;
- explicit SimpleObjectParams(const std::vector<Value::CREF> &params_in) : params(params_in) {}
- ~SimpleObjectParams();
- const Value &resolve(size_t idx, Stash &stash) const override;
- };
struct State {
const TensorEngine &engine;
const LazyParams *params;
diff --git a/eval/src/vespa/eval/eval/lazy_params.cpp b/eval/src/vespa/eval/eval/lazy_params.cpp
index ba8f8a2a002..1aea00eb592 100644
--- a/eval/src/vespa/eval/eval/lazy_params.cpp
+++ b/eval/src/vespa/eval/eval/lazy_params.cpp
@@ -1,6 +1,7 @@
// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "lazy_params.h"
+#include <assert.h>
namespace vespalib::eval {
@@ -8,4 +9,15 @@ LazyParams::~LazyParams()
{
}
+SimpleObjectParams::~SimpleObjectParams()
+{
+}
+
+const Value &
+SimpleObjectParams::resolve(size_t idx, Stash &) const
+{
+ assert(idx < params.size());
+ return params[idx];
+}
+
} // namespace vespalib::eval
diff --git a/eval/src/vespa/eval/eval/lazy_params.h b/eval/src/vespa/eval/eval/lazy_params.h
index 40436fc2c92..d2c7b066162 100644
--- a/eval/src/vespa/eval/eval/lazy_params.h
+++ b/eval/src/vespa/eval/eval/lazy_params.h
@@ -2,7 +2,8 @@
#pragma once
-#include <stddef.h>
+#include <vector>
+#include "value.h"
namespace vespalib {
@@ -10,8 +11,6 @@ class Stash;
namespace eval {
-class Value;
-
/**
* Interface used to lazy-resolve parameters.
**/
@@ -23,5 +22,16 @@ struct LazyParams {
virtual ~LazyParams();
};
+/**
+ * Simple wrapper for object parameters that are known up
+ * front. Intended for convenience (testing), not performance.
+ **/
+struct SimpleObjectParams : LazyParams {
+ std::vector<Value::CREF> params;
+ explicit SimpleObjectParams(const std::vector<Value::CREF> &params_in) : params(params_in) {}
+ ~SimpleObjectParams();
+ const Value &resolve(size_t idx, Stash &stash) const override;
+};
+
} // namespace vespalib::eval
} // namespace vespalib
diff --git a/eval/src/vespa/eval/eval/tensor_function.cpp b/eval/src/vespa/eval/eval/tensor_function.cpp
index 763f1cc39ff..83ac51bdc09 100644
--- a/eval/src/vespa/eval/eval/tensor_function.cpp
+++ b/eval/src/vespa/eval/eval/tensor_function.cpp
@@ -23,9 +23,9 @@ const TensorEngine &infer_engine(const std::initializer_list<Value::CREF> &value
//-----------------------------------------------------------------------------
const Value &
-Inject::eval(ConstArrayRef<Value::CREF> params, Stash &) const
+Inject::eval(const LazyParams &params, Stash &stash) const
{
- return params[tensor_id];
+ return params.resolve(tensor_id, stash);
}
void
@@ -36,7 +36,7 @@ Inject::push_children(std::vector<Child::CREF> &) const
//-----------------------------------------------------------------------------
const Value &
-Reduce::eval(ConstArrayRef<Value::CREF> params, Stash &stash) const
+Reduce::eval(const LazyParams &params, Stash &stash) const
{
const Value &a = tensor.get().eval(params, stash);
const TensorEngine &engine = infer_engine({a});
@@ -52,7 +52,7 @@ Reduce::push_children(std::vector<Child::CREF> &children) const
//-----------------------------------------------------------------------------
const Value &
-Map::eval(ConstArrayRef<Value::CREF> params, Stash &stash) const
+Map::eval(const LazyParams &params, Stash &stash) const
{
const Value &a = tensor.get().eval(params, stash);
const TensorEngine &engine = infer_engine({a});
@@ -68,7 +68,7 @@ Map::push_children(std::vector<Child::CREF> &children) const
//-----------------------------------------------------------------------------
const Value &
-Join::eval(ConstArrayRef<Value::CREF> params, Stash &stash) const
+Join::eval(const LazyParams &params, Stash &stash) const
{
const Value &a = lhs_tensor.get().eval(params, stash);
const Value &b = rhs_tensor.get().eval(params, stash);
diff --git a/eval/src/vespa/eval/eval/tensor_function.h b/eval/src/vespa/eval/eval/tensor_function.h
index 4b0db486971..f2075e5d4ea 100644
--- a/eval/src/vespa/eval/eval/tensor_function.h
+++ b/eval/src/vespa/eval/eval/tensor_function.h
@@ -6,6 +6,7 @@
#include <vector>
#include <vespa/vespalib/stllike/string.h>
#include <vespa/vespalib/util/arrayref.h>
+#include "lazy_params.h"
#include "value_type.h"
#include "value.h"
#include "aggr.h"
@@ -41,7 +42,7 @@ struct TensorFunction
* @param params external values needed to evaluate this function
* @param stash heterogeneous object store
**/
- virtual const Value &eval(ConstArrayRef<Value::CREF> params, Stash &stash) const = 0;
+ virtual const Value &eval(const LazyParams &params, Stash &stash) const = 0;
virtual ~TensorFunction() {}
};
@@ -107,7 +108,7 @@ struct Inject : Node {
Inject(const ValueType &result_type_in,
size_t tensor_id_in)
: Node(result_type_in), tensor_id(tensor_id_in) {}
- const Value &eval(ConstArrayRef<Value::CREF> params, Stash &) const override;
+ const Value &eval(const LazyParams &params, Stash &) const override;
void push_children(std::vector<Child::CREF> &children) const override;
};
@@ -120,7 +121,7 @@ struct Reduce : Node {
Aggr aggr_in,
const std::vector<vespalib::string> &dimensions_in)
: Node(result_type_in), tensor(tensor_in), aggr(aggr_in), dimensions(dimensions_in) {}
- const Value &eval(ConstArrayRef<Value::CREF> params, Stash &stash) const override;
+ const Value &eval(const LazyParams &params, Stash &stash) const override;
void push_children(std::vector<Child::CREF> &children) const override;
};
@@ -131,7 +132,7 @@ struct Map : Node {
const TensorFunction &tensor_in,
map_fun_t function_in)
: Node(result_type_in), tensor(tensor_in), function(function_in) {}
- const Value &eval(ConstArrayRef<Value::CREF> params, Stash &stash) const override;
+ const Value &eval(const LazyParams &params, Stash &stash) const override;
void push_children(std::vector<Child::CREF> &children) const override;
};
@@ -145,7 +146,7 @@ struct Join : Node {
join_fun_t function_in)
: Node(result_type_in), lhs_tensor(lhs_tensor_in),
rhs_tensor(rhs_tensor_in), function(function_in) {}
- const Value &eval(ConstArrayRef<Value::CREF> params, Stash &stash) const override;
+ const Value &eval(const LazyParams &params, Stash &stash) const override;
void push_children(std::vector<Child::CREF> &children) const override;
};
diff --git a/eval/src/vespa/eval/eval/test/tensor_conformance.cpp b/eval/src/vespa/eval/eval/test/tensor_conformance.cpp
index 23562f4a186..05acc0912ef 100644
--- a/eval/src/vespa/eval/eval/test/tensor_conformance.cpp
+++ b/eval/src/vespa/eval/eval/test/tensor_conformance.cpp
@@ -123,7 +123,7 @@ struct Expr_V : Eval {
NodeTypes types(fun, {});
InterpretedFunction ifun(engine, fun, types);
InterpretedFunction::Context ctx(ifun);
- InterpretedFunction::SimpleObjectParams params({});
+ SimpleObjectParams params({});
return Result(engine, check_type(ifun.eval(ctx, params), types.get_type(fun.root())));
}
};
@@ -139,7 +139,7 @@ struct Expr_T : Eval {
InterpretedFunction ifun(engine, fun, types);
InterpretedFunction::Context ctx(ifun);
Value::UP va = engine.from_spec(a);
- InterpretedFunction::SimpleObjectParams params({*va});
+ SimpleObjectParams params({*va});
return Result(engine, check_type(ifun.eval(ctx, params), types.get_type(fun.root())));
}
};
@@ -157,7 +157,7 @@ struct Expr_TT : Eval {
InterpretedFunction::Context ctx(ifun);
Value::UP va = engine.from_spec(a);
Value::UP vb = engine.from_spec(b);
- InterpretedFunction::SimpleObjectParams params({*va,*vb});
+ SimpleObjectParams params({*va,*vb});
return Result(engine, check_type(ifun.eval(ctx, params), types.get_type(fun.root())));
}
};
@@ -259,7 +259,9 @@ struct Input {
tensors.push_back(std::move(b));
params.emplace_back(*tensors.back());
}
- ConstArrayRef<Value::CREF> get() const { return params; }
+ SimpleObjectParams get() const {
+ return SimpleObjectParams(params);
+ }
};
// evaluate tensor reduce operation using tensor engine retained api
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 fdd0cd6638f..de9963a0c9a 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
@@ -29,10 +29,10 @@ getCellsRef(const eval::Value &value)
}
const eval::Value &
-DenseDotProductFunction::eval(ConstArrayRef<eval::Value::CREF> params, Stash &stash) const
+DenseDotProductFunction::eval(const eval::LazyParams &params, Stash &stash) const
{
- DenseTensorView::CellsRef lhsCells = getCellsRef(params[_lhsTensorId]);
- DenseTensorView::CellsRef rhsCells = getCellsRef(params[_rhsTensorId]);
+ DenseTensorView::CellsRef lhsCells = getCellsRef(params.resolve(_lhsTensorId, stash));
+ DenseTensorView::CellsRef rhsCells = getCellsRef(params.resolve(_rhsTensorId, stash));
size_t numCells = std::min(lhsCells.size(), rhsCells.size());
double result = _hwAccelerator->dotProduct(lhsCells.cbegin(), rhsCells.cbegin(), numCells);
return stash.create<eval::DoubleValue>(result);
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 288f2afd084..20c293444f3 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
@@ -23,7 +23,7 @@ public:
DenseDotProductFunction(size_t lhsTensorId_, size_t rhsTensorId_);
size_t lhsTensorId() const { return _lhsTensorId; }
size_t rhsTensorId() const { return _rhsTensorId; }
- const eval::Value &eval(ConstArrayRef<eval::Value::CREF> params, Stash &stash) const override;
+ const eval::Value &eval(const eval::LazyParams &params, Stash &stash) const override;
};
}
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 1ab78b8ee30..caf8f0de1d7 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
@@ -72,10 +72,10 @@ getCellsRef(const eval::Value &value)
} // namespace <unnamed>
const eval::Value &
-DenseXWProductFunction::eval(ConstArrayRef<eval::Value::CREF> params, Stash &stash) const
+DenseXWProductFunction::eval(const eval::LazyParams &params, Stash &stash) const
{
- DenseTensorView::CellsRef vectorCells = getCellsRef(params[_vectorId]);
- DenseTensorView::CellsRef matrixCells = getCellsRef(params[_matrixId]);
+ DenseTensorView::CellsRef vectorCells = getCellsRef(params.resolve(_vectorId, stash));
+ DenseTensorView::CellsRef matrixCells = getCellsRef(params.resolve(_matrixId, stash));
ArrayRef<double> outputCells = stash.create_array<double>(_resultSize);
if (_commonDimensionInnermost) {
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 151f1f13800..6e8104fff44 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
@@ -45,7 +45,7 @@ public:
bool matrixHasCommonDimensionInnermost() const { return _commonDimensionInnermost; }
- const eval::Value &eval(ConstArrayRef<eval::Value::CREF> params, Stash &stash) const override;
+ const eval::Value &eval(const eval::LazyParams &params, Stash &stash) const override;
};
}