!19604 Record and Dump func graph call stack with context info.

Merge pull request !19604 from 张清华/opt0
This commit is contained in:
i-robot 2021-07-08 01:35:40 +00:00 committed by Gitee
commit 1a2fbdb6ac
5 changed files with 112 additions and 172 deletions

View File

@ -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> &parameters,
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_;

View File

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

View File

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

View File

@ -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 &current_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()

View File

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