!20078 Export IR with FV informations.

Merge pull request !20078 from 张清华/opt
This commit is contained in:
i-robot 2021-07-14 08:50:14 +00:00 committed by Gitee
commit 40370dc8d7
6 changed files with 127 additions and 225 deletions

View File

@ -97,7 +97,7 @@ int AnfExporter::GetParamIndex(const FuncGraphPtr &func_graph, const AnfNodePtr
return -1; return -1;
} }
// try to find index of parameter for SymbolicKeyInstance from all exported graphs // Try to find index of parameter for SymbolicKeyInstance from all exported graphs
// NOTICE: Suppose name of all parameters in SymbolicKeyInstance are different // NOTICE: Suppose name of all parameters in SymbolicKeyInstance are different
int AnfExporter::GetParamIndexFromExported(const AnfNodePtr &param) { int AnfExporter::GetParamIndexFromExported(const AnfNodePtr &param) {
if (param == nullptr) { if (param == nullptr) {
@ -183,7 +183,7 @@ std::string AnfExporter::GetMetaFuncGraphText(const MetaFuncGraphPtr &meta_func_
prim::MultitypeFuncGraphPtr mt_func_graph = meta_func_graph->cast<prim::MultitypeFuncGraphPtr>(); prim::MultitypeFuncGraphPtr mt_func_graph = meta_func_graph->cast<prim::MultitypeFuncGraphPtr>();
oss << GetMultitypeFuncGraphText(mt_func_graph); oss << GetMultitypeFuncGraphText(mt_func_graph);
} else if (meta_func_graph } else if (meta_func_graph
->isa<prim::HyperMapPy>()) { // this statement must before 'meta_graph->isa<prim::HyperMap>()' ->isa<prim::HyperMapPy>()) { // This statement must before 'meta_graph->isa<prim::HyperMap>()'
auto hyper_map = meta_func_graph->cast<prim::HyperMapPyPtr>(); auto hyper_map = meta_func_graph->cast<prim::HyperMapPyPtr>();
if (hyper_map->GetFnLeaf() != nullptr) { if (hyper_map->GetFnLeaf() != nullptr) {
oss << "{fn_leaf=" << GetMetaFuncGraphText(hyper_map->GetFnLeaf()) << "}"; oss << "{fn_leaf=" << GetMetaFuncGraphText(hyper_map->GetFnLeaf()) << "}";
@ -193,7 +193,7 @@ std::string AnfExporter::GetMetaFuncGraphText(const MetaFuncGraphPtr &meta_func_
if (hyper_map->GetFnLeaf() != nullptr) { if (hyper_map->GetFnLeaf() != nullptr) {
oss << "{fn_leaf=" << GetMetaFuncGraphText(hyper_map->GetFnLeaf()) << "}"; oss << "{fn_leaf=" << GetMetaFuncGraphText(hyper_map->GetFnLeaf()) << "}";
} }
} else if (meta_func_graph->isa<prim::MapPy>()) { // this statement must before 'meta_graph->isa<prim::Map>()' } else if (meta_func_graph->isa<prim::MapPy>()) { // This statement must before 'meta_graph->isa<prim::Map>()'
auto map = meta_func_graph->cast<prim::MapPyPtr>(); auto map = meta_func_graph->cast<prim::MapPyPtr>();
if (map->GetFnLeaf() != nullptr) { if (map->GetFnLeaf() != nullptr) {
oss << "{fn_leaf=" << GetMetaFuncGraphText(map->GetFnLeaf()) << "}"; oss << "{fn_leaf=" << GetMetaFuncGraphText(map->GetFnLeaf()) << "}";
@ -208,7 +208,7 @@ std::string AnfExporter::GetMetaFuncGraphText(const MetaFuncGraphPtr &meta_func_
oss << "{get_all=" << grad_op->get_all_ << ", get_by_list=" << grad_op->get_by_list_ oss << "{get_all=" << grad_op->get_all_ << ", get_by_list=" << grad_op->get_by_list_
<< ", sens_param=" << grad_op->sens_param_ << "}"; << ", sens_param=" << grad_op->sens_param_ << "}";
} else if (Skip(meta_func_graph)) { } else if (Skip(meta_func_graph)) {
// do nothing // Do nothing
} else { } else {
MS_LOG(EXCEPTION) << "Unknown MetaFuncGraph type " << meta_func_graph->type_name(); MS_LOG(EXCEPTION) << "Unknown MetaFuncGraph type " << meta_func_graph->type_name();
} }
@ -222,9 +222,9 @@ std::string AnfExporter::GetPrimitiveText(const PrimitivePtr &prim) {
return oss.str(); return oss.str();
} }
oss << prim->type_name() << "::" << prim->name(); oss << prim->type_name() << "::" << prim->name();
// output primitive type // Output primitive type
oss << "{prim_type=" << static_cast<int>(prim->prim_type()) << "}"; oss << "{prim_type=" << static_cast<int>(prim->prim_type()) << "}";
// output primitive attributes // Output primitive attributes
oss << prim->GetAttrsText(); oss << prim->GetAttrsText();
if (prim->isa<prim::DoSignaturePrimitive>()) { if (prim->isa<prim::DoSignaturePrimitive>()) {
@ -245,7 +245,7 @@ std::string AnfExporter::GetNameSpaceText(const parse::NameSpacePtr &ns) {
return oss.str(); return oss.str();
} }
// dump related module information in Namespace // Dump related module information in Namespace
oss << ns->type_name() << "::" << ns->module(); oss << ns->type_name() << "::" << ns->module();
return oss.str(); return oss.str();
@ -260,7 +260,7 @@ std::string AnfExporter::GetSymbolicKeyInstanceText(const FuncGraphPtr &func_gra
std::ostringstream oss; std::ostringstream oss;
if (sym_node->isa<Parameter>()) { if (sym_node->isa<Parameter>()) {
int idx = GetParamIndex(func_graph, sym_node, false); int idx = GetParamIndex(func_graph, sym_node, false);
// if can not find SymbolicKeyInstance related parameter from ancestors, // If can not find SymbolicKeyInstance related parameter from ancestors,
// try to find from all exported graphs // try to find from all exported graphs
if (idx < 0) { if (idx < 0) {
idx = GetParamIndexFromExported(sym_node); idx = GetParamIndexFromExported(sym_node);
@ -283,7 +283,7 @@ std::string AnfExporter::GetSymbolicKeyInstanceText(const FuncGraphPtr &func_gra
std::string AnfExporter::GetSequenceText(const FuncGraphPtr &func_graph, const ValuePtr &value) { std::string AnfExporter::GetSequenceText(const FuncGraphPtr &func_graph, const ValuePtr &value) {
std::ostringstream oss; std::ostringstream oss;
// output ValueList, ValueTuple // Output ValueList, ValueTuple
ValueSequeuePtr seq = dyn_cast<ValueSequeue>(value); ValueSequeuePtr seq = dyn_cast<ValueSequeue>(value);
MS_EXCEPTION_IF_NULL(seq); MS_EXCEPTION_IF_NULL(seq);
MS_EXCEPTION_IF_NULL(value); MS_EXCEPTION_IF_NULL(value);
@ -375,7 +375,7 @@ std::string AnfExporter::GetValueText(const FuncGraphPtr &func_graph, const Valu
return oss.str(); return oss.str();
} }
// this function is used to output node in CNode's inputs // This function is used to output node in CNode's inputs
std::string AnfExporter::GetAnfNodeText(const FuncGraphPtr &func_graph, const AnfNodePtr &node, std::string AnfExporter::GetAnfNodeText(const FuncGraphPtr &func_graph, const AnfNodePtr &node,
const std::map<AnfNodePtr, int> &apply_map) { const std::map<AnfNodePtr, int> &apply_map) {
std::ostringstream oss; std::ostringstream oss;
@ -420,13 +420,13 @@ void AnfExporter::OutputParameters(std::ofstream &ofs, const std::vector<AnfNode
} }
(*param_map)[param] = param_index; (*param_map)[param] = param_index;
std::string type_info = GetNodeType(param); std::string type_info = GetNodeType(param);
// output parameter and type // Output parameter and type
if (type_info == "Undefined") { if (type_info == "Undefined") {
ofs << "%para" << param_index; ofs << "%para" << param_index;
} else { } else {
ofs << "%para" << param_index << " : " << type_info; ofs << "%para" << param_index << " : " << type_info;
} }
// output comment // Output comment
ofs << " # " << param->DumpText() << "\n"; ofs << " # " << param->DumpText() << "\n";
param_index += 1; param_index += 1;
} }
@ -437,7 +437,7 @@ void AnfExporter::OutputStatementComment(std::ofstream &ofs, const CNodePtr &nod
return; return;
} }
// output type of each input argument // Output type of each input argument
auto &inputs = node->inputs(); auto &inputs = node->inputs();
if (inputs.size() > 1) { if (inputs.size() > 1) {
ofs << " #("; ofs << " #(";
@ -450,7 +450,7 @@ void AnfExporter::OutputStatementComment(std::ofstream &ofs, const CNodePtr &nod
} }
ofs << ")"; ofs << ")";
} }
// output other comment, map the graph name to original representation(containing unicode character) // Output other comment, map the graph name to original representation(containing unicode character)
std::ostringstream comment; std::ostringstream comment;
comment << " #"; comment << " #";
bool has_comment = false; bool has_comment = false;
@ -474,8 +474,45 @@ void AnfExporter::OutputStatementComment(std::ofstream &ofs, const CNodePtr &nod
ofs << " #scope: " << node->scope()->name(); ofs << " #scope: " << node->scope()->name();
} }
void AnfExporter::OutputCNodes(std::ofstream &ofs, const std::vector<AnfNodePtr> &nodes, void AnfExporter::OutputCNodeText(std::ofstream &ofs, const CNodePtr &cnode, const FuncGraphPtr &func_graph, int *idx,
const FuncGraphPtr &func_graph) { std::map<AnfNodePtr, int> *const apply_map) {
auto &inputs = cnode->inputs();
std::string op_text = GetAnfNodeText(func_graph, inputs[0], *apply_map);
std::string fv_text = (cnode->func_graph() != func_graph) ? ("$(" + cnode->func_graph()->ToString() + "):") : "";
// Non-return node
if (cnode != func_graph->get_return()) {
int apply_idx = (*idx)++;
(*apply_map)[cnode] = apply_idx;
std::string type_info = GetNodeType(cnode);
if (type_info == "Undefined") {
ofs << " %" << apply_idx << " = " << fv_text << op_text << "(";
} else {
ofs << " %" << apply_idx << " : " << fv_text << type_info << " = " << op_text << "(";
}
} else {
ofs << " " << fv_text << op_text << "(";
}
for (size_t i = 1; i < inputs.size(); ++i) {
if (i != 1) {
ofs << ", ";
}
AnfNodePtr arg = inputs[i];
ofs << GetAnfNodeText(func_graph, arg, *apply_map);
}
ofs << ")";
}
void AnfExporter::OutputCNode(std::ofstream &ofs, const CNodePtr &cnode, const FuncGraphPtr &func_graph, int *idx,
std::map<AnfNodePtr, int> *const apply_map) {
OutputCNodeText(ofs, cnode, func_graph, idx, apply_map);
// Output comment
OutputStatementComment(ofs, cnode);
ofs << "\n";
}
void AnfExporter::OutputCNodes(std::ofstream &ofs, const std::vector<AnfNodePtr> &nodes, const FuncGraphPtr &func_graph,
const TaggedNodeMap &tagged_cnodes_map) {
if (func_graph == nullptr) { if (func_graph == nullptr) {
return; return;
} }
@ -488,40 +525,15 @@ void AnfExporter::OutputCNodes(std::ofstream &ofs, const std::vector<AnfNodePtr>
continue; continue;
} }
auto iter = tagged_cnodes_.find(node); if (!tagged_cnodes_map.empty()) {
if (iter != tagged_cnodes_.end()) { auto iter = tagged_cnodes_map.find(node);
ofs << "\n#------------------------> " << iter->second << "\n"; if (iter != tagged_cnodes_map.end()) {
ofs << "\n#------------------------> " << iter->second << "\n";
}
} }
auto cnode = node->cast<CNodePtr>(); auto cnode = node->cast<CNodePtr>();
auto &inputs = cnode->inputs(); OutputCNode(ofs, cnode, func_graph, &idx, &apply_map);
std::string op_text = GetAnfNodeText(func_graph, inputs[0], apply_map);
// non-return node
if (node != func_graph->get_return()) {
int apply_idx = idx++;
apply_map[node] = apply_idx;
std::string type_info = GetNodeType(node);
if (type_info == "Undefined") {
ofs << " %" << apply_idx << " = " << op_text << "(";
} else {
ofs << " %" << apply_idx << " : " << type_info << " = " << op_text << "(";
}
} else {
ofs << " " << op_text << "(";
}
for (size_t i = 1; i < inputs.size(); ++i) {
if (i != 1) {
ofs << ", ";
}
AnfNodePtr arg = inputs[i];
ofs << GetAnfNodeText(func_graph, arg, apply_map);
}
ofs << ")";
// output comment
OutputStatementComment(ofs, cnode);
ofs << "\n";
if (label_manage::GetGlobalTraceLabelType() == label_manage::TraceLabelType::kWithUniqueId) { if (label_manage::GetGlobalTraceLabelType() == label_manage::TraceLabelType::kWithUniqueId) {
ofs << trace::GetDebugInfo(cnode->debug_info(), " # ", kSourceLineTipDiscard) << "#" ofs << trace::GetDebugInfo(cnode->debug_info(), " # ", kSourceLineTipDiscard) << "#"
<< label_manage::Label(cnode->debug_info()) << "\n"; << label_manage::Label(cnode->debug_info()) << "\n";
@ -546,7 +558,8 @@ void AnfExporter::OutputOrderList(std::ofstream &ofs, const FuncGraphPtr &func_g
} }
} }
void AnfExporter::ExportOneFuncGraph(std::ofstream &ofs, const FuncGraphPtr &func_graph) { void AnfExporter::ExportOneFuncGraph(std::ofstream &ofs, const FuncGraphPtr &func_graph,
const TaggedNodeMap &tagged_cnodes_map) {
if (func_graph == nullptr) { if (func_graph == nullptr) {
return; return;
} }
@ -569,7 +582,7 @@ void AnfExporter::ExportOneFuncGraph(std::ofstream &ofs, const FuncGraphPtr &fun
ofs << trace::GetDebugInfo(func_graph->debug_info(), "# ", kSourceLineTipDiscard) << "\n"; ofs << trace::GetDebugInfo(func_graph->debug_info(), "# ", kSourceLineTipDiscard) << "\n";
} }
ofs << "funcgraph fg_" << func_graph->debug_info()->get_id(); ofs << "funcgraph fg_" << func_graph->debug_info()->get_id();
// output name of parent of graph if exists // Output name of parent of graph if exists
if (func_graph->parent() != nullptr) { if (func_graph->parent() != nullptr) {
ofs << "[fg_" << func_graph->parent()->debug_info()->get_id() << "]"; ofs << "[fg_" << func_graph->parent()->debug_info()->get_id() << "]";
} }
@ -580,7 +593,7 @@ void AnfExporter::ExportOneFuncGraph(std::ofstream &ofs, const FuncGraphPtr &fun
exported[func_graph] = param_map; exported[func_graph] = param_map;
ofs << (!parameters.empty() ? " " : "") << ") {\n"; ofs << (!parameters.empty() ? " " : "") << ") {\n";
OutputCNodes(ofs, nodes, func_graph); OutputCNodes(ofs, nodes, func_graph, tagged_cnodes_map);
ofs << "}\n"; ofs << "}\n";
@ -600,10 +613,11 @@ void AnfExporter::ExportFuncGraph(const std::string &filename, const FuncGraphPt
param_index = 1; param_index = 1;
TaggedNodeMap tagged_cnodes_map;
func_graph_set.add(func_graph); func_graph_set.add(func_graph);
while (!func_graph_set.empty()) { while (!func_graph_set.empty()) {
FuncGraphPtr fg = *func_graph_set.begin(); FuncGraphPtr fg = *func_graph_set.begin();
ExportOneFuncGraph(ofs, fg); ExportOneFuncGraph(ofs, fg, tagged_cnodes_map);
ofs << "\n\n"; ofs << "\n\n";
(void)func_graph_set.erase(fg); (void)func_graph_set.erase(fg);
} }
@ -612,31 +626,6 @@ void AnfExporter::ExportFuncGraph(const std::string &filename, const FuncGraphPt
ofs.close(); ofs.close();
} }
void AnfExporter::ExportFuncGraph(const std::string &filename, const std::vector<TaggedGraph> &graphs) {
if (graphs.empty()) {
return;
}
std::ofstream ofs(filename);
if (!ofs.is_open()) {
MS_LOG(ERROR) << "Open file '" << filename << "' failed!";
return;
}
param_index = 1;
for (const auto &tagged_graph : graphs) {
tagged_cnodes_ = tagged_graph.second;
ExportOneFuncGraph(ofs, tagged_graph.first);
tagged_cnodes_.clear();
ofs << "\n\n";
}
ofs << "# num of total function graphs: " << graphs.size();
ofs.close();
}
#ifdef ENABLE_DUMP_IR #ifdef ENABLE_DUMP_IR
void ExportIR(const std::string &filename, const FuncGraphPtr &func_graph) { void ExportIR(const std::string &filename, const FuncGraphPtr &func_graph) {
if (func_graph == nullptr) { if (func_graph == nullptr) {
@ -652,21 +641,7 @@ void ExportIR(const std::string &filename, const FuncGraphPtr &func_graph) {
ChangeFileMode(real_filepath.value(), S_IWUSR); ChangeFileMode(real_filepath.value(), S_IWUSR);
AnfExporter exporter; AnfExporter exporter;
exporter.ExportFuncGraph(real_filepath.value(), func_graph); exporter.ExportFuncGraph(real_filepath.value(), func_graph);
// set file mode to read only by user // Set file mode to read only by user
ChangeFileMode(real_filepath.value(), S_IRUSR);
}
void ExportIR(const std::string &filename, const std::vector<TaggedGraph> &graphs) {
auto filepath = pipeline::GetSaveGraphsPathName(Common::AddId(filename, ".dat"));
auto real_filepath = Common::GetRealPath(filepath);
if (!real_filepath.has_value()) {
MS_LOG(ERROR) << "The export ir path: " << filepath << " is not illegal.";
return;
}
ChangeFileMode(real_filepath.value(), S_IWUSR);
AnfExporter exporter("", false);
exporter.ExportFuncGraph(real_filepath.value(), graphs);
// set file mode to read only by user
ChangeFileMode(real_filepath.value(), S_IRUSR); ChangeFileMode(real_filepath.value(), S_IRUSR);
} }
#else #else

View File

@ -72,7 +72,6 @@ class AnfExporter {
virtual ~AnfExporter() {} virtual ~AnfExporter() {}
void ExportFuncGraph(const std::string &filename, const FuncGraphPtr &func_graph); void ExportFuncGraph(const std::string &filename, const FuncGraphPtr &func_graph);
void ExportFuncGraph(const std::string &filename, const std::vector<TaggedGraph> &graphs);
protected: protected:
virtual std::string GetNodeType(const AnfNodePtr &nd); virtual std::string GetNodeType(const AnfNodePtr &nd);
@ -96,21 +95,25 @@ class AnfExporter {
void OutputStatementComment(std::ofstream &ofs, const CNodePtr &node); void OutputStatementComment(std::ofstream &ofs, const CNodePtr &node);
void OutputOrderList(std::ofstream &ofs, const FuncGraphPtr &func_graph); void OutputOrderList(std::ofstream &ofs, const FuncGraphPtr &func_graph);
void OutputCNodeText(std::ofstream &ofs, const CNodePtr &cnode, const FuncGraphPtr &func_graph, int *idx,
std::map<AnfNodePtr, int> *const apply_map);
virtual void OutputCNode(std::ofstream &ofs, const CNodePtr &cnode, const FuncGraphPtr &func_graph, int *idx,
std::map<AnfNodePtr, int> *const apply_map);
void ExportOneFuncGraph(std::ofstream &ofs, const FuncGraphPtr &func_graph, const TaggedNodeMap &tagged_cnodes_map);
OrderedMap<FuncGraphPtr, OrderedMap<AnfNodePtr, int, ParamPtrHasher, ParamPtrEqual>> exported; OrderedMap<FuncGraphPtr, OrderedMap<AnfNodePtr, int, ParamPtrHasher, ParamPtrEqual>> exported;
private: private:
void ExportOneFuncGraph(std::ofstream &ofs, const FuncGraphPtr &func_graph); void OutputCNodes(std::ofstream &ofs, const std::vector<AnfNodePtr> &nodes, const FuncGraphPtr &func_graph,
void OutputCNodes(std::ofstream &ofs, const std::vector<AnfNodePtr> &nodes, const FuncGraphPtr &func_graph); const TaggedNodeMap &tagged_cnodes_map);
int param_index; int param_index;
OrderedSet<FuncGraphPtr> func_graph_set{}; OrderedSet<FuncGraphPtr> func_graph_set{};
bool export_used_ = true; // whether export function graphs used in current exporting function graph bool export_used_ = true; // whether export function graphs used in current exporting function graph
bool check_integrity_ = false; // whether check integrity or not, when dumping ir for loading, must set it to true bool check_integrity_ = false; // whether check integrity or not, when dumping ir for loading, must set it to true
TaggedNodeMap tagged_cnodes_;
}; };
void ExportIR(const std::string &filename, const FuncGraphPtr &func_graph); void ExportIR(const std::string &filename, const FuncGraphPtr &func_graph);
void ExportIR(const std::string &filename, const std::vector<TaggedGraph> &graphs);
std::string GetKernelNodeName(const AnfNodePtr &anf_node); std::string GetKernelNodeName(const AnfNodePtr &anf_node);
} // namespace mindspore } // namespace mindspore

View File

@ -134,12 +134,8 @@ class AnalyzeFailExporter : public AnfExporter {
bool ExportFuncGraph(const std::string &filename, const std::vector<abstract::AnfNodeConfigPtr> &node_config_stack); bool ExportFuncGraph(const std::string &filename, const std::vector<abstract::AnfNodeConfigPtr> &node_config_stack);
private: private:
void ExportOneFuncGraph(std::ofstream &ofs, const FuncGraphPtr &func_graph, const TaggedNodeMap &tagged_cnodes_map);
void OutputCNodes(std::ofstream &ofs, const std::vector<AnfNodePtr> &nodes, const FuncGraphPtr &func_graph,
const TaggedNodeMap &tagged_cnodes_map);
void OutputCNode(std::ofstream &ofs, const CNodePtr &cnode, const FuncGraphPtr &func_graph, int *idx, void OutputCNode(std::ofstream &ofs, const CNodePtr &cnode, const FuncGraphPtr &func_graph, int *idx,
std::map<AnfNodePtr, int> *const apply_map); std::map<AnfNodePtr, int> *const apply_map) override;
std::string GetNodeType(const AnfNodePtr &nd) override; std::string GetNodeType(const AnfNodePtr &nd) override;
AbstractBasePtr GetNodeAbstract(const AnfNodePtr &nd); AbstractBasePtr GetNodeAbstract(const AnfNodePtr &nd);
AnfNodeConfigPtr GetFordwardConfig(const AnfNodeConfigPtr &cfg); AnfNodeConfigPtr GetFordwardConfig(const AnfNodeConfigPtr &cfg);
@ -175,13 +171,17 @@ std::string AnalyzeFailExporter::GetNodeType(const AnfNodePtr &node) {
} }
MS_EXCEPTION_IF_NULL(engine_); MS_EXCEPTION_IF_NULL(engine_);
FuncGraphPtr dummy_call_func_graph = nullptr; try {
auto cfg = engine_->MakeConfig(node, current_context_, dummy_call_func_graph); FuncGraphPtr dummy_call_func_graph = nullptr;
auto ret = abstract::AnalysisResultCacheMgr::GetInstance().GetValue(cfg); auto cfg = engine_->MakeConfig(node, current_context_, dummy_call_func_graph);
if (ret == nullptr) { auto res = abstract::AnalysisResultCacheMgr::GetInstance().GetValue(cfg);
return "Undefined"; if (res != nullptr) {
return GetAbstractStr(res->abstract());
}
} catch (const std::exception &e) {
MS_LOG(INFO) << "Exception: " << e.what();
} }
return GetAbstractStr(ret->abstract()); return "Undefined";
} }
AbstractBasePtr AnalyzeFailExporter::GetNodeAbstract(const AnfNodePtr &node) { AbstractBasePtr AnalyzeFailExporter::GetNodeAbstract(const AnfNodePtr &node) {
@ -189,10 +189,15 @@ AbstractBasePtr AnalyzeFailExporter::GetNodeAbstract(const AnfNodePtr &node) {
return nullptr; return nullptr;
} }
MS_EXCEPTION_IF_NULL(engine_); MS_EXCEPTION_IF_NULL(engine_);
FuncGraphPtr dummy_call_func_graph = nullptr; try {
auto cfg = engine_->MakeConfig(node, current_context_, dummy_call_func_graph); FuncGraphPtr dummy_call_func_graph = nullptr;
auto ret = abstract::AnalysisResultCacheMgr::GetInstance().GetValue(cfg); auto cfg = engine_->MakeConfig(node, current_context_, dummy_call_func_graph);
return ret == nullptr ? nullptr : ret->abstract(); auto res = abstract::AnalysisResultCacheMgr::GetInstance().GetValue(cfg);
return res == nullptr ? nullptr : res->abstract();
} catch (const std::exception &e) {
MS_LOG(INFO) << "Exception: " << e.what();
}
return nullptr;
} }
AnfNodeConfigPtr AnalyzeFailExporter::GetFordwardConfig(const AnfNodeConfigPtr &cfg) { AnfNodeConfigPtr AnalyzeFailExporter::GetFordwardConfig(const AnfNodeConfigPtr &cfg) {
@ -213,12 +218,17 @@ void AnalyzeFailExporter::ProcessFuncGraphCall(const CNodePtr &node, std::string
MS_LOG(ERROR) << "Node is nullptr"; MS_LOG(ERROR) << "Node is nullptr";
return; return;
} }
FuncGraphPtr dummy_call_func_graph = nullptr; CNodePtr cnode = nullptr;
auto cfg = engine_->MakeConfig(node, current_context_, dummy_call_func_graph); try {
cfg = GetFordwardConfig(cfg); FuncGraphPtr dummy_call_func_graph = nullptr;
auto cnode = dyn_cast<CNode>(cfg->node()); auto cfg = engine_->MakeConfig(node, current_context_, dummy_call_func_graph);
cfg = GetFordwardConfig(cfg);
cnode = dyn_cast<CNode>(cfg->node());
} catch (const std::exception &e) {
MS_LOG(INFO) << "Exception: " << e.what();
}
if (cnode == nullptr) { if (cnode == nullptr) {
MS_LOG(ERROR) << "CNode is nullptr"; MS_LOG(INFO) << "CNode is nullptr";
return; return;
} }
@ -259,7 +269,7 @@ void AnalyzeFailExporter::OutputStatementComment(std::ofstream &ofs, const CNode
return; return;
} }
// output type of each input argument // Output type of each input argument
auto &inputs = node->inputs(); auto &inputs = node->inputs();
if (inputs.size() > 1) { if (inputs.size() > 1) {
ofs << " #("; ofs << " #(";
@ -272,7 +282,7 @@ void AnalyzeFailExporter::OutputStatementComment(std::ofstream &ofs, const CNode
} }
ofs << ")"; ofs << ")";
} }
// output other comment, map the graph name to original representation(containing unicode character) // Output other comment, map the graph name to original representation(containing unicode character)
std::ostringstream comment; std::ostringstream comment;
comment << " #"; comment << " #";
bool has_comment = false; bool has_comment = false;
@ -298,109 +308,17 @@ void AnalyzeFailExporter::OutputStatementComment(std::ofstream &ofs, const CNode
void AnalyzeFailExporter::OutputCNode(std::ofstream &ofs, const CNodePtr &cnode, const FuncGraphPtr &func_graph, void AnalyzeFailExporter::OutputCNode(std::ofstream &ofs, const CNodePtr &cnode, const FuncGraphPtr &func_graph,
int *idx, std::map<AnfNodePtr, int> *const apply_map) { int *idx, std::map<AnfNodePtr, int> *const apply_map) {
auto &inputs = cnode->inputs(); OutputCNodeText(ofs, cnode, func_graph, idx, apply_map);
std::string op_text = GetAnfNodeText(func_graph, inputs[0], *apply_map); // Process function graph call
// non-return node
if (cnode != func_graph->get_return()) {
int apply_idx = (*idx)++;
(*apply_map)[cnode] = apply_idx;
std::string type_info = GetNodeType(cnode);
if (type_info == "Undefined") {
ofs << " %" << apply_idx << " = " << op_text << "(";
} else {
ofs << " %" << apply_idx << " : " << type_info << " = " << op_text << "(";
}
} else {
ofs << " " << op_text << "(";
}
for (size_t i = 1; i < inputs.size(); ++i) {
if (i != 1) {
ofs << ", ";
}
AnfNodePtr arg = inputs[i];
ofs << GetAnfNodeText(func_graph, arg, *apply_map);
}
ofs << ")";
// process function graph call
std::string op_comment; std::string op_comment;
ProcessFuncGraphCall(cnode, &op_comment); ProcessFuncGraphCall(cnode, &op_comment);
if (!op_comment.empty()) { if (!op_comment.empty()) {
auto &inputs = cnode->inputs();
ofs << " #" << GetAnfNodeText(func_graph, inputs[0], *apply_map) << ".prototype = " << op_comment; ofs << " #" << GetAnfNodeText(func_graph, inputs[0], *apply_map) << ".prototype = " << op_comment;
} }
// output comment // Output comment
OutputStatementComment(ofs, cnode); OutputStatementComment(ofs, cnode);
ofs << "\n"; ofs << "\n";
if (label_manage::GetGlobalTraceLabelType() == label_manage::TraceLabelType::kWithUniqueId) {
ofs << trace::GetDebugInfo(cnode->debug_info(), " # ", kSourceLineTipDiscard) << "#"
<< label_manage::Label(cnode->debug_info()) << "\n";
} else {
ofs << trace::GetDebugInfo(cnode->debug_info(), " # ", kSourceLineTipDiscard) << "\n";
}
}
void AnalyzeFailExporter::OutputCNodes(std::ofstream &ofs, const std::vector<AnfNodePtr> &nodes,
const FuncGraphPtr &func_graph, const TaggedNodeMap &tagged_cnodes_map) {
if (func_graph == nullptr) {
return;
}
int idx = 1;
std::map<AnfNodePtr, int> apply_map;
for (const AnfNodePtr &node : nodes) {
MS_EXCEPTION_IF_NULL(node);
if (!node->isa<CNode>()) {
continue;
}
auto iter = tagged_cnodes_map.find(node);
if (iter != tagged_cnodes_map.end()) {
ofs << "\n#------------------------> " << iter->second << "\n";
}
auto cnode = node->cast<CNodePtr>();
OutputCNode(ofs, cnode, func_graph, &idx, &apply_map);
}
}
void AnalyzeFailExporter::ExportOneFuncGraph(std::ofstream &ofs, const FuncGraphPtr &func_graph,
const TaggedNodeMap &tagged_cnodes_map) {
if (func_graph == nullptr) {
return;
}
std::vector<AnfNodePtr> nodes = TopoSort(func_graph->get_return(), SuccIncoming, AlwaysInclude);
std::vector<AnfNodePtr> parameters = func_graph->parameters();
OrderedMap<AnfNodePtr, int, ParamPtrHasher, ParamPtrEqual> param_map;
ofs << "# [No." << (exported.size() + 1) << "] " << func_graph->DumpText();
if (current_context_ != nullptr) {
ofs << " @ctx.addr=" << current_context_.get();
}
ofs << "\n";
if (label_manage::GetGlobalTraceLabelType() == label_manage::TraceLabelType::kWithUniqueId) {
ofs << trace::GetDebugInfo(func_graph->debug_info(), "# ", kSourceLineTipDiscard) << "#"
<< label_manage::Label(func_graph->debug_info()) << "\n";
} else {
ofs << trace::GetDebugInfo(func_graph->debug_info(), "# ", kSourceLineTipDiscard) << "\n";
}
ofs << "funcgraph fg_" << func_graph->debug_info()->get_id();
// output name of parent of graph if exists
if (func_graph->parent() != nullptr) {
ofs << "[fg_" << func_graph->parent()->debug_info()->get_id() << "]";
}
ofs << "(\n";
OutputParameters(ofs, parameters, &param_map);
exported[func_graph] = param_map;
ofs << (!parameters.empty() ? " " : "") << ") {\n";
OutputCNodes(ofs, nodes, func_graph, tagged_cnodes_map);
ofs << "}\n";
} }
bool AnalyzeFailExporter::ExportFuncGraph(const std::string &filename, bool AnalyzeFailExporter::ExportFuncGraph(const std::string &filename,
@ -495,9 +413,9 @@ void GetEvalStackInfo(std::ostringstream &oss) {
MS_LOG(INFO) << "Get graph analysis information *end*"; MS_LOG(INFO) << "Get graph analysis information *end*";
} }
// trace the graph evaluator stack // Trace the graph evaluator stack
thread_local static std::stack<std::pair<abstract::AnalysisContextPtr, abstract::AnfNodeConfigPtr>> graph_infer_stack; thread_local static std::stack<std::pair<abstract::AnalysisContextPtr, abstract::AnfNodeConfigPtr>> graph_infer_stack;
// trace the cnode infer debug info // Trace the cnode infer debug info
thread_local static std::vector<abstract::AnfNodeConfigPtr> cnode_debug_stack{}; thread_local static std::vector<abstract::AnfNodeConfigPtr> cnode_debug_stack{};
void TraceGraphEvalEnter(const abstract::AnalysisContextPtr &context, const abstract::AnfNodeConfigPtr &node) { void TraceGraphEvalEnter(const abstract::AnalysisContextPtr &context, const abstract::AnfNodeConfigPtr &node) {

View File

@ -33,12 +33,13 @@ void HealthPointMgr::Clear() {
void HealthPointMgr::HandleException() { void HealthPointMgr::HandleException() {
// Just record the first exception information. // Just record the first exception information.
if (!StaticAnalysisException::Instance().HasException()) { if (!StaticAnalysisException::Instance().HasException()) {
std::ostringstream oss;
trace::GetEvalStackInfo(oss);
if (!oss.str().empty()) {
MS_LOG(ERROR) << oss.str();
}
StaticAnalysisException::Instance().SetException(); StaticAnalysisException::Instance().SetException();
try {
// We want to call the LogWrite::^() here.
MS_LOG(EXCEPTION) << "Exception happened, check the information as below.";
} catch (const std::exception &e) {
// Ignored.
}
} }
// Free all the locks. Let all the threads continue to run. // Free all the locks. Let all the threads continue to run.
std::lock_guard<std::recursive_mutex> lock(lock_); std::lock_guard<std::recursive_mutex> lock(lock_);

View File

@ -140,14 +140,18 @@ void LogWriter::operator<(const LogStream &stream) const noexcept {
void LogWriter::operator^(const LogStream &stream) const { void LogWriter::operator^(const LogStream &stream) const {
std::ostringstream msg; std::ostringstream msg;
msg << stream.sstream_->rdbuf(); msg << stream.sstream_->rdbuf();
OutputLog(msg);
std::ostringstream oss; std::ostringstream oss;
oss << location_.file_ << ":" << location_.line_ << " " << location_.func_ << "] "; oss << location_.file_ << ":" << location_.line_ << " " << location_.func_ << "] ";
oss << msg.str(); oss << msg.str();
if (trace_provider_ != nullptr) { thread_local bool running = false;
trace_provider_(oss); if (!running) {
running = true;
OutputLog(msg);
if (trace_provider_ != nullptr) {
trace_provider_(oss);
}
running = false;
} }
if (exception_handler_ != nullptr) { if (exception_handler_ != nullptr) {

View File

@ -180,6 +180,7 @@ class LogWriter {
static void set_exception_handler(ExceptionHandler exception_handler) { exception_handler_ = exception_handler; } static void set_exception_handler(ExceptionHandler exception_handler) { exception_handler_ = exception_handler; }
static void set_trace_provider(TraceProvider trace_provider) { trace_provider_ = trace_provider; } static void set_trace_provider(TraceProvider trace_provider) { trace_provider_ = trace_provider; }
static TraceProvider trace_provider() { return trace_provider_; }
private: private:
void OutputLog(const std::ostringstream &msg) const; void OutputLog(const std::ostringstream &msg) const;