show line of code when parse or resolve phase exception

This commit is contained in:
buxue 2021-01-15 14:56:05 +08:00
parent 7de625fbca
commit 69d9a33ddb
8 changed files with 47 additions and 65 deletions

View File

@ -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;

View File

@ -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<py::list>(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<std::string>();
auto line_no = location[1].cast<int64_t>();
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<std::string>() << ".";
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<std::string>();
auto line_no = ret[1].cast<int64_t>();
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<std::string>() << ".";
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<std::string>(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<py::int_>(obj)) {
MS_LOG(INFO) << "The Num is int64_t:" << (std::string)py::str(obj);
auto data = py::cast<int64_t>(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<py::bool_>(obj)) {
MS_LOG(INFO) << "The Constant is bool:" << (std::string)py::str(obj);
auto data = py::cast<bool>(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<py::bool_>(obj)) {
MS_LOG(INFO) << "The NameConstant is bool:" << (std::string)py::str(obj);
auto data = py::cast<bool>(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<std::string>();
auto line_no = location[1].cast<int64_t>();
// 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<std::string>() << "' with type '"
<< py::str(obj_type).cast<std::string>() << "' at " << filename << ":" << line_no;
<< py::str(obj_type).cast<std::string>() << ".";
}
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<std::string>();
auto line_no = location[1].cast<int64_t>();
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<std::string>();
auto line_no = location[1].cast<int64_t>();
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();

View File

@ -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<TraceResolve>(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<FuncGraph>(resolved_node)) {
auto new_fg = GetValueNode<FuncGraphPtr>(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<TraceResolve>(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<TraceResolve>(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();

View File

@ -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);

View File

@ -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<TraceContext>(location);
TraceManager::trace_context_stack_.push(context);
TraceManager::debug_info_ = std::make_shared<DebugInfo>(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<TraceContextPtr> TraceManager::trace_context_stack_;
DebugInfoPtr TraceManager::debug_info_ = nullptr;
} // namespace mindspore

View File

@ -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<TraceContextPtr> trace_context_stack_;
static DebugInfoPtr debug_info_;
};
class TraceGuard {

View File

@ -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):

View File

@ -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():