aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArne Juul <arnej@yahoo-inc.com>2018-03-06 12:24:47 +0000
committerArne Juul <arnej@yahoo-inc.com>2018-03-08 10:47:56 +0000
commit4e4d19ddb273648aa5396f094970149d08d03ab3 (patch)
tree956a040607cd1fe50a7e1fd261771205ebc97781
parenta405462e2408a274ab66fab963413c663c168aab (diff)
add dump_tree API for tensor functions
* NOTE: recursive implementation, use sparingly. * turn on debug logging to get a dump of tensor functions before and after optimizations.
-rw-r--r--eval/src/vespa/eval/eval/CMakeLists.txt1
-rw-r--r--eval/src/vespa/eval/eval/dump_target.cpp156
-rw-r--r--eval/src/vespa/eval/eval/dump_target.h54
-rw-r--r--eval/src/vespa/eval/eval/tensor_function.cpp122
-rw-r--r--eval/src/vespa/eval/eval/tensor_function.h15
-rw-r--r--eval/src/vespa/eval/tensor/default_tensor_engine.cpp14
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_dot_product_function.cpp9
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_dot_product_function.h1
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_fast_rename_function.cpp8
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_fast_rename_function.h1
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_inplace_join_function.cpp7
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_inplace_join_function.h1
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_inplace_map_function.cpp7
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_inplace_map_function.h1
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_xw_product_function.cpp12
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_xw_product_function.h1
-rw-r--r--eval/src/vespa/eval/tensor/dense/vector_from_doubles_function.cpp12
-rw-r--r--eval/src/vespa/eval/tensor/dense/vector_from_doubles_function.h1
18 files changed, 423 insertions, 0 deletions
diff --git a/eval/src/vespa/eval/eval/CMakeLists.txt b/eval/src/vespa/eval/eval/CMakeLists.txt
index 0eabb4f4219..6ff4b5447ce 100644
--- a/eval/src/vespa/eval/eval/CMakeLists.txt
+++ b/eval/src/vespa/eval/eval/CMakeLists.txt
@@ -6,6 +6,7 @@ vespa_add_library(eval_eval OBJECT
call_nodes.cpp
compile_tensor_function.cpp
delete_node.cpp
+ dump_target.cpp
function.cpp
gbdt.cpp
interpreted_function.cpp
diff --git a/eval/src/vespa/eval/eval/dump_target.cpp b/eval/src/vespa/eval/eval/dump_target.cpp
new file mode 100644
index 00000000000..2d5363f50b0
--- /dev/null
+++ b/eval/src/vespa/eval/eval/dump_target.cpp
@@ -0,0 +1,156 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "dump_target.h"
+#include "tensor_function.h"
+#include "aggr.h"
+#include "operation.h"
+
+namespace vespalib {
+namespace eval {
+
+namespace {
+
+using map_fun_t = double (*)(double);
+using join_fun_t = double (*)(double, double);
+
+vespalib::string
+name_of(map_fun_t fun)
+{
+ if (fun == operation::Neg::f) return "-";
+ if (fun == operation::Not::f) return "!";
+ if (fun == operation::Cos::f) return "cos";
+ if (fun == operation::Sin::f) return "sin";
+ if (fun == operation::Tan::f) return "tan";
+ if (fun == operation::Cosh::f) return "cosh";
+ if (fun == operation::Sinh::f) return "sinh";
+ if (fun == operation::Tanh::f) return "tanh";
+ if (fun == operation::Acos::f) return "acos";
+ if (fun == operation::Asin::f) return "asin";
+ if (fun == operation::Atan::f) return "atan";
+ if (fun == operation::Exp::f) return "exp";
+ if (fun == operation::Log10::f) return "log10";
+ if (fun == operation::Log::f) return "log";
+ if (fun == operation::Sqrt::f) return "sqrt";
+ if (fun == operation::Ceil::f) return "ceil";
+ if (fun == operation::Fabs::f) return "fabs";
+ if (fun == operation::Floor::f) return "floor";
+ if (fun == operation::IsNan::f) return "isnan";
+ if (fun == operation::Relu::f) return "relu";
+ if (fun == operation::Sigmoid::f) return "sigmoid";
+ if (fun == operation::Elu::f) return "elu";
+ return "[other map function]";
+}
+
+vespalib::string
+name_of(join_fun_t fun)
+{
+ if (fun == operation::Add::f) return "+";
+ if (fun == operation::Sub::f) return "-";
+ if (fun == operation::Mul::f) return "*";
+ if (fun == operation::Div::f) return "/";
+ if (fun == operation::Mod::f) return "%";
+ if (fun == operation::Pow::f) return "^";
+ if (fun == operation::Equal::f) return "==";
+ if (fun == operation::NotEqual::f) return "!=";
+ if (fun == operation::Approx::f) return "~";
+ if (fun == operation::Less::f) return "<";
+ if (fun == operation::LessEqual::f) return "<=";
+ if (fun == operation::Greater::f) return ">";
+ if (fun == operation::GreaterEqual::f) return ">=";
+ if (fun == operation::And::f) return "&&";
+ if (fun == operation::Or::f) return "||";
+ if (fun == operation::Atan2::f) return "atan2";
+ if (fun == operation::Ldexp::f) return "ldexp";
+ if (fun == operation::Min::f) return "min";
+ if (fun == operation::Max::f) return "max";
+ return "[other join function]";
+}
+
+} // namespace vespalib::eval::<unnamed>
+
+struct DumpTargetBackend {
+public:
+ asciistream stream;
+ asciistream &indent(size_t level) {
+ stream << "\n";
+ stream << asciistream::Width(level*2) << "";
+ return stream;
+ }
+};
+
+DumpTarget::DumpTarget(DumpTargetBackend &back_end)
+ : _back_end(back_end), _indentLevel(0), _nodeName("root")
+{}
+
+DumpTarget::DumpTarget(DumpTargetBackend &back_end, size_t level)
+ : _back_end(back_end), _indentLevel(level), _nodeName("child")
+{}
+
+void
+DumpTarget::indent()
+{
+ _back_end.indent(_indentLevel);
+}
+
+vespalib::string
+DumpTarget::dump(const TensorFunction &root)
+{
+ DumpTargetBackend back_end;
+ back_end.stream << "root type: " << root.result_type().to_spec();
+ DumpTarget target(back_end);
+ root.dump_tree(target);
+ back_end.stream << "\n";
+ return back_end.stream.str();
+}
+
+void
+DumpTarget::node(const vespalib::string &name)
+{
+ _nodeName = name;
+ indent();
+ _back_end.stream << "node name='" << name << "'";
+}
+
+void
+DumpTarget::child(const vespalib::string &name, const TensorFunction &child)
+{
+ indent();
+ _back_end.stream << _nodeName << " child name='" << name
+ << "' type: " << child.result_type().to_spec();
+ DumpTarget nextLevel(_back_end, _indentLevel + 1);
+ child.dump_tree(nextLevel);
+}
+
+DumpTarget::Arg::Arg(DumpTargetBackend &back_end)
+ : _back_end(back_end)
+{}
+
+void DumpTarget::Arg::value(bool v) { _back_end.stream << (v ? "true" : "false"); }
+void DumpTarget::Arg::value(size_t v) { _back_end.stream << v; }
+void DumpTarget::Arg::value(map_fun_t v) { value(name_of(v)); }
+void DumpTarget::Arg::value(join_fun_t v) { value(name_of(v)); }
+void DumpTarget::Arg::value(const vespalib::string &v) { _back_end.stream << "'" << v << "'"; }
+void DumpTarget::Arg::value(const std::vector<vespalib::string> &v) {
+ _back_end.stream << "[";
+ for (size_t i = 0; i < v.size(); ++i) {
+ if (i > 0) { _back_end.stream << ", "; }
+ _back_end.stream << "'" << v[i] << "'";
+ }
+ _back_end.stream << "]";
+}
+void DumpTarget::Arg::value(const Aggr &aggr) { value(*AggrNames::name_of(aggr)); }
+
+DumpTarget::Arg
+DumpTarget::arg(const vespalib::string &name)
+{
+ indent();
+ _back_end.stream << _nodeName << " arg name='" << name << "' value=";
+ return Arg(_back_end);
+}
+
+DumpTarget::~DumpTarget()
+{
+}
+
+} // namespace vespalib::eval
+} // namespace vespalib
diff --git a/eval/src/vespa/eval/eval/dump_target.h b/eval/src/vespa/eval/eval/dump_target.h
new file mode 100644
index 00000000000..6d4b5088cd0
--- /dev/null
+++ b/eval/src/vespa/eval/eval/dump_target.h
@@ -0,0 +1,54 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#pragma once
+
+#include <memory>
+#include <vector>
+#include <vespa/vespalib/stllike/string.h>
+
+namespace vespalib {
+namespace eval {
+
+struct TensorFunction;
+struct DumpTargetBackend;
+enum class Aggr;
+
+class DumpTarget
+{
+private:
+ DumpTargetBackend &_back_end;
+ DumpTarget(DumpTargetBackend &back_end);
+ DumpTarget(DumpTargetBackend &back_end, size_t level);
+ size_t _indentLevel;
+ vespalib::string _nodeName;
+ void indent();
+public:
+ static vespalib::string dump(const TensorFunction &root);
+
+ void node(const vespalib::string &name);
+ void child(const vespalib::string &name, const TensorFunction &child);
+
+ using map_fun_t = double (*)(double);
+ using join_fun_t = double (*)(double, double);
+
+ class Arg {
+ private:
+ DumpTargetBackend &_back_end;
+ public:
+ Arg(DumpTargetBackend &back_end);
+ void value(bool v);
+ void value(size_t v);
+ void value(map_fun_t v);
+ void value(join_fun_t v);
+ void value(const vespalib::string &v);
+ void value(const std::vector<vespalib::string> &v);
+ void value(const Aggr &aggr);
+ };
+
+ Arg arg(const vespalib::string &name);
+
+ ~DumpTarget();
+};
+
+} // 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 23ab2d225a7..499f46e1c8e 100644
--- a/eval/src/vespa/eval/eval/tensor_function.cpp
+++ b/eval/src/vespa/eval/eval/tensor_function.cpp
@@ -115,6 +115,13 @@ ConstValue::compile_self(Stash &) const
return Instruction(op_load_const, wrap_param<Value>(_value));
}
+void
+ConstValue::dump_tree(DumpTarget &target) const
+{
+ target.node("ConstValue");
+}
+
+
//-----------------------------------------------------------------------------
Instruction
@@ -123,6 +130,13 @@ Inject::compile_self(Stash &) const
return Instruction::fetch_param(_param_idx);
}
+void
+Inject::dump_tree(DumpTarget &target) const
+{
+ target.node("Inject");
+}
+
+
//-----------------------------------------------------------------------------
Instruction
@@ -132,6 +146,15 @@ Reduce::compile_self(Stash &stash) const
return Instruction(op_tensor_reduce, wrap_param<ReduceParams>(params));
}
+void
+Reduce::dump_tree(DumpTarget &target) const
+{
+ target.node("Reduce");
+ target.arg("aggr").value(aggr());
+ target.arg("dimensions").value(dimensions());
+ target.child("child", child());
+}
+
//-----------------------------------------------------------------------------
Instruction
@@ -143,6 +166,67 @@ Map::compile_self(Stash &) const
return Instruction(op_tensor_map, to_param(_function));
}
+vespalib::string
+name_of(map_fun_t fun)
+{
+ if (fun == operation::Neg::f) return "-";
+ if (fun == operation::Not::f) return "!";
+ if (fun == operation::Cos::f) return "cos";
+ if (fun == operation::Sin::f) return "sin";
+ if (fun == operation::Tan::f) return "tan";
+ if (fun == operation::Cosh::f) return "cosh";
+ if (fun == operation::Sinh::f) return "sinh";
+ if (fun == operation::Tanh::f) return "tanh";
+ if (fun == operation::Acos::f) return "acos";
+ if (fun == operation::Asin::f) return "asin";
+ if (fun == operation::Atan::f) return "atan";
+ if (fun == operation::Exp::f) return "exp";
+ if (fun == operation::Log10::f) return "log10";
+ if (fun == operation::Log::f) return "log";
+ if (fun == operation::Sqrt::f) return "sqrt";
+ if (fun == operation::Ceil::f) return "ceil";
+ if (fun == operation::Fabs::f) return "fabs";
+ if (fun == operation::Floor::f) return "floor";
+ if (fun == operation::IsNan::f) return "isnan";
+ if (fun == operation::Relu::f) return "relu";
+ if (fun == operation::Sigmoid::f) return "sigmoid";
+ if (fun == operation::Elu::f) return "elu";
+ return "[other map function]";
+}
+
+vespalib::string
+name_of(join_fun_t fun)
+{
+ if (fun == operation::Add::f) return "+";
+ if (fun == operation::Sub::f) return "-";
+ if (fun == operation::Mul::f) return "*";
+ if (fun == operation::Div::f) return "/";
+ if (fun == operation::Mod::f) return "%";
+ if (fun == operation::Pow::f) return "^";
+ if (fun == operation::Equal::f) return "==";
+ if (fun == operation::NotEqual::f) return "!=";
+ if (fun == operation::Approx::f) return "~";
+ if (fun == operation::Less::f) return "<";
+ if (fun == operation::LessEqual::f) return "<=";
+ if (fun == operation::Greater::f) return ">";
+ if (fun == operation::GreaterEqual::f) return ">=";
+ if (fun == operation::And::f) return "&&";
+ if (fun == operation::Or::f) return "||";
+ if (fun == operation::Atan2::f) return "atan2";
+ if (fun == operation::Ldexp::f) return "ldexp";
+ if (fun == operation::Min::f) return "min";
+ if (fun == operation::Max::f) return "max";
+ return "[other join function]";
+}
+
+void
+Map::dump_tree(DumpTarget &target) const
+{
+ target.node("Map");
+ target.arg("function").value(function());
+ target.child("child", child());
+}
+
//-----------------------------------------------------------------------------
Instruction
@@ -160,6 +244,16 @@ Join::compile_self(Stash &) const
return Instruction(op_tensor_join, to_param(_function));
}
+void
+Join::dump_tree(DumpTarget &target) const
+{
+ target.node("Join");
+ target.arg("function").value(function());
+ target.child("lhs", lhs());
+ target.child("rhs", rhs());
+}
+
+
//-----------------------------------------------------------------------------
Instruction
@@ -168,6 +262,15 @@ Concat::compile_self(Stash &) const
return Instruction(op_tensor_concat, wrap_param<vespalib::string>(_dimension));
}
+void
+Concat::dump_tree(DumpTarget &target) const
+{
+ target.node("Concat");
+ target.arg("dimension").value(dimension());
+ target.child("lhs", lhs());
+ target.child("rhs", rhs());
+}
+
//-----------------------------------------------------------------------------
Instruction
@@ -177,6 +280,16 @@ Rename::compile_self(Stash &stash) const
return Instruction(op_tensor_rename, wrap_param<RenameParams>(params));
}
+
+void
+Rename::dump_tree(DumpTarget &target) const
+{
+ target.node("Rename");
+ target.arg("from").value(from());
+ target.arg("to").value(to());
+ target.child("child", child());
+}
+
//-----------------------------------------------------------------------------
void
@@ -195,6 +308,15 @@ If::compile_self(Stash &) const
abort();
}
+void
+If::dump_tree(DumpTarget &target) const
+{
+ target.node("If");
+ target.child("cond", _cond.get());
+ target.child("t_child", _true_child.get());
+ target.child("f_child", _false_child.get());
+}
+
//-----------------------------------------------------------------------------
const Node &const_value(const Value &value, Stash &stash) {
diff --git a/eval/src/vespa/eval/eval/tensor_function.h b/eval/src/vespa/eval/eval/tensor_function.h
index 4e989d251c1..2fa8b3c15c2 100644
--- a/eval/src/vespa/eval/eval/tensor_function.h
+++ b/eval/src/vespa/eval/eval/tensor_function.h
@@ -4,6 +4,7 @@
#include <memory>
#include <vector>
+#include <vespa/vespalib/stllike/asciistream.h>
#include <vespa/vespalib/stllike/string.h>
#include <vespa/vespalib/util/arrayref.h>
#include "make_tensor_function.h"
@@ -13,6 +14,7 @@
#include "aggr.h"
#include "interpreted_function.h"
+#include "dump_target.h"
namespace vespalib {
@@ -92,6 +94,11 @@ struct TensorFunction
**/
virtual InterpretedFunction::Instruction compile_self(Stash &stash) const = 0;
+ /**
+ * debug logging facility.
+ **/
+ virtual void dump_tree(DumpTarget &target) const = 0;
+
virtual ~TensorFunction() {}
};
@@ -164,6 +171,7 @@ public:
ConstValue(const Value &value_in) : Leaf(value_in.type()), _value(value_in) {}
bool result_is_mutable() const override { return false; }
InterpretedFunction::Instruction compile_self(Stash &stash) const final override;
+ void dump_tree(DumpTarget &target) const override;
};
//-----------------------------------------------------------------------------
@@ -178,6 +186,7 @@ public:
size_t param_idx() const { return _param_idx; }
bool result_is_mutable() const override { return false; }
InterpretedFunction::Instruction compile_self(Stash &stash) const final override;
+ void dump_tree(DumpTarget &target) const override;
};
//-----------------------------------------------------------------------------
@@ -197,6 +206,7 @@ public:
const std::vector<vespalib::string> &dimensions() const { return _dimensions; }
bool result_is_mutable() const override { return true; }
InterpretedFunction::Instruction compile_self(Stash &stash) const final override;
+ void dump_tree(DumpTarget &target) const override;
};
//-----------------------------------------------------------------------------
@@ -213,6 +223,7 @@ public:
map_fun_t function() const { return _function; }
bool result_is_mutable() const override { return true; }
InterpretedFunction::Instruction compile_self(Stash &stash) const override;
+ void dump_tree(DumpTarget &target) const override;
};
//-----------------------------------------------------------------------------
@@ -230,6 +241,7 @@ public:
join_fun_t function() const { return _function; }
bool result_is_mutable() const override { return true; }
InterpretedFunction::Instruction compile_self(Stash &stash) const override;
+ void dump_tree(DumpTarget &target) const override;
};
//-----------------------------------------------------------------------------
@@ -247,6 +259,7 @@ public:
const vespalib::string &dimension() const { return _dimension; }
bool result_is_mutable() const override { return true; }
InterpretedFunction::Instruction compile_self(Stash &stash) const final override;
+ void dump_tree(DumpTarget &target) const override;
};
//-----------------------------------------------------------------------------
@@ -266,6 +279,7 @@ public:
const std::vector<vespalib::string> &to() const { return _to; }
bool result_is_mutable() const override { return true; }
InterpretedFunction::Instruction compile_self(Stash &stash) const final override;
+ void dump_tree(DumpTarget &target) const override;
};
//-----------------------------------------------------------------------------
@@ -291,6 +305,7 @@ public:
false_child().result_is_mutable());
}
InterpretedFunction::Instruction compile_self(Stash &stash) const final override;
+ void dump_tree(DumpTarget &target) const override;
};
//-----------------------------------------------------------------------------
diff --git a/eval/src/vespa/eval/tensor/default_tensor_engine.cpp b/eval/src/vespa/eval/tensor/default_tensor_engine.cpp
index 457e9310b80..73648cc8dbd 100644
--- a/eval/src/vespa/eval/tensor/default_tensor_engine.cpp
+++ b/eval/src/vespa/eval/tensor/default_tensor_engine.cpp
@@ -15,11 +15,15 @@
#include "dense/vector_from_doubles_function.h"
#include <vespa/eval/eval/value.h>
#include <vespa/eval/eval/tensor_spec.h>
+#include <vespa/eval/eval/dump_target.h>
+#include <vespa/eval/eval/tensor_spec.h>
#include <vespa/eval/eval/simple_tensor_engine.h>
#include <vespa/eval/eval/operation.h>
#include <vespa/vespalib/objects/nbostream.h>
#include <cassert>
+#include <vespa/log/log.h>
+LOG_SETUP(".eval.tensor.default_tensor_engine");
namespace vespalib {
namespace tensor {
@@ -213,6 +217,11 @@ DefaultTensorEngine::decode(nbostream &input) const
const TensorFunction &
DefaultTensorEngine::optimize(const TensorFunction &expr, Stash &stash) const
{
+ if (LOG_WOULD_LOG(debug)) {
+ vespalib::string dump = eval::DumpTarget::dump(expr);
+ LOG(debug, "Optimizing tensor function:\n%s\n",
+ dump.c_str());
+ }
using Child = TensorFunction::Child;
Child root(expr);
std::vector<Child::CREF> nodes({root});
@@ -229,6 +238,11 @@ DefaultTensorEngine::optimize(const TensorFunction &expr, Stash &stash) const
child.set(DenseInplaceJoinFunction::optimize(child.get(), stash));
nodes.pop_back();
}
+ if (LOG_WOULD_LOG(debug)) {
+ vespalib::string dump = eval::DumpTarget::dump(root.get());
+ LOG(debug, "Optimized tensor function:\n%s\n",
+ dump.c_str());
+ }
return root.get();
}
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 ae217935fd9..5452ae1994d 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
@@ -59,6 +59,15 @@ DenseDotProductFunction::compile_self(Stash &) const
return eval::InterpretedFunction::Instruction(my_dot_product_op, (uint64_t)(_hwAccelerator.get()));
}
+void
+DenseDotProductFunction::dump_tree(eval::DumpTarget &target) const
+{
+ target.node("DenseDotProduct");
+ target.child("lhs", lhs());
+ target.child("rhs", rhs());
+}
+
+
const TensorFunction &
DenseDotProductFunction::optimize(const eval::TensorFunction &expr, Stash &stash)
{
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 46b04a446d4..fe9a92adbf2 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
@@ -19,6 +19,7 @@ public:
DenseDotProductFunction(const eval::TensorFunction &lhs_in,
const eval::TensorFunction &rhs_in);
eval::InterpretedFunction::Instruction compile_self(Stash &stash) const override;
+ void dump_tree(eval::DumpTarget &target) 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_fast_rename_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_fast_rename_function.cpp
index dda95d5a657..ede5f433ca4 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_fast_rename_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_fast_rename_function.cpp
@@ -68,6 +68,14 @@ DenseFastRenameFunction::compile_self(Stash &) const
return eval::InterpretedFunction::Instruction(my_fast_rename_op, (uint64_t)&(result_type()));
}
+void
+DenseFastRenameFunction::dump_tree(eval::DumpTarget &target) const
+{
+ target.node("DenseFastRename");
+ target.child("child", child());
+}
+
+
const TensorFunction &
DenseFastRenameFunction::optimize(const eval::TensorFunction &expr, Stash &stash)
{
diff --git a/eval/src/vespa/eval/tensor/dense/dense_fast_rename_function.h b/eval/src/vespa/eval/tensor/dense/dense_fast_rename_function.h
index 1ca61d52915..1427ab908e4 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_fast_rename_function.h
+++ b/eval/src/vespa/eval/tensor/dense/dense_fast_rename_function.h
@@ -17,6 +17,7 @@ public:
const eval::TensorFunction &child);
~DenseFastRenameFunction();
eval::InterpretedFunction::Instruction compile_self(Stash &stash) const override;
+ void dump_tree(eval::DumpTarget &target) const override;
bool result_is_mutable() const override { return child().result_is_mutable(); }
static const eval::TensorFunction &optimize(const eval::TensorFunction &expr, Stash &stash);
};
diff --git a/eval/src/vespa/eval/tensor/dense/dense_inplace_join_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_inplace_join_function.cpp
index 78a407062c6..be4befcc5bf 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_inplace_join_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_inplace_join_function.cpp
@@ -67,6 +67,13 @@ DenseInplaceJoinFunction::compile_self(Stash &) const
return eval::InterpretedFunction::Instruction(op, (uint64_t)function());
}
+void
+DenseInplaceJoinFunction::dump_tree(eval::DumpTarget &target) const
+{
+ target.node("DenseInplaceJoin replacing:");
+ Join::dump_tree(target);
+}
+
const TensorFunction &
DenseInplaceJoinFunction::optimize(const eval::TensorFunction &expr, Stash &stash)
{
diff --git a/eval/src/vespa/eval/tensor/dense/dense_inplace_join_function.h b/eval/src/vespa/eval/tensor/dense/dense_inplace_join_function.h
index d31ce99dda4..ceae1a258bc 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_inplace_join_function.h
+++ b/eval/src/vespa/eval/tensor/dense/dense_inplace_join_function.h
@@ -25,6 +25,7 @@ public:
bool write_left() const { return _write_left; }
bool result_is_mutable() const override { return true; }
eval::InterpretedFunction::Instruction compile_self(Stash &stash) const override;
+ void dump_tree(eval::DumpTarget &target) const override;
static const eval::TensorFunction &optimize(const eval::TensorFunction &expr, Stash &stash);
};
diff --git a/eval/src/vespa/eval/tensor/dense/dense_inplace_map_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_inplace_map_function.cpp
index a0aba25f342..a11db454374 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_inplace_map_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_inplace_map_function.cpp
@@ -52,6 +52,13 @@ DenseInplaceMapFunction::compile_self(Stash &) const
return eval::InterpretedFunction::Instruction(my_inplace_map_op, (uint64_t)function());
}
+void
+DenseInplaceMapFunction::dump_tree(eval::DumpTarget &target) const
+{
+ target.node("DenseInplaceMap replacing:");
+ Map::dump_tree(target);
+}
+
const TensorFunction &
DenseInplaceMapFunction::optimize(const eval::TensorFunction &expr, Stash &stash)
{
diff --git a/eval/src/vespa/eval/tensor/dense/dense_inplace_map_function.h b/eval/src/vespa/eval/tensor/dense/dense_inplace_map_function.h
index bfa5760aa3c..1634fc23e50 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_inplace_map_function.h
+++ b/eval/src/vespa/eval/tensor/dense/dense_inplace_map_function.h
@@ -22,6 +22,7 @@ public:
~DenseInplaceMapFunction();
bool result_is_mutable() const override { return true; }
eval::InterpretedFunction::Instruction compile_self(Stash &stash) const override;
+ void dump_tree(eval::DumpTarget &target) const override;
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 24b1d8abfcf..4788dae5dc4 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
@@ -133,6 +133,18 @@ DenseXWProductFunction::compile_self(Stash &stash) const
return eval::InterpretedFunction::Instruction(op, (uint64_t)(&self));
}
+void
+DenseXWProductFunction::dump_tree(eval::DumpTarget &target) const
+{
+ target.node("DenseXWProduct");
+ target.arg("common dimension innermost").value(_commonDimensionInnermost);
+ target.arg("vector size").value(_vectorSize);
+ target.arg("result size").value(_resultSize);
+ target.child("lhs", lhs());
+ target.child("rhs", rhs());
+}
+
+
const TensorFunction &
DenseXWProductFunction::optimize(const eval::TensorFunction &expr, Stash &stash)
{
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 100d5c4e247..ae74863200f 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
@@ -51,6 +51,7 @@ public:
bool matrixHasCommonDimensionInnermost() const { return _commonDimensionInnermost; }
eval::InterpretedFunction::Instruction compile_self(Stash &stash) const override;
+ void dump_tree(eval::DumpTarget &target) 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 445b08ab114..7bb112d275f 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
@@ -91,6 +91,18 @@ VectorFromDoublesFunction::compile_self(Stash &) const
return eval::InterpretedFunction::Instruction(my_vector_from_doubles_op, (uint64_t)&_self);
}
+void
+VectorFromDoublesFunction::dump_tree(eval::DumpTarget &target) const
+{
+ target.node("VectorFromDoubles");
+ target.arg("size").value(size());
+ target.arg("dimension").value(dimension());
+ for (const auto & child : _children) {
+ target.child("child", child.get());
+ }
+}
+
+
const TensorFunction &
VectorFromDoublesFunction::optimize(const eval::TensorFunction &expr, Stash &stash)
{
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 378c9026f84..ffd40d8acc0 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
@@ -31,6 +31,7 @@ public:
}
size_t size() const { return _self.resultSize; }
eval::InterpretedFunction::Instruction compile_self(Stash &stash) const override;
+ void dump_tree(eval::DumpTarget &target) const override;
bool result_is_mutable() const override { return true; }
static const eval::TensorFunction &optimize(const eval::TensorFunction &expr, Stash &stash);
};