diff options
author | Arne Juul <arnej@yahoo-inc.com> | 2018-03-06 12:24:47 +0000 |
---|---|---|
committer | Arne Juul <arnej@yahoo-inc.com> | 2018-03-08 10:47:56 +0000 |
commit | 4e4d19ddb273648aa5396f094970149d08d03ab3 (patch) | |
tree | 956a040607cd1fe50a7e1fd261771205ebc97781 | |
parent | a405462e2408a274ab66fab963413c663c168aab (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.
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); }; |