From 337e6c92930fcb890359127f482bfa7962e4fcf1 Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Sun, 2 Dec 2018 22:11:15 -0800 Subject: [PATCH 01/15] Add new debugger --- include/tvm/relay/op_attr_types.h | 5 +++ python/tvm/relay/__init__.py | 7 +--- python/tvm/relay/backend/interpreter.py | 1 + python/tvm/relay/debug.py | 24 +++++++++++ python/tvm/relay/op/__init__.py | 2 + python/tvm/relay/op/op.py | 4 ++ src/relay/backend/interpreter.cc | 53 +++++++++++++++++++++++++ src/relay/op/debug.cc | 46 +++++++++++++++++++++ 8 files changed, 136 insertions(+), 6 deletions(-) create mode 100644 python/tvm/relay/debug.py create mode 100644 src/relay/op/debug.cc diff --git a/include/tvm/relay/op_attr_types.h b/include/tvm/relay/op_attr_types.h index 1f37e9947bb8..c2839a471d20 100644 --- a/include/tvm/relay/op_attr_types.h +++ b/include/tvm/relay/op_attr_types.h @@ -48,6 +48,11 @@ using TOpPattern = int; */ using TOpIsStateful = bool; +/*! + * \brief Mark the operator as non-computational. + */ +using TNonComputational = bool; + /*! * \brief Computation description interface. * diff --git a/python/tvm/relay/__init__.py b/python/tvm/relay/__init__.py index b66132f27775..ff3747961602 100644 --- a/python/tvm/relay/__init__.py +++ b/python/tvm/relay/__init__.py @@ -9,6 +9,7 @@ from . import ir_pass from .build_module import build, build_config, create_executor from . import parser +from . import debug # Root operators from .op import Op @@ -58,11 +59,5 @@ const = expr.const bind = expr.bind -# pylint: disable=unused-argument -@register_func("relay.debug") -def _debug(*args): - import pdb - pdb.set_trace() - # Parser fromtext = parser.fromtext diff --git a/python/tvm/relay/backend/interpreter.py b/python/tvm/relay/backend/interpreter.py index ff6cf6aa1d5c..510850734149 100644 --- a/python/tvm/relay/backend/interpreter.py +++ b/python/tvm/relay/backend/interpreter.py @@ -21,6 +21,7 @@ def from_scalar(value, dtype=None): return TensorValue(const(value, dtype).data) + @register_relay_node class TupleValue(Value): """A tuple value produced by the interpreter.""" diff --git a/python/tvm/relay/debug.py b/python/tvm/relay/debug.py new file mode 100644 index 000000000000..26fae261aecd --- /dev/null +++ b/python/tvm/relay/debug.py @@ -0,0 +1,24 @@ +# pylint: disable=wildcard-import, redefined-builtin, invalid-name +"""The Relay IR namespace containing the IR definition and compiler.""" +from __future__ import absolute_import +from .base import NodeBase, register_relay_node +from ..api import register_func + +@register_relay_node +class InterpreterState(NodeBase): + pass + +def _debugger_init(expr, stack): + import pdb + pdb.set_trace() + +# pylint: disable=unused-argument +@register_func("relay.debug") +def _debug(*args): + _, _, _, ist = args + print("Relay Debugger") + print(" You can manipulate the expression under evaluation by the name `expr`.") + print(" You can manipulate the call stack by the name `stack`.") + print("--------------") + print("--------------") + _debugger_init(ist.current_expr , ist.stack) diff --git a/python/tvm/relay/op/__init__.py b/python/tvm/relay/op/__init__.py index 4a6dfd9f7335..63baa5128bb9 100644 --- a/python/tvm/relay/op/__init__.py +++ b/python/tvm/relay/op/__init__.py @@ -3,6 +3,7 @@ # operator defs from .op import get, register, register_schedule, register_compute, register_alter_op_layout, \ Op +from .op import debug # Operators from .reduce import * @@ -13,6 +14,7 @@ from . import vision from . import op_attrs + # operator registry from . import _tensor from . import _transform diff --git a/python/tvm/relay/op/op.py b/python/tvm/relay/op/op.py index dd3af9c44e42..c97b88fab4b0 100644 --- a/python/tvm/relay/op/op.py +++ b/python/tvm/relay/op/op.py @@ -8,6 +8,7 @@ from ..expr import Expr from ...api import register_func from ...build_module import lower, build +from . import _make @register_relay_node class Op(Expr): @@ -183,3 +184,6 @@ def schedule_injective(attrs, outputs, target): """Generic schedule for binary broadcast.""" with target: return topi.generic.schedule_injective(outputs) + +def debug(expr, debug_func=None): + return _make.debug(expr) diff --git a/src/relay/backend/interpreter.cc b/src/relay/backend/interpreter.cc index 5bef4a22f371..60cd55aed5ac 100644 --- a/src/relay/backend/interpreter.cc +++ b/src/relay/backend/interpreter.cc @@ -124,6 +124,38 @@ struct Stack { }; }; +/*! \brief A representation of the interpreter state which can be passed back to Python. */ +class InterpreterState; + +/*! \brief Interpreter state container. */ +class InterpreterStateNode : public Node { + public: + using Frame = tvm::Map; + using Stack = tvm::Array; + /*! \brief the fields of the tuple */ + Expr current_expr; + Stack stack; + + void VisitAttrs(tvm::AttrVisitor* v) final { + v->Visit("current_expr", ¤t_expr); + v->Visit("stack", &stack); + } + + TVM_DLL static InterpreterState make(Expr current_expr, Stack stack); + + static constexpr const char* _type_key = "relay.InterpreterState"; + TVM_DECLARE_NODE_TYPE_INFO(InterpreterStateNode, Node); +}; + +RELAY_DEFINE_NODE_REF(InterpreterState, InterpreterStateNode, NodeRef); + +InterpreterState InterpreterStateNode::make(Expr current_expr, Stack stack) { + NodePtr n = make_node(); + n->current_expr = std::move(current_expr); + n->stack = std::move(stack); + return InterpreterState(n); +} + // NOTE: the current interpreter assumes A-normal form. // which is better for execution. // @@ -209,6 +241,17 @@ class Interpreter : Value InvokePrimitiveOp(Function func, const Array& args) { + auto call_node = func->body.as(); + if (call_node) { + auto debug = Op::Get("debug"); + if (call_node->op == debug) { + auto is = this->get_state(); + is->current_expr = expr; + RELAY_DEBUG(is); + return Eval(call_node->args[0]); + } + } + // Marshal the arguments. // Handle tuple input/output by flattening them. size_t arg_len = 0; @@ -388,6 +431,16 @@ class Interpreter : } } + InterpreterState get_state(Expr e = Expr()) const { + InterpreterStateNode::Stack stack; + for (auto fr : this->stack_.frames) { + InterpreterStateNode::Frame frame = fr.locals; + stack.push_back(frame); + } + auto state = InterpreterStateNode::make(Expr(), stack); + return state; + } + private: // module Module mod_; diff --git a/src/relay/op/debug.cc b/src/relay/op/debug.cc new file mode 100644 index 000000000000..795b93087538 --- /dev/null +++ b/src/relay/op/debug.cc @@ -0,0 +1,46 @@ + +/*! + * Copyright (c) 2018 by Contributors + * \file nn.cc + * \brief Property def of nn operators. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "./type_relations.h" +#include "./op_common.h" +#include "./layout.h" + +namespace tvm { +namespace relay { + +RELAY_REGISTER_OP("debug") +.describe(R"code(Enter the interpreter's debugger. + +)code" TVM_ADD_FILELINE) +.set_num_inputs(1) +.add_argument("data", "Tuple", "The input list of tensors.") +.set_support_level(1) +.add_type_rel("Debug", IdentityRel) +.set_attr("TNonComputational", true) +.set_attr("TOpPattern", kInjective); + +Expr MakeDebug(Expr expr) { + static const Op& op = Op::Get("debug"); + return CallNode::make(op, {expr}, Attrs(), {}); +} + +TVM_REGISTER_API("relay.op._make.debug") +.set_body([](const TVMArgs& args, TVMRetValue* rv) { + runtime::detail::unpack_call(MakeDebug, args, rv); + }); + + +} // namespace relay +} // namespace tvm + From a063fa5cdb6ab2ad6e770d9aebfdd88d28415fac Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Mon, 3 Dec 2018 10:42:39 -0800 Subject: [PATCH 02/15] WIP --- include/tvm/relay/attrs/debug.h | 29 +++++++++++++++++++++++++++++ python/tvm/relay/op/op.py | 13 ++++++++++++- src/relay/backend/interpreter.cc | 17 +++++++++++++---- src/relay/op/debug.cc | 20 ++++++++++---------- 4 files changed, 64 insertions(+), 15 deletions(-) create mode 100644 include/tvm/relay/attrs/debug.h diff --git a/include/tvm/relay/attrs/debug.h b/include/tvm/relay/attrs/debug.h new file mode 100644 index 000000000000..8243dc0a3b91 --- /dev/null +++ b/include/tvm/relay/attrs/debug.h @@ -0,0 +1,29 @@ +/*! + * Copyright (c) 2018 by Contributors + * \file tvm/relay/attrs/debug.h + * \brief Auxiliary attributes for debug operators. + */ +#ifndef TVM_RELAY_ATTRS_DEBUG_H_ +#define TVM_RELAY_ATTRS_DEBUG_H_ + +#include +#include + +namespace tvm { +namespace relay { + +/*! + * \brief Options for the debug operators. + */ +struct DebugAttrs : public tvm::AttrsNode { + EnvFunc debug_func; + + TVM_DECLARE_ATTRS(DebugAttrs, "relay.attrs.DebugAttrs") { + TVM_ATTR_FIELD(debug_func) + .describe("The function to use when debugging."); + } +}; + +} // namespace relay +} // namespace tvm +#endif // TVM_RELAY_ATTRS_DEBUG_H_ diff --git a/python/tvm/relay/op/op.py b/python/tvm/relay/op/op.py index c97b88fab4b0..ae4b5fec73b6 100644 --- a/python/tvm/relay/op/op.py +++ b/python/tvm/relay/op/op.py @@ -185,5 +185,16 @@ def schedule_injective(attrs, outputs, target): with target: return topi.generic.schedule_injective(outputs) +__DEBUG_COUNTER__ = 0 + def debug(expr, debug_func=None): - return _make.debug(expr) + global __DEBUG_COUNTER__ + + if debug_func: + name = "debugger_func{}".format(__DEBUG_COUNTER__) + register_func(name, debug_func) + __DEBUG_COUNTER__ += 1 + else: + name = '' + + return _make.debug(expr, name) diff --git a/src/relay/backend/interpreter.cc b/src/relay/backend/interpreter.cc index 60cd55aed5ac..e10aff976856 100644 --- a/src/relay/backend/interpreter.cc +++ b/src/relay/backend/interpreter.cc @@ -8,6 +8,7 @@ #include #include #include +#include #include "compile_engine.h" namespace tvm { @@ -245,10 +246,18 @@ class Interpreter : if (call_node) { auto debug = Op::Get("debug"); if (call_node->op == debug) { - auto is = this->get_state(); - is->current_expr = expr; - RELAY_DEBUG(is); - return Eval(call_node->args[0]); + auto dattrs = call_node->attrs.as(); + auto is = this->get_state(call_node->args[0]); + if (dattrs->debug_func.defined()) { + dattrs->debug_func(is); + } else { + RELAY_DEBUG(is); + } + auto kont = FunctionNode::make( + func->params, + call_node->args[0], + Type(), {}, Attrs()); + return this->Eval(kont); } } diff --git a/src/relay/op/debug.cc b/src/relay/op/debug.cc index 795b93087538..087f85a873cb 100644 --- a/src/relay/op/debug.cc +++ b/src/relay/op/debug.cc @@ -1,4 +1,3 @@ - /*! * Copyright (c) 2018 by Contributors * \file nn.cc @@ -6,11 +5,7 @@ */ #include -#include -#include -#include -#include -#include +#include #include #include "./type_relations.h" #include "./op_common.h" @@ -30,17 +25,22 @@ RELAY_REGISTER_OP("debug") .set_attr("TNonComputational", true) .set_attr("TOpPattern", kInjective); -Expr MakeDebug(Expr expr) { +Expr MakeDebug(Expr expr, std::string name) { + auto dattrs = make_node(); + if (name.size() > 0) { + dattrs->debug_func = EnvFunc::Get(name); + } else { + dattrs->debug_func = EnvFunc(); + } static const Op& op = Op::Get("debug"); - return CallNode::make(op, {expr}, Attrs(), {}); + return CallNode::make(op, {expr}, Attrs(dattrs), {}); } TVM_REGISTER_API("relay.op._make.debug") .set_body([](const TVMArgs& args, TVMRetValue* rv) { - runtime::detail::unpack_call(MakeDebug, args, rv); + runtime::detail::unpack_call(MakeDebug, args, rv); }); - } // namespace relay } // namespace tvm From 4a0e867138c7b827701bb8c894054473430f02dc Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Mon, 3 Dec 2018 12:43:37 -0800 Subject: [PATCH 03/15] Add test_debug.py --- tests/python/relay/test_debug.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 tests/python/relay/test_debug.py diff --git a/tests/python/relay/test_debug.py b/tests/python/relay/test_debug.py new file mode 100644 index 000000000000..72963560a706 --- /dev/null +++ b/tests/python/relay/test_debug.py @@ -0,0 +1,14 @@ +from tvm.relay import var, const, create_executor +from tvm.relay.op import debug + + +def test_debug(): + exec = create_executor() + x = var('x', shape=(), dtype='int32') + hit = False + def did_exec(x): + global hit + hit = True + prog = debug(x, debug_func=did_exec) + exec.evaluate(prog, { x: const(1) }) + assert hit From 694d46de51275c001682a81065ef7ed7cfc0890c Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Wed, 12 Dec 2018 10:42:22 -0800 Subject: [PATCH 04/15] Add test for debugging code --- tests/python/relay/test_debug.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/python/relay/test_debug.py b/tests/python/relay/test_debug.py index 72963560a706..a4b95e4d9fa7 100644 --- a/tests/python/relay/test_debug.py +++ b/tests/python/relay/test_debug.py @@ -2,13 +2,16 @@ from tvm.relay.op import debug +_test_debug_hit = False + def test_debug(): + global _test_debug_hit exec = create_executor() x = var('x', shape=(), dtype='int32') - hit = False + _test_debug_hit = False def did_exec(x): - global hit - hit = True + global _test_debug_hit + _test_debug_hit = True prog = debug(x, debug_func=did_exec) exec.evaluate(prog, { x: const(1) }) - assert hit + assert _test_debug_hit From 72cb372a6727a9ae93a1057da33411a51fdda9b6 Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Wed, 12 Dec 2018 10:48:42 -0800 Subject: [PATCH 05/15] Fix linting --- python/tvm/relay/debug.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/tvm/relay/debug.py b/python/tvm/relay/debug.py index 26fae261aecd..8369bab369f9 100644 --- a/python/tvm/relay/debug.py +++ b/python/tvm/relay/debug.py @@ -8,6 +8,7 @@ class InterpreterState(NodeBase): pass +# pylint: disable=unused-argument def _debugger_init(expr, stack): import pdb pdb.set_trace() @@ -21,4 +22,4 @@ def _debug(*args): print(" You can manipulate the call stack by the name `stack`.") print("--------------") print("--------------") - _debugger_init(ist.current_expr , ist.stack) + _debugger_init(ist.current_expr, ist.stack) From 0fb114d39d0fcd46a2a030771689c9fb8a6bcab0 Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Tue, 18 Dec 2018 14:39:49 -0800 Subject: [PATCH 06/15] Add docstring --- python/tvm/relay/op/op.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/tvm/relay/op/op.py b/python/tvm/relay/op/op.py index ae4b5fec73b6..b027211acf47 100644 --- a/python/tvm/relay/op/op.py +++ b/python/tvm/relay/op/op.py @@ -188,6 +188,7 @@ def schedule_injective(attrs, outputs, target): __DEBUG_COUNTER__ = 0 def debug(expr, debug_func=None): + """The main entry point to the debugger.""" global __DEBUG_COUNTER__ if debug_func: From b28e88bdd6a5e6372f1e1edee02b0649ffe73118 Mon Sep 17 00:00:00 2001 From: Josh Pollock Date: Thu, 20 Dec 2018 17:06:08 -0800 Subject: [PATCH 07/15] Update python/tvm/relay/debug.py Co-Authored-By: jroesch --- python/tvm/relay/debug.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/tvm/relay/debug.py b/python/tvm/relay/debug.py index 8369bab369f9..6a560f575a75 100644 --- a/python/tvm/relay/debug.py +++ b/python/tvm/relay/debug.py @@ -18,7 +18,7 @@ def _debugger_init(expr, stack): def _debug(*args): _, _, _, ist = args print("Relay Debugger") - print(" You can manipulate the expression under evaluation by the name `expr`.") + print(" You can manipulate the expression under evaluation with the name `expr`.") print(" You can manipulate the call stack by the name `stack`.") print("--------------") print("--------------") From 0f99bfc04030e67343c9721b030494301c44e72a Mon Sep 17 00:00:00 2001 From: Josh Pollock Date: Thu, 20 Dec 2018 17:07:36 -0800 Subject: [PATCH 08/15] Update python/tvm/relay/debug.py Co-Authored-By: jroesch --- python/tvm/relay/debug.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/tvm/relay/debug.py b/python/tvm/relay/debug.py index 6a560f575a75..00ad7b4401b0 100644 --- a/python/tvm/relay/debug.py +++ b/python/tvm/relay/debug.py @@ -19,7 +19,7 @@ def _debug(*args): _, _, _, ist = args print("Relay Debugger") print(" You can manipulate the expression under evaluation with the name `expr`.") - print(" You can manipulate the call stack by the name `stack`.") + print(" You can manipulate the call stack with the name `stack`.") print("--------------") print("--------------") _debugger_init(ist.current_expr, ist.stack) From c7ffd609986b24a5896f385ab1bb7aa70c163e64 Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Fri, 21 Dec 2018 20:37:54 -0800 Subject: [PATCH 09/15] Address some feedback --- src/relay/backend/interpreter.cc | 39 +++++++++++++++++--------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/relay/backend/interpreter.cc b/src/relay/backend/interpreter.cc index e10aff976856..9175d230fba5 100644 --- a/src/relay/backend/interpreter.cc +++ b/src/relay/backend/interpreter.cc @@ -128,13 +128,16 @@ struct Stack { /*! \brief A representation of the interpreter state which can be passed back to Python. */ class InterpreterState; -/*! \brief Interpreter state container. */ +/*! \brief A container capturing the state of the interpreter. */ class InterpreterStateNode : public Node { public: using Frame = tvm::Map; using Stack = tvm::Array; - /*! \brief the fields of the tuple */ + + /*! \brief The current expression under evaluation. */ Expr current_expr; + + /*! \brief The call stack of the interpreter. */ Stack stack; void VisitAttrs(tvm::AttrVisitor* v) final { @@ -162,8 +165,8 @@ InterpreterState InterpreterStateNode::make(Expr current_expr, Stack stack) { // // It will run duplicated computations when taking program that // contains DAG in dataflow-form. -// Conversion to ANF is recommended before running the interpretation. // +// Conversion to ANF is recommended before running the interpretation. class Interpreter : public ExprFunctor { public: @@ -243,22 +246,22 @@ class Interpreter : Value InvokePrimitiveOp(Function func, const Array& args) { auto call_node = func->body.as(); - if (call_node) { - auto debug = Op::Get("debug"); - if (call_node->op == debug) { - auto dattrs = call_node->attrs.as(); - auto is = this->get_state(call_node->args[0]); - if (dattrs->debug_func.defined()) { - dattrs->debug_func(is); - } else { - RELAY_DEBUG(is); - } - auto kont = FunctionNode::make( - func->params, - call_node->args[0], - Type(), {}, Attrs()); - return this->Eval(kont); + if (call_node && call_node->op == Op::Get("debug")) { + auto dattrs = call_node->attrs.as(); + auto interp_state = this->get_state(call_node->args[0]); + + if (dattrs->debug_func.defined()) { + dattrs->debug_func(interp_state); + } else { + RELAY_DEBUG(interp_state); } + + auto kont = FunctionNode::make( + func->params, + call_node->args[0], + Type(), {}, Attrs()); + + return this->Eval(kont); } // Marshal the arguments. From ba1aab26a544aabc55b8ee146ed4cb120940cbe6 Mon Sep 17 00:00:00 2001 From: Josh Pollock Date: Fri, 21 Dec 2018 20:38:51 -0800 Subject: [PATCH 10/15] Update src/relay/backend/interpreter.cc Co-Authored-By: jroesch --- src/relay/backend/interpreter.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/relay/backend/interpreter.cc b/src/relay/backend/interpreter.cc index 9175d230fba5..1100eb4d5e3e 100644 --- a/src/relay/backend/interpreter.cc +++ b/src/relay/backend/interpreter.cc @@ -449,7 +449,7 @@ class Interpreter : InterpreterStateNode::Frame frame = fr.locals; stack.push_back(frame); } - auto state = InterpreterStateNode::make(Expr(), stack); + auto state = InterpreterStateNode::make(e, stack); return state; } From 3157c10fb53d58654f08db00dd914281dd4f2f07 Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Fri, 21 Dec 2018 20:50:46 -0800 Subject: [PATCH 11/15] Address more CR --- python/tvm/relay/backend/interpreter.py | 1 - src/relay/backend/interpreter.cc | 8 ++------ src/relay/op/debug.cc | 14 +++++++++++--- tests/python/relay/test_debug.py | 3 ++- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/python/tvm/relay/backend/interpreter.py b/python/tvm/relay/backend/interpreter.py index 510850734149..ff6cf6aa1d5c 100644 --- a/python/tvm/relay/backend/interpreter.py +++ b/python/tvm/relay/backend/interpreter.py @@ -21,7 +21,6 @@ def from_scalar(value, dtype=None): return TensorValue(const(value, dtype).data) - @register_relay_node class TupleValue(Value): """A tuple value produced by the interpreter.""" diff --git a/src/relay/backend/interpreter.cc b/src/relay/backend/interpreter.cc index 1100eb4d5e3e..430b5a27fbad 100644 --- a/src/relay/backend/interpreter.cc +++ b/src/relay/backend/interpreter.cc @@ -246,6 +246,7 @@ class Interpreter : Value InvokePrimitiveOp(Function func, const Array& args) { auto call_node = func->body.as(); + if (call_node && call_node->op == Op::Get("debug")) { auto dattrs = call_node->attrs.as(); auto interp_state = this->get_state(call_node->args[0]); @@ -256,12 +257,7 @@ class Interpreter : RELAY_DEBUG(interp_state); } - auto kont = FunctionNode::make( - func->params, - call_node->args[0], - Type(), {}, Attrs()); - - return this->Eval(kont); + return args[0]; } // Marshal the arguments. diff --git a/src/relay/op/debug.cc b/src/relay/op/debug.cc index 087f85a873cb..61d1536adc78 100644 --- a/src/relay/op/debug.cc +++ b/src/relay/op/debug.cc @@ -6,6 +6,7 @@ #include #include +#include #include #include "./type_relations.h" #include "./op_common.h" @@ -14,16 +15,23 @@ namespace tvm { namespace relay { +Array DebugCompute(const Attrs& attrs, + const Array& inputs, + const Type& out_type, + const Target& target) { + return Array{ topi::identity(inputs[0]) }; +} + RELAY_REGISTER_OP("debug") .describe(R"code(Enter the interpreter's debugger. )code" TVM_ADD_FILELINE) .set_num_inputs(1) -.add_argument("data", "Tuple", "The input list of tensors.") +.add_argument("program", "Tuple", "The program to execute before debugging.") .set_support_level(1) .add_type_rel("Debug", IdentityRel) -.set_attr("TNonComputational", true) -.set_attr("TOpPattern", kInjective); +.set_attr("TOpPattern", kInjective) +.set_attr("FTVMCompute", DebugCompute); Expr MakeDebug(Expr expr, std::string name) { auto dattrs = make_node(); diff --git a/tests/python/relay/test_debug.py b/tests/python/relay/test_debug.py index a4b95e4d9fa7..7d35bf80263f 100644 --- a/tests/python/relay/test_debug.py +++ b/tests/python/relay/test_debug.py @@ -13,5 +13,6 @@ def did_exec(x): global _test_debug_hit _test_debug_hit = True prog = debug(x, debug_func=did_exec) - exec.evaluate(prog, { x: const(1) }) + result = exec.evaluate(prog, { x: const(1) }) assert _test_debug_hit + assert result.asnumpy() == 1 From 6dc19418dfd997d5d7f0960a8e1ba8fc6ccdf1f5 Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Fri, 21 Dec 2018 20:52:27 -0800 Subject: [PATCH 12/15] Add second test --- tests/python/relay/test_debug.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/python/relay/test_debug.py b/tests/python/relay/test_debug.py index 7d35bf80263f..cc9282e26ab9 100644 --- a/tests/python/relay/test_debug.py +++ b/tests/python/relay/test_debug.py @@ -16,3 +16,17 @@ def did_exec(x): result = exec.evaluate(prog, { x: const(1) }) assert _test_debug_hit assert result.asnumpy() == 1 + +def test_debug_with_expr(): + global _test_debug_hit + _test_debug_hit = False + exec = create_executor() + x = var('x', shape=(), dtype='int32') + _test_debug_hit = False + def did_exec(x): + global _test_debug_hit + _test_debug_hit = True + prog = debug(x + x * x, debug_func=did_exec) + result = exec.evaluate(prog, { x: const(2) }) + assert _test_debug_hit + assert result.asnumpy() == 6 From ab8e97f89e15985a8251163eacdf82b6268ad1ef Mon Sep 17 00:00:00 2001 From: Josh Pollock Date: Fri, 21 Dec 2018 20:53:16 -0800 Subject: [PATCH 13/15] Update src/relay/op/debug.cc Co-Authored-By: jroesch --- src/relay/op/debug.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/relay/op/debug.cc b/src/relay/op/debug.cc index 61d1536adc78..4aab73c79467 100644 --- a/src/relay/op/debug.cc +++ b/src/relay/op/debug.cc @@ -38,7 +38,7 @@ Expr MakeDebug(Expr expr, std::string name) { if (name.size() > 0) { dattrs->debug_func = EnvFunc::Get(name); } else { - dattrs->debug_func = EnvFunc(); + dattrs->debug_func = EnvFunc(); } static const Op& op = Op::Get("debug"); return CallNode::make(op, {expr}, Attrs(dattrs), {}); From 160ad3d5bba7f7da3cb5bee2f1259c0c50ad6c7f Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Fri, 21 Dec 2018 20:55:28 -0800 Subject: [PATCH 14/15] Fix 2.7 failure --- tests/python/relay/test_debug.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/python/relay/test_debug.py b/tests/python/relay/test_debug.py index cc9282e26ab9..3463e2916147 100644 --- a/tests/python/relay/test_debug.py +++ b/tests/python/relay/test_debug.py @@ -6,27 +6,27 @@ def test_debug(): global _test_debug_hit - exec = create_executor() + ex = create_executor() x = var('x', shape=(), dtype='int32') _test_debug_hit = False def did_exec(x): global _test_debug_hit _test_debug_hit = True prog = debug(x, debug_func=did_exec) - result = exec.evaluate(prog, { x: const(1) }) + result = ex.evaluate(prog, { x: const(1) }) assert _test_debug_hit assert result.asnumpy() == 1 def test_debug_with_expr(): global _test_debug_hit _test_debug_hit = False - exec = create_executor() + ex = create_executor() x = var('x', shape=(), dtype='int32') _test_debug_hit = False def did_exec(x): global _test_debug_hit _test_debug_hit = True prog = debug(x + x * x, debug_func=did_exec) - result = exec.evaluate(prog, { x: const(2) }) + result = ex.evaluate(prog, { x: const(2) }) assert _test_debug_hit assert result.asnumpy() == 6 From 922f123aafe02c833195f48d67b043d9768fbff9 Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Mon, 24 Dec 2018 15:33:39 -0800 Subject: [PATCH 15/15] Make opaque --- src/relay/op/debug.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/relay/op/debug.cc b/src/relay/op/debug.cc index 4aab73c79467..4c9b0a5ca83e 100644 --- a/src/relay/op/debug.cc +++ b/src/relay/op/debug.cc @@ -30,7 +30,7 @@ RELAY_REGISTER_OP("debug") .add_argument("program", "Tuple", "The program to execute before debugging.") .set_support_level(1) .add_type_rel("Debug", IdentityRel) -.set_attr("TOpPattern", kInjective) +.set_attr("TOpPattern", kOpaque) .set_attr("FTVMCompute", DebugCompute); Expr MakeDebug(Expr expr, std::string name) {