forked from mindspore-Ecosystem/mindspore
!19604 Record and Dump func graph call stack with context info.
Merge pull request !19604 from 张清华/opt0
This commit is contained in:
commit
1a2fbdb6ac
|
@ -65,7 +65,7 @@ struct ParamPtrHasher {
|
|||
class AnfExporter {
|
||||
public:
|
||||
explicit AnfExporter(bool export_used = true, bool check_integrity = false)
|
||||
: param_index(-1), export_used_(export_used), check_integrity_(check_integrity) {
|
||||
: param_index(1), export_used_(export_used), check_integrity_(check_integrity) {
|
||||
func_graph_set.clear();
|
||||
exported.clear();
|
||||
}
|
||||
|
@ -90,17 +90,20 @@ class AnfExporter {
|
|||
std::string GetMetaFuncGraphText(const MetaFuncGraphPtr &meta_func_graph);
|
||||
std::string GetAnfNodeText(const FuncGraphPtr &func_graph, const AnfNodePtr &node,
|
||||
const std::map<AnfNodePtr, int> &apply_map);
|
||||
virtual void ExportOneFuncGraph(std::ofstream &ofs, const FuncGraphPtr &func_graph);
|
||||
void OutputParameters(std::ofstream &ofs, const std::vector<AnfNodePtr> ¶meters,
|
||||
OrderedMap<AnfNodePtr, int, ParamPtrHasher, ParamPtrEqual> *param_map);
|
||||
|
||||
void OutputStatementComment(std::ofstream &ofs, const CNodePtr &node);
|
||||
virtual void OutputCNodes(std::ofstream &ofs, const std::vector<AnfNodePtr> &nodes, const FuncGraphPtr &func_graph);
|
||||
void OutputOrderList(std::ofstream &ofs, const FuncGraphPtr &func_graph);
|
||||
|
||||
OrderedMap<FuncGraphPtr, OrderedMap<AnfNodePtr, int, ParamPtrHasher, ParamPtrEqual>> exported;
|
||||
|
||||
private:
|
||||
void ExportOneFuncGraph(std::ofstream &ofs, const FuncGraphPtr &func_graph);
|
||||
void OutputCNodes(std::ofstream &ofs, const std::vector<AnfNodePtr> &nodes, const FuncGraphPtr &func_graph);
|
||||
|
||||
int param_index;
|
||||
OrderedSet<FuncGraphPtr> func_graph_set{};
|
||||
OrderedMap<FuncGraphPtr, OrderedMap<AnfNodePtr, int, ParamPtrHasher, ParamPtrEqual>> exported;
|
||||
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
|
||||
TaggedNodeMap tagged_cnodes_;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <fstream>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
@ -82,85 +83,75 @@ std::string GetGraphParamString(const FuncGraphPtr &graph, abstract::AbstractBas
|
|||
}
|
||||
|
||||
void DumpInferStack(std::ostringstream &oss) {
|
||||
auto &infer_stack = GetCurrenGraphEvalStack();
|
||||
if (infer_stack.empty()) {
|
||||
auto &graph_stack = GetCurrenGraphEvalStack();
|
||||
if (graph_stack.empty()) {
|
||||
return;
|
||||
}
|
||||
std::vector<std::pair<abstract::EvaluatorPtr, abstract::AnfNodeConfigPtr>> infer_vec;
|
||||
while (!infer_stack.empty()) {
|
||||
auto top = infer_stack.top();
|
||||
std::vector<std::pair<abstract::AnalysisContextPtr, abstract::AnfNodeConfigPtr>> infer_vec;
|
||||
while (!graph_stack.empty()) {
|
||||
auto top = graph_stack.top();
|
||||
infer_vec.push_back(top);
|
||||
infer_stack.pop();
|
||||
graph_stack.pop();
|
||||
}
|
||||
std::reverse(infer_vec.begin(), infer_vec.end());
|
||||
int index = 0;
|
||||
for (auto &item : infer_vec) {
|
||||
auto graph_infer = std::dynamic_pointer_cast<abstract::BaseFuncGraphEvaluator>(item.first);
|
||||
if (graph_infer == nullptr) {
|
||||
MS_LOG(WARNING) << "DumpInferStack failed, got null graph evaluator";
|
||||
infer_vec.clear();
|
||||
break;
|
||||
for (const auto &item : infer_vec) {
|
||||
auto context = item.first;
|
||||
if (context == nullptr) {
|
||||
MS_LOG(EXCEPTION) << "DumpInferStack failed, got null graph context";
|
||||
}
|
||||
auto graph_context = graph_infer->parent_context();
|
||||
if (graph_context == nullptr) {
|
||||
MS_LOG(INFO) << "Null context continue";
|
||||
auto graph = context->func_graph();
|
||||
if (graph == nullptr) { // Top context.
|
||||
continue;
|
||||
}
|
||||
auto graph = graph_context->func_graph();
|
||||
if (graph == nullptr) {
|
||||
continue;
|
||||
}
|
||||
auto args_spec_list = graph_context->args_spec_list();
|
||||
auto args_spec_list = context->args_spec_list();
|
||||
oss << " #" << index++ << " " << GetGraphParamString(graph, args_spec_list);
|
||||
}
|
||||
}
|
||||
|
||||
void TraceGraphEval() {
|
||||
auto &infer_stack = GetCurrenGraphEvalStack();
|
||||
std::ostringstream oss;
|
||||
if (infer_stack.empty()) {
|
||||
MS_LOG(ERROR) << "Length of analysis graph stack is empty.";
|
||||
auto &graph_stack = GetCurrenGraphEvalStack();
|
||||
if (graph_stack.empty()) {
|
||||
MS_LOG(INFO) << "Length of analysis graph stack is empty.";
|
||||
return;
|
||||
}
|
||||
MS_LOG(ERROR) << "\n*******************************graph evaluate stack**********************************";
|
||||
std::ostringstream oss;
|
||||
oss << std::endl;
|
||||
DumpInferStack(oss);
|
||||
MS_LOG(ERROR) << oss.str();
|
||||
MS_LOG(ERROR) << "\n*************************************************************************************";
|
||||
}
|
||||
|
||||
class AnalyzedFuncGraphExporter : public AnfExporter {
|
||||
class AnalyzeFailExporter : public AnfExporter {
|
||||
public:
|
||||
AnalyzedFuncGraphExporter() : AnfExporter(true, false) {}
|
||||
~AnalyzedFuncGraphExporter() override = default;
|
||||
AnalyzeFailExporter() : AnfExporter(true, false) {}
|
||||
~AnalyzeFailExporter() override = default;
|
||||
|
||||
bool ExportFuncGraph(const std::string &filename, const std::vector<abstract::AnfNodeConfigPtr> &node_cfgs);
|
||||
bool ExportFuncGraph(const std::string &filename, const std::vector<abstract::AnfNodeConfigPtr> &node_cfg_stack);
|
||||
|
||||
void ExportOneFuncGraph(std::ofstream &ofs, const FuncGraphPtr &func_graph) override;
|
||||
void OutputCNodes(std::ofstream &ofs, const std::vector<AnfNodePtr> &nodes, const FuncGraphPtr &func_graph) override;
|
||||
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,
|
||||
std::map<AnfNodePtr, int> *const apply_map);
|
||||
|
||||
private:
|
||||
std::string GetNodeType(const AnfNodePtr &nd) override;
|
||||
AbstractBasePtr GetNodeAbstract(const AnfNodePtr &nd);
|
||||
AnfNodeConfigPtr GetFordwardConfigPtr(const AnfNodeConfigPtr &cfg);
|
||||
std::vector<AnalysisContextPtr> ProcessFuncGraphCall(const CNodePtr &node, std::string *const op_comment);
|
||||
void OutputStatementComment(std::ofstream &ofs, const CNodePtr &node, const std::vector<AnalysisContextPtr> &ctxs);
|
||||
|
||||
// key: context, val: whether the context has already been printed
|
||||
std::unordered_map<AnalysisContextPtr, bool> context_map_;
|
||||
std::vector<AnalysisContextPtr> context_vec_;
|
||||
void ProcessFuncGraphCall(const CNodePtr &node, std::string *const op_comment);
|
||||
void OutputStatementComment(std::ofstream &ofs, const CNodePtr &node);
|
||||
|
||||
AnalysisContextPtr cur_ctx_ = nullptr;
|
||||
AnalysisEnginePtr engine_ = nullptr;
|
||||
};
|
||||
|
||||
std::unordered_map<FuncGraphPtr, TaggedNodeMap> CalcTaggedFuncGraphs() {
|
||||
std::unordered_map<FuncGraphPtr, TaggedNodeMap> CalcTaggedFuncGraphs(
|
||||
const std::vector<abstract::AnfNodeConfigPtr> &node_cfg_stack) {
|
||||
std::unordered_map<FuncGraphPtr, TaggedNodeMap> tagged_func_graphs;
|
||||
auto &list = GetCNodeDebugStack();
|
||||
for (size_t i = 0; i < list.size(); ++i) {
|
||||
auto node_cfg = list[i];
|
||||
for (size_t i = 0; i < node_cfg_stack.size(); ++i) {
|
||||
auto node_cfg = node_cfg_stack[i];
|
||||
MS_EXCEPTION_IF_NULL(node_cfg);
|
||||
auto fg = node_cfg->context()->func_graph();
|
||||
MS_EXCEPTION_IF_NULL(fg);
|
||||
|
@ -171,11 +162,11 @@ std::unordered_map<FuncGraphPtr, TaggedNodeMap> CalcTaggedFuncGraphs() {
|
|||
}
|
||||
|
||||
bool OutputAnalyzedGraphWithType(const string &file_path) {
|
||||
AnalyzedFuncGraphExporter exporter;
|
||||
AnalyzeFailExporter exporter;
|
||||
return exporter.ExportFuncGraph(file_path, GetCNodeDebugStack());
|
||||
}
|
||||
|
||||
std::string AnalyzedFuncGraphExporter::GetNodeType(const AnfNodePtr &node) {
|
||||
std::string AnalyzeFailExporter::GetNodeType(const AnfNodePtr &node) {
|
||||
if (cur_ctx_ == nullptr) {
|
||||
return AnfExporter::GetNodeType(node);
|
||||
}
|
||||
|
@ -189,7 +180,7 @@ std::string AnalyzedFuncGraphExporter::GetNodeType(const AnfNodePtr &node) {
|
|||
return GetAbstractStr(ret->abstract());
|
||||
}
|
||||
|
||||
AbstractBasePtr AnalyzedFuncGraphExporter::GetNodeAbstract(const AnfNodePtr &node) {
|
||||
AbstractBasePtr AnalyzeFailExporter::GetNodeAbstract(const AnfNodePtr &node) {
|
||||
if (cur_ctx_ == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -199,7 +190,7 @@ AbstractBasePtr AnalyzedFuncGraphExporter::GetNodeAbstract(const AnfNodePtr &nod
|
|||
return ret == nullptr ? nullptr : ret->abstract();
|
||||
}
|
||||
|
||||
AnfNodeConfigPtr AnalyzedFuncGraphExporter::GetFordwardConfigPtr(const AnfNodeConfigPtr &cfg) {
|
||||
AnfNodeConfigPtr AnalyzeFailExporter::GetFordwardConfigPtr(const AnfNodeConfigPtr &cfg) {
|
||||
AnfNodeConfigPtr cur_cfg = cfg;
|
||||
auto iter = engine_->anfnode_config_map().find(cur_cfg);
|
||||
while (iter != engine_->anfnode_config_map().end()) {
|
||||
|
@ -212,22 +203,18 @@ AnfNodeConfigPtr AnalyzedFuncGraphExporter::GetFordwardConfigPtr(const AnfNodeCo
|
|||
return cur_cfg;
|
||||
}
|
||||
|
||||
std::vector<AnalysisContextPtr> AnalyzedFuncGraphExporter::ProcessFuncGraphCall(const CNodePtr &node,
|
||||
std::string *const op_comment) {
|
||||
std::vector<AnalysisContextPtr> ret_contexts;
|
||||
void AnalyzeFailExporter::ProcessFuncGraphCall(const CNodePtr &node, std::string *const op_comment) {
|
||||
if (node == nullptr) {
|
||||
return ret_contexts;
|
||||
return;
|
||||
}
|
||||
auto cfg = engine_->MakeConfig(node, cur_ctx_);
|
||||
cfg = GetFordwardConfigPtr(cfg);
|
||||
auto cnode = dyn_cast<CNode>(cfg->node());
|
||||
if (cnode == nullptr) {
|
||||
MS_LOG(DEBUG) << "CNode is nullptr";
|
||||
return ret_contexts;
|
||||
return;
|
||||
}
|
||||
|
||||
ret_contexts.resize(cnode->size());
|
||||
|
||||
const auto &inputs = cnode->inputs();
|
||||
for (size_t i = 0; i < inputs.size(); ++i) {
|
||||
auto op_abs = GetNodeAbstract(inputs[i]);
|
||||
|
@ -256,29 +243,11 @@ std::vector<AnalysisContextPtr> AnalyzedFuncGraphExporter::ProcessFuncGraphCall(
|
|||
oss << ") -> " << GetAbstractStr(func->output()) << " ";
|
||||
*op_comment = oss.str();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
auto evaluator = engine_->GetEvaluatorFor(dyn_cast<abstract::AbstractFunction>(op_abs));
|
||||
if (!evaluator->isa<abstract::BaseFuncGraphEvaluator>()) {
|
||||
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<abstract::BaseFuncGraphEvaluator>(evaluator);
|
||||
auto ctx = base_fg_evaluator->parent_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;
|
||||
}
|
||||
|
||||
void AnalyzedFuncGraphExporter::OutputStatementComment(std::ofstream &ofs, const CNodePtr &node,
|
||||
const std::vector<AnalysisContextPtr> &ctxs) {
|
||||
void AnalyzeFailExporter::OutputStatementComment(std::ofstream &ofs, const CNodePtr &node) {
|
||||
if (node == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
@ -313,9 +282,6 @@ void AnalyzedFuncGraphExporter::OutputStatementComment(std::ofstream &ofs, const
|
|||
FuncGraphPtr fg = GetValueNode<FuncGraphPtr>(arg);
|
||||
std::string func_graph_id = fg->debug_info()->get_id();
|
||||
comment << " fg_" << func_graph_id << "=" << fg->ToString();
|
||||
if (ctxs.size() > i && ctxs[i] != nullptr) {
|
||||
comment << "(@ctx.addr=" << ctxs[i].get() << ")";
|
||||
}
|
||||
}
|
||||
if (has_comment) {
|
||||
ofs << comment.str();
|
||||
|
@ -323,8 +289,8 @@ void AnalyzedFuncGraphExporter::OutputStatementComment(std::ofstream &ofs, const
|
|||
ofs << " #scope: " << node->scope()->name();
|
||||
}
|
||||
|
||||
void AnalyzedFuncGraphExporter::OutputCNode(std::ofstream &ofs, const CNodePtr &cnode, const FuncGraphPtr &func_graph,
|
||||
int *idx, std::map<AnfNodePtr, int> *const apply_map) {
|
||||
void AnalyzeFailExporter::OutputCNode(std::ofstream &ofs, const CNodePtr &cnode, const FuncGraphPtr &func_graph,
|
||||
int *idx, std::map<AnfNodePtr, int> *const apply_map) {
|
||||
auto &inputs = cnode->inputs();
|
||||
std::string op_text = GetAnfNodeText(func_graph, inputs[0], *apply_map);
|
||||
// non-return node
|
||||
|
@ -352,17 +318,12 @@ void AnalyzedFuncGraphExporter::OutputCNode(std::ofstream &ofs, const CNodePtr &
|
|||
|
||||
// process function graph call
|
||||
std::string op_comment;
|
||||
auto contexts = ProcessFuncGraphCall(cnode, &op_comment);
|
||||
AnalysisContextPtr ctx = contexts.empty() ? nullptr : contexts[0];
|
||||
|
||||
ProcessFuncGraphCall(cnode, &op_comment);
|
||||
if (!op_comment.empty()) {
|
||||
ofs << " #" << GetAnfNodeText(func_graph, inputs[0], *apply_map) << ".prototype = " << op_comment;
|
||||
}
|
||||
// output comment
|
||||
OutputStatementComment(ofs, cnode, contexts);
|
||||
if (ctx != nullptr) {
|
||||
ofs << " @ctx.addr=" << ctx.get();
|
||||
}
|
||||
OutputStatementComment(ofs, cnode);
|
||||
ofs << "\n";
|
||||
|
||||
if (label_manage::GetGlobalTraceLabelType() == label_manage::TraceLabelType::kWithUniqueId) {
|
||||
|
@ -373,8 +334,8 @@ void AnalyzedFuncGraphExporter::OutputCNode(std::ofstream &ofs, const CNodePtr &
|
|||
}
|
||||
}
|
||||
|
||||
void AnalyzedFuncGraphExporter::OutputCNodes(std::ofstream &ofs, const std::vector<AnfNodePtr> &nodes,
|
||||
const FuncGraphPtr &func_graph) {
|
||||
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;
|
||||
}
|
||||
|
@ -387,8 +348,8 @@ void AnalyzedFuncGraphExporter::OutputCNodes(std::ofstream &ofs, const std::vect
|
|||
continue;
|
||||
}
|
||||
|
||||
auto iter = tagged_cnodes_.find(node);
|
||||
if (iter != tagged_cnodes_.end()) {
|
||||
auto iter = tagged_cnodes_map.find(node);
|
||||
if (iter != tagged_cnodes_map.end()) {
|
||||
ofs << "\n#------------------------> " << iter->second << "\n";
|
||||
}
|
||||
|
||||
|
@ -397,7 +358,8 @@ void AnalyzedFuncGraphExporter::OutputCNodes(std::ofstream &ofs, const std::vect
|
|||
}
|
||||
}
|
||||
|
||||
void AnalyzedFuncGraphExporter::ExportOneFuncGraph(std::ofstream &ofs, const FuncGraphPtr &func_graph) {
|
||||
void AnalyzeFailExporter::ExportOneFuncGraph(std::ofstream &ofs, const FuncGraphPtr &func_graph,
|
||||
const TaggedNodeMap &tagged_cnodes_map) {
|
||||
if (func_graph == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
@ -429,74 +391,50 @@ void AnalyzedFuncGraphExporter::ExportOneFuncGraph(std::ofstream &ofs, const Fun
|
|||
exported[func_graph] = param_map;
|
||||
ofs << (!parameters.empty() ? " " : "") << ") {\n";
|
||||
|
||||
OutputCNodes(ofs, nodes, func_graph);
|
||||
OutputCNodes(ofs, nodes, func_graph, tagged_cnodes_map);
|
||||
|
||||
ofs << "}\n";
|
||||
}
|
||||
|
||||
bool AnalyzedFuncGraphExporter::ExportFuncGraph(const std::string &filename,
|
||||
const std::vector<abstract::AnfNodeConfigPtr> &node_cfgs) {
|
||||
if (node_cfgs.empty()) {
|
||||
bool AnalyzeFailExporter::ExportFuncGraph(const std::string &filename,
|
||||
const std::vector<abstract::AnfNodeConfigPtr> &node_cfg_stack) {
|
||||
if (node_cfg_stack.empty()) {
|
||||
MS_LOG(DEBUG) << "Node configs is empty";
|
||||
return false;
|
||||
}
|
||||
|
||||
context_map_.clear();
|
||||
context_vec_.clear();
|
||||
|
||||
std::ofstream ofs(filename);
|
||||
if (!ofs.is_open()) {
|
||||
MS_LOG(ERROR) << "Open file '" << filename << "' failed!";
|
||||
return false;
|
||||
}
|
||||
|
||||
param_index = 1;
|
||||
auto tagged_func_graphs = CalcTaggedFuncGraphs();
|
||||
|
||||
// 1. Output graph on the analysis stack
|
||||
for (const auto &node_cfg : node_cfgs) {
|
||||
auto tagged_func_graphs = CalcTaggedFuncGraphs(node_cfg_stack);
|
||||
std::unordered_set<FuncGraphPtr> printed_func_graphs; // Check if func graph has been printed.
|
||||
// Output graph on the analysis stack
|
||||
for (const auto &node_cfg : node_cfg_stack) {
|
||||
auto ctx = node_cfg->context();
|
||||
auto fg = ctx->func_graph();
|
||||
if (fg == nullptr) {
|
||||
MS_LOG(ERROR) << "FuncGraph is null, context: " << node_cfg->context()->ToString();
|
||||
continue;
|
||||
}
|
||||
if (printed_func_graphs.find(fg) != printed_func_graphs.end()) {
|
||||
continue;
|
||||
}
|
||||
printed_func_graphs.emplace(fg);
|
||||
|
||||
if (engine_ == nullptr) {
|
||||
engine_ = node_cfg->engine();
|
||||
}
|
||||
if (context_map_.insert({ctx, false}).second) {
|
||||
context_vec_.push_back(ctx);
|
||||
}
|
||||
// If the graph has already been printed
|
||||
if (context_map_[ctx]) {
|
||||
continue;
|
||||
}
|
||||
context_map_[ctx] = true;
|
||||
|
||||
auto fg = ctx->func_graph();
|
||||
|
||||
// Set current context
|
||||
cur_ctx_ = ctx;
|
||||
tagged_cnodes_ = tagged_func_graphs[fg];
|
||||
ExportOneFuncGraph(ofs, fg);
|
||||
cur_ctx_ = ctx; // Set current context.
|
||||
ExportOneFuncGraph(ofs, fg, tagged_func_graphs[fg]);
|
||||
ofs << "\n\n";
|
||||
}
|
||||
|
||||
tagged_cnodes_.clear();
|
||||
|
||||
// Print separator between function graphs on analyzed graph call stack and others
|
||||
ofs << "#===============================================================================\n\n\n";
|
||||
|
||||
// 2. Output other graphs
|
||||
size_t ctx_idx = 0;
|
||||
while (ctx_idx < context_vec_.size()) {
|
||||
auto ctx = context_vec_[ctx_idx++];
|
||||
if (context_map_[ctx]) {
|
||||
continue;
|
||||
}
|
||||
context_map_[ctx] = true;
|
||||
cur_ctx_ = ctx;
|
||||
ExportOneFuncGraph(ofs, ctx->func_graph());
|
||||
ofs << "\n\n";
|
||||
}
|
||||
|
||||
ofs << "# num of total function graphs: " << context_map_.size() << "\n";
|
||||
|
||||
ofs << "#===============================================================================\n";
|
||||
ofs << "# num of function graphs printed: " << printed_func_graphs.size() << "/" << node_cfg_stack.size() << "\n";
|
||||
ofs.close();
|
||||
return true;
|
||||
}
|
||||
|
@ -505,7 +443,7 @@ void GetEvalStackInfo(std::ostringstream &oss) {
|
|||
MS_LOG(INFO) << "Get graph analysis information begin";
|
||||
auto stack = GetCNodeDebugStack();
|
||||
if (stack.empty()) {
|
||||
MS_LOG(ERROR) << "Length of analysis information stack is empty.";
|
||||
MS_LOG(INFO) << "Length of analysis information stack is empty.";
|
||||
return;
|
||||
}
|
||||
static int fileNumber = 0;
|
||||
|
@ -553,26 +491,26 @@ void GetEvalStackInfo(std::ostringstream &oss) {
|
|||
}
|
||||
|
||||
// trace the graph evaluator stack
|
||||
thread_local static std::stack<std::pair<abstract::EvaluatorPtr, 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
|
||||
thread_local static std::vector<abstract::AnfNodeConfigPtr> cnode_debug_stack{};
|
||||
|
||||
void TraceGraphEvalEnter(const abstract::EvaluatorPtr &eval, const abstract::AnfNodeConfigPtr &node) {
|
||||
if (eval == nullptr) {
|
||||
MS_LOG(EXCEPTION) << "GraphInferEnter got null eval";
|
||||
}
|
||||
if (eval->isa<abstract::FuncGraphEvaluator>() || eval->isa<abstract::MetaFuncGraphEvaluator>()) {
|
||||
(void)graph_infer_stack.emplace(std::pair<abstract::EvaluatorPtr, abstract::AnfNodeConfigPtr>(eval, node));
|
||||
void TraceGraphEvalEnter(const abstract::AnalysisContextPtr &context, const abstract::AnfNodeConfigPtr &node) {
|
||||
if (context == nullptr) {
|
||||
MS_LOG(EXCEPTION) << "GraphInferEnter got null context";
|
||||
}
|
||||
(void)graph_infer_stack.emplace(std::pair<abstract::AnalysisContextPtr, abstract::AnfNodeConfigPtr>(context, node));
|
||||
}
|
||||
|
||||
void TraceGraphEvalLeave(const abstract::EvaluatorPtr &eval) {
|
||||
if (eval == nullptr) {
|
||||
MS_LOG(EXCEPTION) << "GraphInferEnter got null eval";
|
||||
void TraceGraphEvalLeave(const abstract::AnalysisContextPtr &context) {
|
||||
if (context == nullptr || graph_infer_stack.empty()) {
|
||||
MS_LOG(EXCEPTION) << "The context is null, or call stack is empty.";
|
||||
}
|
||||
if (eval->isa<abstract::FuncGraphEvaluator>() || eval->isa<abstract::MetaFuncGraphEvaluator>()) {
|
||||
graph_infer_stack.pop();
|
||||
if (context != graph_infer_stack.top().first) {
|
||||
MS_LOG(EXCEPTION) << "Different context: " << context->func_graph()->ToString() << ", "
|
||||
<< graph_infer_stack.top().first->func_graph()->ToString();
|
||||
}
|
||||
graph_infer_stack.pop();
|
||||
}
|
||||
|
||||
void TraceEvalCNodeEnter(const abstract::AnfNodeConfigPtr &node_cfg) { cnode_debug_stack.push_back(node_cfg); }
|
||||
|
@ -581,7 +519,7 @@ void TraceEvalCNodeLeave() { cnode_debug_stack.pop_back(); }
|
|||
|
||||
std::vector<abstract::AnfNodeConfigPtr> &GetCNodeDebugStack() { return cnode_debug_stack; }
|
||||
|
||||
std::stack<std::pair<abstract::EvaluatorPtr, abstract::AnfNodeConfigPtr>> &GetCurrenGraphEvalStack() {
|
||||
std::stack<std::pair<abstract::AnalysisContextPtr, abstract::AnfNodeConfigPtr>> &GetCurrenGraphEvalStack() {
|
||||
return graph_infer_stack;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,12 +35,12 @@ namespace trace {
|
|||
DebugInfoPtr GetSourceCodeDebugInfo(const DebugInfoPtr &info);
|
||||
void TraceGraphEval();
|
||||
void GetEvalStackInfo(std::ostringstream &oss);
|
||||
void TraceGraphEvalEnter(const abstract::EvaluatorPtr &eval, const abstract::AnfNodeConfigPtr &node);
|
||||
void TraceGraphEvalLeave(const abstract::EvaluatorPtr &eval);
|
||||
void TraceGraphEvalEnter(const abstract::AnalysisContextPtr &context, const abstract::AnfNodeConfigPtr &node);
|
||||
void TraceGraphEvalLeave(const abstract::AnalysisContextPtr &context);
|
||||
void TraceEvalCNodeEnter(const abstract::AnfNodeConfigPtr &node_cfg);
|
||||
void TraceEvalCNodeLeave();
|
||||
std::vector<abstract::AnfNodeConfigPtr> &GetCNodeDebugStack();
|
||||
std::stack<std::pair<abstract::EvaluatorPtr, abstract::AnfNodeConfigPtr>> &GetCurrenGraphEvalStack();
|
||||
std::stack<std::pair<abstract::AnalysisContextPtr, abstract::AnfNodeConfigPtr>> &GetCurrenGraphEvalStack();
|
||||
std::string GetAbstractStr(const abstract::AbstractBasePtr &abs);
|
||||
void ClearTraceStack();
|
||||
} // namespace trace
|
||||
|
|
|
@ -66,7 +66,8 @@ void BaseFuncGraphEvaluator::EnterStackFrame(const AnalysisEnginePtr &engine, co
|
|||
AnfNodeConfigPtr call_conf = engine->MakeConfig(current_node, current_context);
|
||||
auto evaluator = new_stack_frame->evaluator();
|
||||
MS_EXCEPTION_IF_NULL(evaluator);
|
||||
trace::TraceGraphEvalEnter(evaluator, call_conf);
|
||||
auto new_context = new_stack_frame->current_context();
|
||||
trace::TraceGraphEvalEnter(new_context, call_conf);
|
||||
|
||||
// Increase & Check the func graph call depth.
|
||||
IncreaseFunctionCallDepth();
|
||||
|
@ -85,13 +86,15 @@ void BaseFuncGraphEvaluator::EnterStackFrame(const AnalysisEnginePtr &engine, co
|
|||
void BaseFuncGraphEvaluator::LeaveStackFrame(const AnalysisEnginePtr &engine,
|
||||
const StackFramePtr ¤t_stack_frame) {
|
||||
// Leave current func graph.
|
||||
auto evaluator = current_stack_frame->evaluator();
|
||||
MS_EXCEPTION_IF_NULL(evaluator);
|
||||
trace::TraceGraphEvalLeave(evaluator);
|
||||
auto current_context = current_stack_frame->current_context();
|
||||
trace::TraceGraphEvalLeave(current_context);
|
||||
|
||||
// Decrease the func graph call depth.
|
||||
DecreaseFunctionCallDepth();
|
||||
DecreaseStackFrameDepth();
|
||||
|
||||
auto evaluator = current_stack_frame->evaluator();
|
||||
MS_EXCEPTION_IF_NULL(evaluator);
|
||||
MS_LOG(DEBUG) << evaluator << "(" << evaluator->type_name() << "/" << evaluator->ToString()
|
||||
<< "), leave, function call depth: " << FunctionCallDepth() << " - " << StackFrameDepth();
|
||||
}
|
||||
|
@ -177,7 +180,6 @@ EvalResultPtr BaseFuncGraphEvaluator::Eval(AnalysisEnginePtr engine, const Abstr
|
|||
}
|
||||
MS_EXCEPTION_IF_NULL(engine);
|
||||
|
||||
trace::TraceGraphEvalEnter(shared_from_base<Evaluator>(), out_conf);
|
||||
// Increase & Check the func graph call depth.
|
||||
IncreaseFunctionCallDepth();
|
||||
const uint32_t max_depth = MsContext::GetInstance()->get_param<uint32_t>(MS_CTX_MAX_CALL_DEPTH);
|
||||
|
@ -190,9 +192,11 @@ EvalResultPtr BaseFuncGraphEvaluator::Eval(AnalysisEnginePtr engine, const Abstr
|
|||
MS_LOG(DEBUG) << this << "(" << type_name() << "/" << ToString()
|
||||
<< "), enter, function call depth: " << FunctionCallDepth() << " - " << StackFrameDepth();
|
||||
|
||||
// Initialize evaluator starter with args_abs_list.
|
||||
FuncGraphPtr fg = GetFuncGraph(engine, args_abs_list);
|
||||
MS_EXCEPTION_IF_NULL(fg);
|
||||
auto context = parent_context_->NewContext(fg, args_abs_list);
|
||||
trace::TraceGraphEvalEnter(context, out_conf);
|
||||
|
||||
std::size_t nargs = fg->parameters().size();
|
||||
if (args_abs_list.size() != nargs) {
|
||||
MS_EXCEPTION(TypeError) << "For function " << fg->ToString() << ", the number of parameters of this function is "
|
||||
|
@ -206,7 +210,7 @@ EvalResultPtr BaseFuncGraphEvaluator::Eval(AnalysisEnginePtr engine, const Abstr
|
|||
<< parent_context_->func_graph()->ToString() << "()->" << AnalysisResultCacheMgr::GetThreadid() << ":"
|
||||
<< fg->ToString() << "();";
|
||||
}
|
||||
auto context = parent_context_->NewContext(fg, args_abs_list);
|
||||
|
||||
auto func_graph_evaluator = dyn_cast<FuncGraphEvaluator>(shared_from_base<BaseFuncGraphEvaluator>());
|
||||
if (func_graph_evaluator != nullptr) {
|
||||
if (engine->root_func_graph() == func_graph_evaluator->func_graph()) {
|
||||
|
@ -240,7 +244,7 @@ EvalResultPtr BaseFuncGraphEvaluator::Eval(AnalysisEnginePtr engine, const Abstr
|
|||
}
|
||||
MS_LOG(DEBUG) << GetInferThread() << "} //" << fg->ToString() << " = " << res_base->ToString();
|
||||
|
||||
trace::TraceGraphEvalLeave(shared_from_base<Evaluator>());
|
||||
trace::TraceGraphEvalLeave(context);
|
||||
// Decrease the func graph call depth.
|
||||
DecreaseFunctionCallDepth();
|
||||
MS_LOG(DEBUG) << this << "(" << type_name() << "/" << ToString()
|
||||
|
|
|
@ -256,17 +256,12 @@ void AnalysisEngine::CheckNoStackInSameFuncGraph(const AnfNodeConfigPtr &conf) {
|
|||
if (forward_count_ != 0) { // Ignore Forward Config.
|
||||
return;
|
||||
}
|
||||
auto &infer_stack = trace::GetCurrenGraphEvalStack();
|
||||
if (infer_stack.empty()) {
|
||||
auto &graph_stack = trace::GetCurrenGraphEvalStack();
|
||||
if (graph_stack.empty()) {
|
||||
return;
|
||||
}
|
||||
auto top_evaluator = infer_stack.top().first;
|
||||
// Top or root func_graph must be FuncGraph other than MetaFuncGraph;
|
||||
if (!top_evaluator->isa<FuncGraphEvaluator>()) {
|
||||
MS_LOG(EXCEPTION) << "Top evaluator is " << top_evaluator->ToString();
|
||||
}
|
||||
auto top_fg_evaluator = dyn_cast<FuncGraphEvaluator>(top_evaluator);
|
||||
auto top_context_fg = top_fg_evaluator->func_graph();
|
||||
auto top_context = graph_stack.top().first;
|
||||
auto top_context_fg = top_context->func_graph();
|
||||
if (current_cnode_fg != top_context_fg) { // Ignore FV call.
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue