From 1dbc3b491a01642b04268cac7542fc3dc000f9ed Mon Sep 17 00:00:00 2001 From: fary86 Date: Thu, 3 Sep 2020 10:08:34 +0800 Subject: [PATCH] fix bug of no line info when error reporting --- mindspore/ccsrc/debug/trace.cc | 162 +++++++++++++++++++++++---------- 1 file changed, 113 insertions(+), 49 deletions(-) diff --git a/mindspore/ccsrc/debug/trace.cc b/mindspore/ccsrc/debug/trace.cc index ecb1dca441..8f5bf7bbef 100644 --- a/mindspore/ccsrc/debug/trace.cc +++ b/mindspore/ccsrc/debug/trace.cc @@ -45,7 +45,7 @@ using abstract::AnfNodeConfigPtr; std::string GetAbstractStr(const abstract::AbstractBasePtr &abs) { if (abs == nullptr) { - return "Null Abstract"; + return "NullAbstract"; } auto shape = abs->BuildShape()->cast(); TypePtr type = abs->BuildType(); @@ -132,7 +132,8 @@ class AnalyzedFuncGraphExporter : public AnfExporter { std::string GetNodeType(const AnfNodePtr &nd) override; AbstractBasePtr GetNodeAbstract(const AnfNodePtr &nd); AnfNodeConfigPtr GetFordwardConfigPtr(const AnfNodeConfigPtr &cfg); - AnalysisContextPtr ProcessFuncGraphCall(const CNodePtr &node); + std::vector ProcessFuncGraphCall(const CNodePtr &node, std::string *const op_comment); + void OutputStatementComment(std::ofstream &ofs, const CNodePtr &node, const std::vector &ctxs); // key: context, val: whether the context has already been printed std::unordered_map context_map_; @@ -170,21 +171,7 @@ std::string AnalyzedFuncGraphExporter::GetNodeType(const AnfNodePtr &node) { if (ret == nullptr) { return "Undefined"; } - auto abs = ret->abstract(); - if (abs == nullptr) { - return "Undefined"; - } - auto dtype = abs->BuildType(); - auto shape = abs->BuildShape(); - std::ostringstream oss; - if (dtype != nullptr && abs->isa() && shape != nullptr) { - oss << dtype->DumpText() << shape->DumpText(); - } else if (dtype != nullptr) { - oss << dtype->DumpText(); - } else { - oss << "Undefined"; - } - return oss.str(); + return GetAbstractStr(ret->abstract()); } AbstractBasePtr AnalyzedFuncGraphExporter::GetNodeAbstract(const AnfNodePtr &node) { @@ -210,44 +197,115 @@ AnfNodeConfigPtr AnalyzedFuncGraphExporter::GetFordwardConfigPtr(const AnfNodeCo return cur_cfg; } -AnalysisContextPtr AnalyzedFuncGraphExporter::ProcessFuncGraphCall(const CNodePtr &node) { +std::vector AnalyzedFuncGraphExporter::ProcessFuncGraphCall(const CNodePtr &node, + std::string *const op_comment) { + std::vector ret_contexts; if (node == nullptr) { - return nullptr; + return ret_contexts; } auto cfg = engine_->MakeConfig(node, cur_ctx_); cfg = GetFordwardConfigPtr(cfg); auto cnode = dyn_cast(cfg->node()); if (cnode == nullptr) { MS_LOG(DEBUG) << "CNode is nullptr"; - return nullptr; + return ret_contexts; } + + ret_contexts.resize(cnode->size()); + const auto &inputs = cnode->inputs(); - auto op_abs = GetNodeAbstract(inputs[0]); - if (op_abs == nullptr) { - MS_LOG(DEBUG) << "Abstract of inputs[0] of cnode " << cnode->ToString() << " is nullptr"; - return nullptr; - } + for (size_t i = 0; i < inputs.size(); ++i) { + auto op_abs = GetNodeAbstract(inputs[i]); + if (op_abs == nullptr) { + MS_LOG(DEBUG) << "Abstract of inputs[" << i << "] of cnode " << cnode->ToString() << " is nullptr"; + continue; + } - if (!op_abs->isa() && !op_abs->isa()) { - MS_LOG(DEBUG) << "Inputs[0] of cnode " << cnode->ToString() << " is of type " << op_abs->type_name() - << ", not function, ignore it"; - return nullptr; + if (!op_abs->isa() && !op_abs->isa()) { + MS_LOG(DEBUG) << "Inputs[" << i << "] of cnode " << cnode->ToString() << " is of type " << op_abs->type_name() + << ", not function, ignore it"; + // Get prototype of VirtualEvaluator for printing + if (i == 0 && op_abs->isa()) { + auto func = dyn_cast(op_abs); + std::ostringstream oss; + oss << "("; + bool first_flag = false; + for (const auto &arg : func->args_spec_list()) { + if (!first_flag) { + first_flag = true; + } else { + oss << ", "; + } + oss << GetAbstractStr(arg); + } + oss << ") -> " << GetAbstractStr(func->output()) << " "; + *op_comment = oss.str(); + } + continue; + } + + auto evaluator = engine_->GetEvaluatorFor(dyn_cast(op_abs)); + if (!evaluator->isa()) { + MS_LOG(DEBUG) << "Evaluator for inputs[" << i << "] of cnode " << cnode->ToString() << " is of type " + << evaluator->type_name() << ", not BaseFuncGraphEvaluator, ignore it."; + continue; + } + + auto base_fg_evaluator = dyn_cast(evaluator); + auto ctx = base_fg_evaluator->graph_context(); + if (ctx != nullptr && context_map_.insert({ctx, false}).second) { + MS_LOG(DEBUG) << "Add new context, ctx.addr = " << ctx.get() << "ctx = " << ctx->ToString(); + context_vec_.push_back(ctx); + } + ret_contexts[i] = ctx; } + return ret_contexts; +} - auto evaluator = engine_->GetEvaluatorFor(dyn_cast(op_abs)); - if (!evaluator->isa()) { - MS_LOG(DEBUG) << "Evaluator for inputs[0] of cnode " << cnode->ToString() << " is of type " - << evaluator->type_name() << ", not BaseFuncGraphEvaluator, ignore it."; - return nullptr; +void AnalyzedFuncGraphExporter::OutputStatementComment(std::ofstream &ofs, const CNodePtr &node, + const std::vector &ctxs) { + if (node == nullptr) { + return; } - auto base_fg_evaluator = dyn_cast(evaluator); - auto ctx = base_fg_evaluator->graph_context(); - if (ctx != nullptr && context_map_.insert({ctx, false}).second) { - MS_LOG(DEBUG) << "Add new context, ctx.addr = " << ctx.get() << "ctx = " << ctx->ToString(); - context_vec_.push_back(ctx); + // output type of each input argument + auto &inputs = node->inputs(); + if (inputs.size() > 1) { + ofs << " #("; + for (size_t i = 1; i < inputs.size(); ++i) { + if (i != 1) { + ofs << ", "; + } + AnfNodePtr arg = inputs[i]; + ofs << GetNodeType(arg); + } + ofs << ")"; + } + // output other comment, map the graph name to original representation(containing unicode character) + std::ostringstream comment; + comment << " #"; + bool has_comment = false; + for (size_t i = 0; i < inputs.size(); ++i) { + AnfNodePtr arg = inputs[i]; + if (!IsValueNode(arg)) { + continue; + } + if (!has_comment) { + has_comment = true; + } else { + comment << ","; + } + FuncGraphPtr fg = GetValueNode(arg); + std::string func_graph_id = fg->debug_info()->get_id(); + comment << " fg_" << func_graph_id << "=" << fg->ToString() << "." << func_graph_id; + if (ctxs.size() > i && ctxs[i] != nullptr) { + comment << "(@ctx.addr=" << ctxs[i].get() << ")"; + } + } + if (has_comment) { + ofs << comment.str(); } - return ctx; + ofs << " #scope: " << node->scope()->name(); } void AnalyzedFuncGraphExporter::OutputCNode(std::ofstream &ofs, const CNodePtr &cnode, const FuncGraphPtr &func_graph, @@ -278,10 +336,15 @@ void AnalyzedFuncGraphExporter::OutputCNode(std::ofstream &ofs, const CNodePtr & ofs << ")"; // process function graph call - auto ctx = ProcessFuncGraphCall(cnode); + std::string op_comment; + auto contexts = ProcessFuncGraphCall(cnode, &op_comment); + AnalysisContextPtr ctx = contexts.empty() ? nullptr : contexts[0]; + if (!op_comment.empty()) { + ofs << " #" << GetAnfNodeText(func_graph, inputs[0], *apply_map) << ".prototype = " << op_comment; + } // output comment - OutputStatementComment(ofs, cnode); + OutputStatementComment(ofs, cnode, contexts); if (ctx != nullptr) { ofs << " @ctx.addr=" << ctx.get(); } @@ -432,10 +495,10 @@ void GetEvalStackInfo(std::ostringstream &oss) { } OutputAnalyzedGraphWithType(); - oss << "\nThe function call stack:\n"; + oss << "\nThe function call stack (See file 'analyze_fail.dat' for details):\n"; int index = 0; - std::string last_py_func = ""; + std::string last_location_info = ""; for (size_t i = 0; i < stack.size(); ++i) { auto node_cfg = stack[i]; @@ -446,13 +509,13 @@ void GetEvalStackInfo(std::ostringstream &oss) { } auto debug_info = cnode->debug_info(); - auto this_py_func = debug_info->get_python_func_belonged(); - if (i > 0 && (this_py_func == last_py_func)) { - MS_LOG(DEBUG) << "Python function of elements[" << i << "] is same as previous."; + auto this_location_info = trace::GetDebugInfo(debug_info, std::string("")); + if (this_location_info.empty() || this_location_info == last_location_info) { continue; } - last_py_func = this_py_func; - oss << "# " << index++ << " " << trace::GetDebugInfo(debug_info, std::string("")); + + last_location_info = this_location_info; + oss << "# " << index++ << " " << this_location_info; } stack.clear(); @@ -463,6 +526,7 @@ void GetEvalStackInfo(std::ostringstream &oss) { static std::stack> graph_infer_stack; // trace the cnode infer debug info static std::vector cnode_debug_stack{}; + void TraceGraphEvalEnter(const abstract::EvaluatorPtr &eval, const abstract::AnfNodeConfigPtr &node) { if (eval == nullptr) { MS_LOG(EXCEPTION) << "GraphInferEnter got null eval";