diff --git a/mindspore/ccsrc/debug/trace.cc b/mindspore/ccsrc/debug/trace.cc index 7c25ad67d6..5530fe6e2b 100644 --- a/mindspore/ccsrc/debug/trace.cc +++ b/mindspore/ccsrc/debug/trace.cc @@ -567,7 +567,16 @@ struct TraceProviderRegister { TraceProviderRegister() { LogWriter::set_trace_provider([](std::ostringstream &oss) { TraceGraphEval(); - GetEvalStackInfo(oss); + std::ostringstream trace_info; + GetEvalStackInfo(trace_info); + if (trace_info.str().empty()) { + DebugInfoPtr debug_info = TraceManager::GetDebugInfoPtr(); + if (debug_info != nullptr) { + oss << "\n\n# " << trace::GetDebugInfo(debug_info); + } + } else { + oss << trace_info.str(); + } }); } ~TraceProviderRegister() = default; diff --git a/mindspore/ccsrc/pipeline/jit/parse/parse.cc b/mindspore/ccsrc/pipeline/jit/parse/parse.cc index 53dec62aa5..bddd1a554a 100644 --- a/mindspore/ccsrc/pipeline/jit/parse/parse.cc +++ b/mindspore/ccsrc/pipeline/jit/parse/parse.cc @@ -347,7 +347,6 @@ FunctionBlockPtr Parser::ParseStatements(FunctionBlockPtr fn_block, const py::ob MS_LOG(DEBUG) << "The nodes count is " << count; for (size_t i = 0; i < count; i++) { auto node = py::cast(nodes)[i]; - TraceGuard guard(GetLocation(node)); fn_block = ParseStatement(fn_block, node); // insert appropriate depended items for the function block if it has a return node if (fn_block->func_graph()->get_return() != nullptr) { @@ -360,6 +359,7 @@ FunctionBlockPtr Parser::ParseStatements(FunctionBlockPtr fn_block, const py::ob } FunctionBlockPtr Parser::ParseStatement(const FunctionBlockPtr &block, const py::object &node) { + TraceGuard trace_guard(GetLocation(node)); auto node_type = ast_->GetNodeType(node); // check the node type @@ -372,27 +372,17 @@ FunctionBlockPtr Parser::ParseStatement(const FunctionBlockPtr &block, const py: std::string node_name = node_type->node_name(); MS_LOG(DEBUG) << "Ast node is " << node_name; if (stmt_method_map_.count(node_name)) { - TraceGuard trace_guard(GetLocation(node)); auto stmt_block = (this->*stmt_method_map_[node_name])(block, node); return stmt_block; } else { errcode_ = PARSE_NODE_METHOD_UNSUPPORTED; - py::list location = ast_->CallParserObjMethod(PYTHON_PARSE_GET_LOCATION, node); - if (location.size() < 2) { - MS_LOG(EXCEPTION) << "List size should not be less than 2."; - } - auto filename = location[0].cast(); - auto line_no = location[1].cast(); - auto fn_loc = block->func_graph()->debug_info()->location(); - py::str desc = python_adapter::CallPyModFn(ast_->module(), PYTHON_MOD_GET_OBJECT_DESCRIPTION, ast_->function(), - fn_loc->file_name(), fn_loc->line()); - MS_LOG(EXCEPTION) << "Unsupported syntax '" << node_name << "' at " << filename << ":" << line_no << " in " - << desc.cast() << "."; + MS_LOG(EXCEPTION) << "Unsupported syntax '" << node_name << "'."; } } AnfNodePtr Parser::ParseExprNode(const FunctionBlockPtr &block, const py::object &node) { MS_LOG(DEBUG) << "Process ast expr"; + TraceGuard trace_guard(GetLocation(node)); auto node_type = ast_->GetNodeType(node); // check the node type AstMainType node_main_type = node_type->main_type(); @@ -405,19 +395,11 @@ AnfNodePtr Parser::ParseExprNode(const FunctionBlockPtr &block, const py::object std::string node_name = node_type->node_name(); MS_LOG(DEBUG) << "Ast node is " << node_name; if (expr_method_map_.count(node_name)) { - TraceGuard trace_guard(GetLocation(node)); auto expr_node = (this->*expr_method_map_[node_name])(block, node); return expr_node; } else { errcode_ = PARSE_NODE_METHOD_UNSUPPORTED; - py::list ret = ast_->CallParserObjMethod(PYTHON_PARSE_GET_LOCATION, node); - auto filename = ret[0].cast(); - auto line_no = ret[1].cast(); - auto fn_loc = block->func_graph()->debug_info()->location(); - py::str desc = python_adapter::CallPyModFn(ast_->module(), PYTHON_MOD_GET_OBJECT_DESCRIPTION, ast_->function(), - fn_loc->file_name(), fn_loc->line()); - MS_LOG(EXCEPTION) << "Unsupported syntax '" << node_name << "' at " << filename << ":" << line_no << " in " - << desc.cast() << "."; + MS_LOG(EXCEPTION) << "Unsupported syntax '" << node_name << "'."; } } @@ -516,7 +498,6 @@ AnfNodePtr Parser::ParseName(const FunctionBlockPtr &block, const py::object &no MS_LOG(DEBUG) << "Process ast Name"; auto name_id = py::cast(python_adapter::GetPyObjAttr(node, "id")); MS_LOG(DEBUG) << "The Name id is " << name_id; - TraceGuard trace_guard(GetLocation(node)); if (block->IsGlobalVar(name_id)) { return block->MakeResolveSymbol(name_id); } @@ -536,7 +517,6 @@ AnfNodePtr Parser::ParseEllipsis(const FunctionBlockPtr &, const py::object &) { AnfNodePtr Parser::ParseNum(const FunctionBlockPtr &, const py::object &node) { MS_LOG(DEBUG) << "Process ast Num"; py::object obj = python_adapter::GetPyObjAttr(node, "n"); - TraceGuard trace_guard(GetLocation(node)); if (py::isinstance(obj)) { MS_LOG(INFO) << "The Num is int64_t:" << (std::string)py::str(obj); auto data = py::cast(obj); @@ -547,7 +527,7 @@ AnfNodePtr Parser::ParseNum(const FunctionBlockPtr &, const py::object &node) { return NewValueNode(data); } else { // no else actually - MS_LOG(ERROR) << "Unsupported Num type : " << (std::string)py::str(obj) << GetLocation(node)->ToString(); + MS_LOG(ERROR) << "Unsupported Num type : " << (std::string)py::str(obj); errcode_ = PARSE_NODE_TYPE_UNKOWN; return nullptr; } @@ -562,7 +542,6 @@ AnfNodePtr Parser::ParseStr(const FunctionBlockPtr &, const py::object &node) { AnfNodePtr Parser::ParseConstant(const FunctionBlockPtr &, const py::object &node) { MS_LOG(DEBUG) << "Process ast Constant"; py::object obj = python_adapter::GetPyObjAttr(node, "value"); - TraceGuard trace_guard(GetLocation(node)); if (py::isinstance(obj)) { MS_LOG(INFO) << "The Constant is bool:" << (std::string)py::str(obj); auto data = py::cast(obj); @@ -584,15 +563,13 @@ AnfNodePtr Parser::ParseConstant(const FunctionBlockPtr &, const py::object &nod return NewValueNode(kNone); } else { // no else actually - MS_EXCEPTION(TypeError) << "Unsupported Constant type : " << (std::string)py::str(obj) - << GetLocation(node)->ToString(); + MS_EXCEPTION(TypeError) << "Unsupported Constant type : " << (std::string)py::str(obj); } } AnfNodePtr Parser::ParseNameConstant(const FunctionBlockPtr &, const py::object &node) { MS_LOG(DEBUG) << "Process ast NameConstant"; py::object obj = python_adapter::GetPyObjAttr(node, "value"); - TraceGuard trace_guard(GetLocation(node)); if (py::isinstance(obj)) { MS_LOG(INFO) << "The NameConstant is bool:" << (std::string)py::str(obj); auto data = py::cast(obj); @@ -602,7 +579,7 @@ AnfNodePtr Parser::ParseNameConstant(const FunctionBlockPtr &, const py::object return NewValueNode(kNone); } else { // no else actually - MS_LOG(ERROR) << "Unsupported NameConstant type: " << (std::string)py::str(obj) << GetLocation(node)->ToString(); + MS_LOG(ERROR) << "Unsupported NameConstant type: " << (std::string)py::str(obj); errcode_ = PARSE_NODE_TYPE_UNKOWN; return nullptr; } @@ -1534,24 +1511,16 @@ void Parser::HandleAssignClassMember(const FunctionBlockPtr &block, const py::ob (void)var_name.append(attr_name); MS_LOG(DEBUG) << "assign " << var_name; - // Get targ location info for error printing - py::list location = ast_->CallParserObjMethod(PYTHON_PARSE_GET_LOCATION, targ); - if (location.size() < 2) { - MS_LOG(EXCEPTION) << "List size should not be less than 2."; - } - auto filename = location[0].cast(); - auto line_no = location[1].cast(); // Now only support the self.xxx = yyy, where self.xxx must be a defined Parameter type if (!py::hasattr(ast()->obj(), common::SafeCStr(attr_name))) { - MS_EXCEPTION(TypeError) << "'" << var_name << "' should be a Parameter, but not defined, at " << filename << ":" - << line_no; + MS_EXCEPTION(TypeError) << "'" << var_name << "' should be a Parameter, but not defined."; } auto obj = ast()->obj().attr(common::SafeCStr(attr_name)); auto obj_type = obj.attr("__class__").attr("__name__"); if (!py::hasattr(obj, "__parameter__")) { MS_EXCEPTION(TypeError) << "'" << var_name << "' should be a Parameter, but got '" << py::str(obj).cast() << "' with type '" - << py::str(obj_type).cast() << "' at " << filename << ":" << line_no; + << py::str(obj_type).cast() << "."; } MS_EXCEPTION_IF_NULL(block); @@ -1637,13 +1606,7 @@ FunctionBlockPtr Parser::ParseAssign(const FunctionBlockPtr &block, const py::ob FunctionBlockPtr Parser::ParseBreak(const FunctionBlockPtr &block, const py::object &node) { if (loops_.empty()) { // Report error if loop context not set for the 'break' statement. - py::list location = ast_->CallParserObjMethod(PYTHON_PARSE_GET_LOCATION, node); - if (location.size() < 2) { - MS_LOG(EXCEPTION) << "List size should not be less than 2."; - } - auto filename = location[0].cast(); - auto line_no = location[1].cast(); - MS_LOG(EXCEPTION) << "Unexpected 'break' at " << filename << ":" << line_no; + MS_LOG(EXCEPTION) << "Unexpected 'break'."; } // Get current loop. Loop &loop = loops_.top(); @@ -1660,13 +1623,7 @@ FunctionBlockPtr Parser::ParseBreak(const FunctionBlockPtr &block, const py::obj FunctionBlockPtr Parser::ParseContinue(const FunctionBlockPtr &block, const py::object &node) { if (loops_.empty()) { // Report error if loop context not set for the 'continue' statement. - py::list location = ast_->CallParserObjMethod(PYTHON_PARSE_GET_LOCATION, node); - if (location.size() < 2) { - MS_LOG(EXCEPTION) << "List size should not be less than 2."; - } - auto filename = location[0].cast(); - auto line_no = location[1].cast(); - MS_LOG(EXCEPTION) << "Unexpected 'continue' at " << filename << ":" << line_no; + MS_LOG(EXCEPTION) << "Unexpected 'continue."; } // Jump to the header of the loop with iterator called. Loop &loop = loops_.top(); diff --git a/mindspore/ccsrc/pipeline/jit/parse/resolve.cc b/mindspore/ccsrc/pipeline/jit/parse/resolve.cc index fc323f247b..260ce084f2 100644 --- a/mindspore/ccsrc/pipeline/jit/parse/resolve.cc +++ b/mindspore/ccsrc/pipeline/jit/parse/resolve.cc @@ -221,10 +221,9 @@ AnfNodePtr ResolveObjectAndAddToManager(const FuncGraphManagerPtr &manager, cons const AnfNodePtr &node) { ScopeGuard scope_guard(node->scope()); AnfNodePtr resolved_node = nullptr; - TraceGuard trace_guard(std::make_shared(node->debug_info())); bool success = ResolveObjectToNode(node->func_graph(), obj, &resolved_node); if (!success) { - MS_LOG(EXCEPTION) << "Parse Resolve covert failed NodeInfo: " << trace::GetDebugInfo(node->debug_info()); + MS_LOG(EXCEPTION) << "Parse Resolve covert failed NodeInfo."; } if (IsValueNode(resolved_node)) { auto new_fg = GetValueNode(resolved_node); @@ -242,12 +241,14 @@ AnfNodePtr ResolveObjectAndAddToManager(const FuncGraphManagerPtr &manager, cons AnfNodePtr ResolveSymbol(const FuncGraphManagerPtr &manager, const NameSpacePtr &name_space, const SymbolPtr &symbol, const AnfNodePtr &node) { + MS_EXCEPTION_IF_NULL(node); + TraceGuard trace_guard(std::make_shared(node->debug_info())); if (node->func_graph() == nullptr || manager == nullptr) { MS_LOG(EXCEPTION) << "Node " << node->DebugString() << " graph or manager is nullptr"; } SymbolResolver symbol_resolver(name_space, symbol, node); if (!symbol_resolver.Resolve()) { - MS_EXCEPTION(TypeError) << "Parse Resolve node failed NodeInfo: " << trace::GetDebugInfo(node->debug_info()); + MS_EXCEPTION(TypeError) << "Parse Resolve node failed NodeInfo."; } py::object obj = symbol_resolver.result(); @@ -259,12 +260,14 @@ AnfNodePtr ResolveSymbol(const FuncGraphManagerPtr &manager, const NameSpacePtr AnfNodePtr ResolveCellwithAttr(const FuncGraphManagerPtr &manager, const NameSpacePtr &name_space, const SymbolPtr &symbol, const AnfNodePtr &node, const std::string &attr) { + MS_EXCEPTION_IF_NULL(node); + TraceGuard trace_guard(std::make_shared(node->debug_info())); if (node->func_graph() == nullptr || manager == nullptr) { MS_LOG(EXCEPTION) << "Node " << node->DebugString() << " graph or manager is nullptr"; } SymbolResolver symbol_resolver(name_space, symbol, node); if (!symbol_resolver.Resolve()) { - MS_LOG(EXCEPTION) << "Parse Resolve node failed NodeInfo: " << trace::GetDebugInfo(node->debug_info()); + MS_LOG(EXCEPTION) << "Parse Resolve node failed NodeInfo."; } py::object obj = symbol_resolver.result(); diff --git a/mindspore/ccsrc/pipeline/jit/pipeline.cc b/mindspore/ccsrc/pipeline/jit/pipeline.cc index 632e3ce247..2d0c8cc90e 100644 --- a/mindspore/ccsrc/pipeline/jit/pipeline.cc +++ b/mindspore/ccsrc/pipeline/jit/pipeline.cc @@ -543,9 +543,12 @@ bool ExecutorPy::Compile(const py::object &obj, const py::tuple &args, const py: std::ostringstream oss; trace::TraceGraphEval(); trace::GetEvalStackInfo(oss); - // call py::print to output function call stack to STDOUT, in case of output the log to file, the user can see - // these info from screen, no need to open log file to find these info - py::print(oss.str()); + if (oss.str().empty()) { + DebugInfoPtr debug_info = TraceManager::GetDebugInfoPtr(); + if (debug_info != nullptr) { + oss << "\n\n# " << trace::GetDebugInfo(debug_info); + } + } MS_LOG(ERROR) << oss.str(); ReleaseResource(phase); diff --git a/mindspore/core/utils/info.cc b/mindspore/core/utils/info.cc index f42d8020d7..feb10c5332 100644 --- a/mindspore/core/utils/info.cc +++ b/mindspore/core/utils/info.cc @@ -190,6 +190,7 @@ void TraceManager::DebugTrace(const std::string &func_name, const LocationPtr &l void TraceManager::DebugTrace(const LocationPtr &location) { TraceContextPtr context = std::make_shared(location); TraceManager::trace_context_stack_.push(context); + TraceManager::debug_info_ = std::make_shared(location); } void TraceManager::DebugTrace(const TraceInfoPtr &trace_info) { @@ -201,6 +202,7 @@ void TraceManager::DebugTrace(const TraceInfoPtr &trace_info) { MS_LOG(EXCEPTION) << "Trace debug info is null"; } TraceManager::trace_context_stack_.push(context); + TraceManager::debug_info_ = trace_info->debug_info(); } void TraceManager::DebugTrace(const DebugInfoPtr &debug_info, const TraceInfoPtr &trace_info) { @@ -218,5 +220,9 @@ void TraceManager::DebugTrace(const DebugInfoPtr &debug_info, const TraceInfoPtr void TraceManager::EndTrace() { TraceManager::trace_context_stack_.pop(); } +DebugInfoPtr TraceManager::GetDebugInfoPtr() { return TraceManager::debug_info_; } + std::stack TraceManager::trace_context_stack_; + +DebugInfoPtr TraceManager::debug_info_ = nullptr; } // namespace mindspore diff --git a/mindspore/core/utils/info.h b/mindspore/core/utils/info.h index 985ce44610..d9fd01fe24 100644 --- a/mindspore/core/utils/info.h +++ b/mindspore/core/utils/info.h @@ -75,7 +75,11 @@ class TraceManager { // debug trace with a cloned trace info with debug_info static void DebugTrace(const DebugInfoPtr &debug_info, const TraceInfoPtr &trace_info); static void EndTrace(); + + static DebugInfoPtr GetDebugInfoPtr(); + static std::stack trace_context_stack_; + static DebugInfoPtr debug_info_; }; class TraceGuard { diff --git a/tests/ut/python/ops/test_ops_check.py b/tests/ut/python/ops/test_ops_check.py index 3d19aef6d6..efbb1bb830 100644 --- a/tests/ut/python/ops/test_ops_check.py +++ b/tests/ut/python/ops/test_ops_check.py @@ -84,7 +84,7 @@ def test_net_with_raise(): inp = Tensor(np.ones([1, 1, 32, 32]).astype(np.float32)) with pytest.raises(RuntimeError) as err: _executor.compile(net, inp) - assert "Unsupported syntax 'Raise' at " in str(err.value) + assert "Unsupported syntax 'Raise'." in str(err.value) class NetAddN(nn.Cell): diff --git a/tests/ut/python/pipeline/parse/test_grammar_constraints.py b/tests/ut/python/pipeline/parse/test_grammar_constraints.py index 0343c93092..b5acf39297 100644 --- a/tests/ut/python/pipeline/parse/test_grammar_constraints.py +++ b/tests/ut/python/pipeline/parse/test_grammar_constraints.py @@ -118,7 +118,7 @@ def test_raise_in_method(): z = Tensor(2, mstype.int32) with pytest.raises(RuntimeError) as er: net(x, y, z) - assert "Unsupported syntax 'Raise' at" in str(er.value) + assert "Unsupported syntax 'Raise'." in str(er.value) def test_raise_in_nested_function(): @@ -145,7 +145,7 @@ def test_raise_in_nested_function(): z = Tensor(2, mstype.int32) with pytest.raises(RuntimeError) as er: net(x, y, z) - assert "Unsupported syntax 'Raise' at " in str(er.value) + assert "Unsupported syntax 'Raise'." in str(er.value) def test_nest_branch_with_return():