diff --git a/mindspore/ccsrc/backend/session/ascend_session.cc b/mindspore/ccsrc/backend/session/ascend_session.cc index e38de71170b..e220f20f122 100644 --- a/mindspore/ccsrc/backend/session/ascend_session.cc +++ b/mindspore/ccsrc/backend/session/ascend_session.cc @@ -82,24 +82,6 @@ void DumpGraphExeOrder(const std::vector &execution_order, const std:: i++; } buf << "================== execution order ==================\n"; - // std::cout << buf.str() << std::endl; -} - -void DumpGraphInputArgs(const VectorRef &args) { - MS_LOG(INFO) << "Args size[%lu]" << args.size(); - for (size_t i = 0; i < args.size(); i++) { - if (utils::isa(args[i])) { - auto anf = utils::cast(args[i]); - MS_EXCEPTION_IF_NULL(anf); - MS_LOG(INFO) << "Parameter arg" << i << " = [%s]" << anf->DebugString(); - } else if (utils::isa(args[i])) { - auto value = utils::cast(args[i]); - MS_EXCEPTION_IF_NULL(value); - MS_LOG(INFO) << "Tensor arg" << i << " = " << value->ToString(); - } else { - MS_LOG(INFO) << "Unknown arg" << i << " = " << args[i].ToString(); - } - } } void SetStreamDistinctionLabel(const KernelGraphPtr &graph, uint32_t label, bool is_override) { @@ -109,52 +91,6 @@ void SetStreamDistinctionLabel(const KernelGraphPtr &graph, uint32_t label, bool } } -std::vector GetRealArgs(const KernelGraphPtr graph, const VectorRef &args) { - MS_EXCEPTION_IF_NULL(graph); - std::vector graph_inputs = graph->inputs(); - auto valid_inputs = graph->valid_inputs(); - size_t real_args_size = 0; - std::vector real_args = {}; - for (size_t i = 0; i < args.size(); i++) { - if (utils::isa(args[i])) { - auto tmp_args = AnfAlgo::GetAllOutput(utils::cast(args[i]), {prim::kPrimTupleGetItem}); - for (auto &real_arg : tmp_args) { - auto anf_node = utils::cast(real_arg); - MS_EXCEPTION_IF_NULL(anf_node); - auto abstract = anf_node->abstract(); - MS_EXCEPTION_IF_NULL(abstract); - // create multiple parameters if is a tuple output real kernel - if (abstract->isa() && - !AnfAlgo::CheckPrimitiveType(anf_node, prim::kPrimTupleGetItem)) { - auto tuple_abstract = abstract->cast(); - MS_EXCEPTION_IF_NULL(tuple_abstract); - real_args_size += tuple_abstract->size(); - continue; - } - real_args_size += 1; - real_args.push_back(real_arg); - } - } else { - real_args_size += 1; - real_args.push_back(args[i]); - } - } - if (graph_inputs.size() != valid_inputs.size()) { - MS_LOG(EXCEPTION) << "Graph_inputs.size(): " << graph_inputs.size() - << ", valid_inputs.size(): " << valid_inputs.size() << " not equal"; - } - if (real_args_size != graph_inputs.size()) { - for (size_t j = 0; j < valid_inputs.size(); j++) { - if (valid_inputs[j]) { - MS_LOG(INFO) << "Index: " << j << ", nodes: " << graph_inputs[j]->DebugString(); - } - } - MS_LOG(WARNING) << "Real_args_size: " << real_args_size << ", graph_inputs.size(): " << graph_inputs.size() - << " not equal"; - } - return real_args; -} - std::vector GetCNodes(const std::vector &anf_nodes) { std::vector cnodes = {}; size_t i = 0; @@ -168,128 +104,6 @@ std::vector GetCNodes(const std::vector &anf_nodes) { return cnodes; } -static std::vector> GetChildList(const std::vector &cnodes, - const std::set &cut_prims) { - size_t after_cut_index = 0; - std::vector> ret; - for (size_t i = 0; i < cnodes.size(); ++i) { - bool is_cut_node = false; - for (auto &prim : cut_prims) { - if (AnfAlgo::CheckPrimitiveType(cnodes[i], prim)) { - is_cut_node = true; - break; - } - } - if (is_cut_node) { - // is call and not switch call,cut to 3 lists - if (!AnfAlgo::CheckPrimitiveType(cnodes[i], prim::kPrimCall)) { - // if is not a call,cut to 2 lists - ret.emplace_back(cnodes.begin() + after_cut_index, cnodes.begin() + i); - after_cut_index = i; - } else if (!AnfAlgo::IsSwitchCall(cnodes[i])) { - ret.emplace_back(cnodes.begin() + after_cut_index, cnodes.begin() + i); - ret.emplace_back(1, cnodes[i]); - after_cut_index = i + 1; - continue; - } - } - // get last child graph list - if (AnfAlgo::CheckPrimitiveType(cnodes[i], prim::kPrimReturn)) { - ret.emplace_back(cnodes.begin() + after_cut_index, cnodes.end()); - continue; - } - } - return ret; -} - -static void BindCallArgsWithParameter(const std::vector ¶meters, const std::vector &args, - const KernelGraphPtr &graph, KernelGraphPtr child_graph, - const NotNull *> memo) { - MS_EXCEPTION_IF_NULL(child_graph); - MS_LOG(INFO) << "Start bind parameter of child graph:" << child_graph->graph_id(); - if (args.empty()) { - return; - } - if (parameters.size() != args.size()) { - MS_LOG(EXCEPTION) << "Graph:" << child_graph->graph_id() << " parameters size:" << parameters.size() - << " and args size:" << args.size() << " not equal!"; - } - child_graph->SetExecOrderByDefault(); - for (size_t i = 0; i < parameters.size(); i++) { - MS_LOG(INFO) << "parameters[" << i << "]" << parameters[i]->DebugString() << ",args[" << i << "]" - << args[i]->DebugString(); - if (args[i] == parameters[i]) { - MS_LOG(INFO) << "Parameter and arg are same."; - continue; - } - child_graph->SetRealInput(parameters[i], args[i]); - if (memo->find(child_graph) != memo->end() || !args[i]->isa()) { - MS_LOG(INFO) << "Add unreused arg,graph:" << graph->graph_id(); - child_graph->AddUnreuseArgs(args[i], graph); - } - } -} - -// if a call has kernel input, it's a child graph split from ME, so these kernel input should be set into real input of -// graph.For example, call input = (prim,graph,kernel1,kernel2),then real_input = [kernel1,kernel2] -static void UpdateRealInput(NotNull graph, bool split_flag, - const NotNull *> memo) { - MS_EXCEPTION_IF_NULL(memo.get()); - auto call_nodes = graph->FindNodeByPrimitive(prim::kPrimCall); - for (auto &call_node : call_nodes) { - MS_EXCEPTION_IF_NULL(call_node); - auto child_graphs = AnfAlgo::GetCallNodeKernelGraph(call_node); - if (child_graphs.size() == 1) { - MS_EXCEPTION_IF_NULL(child_graphs[0]); - std::vector real_args = - std::vector(call_node->inputs().begin() + 2, call_node->inputs().end()); - std::vector child_inputs = child_graphs[0]->inputs(); - BindCallArgsWithParameter(child_inputs, real_args, graph, child_graphs[0], memo); - if (split_flag) { - call_node->set_inputs(std::vector(call_node->inputs().begin(), call_node->inputs().begin() + 2)); - } - } else if (child_graphs.size() == 2) { - auto get_partial_args = [&](size_t input_index) -> std::vector { - auto switch_node = call_node->input(1); - MS_EXCEPTION_IF_NULL(switch_node); - auto switch_cnode = switch_node->cast(); - MS_EXCEPTION_IF_NULL(switch_cnode); - auto partial = switch_cnode->input(input_index); - MS_EXCEPTION_IF_NULL(partial); - if (IsValueNode(partial)) { - return {}; - } - auto partial_cnode = partial->cast(); - MS_EXCEPTION_IF_NULL(partial_cnode); - auto ret = std::vector(partial_cnode->inputs().begin() + 2, partial_cnode->inputs().end()); - if (split_flag) { - partial_cnode->set_inputs( - std::vector(partial_cnode->inputs().begin(), partial_cnode->inputs().begin() + 2)); - } - return ret; - }; - BindCallArgsWithParameter(child_graphs[0]->inputs(), get_partial_args(2), graph, child_graphs[0], memo); - BindCallArgsWithParameter(child_graphs[1]->inputs(), get_partial_args(3), graph, child_graphs[1], memo); - } - } -} - -static void RecurseToUpdateCallRealInput(NotNull graph, - const NotNull *> memo) { - memo->insert(graph.get()); - MS_LOG(INFO) << "Start graph id:" << graph->graph_id(); - for (auto &child_graph : graph->child_graph_order()) { - if (memo->find(child_graph) != memo->end()) { - MS_LOG(INFO) << "Child graph:" << child_graph->graph_id() - << ",parent graph:" << graph->parent_graph()->graph_id(); - continue; - } - RecurseToUpdateCallRealInput(NOT_NULL(child_graph), memo); - } - // this action should from bottom to top - graph->UpdateCallRealInput(); -} - void InsertMakeTupleForOutput(NotNull root_graph) { auto return_node = root_graph->get_return(); MS_EXCEPTION_IF_NULL(return_node); @@ -409,8 +223,6 @@ void AscendSession::BuildGraph(GraphId graph_id) { } // insert assigns to child graph InsertAllAssigns(); - // insert switch and active to child graph - MergeSwitchCompile(); SetFinalGraphSummaryFlag(graph); // OptChildGraphs auto graph_order = GetGraphOrder(final_graph_id_); @@ -423,7 +235,7 @@ void AscendSession::BuildGraph(GraphId graph_id) { auto child_graph = GetGraph(graph_order[i]); CompileChildGraph(child_graph); } - GetSummaryNodes(graph.get()); + SetSummaryNodes(graph.get()); // merge child graph MergeGraphExecOrder(); } else { @@ -570,11 +382,7 @@ void AscendSession::RunOpExecTask(const std::shared_ptr &kernel_gra } bool AscendSession::GraphCacheExist(const GraphInfo &graph_info) const { - if (run_op_graphs_.find(graph_info) != run_op_graphs_.end()) { - return true; - } - - return false; + return run_op_graphs_.find(graph_info) != run_op_graphs_.end(); } void AscendSession::BuildOp(const OpRunInfo &op_run_info, const GraphInfo &graph_info, @@ -851,55 +659,14 @@ void AscendSession::LoadTensor(const std::shared_ptr &kernel_graph) MS_LOG(INFO) << "Finish!"; } -GraphId AscendSession::SetFinalGraphInput(const std::vector &args) { - MS_LOG(INFO) << "Start! Args size " << args.size(); - auto final_graph = NewKernelGraph(); - MS_EXCEPTION_IF_NULL(final_graph); - final_graph_id_ = final_graph->graph_id(); - MS_LOG(INFO) << "Create a new final graph" << final_graph_id_ << " success"; - // init private variables and bind them with final_graph_id - graph_execute_orders_[final_graph_id_] = std::vector(); - graph_order_types_[final_graph_id_] = std::vector(); - for (const auto ¶meter : args) { - MS_EXCEPTION_IF_NULL(parameter); - if (!parameter->isa()) { - MS_LOG(EXCEPTION) << parameter->DebugString() << " is not a parameter type!"; - } - AnfNodePtr parameter_backend = nullptr; - // if function return UINT_MAX,the parameter is not exist in child graph - auto parameter_belong_graph_id = GetGraphIdByNode(parameter); - if (parameter_belong_graph_id == kInvalidGraphId) { - parameter_backend = CreateNewParameterFromParameter(parameter, true, final_graph.get()); - final_graph->FrontBackendlMapAdd(parameter, parameter_backend); - MS_LOG(INFO) << "New parameter" << parameter->DebugString() << "in final_graph"; - } else { - // parametr is a parameter of child graph - auto graph = GetGraph(parameter_belong_graph_id); - MS_EXCEPTION_IF_NULL(graph); - MS_LOG(INFO) << "Reuse parameter [" << parameter->DebugString() << "] of child graph [" - << parameter_belong_graph_id << "]"; - parameter_backend = graph->GetBackendAnfByFrontAnf(parameter); - // add parameter in backend to final graph inputs - auto final_graph_inputs = final_graph->MutableInputs(); - MS_EXCEPTION_IF_NULL(final_graph_inputs); - final_graph_inputs->push_back(parameter_backend); - } - MS_EXCEPTION_IF_NULL(parameter_backend); - MS_LOG(INFO) << "Parameter backend " << parameter_backend->DebugString() << " belong_graph_id " - << AnfAlgo::GetGraphId(parameter_backend.get()); - } - MS_LOG(INFO) << "End final_graph_id " << final_graph_id_; - return final_graph_id_; -} - -void AscendSession::RecurseGetSummaryNodes(KernelGraph *graph, +void AscendSession::RecurseSetSummaryNodes(KernelGraph *graph, std::map> *summary) { MS_EXCEPTION_IF_NULL(graph); MS_EXCEPTION_IF_NULL(summary); // if final graph have no child graph auto graph_order_iter = graph_execute_orders_.find(graph->graph_id()); if (graph_order_iter == graph_execute_orders_.end()) { - SessionBasic::GetSummaryNodes(graph); + SessionBasic::SetSummaryNodes(graph); auto summary_nodes = graph->summary_nodes(); summary->insert(summary_nodes.begin(), summary_nodes.end()); return; @@ -911,293 +678,25 @@ void AscendSession::RecurseGetSummaryNodes(KernelGraph *graph, if (child_graph == nullptr) { continue; } - SessionBasic::GetSummaryNodes(child_graph.get()); + SessionBasic::SetSummaryNodes(child_graph.get()); auto child_graph_summary = child_graph->summary_nodes(); summary->insert(child_graph_summary.begin(), child_graph_summary.end()); - RecurseGetSummaryNodes(child_graph.get(), summary); + RecurseSetSummaryNodes(child_graph.get(), summary); } graph->set_summary_nodes(*summary); } -void AscendSession::GetSummaryNodes(KernelGraph *graph) { +void AscendSession::SetSummaryNodes(KernelGraph *graph) { MS_LOG(DEBUG) << "Update summary Start"; MS_EXCEPTION_IF_NULL(graph); auto summary_nodes = graph->summary_nodes(); std::map> summary; summary.insert(summary_nodes.begin(), summary_nodes.end()); - RecurseGetSummaryNodes(graph, &summary); + RecurseSetSummaryNodes(graph, &summary); graph->set_summary_nodes(summary); MS_LOG(DEBUG) << "Update summary end size: " << summary.size(); } -AnfNodePtr AscendSession::CreateFakeOutput(GraphId fake_graph_id, const AnfNodePtr &true_output) { - auto fake_graph = GetGraph(fake_graph_id); - MS_EXCEPTION_IF_NULL(fake_graph); - auto output_item_with_index = AnfAlgo::VisitKernelWithReturnType(true_output, 0); - auto create_parameter = [&](const AbstractBasePtr &abstract) -> AnfNodePtr { - auto parameter = fake_graph->NewParameter(); - MS_EXCEPTION_IF_NULL(parameter); - parameter->set_abstract(abstract); - auto new_parameter = fake_graph->NewParameter(parameter); - // Add new parameter to the graph input of fake_graph to sure that all parameters will be allocated memory. - auto graph_inputs = fake_graph->MutableInputs(); - MS_EXCEPTION_IF_NULL(graph_inputs); - graph_inputs->push_back(new_parameter); - return new_parameter; - }; - auto create_parameter_from_cnode = [&](const AnfNodePtr &cnode, size_t output_idx) -> AnfNodePtr { - MS_EXCEPTION_IF_NULL(cnode); - auto abstract = cnode->abstract(); - MS_EXCEPTION_IF_NULL(abstract); - // create multiple parameters if is a tuple output real kernel - if (abstract->isa()) { - auto tuple_abstract = abstract->cast(); - MS_EXCEPTION_IF_NULL(tuple_abstract); - MS_LOG(INFO) << "Tuple size [" << tuple_abstract->size() << "]"; - return create_parameter((*tuple_abstract)[output_idx]); - } - return create_parameter(cnode->abstract()); - }; - if (AnfAlgo::CheckPrimitiveType(output_item_with_index.first, prim::kPrimMakeTuple)) { - std::vector make_tuple_inputs = {NewValueNode(prim::kPrimMakeTuple)}; - auto make_tuple = output_item_with_index.first->cast(); - MS_EXCEPTION_IF_NULL(make_tuple); - for (size_t i = 1; i < make_tuple->inputs().size(); i++) { - auto input = make_tuple->inputs()[i]; - make_tuple_inputs.push_back(CreateFakeOutput(fake_graph_id, input)); - } - return fake_graph->NewCNode(make_tuple_inputs); - } - return create_parameter_from_cnode(output_item_with_index.first, output_item_with_index.second); -} - -void AscendSession::SetFinalGraphOutput(const AnfNodePtr &node) { - // get the backend anf node related to the output node of front - auto output_from_graph_id = GetGraphIdByNode(node); - auto output_from_graph = GetGraph(output_from_graph_id); - MS_EXCEPTION_IF_NULL(node); - MS_LOG(INFO) << "Set the output[" << node->DebugString() << "] of graph[" << output_from_graph_id - << "] to final graph"; - MS_EXCEPTION_IF_NULL(output_from_graph); - auto final_graph = GetGraph(final_graph_id_); - MS_EXCEPTION_IF_NULL(final_graph); - // if output is from final graph,it remarks no child graph exist - if (final_graph_id_ == output_from_graph_id) { - MS_LOG(INFO) << "No child graph,output is " << node->DebugString(); - final_graph->set_output(ConstructOutput({node}, final_graph)); - final_graph->set_executable(false); - return; - } - final_graph->set_output(output_from_graph->output()); -} - -void AscendSession::SetFinalGraphOutput(const ValuePtr &value) { - auto value_node = NewValueNode(value); - auto kernel_info = std::make_shared(); - value_node->set_kernel_info(kernel_info); - value_node->set_abstract(abstract::FromValue(value)); - auto final_graph = GetGraph(final_graph_id_); - MS_EXCEPTION_IF_NULL(final_graph); - final_graph->set_output(final_graph->NewCNode({NewValueNode(prim::kPrimMakeTuple), value_node})); - final_graph->set_executable(false); - MS_EXCEPTION_IF_NULL(value); - MS_LOG(INFO) << "Not anf output[" << value->ToString() << "]"; -} - -void AscendSession::SetFinalGraphOutput(const VectorRef &vec_output) { - for (auto &output : vec_output) { - if (utils::isa(output)) { - auto output_anf_node = utils::cast(output); - SetFinalGraphOutput(output_anf_node); - } else if (utils::isa(output)) { - auto value = utils::cast(output); - SetFinalGraphOutput(value); - } else { - MS_LOG(EXCEPTION) << "Unknown output type:" << output.ToString(); - } - } -} - -void AscendSession::SetFinalGraphOutput(const BaseRef &output) { - if (utils::isa(output)) { - auto output_anf_node = utils::cast(output); - SetFinalGraphOutput(output_anf_node); - } else if (utils::isa(output)) { - auto value = utils::cast(output); - SetFinalGraphOutput(value); - } else if (utils::isa(output)) { - auto vec_output = utils::cast(output); - SetFinalGraphOutput(vec_output); - } else { - MS_LOG(EXCEPTION) << "Unknown output type:" << output.ToString(); - } -} - -void AscendSession::InsertSwitchToGraph(GraphId condition_graph_id, GraphId true_graph_id) { - MS_LOG(INFO) << "Start!"; - MS_LOG(INFO) << "Condition graph id[" << condition_graph_id << "],true graph id[" << true_graph_id << "]"; - auto condition_graph = GetGraph(condition_graph_id); - MS_EXCEPTION_IF_NULL(condition_graph); - tensor::TensorPtr tensor = std::make_shared(kNumberTypeInt32, std::vector{1}); - int32_t *val = nullptr; - val = static_cast(tensor->data_c()); - MS_EXCEPTION_IF_NULL(val); - *val = 0; - auto value_node = std::make_shared(tensor); - value_node->set_abstract(abstract::FromValue(tensor, false)); - auto counter_const = condition_graph->NewValueNode(value_node); - condition_graph->AddValueNodeToGraph(counter_const); - // create a new switch op - auto switch_primitive = std::make_shared("StreamSwitch"); - auto cond_output_it = condition_output_.find(condition_graph_id); - if (cond_output_it == condition_output_.end()) { - MS_LOG(EXCEPTION) << "Can't find condition graph" << condition_graph_id; - } - auto cond_output_kernel = - AnfAlgo::VisitKernel(condition_graph->GetBackendAnfByFrontAnf(cond_output_it->second), 0).first; - MS_EXCEPTION_IF_NULL(cond_output_kernel); - std::vector inputs = {NewValueNode(switch_primitive), cond_output_kernel, counter_const}; - CNodePtr switch_node = condition_graph->NewCNode(inputs); - MS_EXCEPTION_IF_NULL(switch_node); - switch_node->set_abstract(std::make_shared()); - AnfAlgo::SetGraphId(condition_graph_id, switch_node.get()); - // set attr: cond_ RT_GREATER - AnfAlgo::SetNodeAttr(kAttrSwitchCondition, MakeValue(static_cast(RT_GREATER)), switch_node); - // set attr:data_type - AnfAlgo::SetNodeAttr(kAttrDataType, MakeValue(static_cast(RT_SWITCH_INT64)), switch_node); - // set attr:true branch graph id ,which is same to stream distinction label - AnfAlgo::SetNodeAttr(kAttrTrueBranchStream, MakeValue(true_graph_id), switch_node); - // append switch at the end of condition graph - auto return_node = condition_graph->get_return(); - MS_EXCEPTION_IF_NULL(return_node); - InsertControlDependToGraph(condition_graph_id, return_node->input(kReturnDataIndex), switch_node); - MS_LOG(INFO) << "Finish!"; -} - -void AscendSession::CopyOutputOfIf(GraphId false_graph_id) { - auto &graph_execute_order = GetGraphOrder(final_graph_id_); - auto &graph_order_type = GetGraphOrderType(final_graph_id_); - auto false_index = ExecOrderOfChildGraph(final_graph_id_, false_graph_id); - if (false_index == kInvalidIndex || false_index == 0) { - return; - } - for (int i = SizeToInt(false_index) - 1; i >= 0; i--) { - size_t graph_index = IntToSize(i); - if (graph_index >= graph_execute_order.size()) { - MS_LOG(EXCEPTION) << "Graph index[" << graph_index << "] out of range[" << graph_execute_order.size() << "]"; - } - if (graph_order_type[graph_index] == COMMON_GRAPH) { - auto true_last_id = graph_execute_order[graph_index]; - MS_LOG(INFO) << "The last graph of if true branch is " << true_last_id; - auto true_last = GetGraph(true_last_id); - auto final_graph = GetGraph(final_graph_id_); - MS_EXCEPTION_IF_NULL(final_graph); - auto false_last = GetGraph(false_graph_id); - MS_EXCEPTION_IF_NULL(true_last); - MS_EXCEPTION_IF_NULL(false_last); - MS_LOG(INFO) << "The last graph of false branch is " << false_graph_id; - // create fake output - auto fake_output_graph = NewKernelGraph(); - MS_EXCEPTION_IF_NULL(fake_output_graph); - graph_execute_order.push_back(fake_output_graph->graph_id()); - graph_order_type.push_back(COMMON_GRAPH); - fake_output_graph->set_output(CreateFakeOutput(fake_output_graph->graph_id(), final_graph->output())); - final_graph->set_output(fake_output_graph->output()); - InsertMultipleAssignToGraph(true_last_id, true_last->output(), final_graph->output()); - InsertMultipleAssignToGraph(false_graph_id, false_last->output(), final_graph->output()); - // insert stream active for loop sink - auto context_ptr = MsContext::GetInstance(); - MS_EXCEPTION_IF_NULL(context_ptr); - if (context_ptr->enable_task_sink() && context_ptr->loop_sink_flag() && - ConfigManager::GetInstance().iter_num() > 1) { - // insert active in true graph, another active will be inserted in kernel adjust - InsertStreamActiveToGraph(true_last_id, kSecondStreamSwitchLabel); - } - break; - } - } -} - -void AscendSession::SwitchCompile(GraphId cond_graph_id, GraphId true_graph_id, GraphId false_graph_id, - const AnfNodePtr &output) { - if (switches_.find(cond_graph_id) != switches_.end()) { - MS_LOG(WARNING) << "Condition graph" << cond_graph_id << " has been set before "; - return; - } - switches_[cond_graph_id] = std::pair(true_graph_id, false_graph_id); - condition_output_[cond_graph_id] = output; - MS_LOG(INFO) << "New switch compile " << cond_graph_id << " " << true_graph_id << " " << false_graph_id; - // set the type of condition graph - auto cond_graph_index = ExecOrderOfChildGraph(final_graph_id_, cond_graph_id); - auto &graph_order_type = GetGraphOrderType(final_graph_id_); - if (cond_graph_index >= graph_order_type.size()) { - MS_LOG(EXCEPTION) << "Cond_graph_index " << cond_graph_index << " out of range " << graph_order_types_.size(); - } - graph_order_type[cond_graph_index] = CONDITION_GRAPH; - // update distinction label of false graph,update before merge to sure the distinction - if (false_graph_id != kInvalidGraphId) { - // false graph and condition in graph same stream - auto condition_graph = GetGraph(cond_graph_id); - MS_EXCEPTION_IF_NULL(condition_graph); - SetStreamDistinctionLabel(GetGraph(false_graph_id), condition_graph->stream_distinction_label(), true); - // if false graph is a condition graph and has been switch compiled before,it's false should be updated again - auto cond_it = switches_.find(false_graph_id); - while (cond_it != switches_.end() && cond_it->second.second != kInvalidGraphId) { - cond_graph_id = cond_it->first; - false_graph_id = cond_it->second.second; - condition_graph = GetGraph(cond_graph_id); - if (condition_graph == nullptr) { - continue; - } - SetStreamDistinctionLabel(GetGraph(false_graph_id), condition_graph->stream_distinction_label(), true); - cond_it = switches_.find(false_graph_id); - } - } -} // namespace session - -void AscendSession::MergeSwitchCompile() { - auto graph_execute_order = GetGraphOrder(final_graph_id_); - auto &graph_order_type = GetGraphOrderType(final_graph_id_); - for (auto switch_compile : switches_) { - auto cond_graph_id = switch_compile.first; - auto true_graph_id = switch_compile.second.first; - auto false_graph_id = switch_compile.second.second; - MS_LOG(INFO) << "Switch compile: " << cond_graph_id << " " << true_graph_id << " " << false_graph_id; - auto condition_graph = GetGraph(cond_graph_id); - auto final_graph = GetGraph(final_graph_id_); - MS_EXCEPTION_IF_NULL(condition_graph); - MS_EXCEPTION_IF_NULL(final_graph); - // insert switch to condition graph - InsertSwitchToGraph(cond_graph_id, true_graph_id); - auto cond_graph_index = ExecOrderOfChildGraph(final_graph_id_, cond_graph_id); - auto prev_graph_id = kInvalidGraphId; - // if condition graph is the first graph and final graph has assign op,then the final graph is the common graph - if (cond_graph_index == 0 && !final_graph->execution_order().empty()) { - prev_graph_id = final_graph_id_; - // set the distinction label of final graph - SetStreamDistinctionLabel(final_graph, final_graph_id_, true); - // if condition graph is not the first graph - } else if ((cond_graph_index - 1 < graph_execute_order.size()) && - (graph_order_type[cond_graph_index - 1] == COMMON_GRAPH)) { - prev_graph_id = graph_execute_order[cond_graph_index - 1]; - } - // insert stream active to common graph - if (prev_graph_id != kInvalidGraphId) { - InsertStreamActiveToGraph(prev_graph_id, condition_graph->stream_distinction_label()); - } - // if this is a 'if' condition - auto it = while_condition_graphs_.find(cond_graph_id); - if (it == while_condition_graphs_.end()) { - CopyOutputOfIf(false_graph_id); - } else { - // if it is a while,insert a stream active to true graph - GraphId from_graph = it->second; - InsertStreamActiveToGraph(from_graph, condition_graph->stream_distinction_label()); - } - } - MS_LOG(INFO) << "Finish!"; -} - void AscendSession::InsertAllAssigns() { std::vector> assigns; for (auto assign : assigns_) { @@ -1229,173 +728,6 @@ void AscendSession::InsertAllAssigns() { } } -// insert active to graph -void AscendSession::SetActive(GraphId from, GraphId to) { - if (while_condition_graphs_.find(to) != while_condition_graphs_.end()) { - MS_LOG(WARNING) << "To " << to << " has been exits in map,from " << from << ",exist from " - << while_condition_graphs_[to]; - return; - } - MS_LOG(INFO) << "From " << from << " to " << to; - auto &graph_order = GetGraphOrder(final_graph_id_); - auto &graph_type = GetGraphOrderType(final_graph_id_); - std::vector graph_order_new; - std::vector graph_type_new; - for (size_t i = 0; i < graph_order.size(); i++) { - auto graph_id = graph_order[i]; - graph_order_new.push_back(graph_id); - graph_type_new.push_back(graph_type[i]); - if (from == graph_id) { - graph_order_new.push_back(kInvalidGraphId); - graph_type_new.push_back(BRANCH_END); - } - } - graph_order = graph_order_new; - graph_type = graph_type_new; - // set the graph type of condition graph - graph_type[ExecOrderOfChildGraph(final_graph_id_, to)] = CONDITION_GRAPH; - // record the condition graph into while condition set - while_condition_graphs_[to] = from; -} - -void AscendSession::SetChildGraphParameter(const AnfNodePtr &front_anf, GraphId to_graph_id, size_t input_idx) { - MS_LOG(INFO) << "Start!"; - MS_EXCEPTION_IF_NULL(front_anf); - auto from_graph_id = GetGraphIdByNode(front_anf); - auto from_graph = GetGraph(from_graph_id); - MS_EXCEPTION_IF_NULL(from_graph); - auto to_graph = GetGraph(to_graph_id); - MS_EXCEPTION_IF_NULL(to_graph); - std::vector graph_inputs = to_graph->inputs(); - if (input_idx >= graph_inputs.size()) { - MS_LOG(EXCEPTION) << "Input_index " << input_idx << " out of range size " << graph_inputs.size(); - } - auto backend_parameter = graph_inputs[input_idx]; - MS_EXCEPTION_IF_NULL(backend_parameter); - auto backend_arg = from_graph->GetBackendAnfByFrontAnf(front_anf); - MS_LOG(INFO) << "Set node[" << front_anf->DebugString() << "] of graph[" << from_graph_id << "]to node[" - << backend_parameter->DebugString() << "] of graph[" << AnfAlgo::GetGraphId(backend_parameter.get()) - << "]"; - // a node should not assign to itself - if (backend_arg.get() == backend_parameter.get()) { - return; - } - // if arg is the the parameter of child graph,it is parameter of final graph too - if (front_anf->isa()) { - MS_EXCEPTION_IF_NULL(backend_arg); - MS_LOG(INFO) << "Reuse node [" << backend_arg->DebugString() << "], old node[" << backend_parameter->DebugString() - << "] will be replaced."; - to_graph->ReplaceNode(NOT_NULL(backend_parameter), NOT_NULL(backend_arg)); - return; - } - MS_LOG(INFO) << "Assign of node" << backend_arg->DebugString() << " of graph " << from_graph_id << " to node" - << backend_parameter->DebugString() << "of graph " << to_graph_id; - assigns_.emplace_back(std::tuple(front_anf, to_graph_id, input_idx)); -} - -void AscendSession::SetChildGraphParameter(const tensor::TensorPtr &front_tensor, GraphId to_graph_id, - size_t input_idx) { - MS_LOG(INFO) << "Start!"; - std::pair graph_input_pair(to_graph_id, input_idx); - initial_tenosrs_[graph_input_pair] = front_tensor; - MS_LOG(INFO) << "Finish!"; -} - -void AscendSession::UpdateGraphOrder(GraphId to_graph_id) { - MS_LOG(INFO) << "To_graph_id " << to_graph_id; - auto &graph_order = GetGraphOrder(final_graph_id_); - auto &graph_type = GetGraphOrderType(final_graph_id_); - for (size_t i = 0; i < graph_order.size(); i++) { - if (graph_order[i] == to_graph_id) { - return; - } - } - // if graph is not in graph order,add it to graph order - SetStreamDistinctionLabel(GetGraph(to_graph_id), to_graph_id, false); - graph_order.push_back(to_graph_id); - graph_type.push_back(COMMON_GRAPH); - for (size_t i = 0; i < graph_order.size(); i++) { - MS_LOG(INFO) << "Index " << i << ",graph_id " << graph_order[i] << ",graph_type" << graph_type[i]; - } -} - -size_t AscendSession::SetChildGraphInput(const KernelGraphPtr &graph, const AnfNodePtr &node, size_t input_index) { - MS_EXCEPTION_IF_NULL(graph); - MS_EXCEPTION_IF_NULL(node); - auto output_num = AnfAlgo::GetOutputTensorNum(node); - if (output_num > 1 && !AnfAlgo::CheckPrimitiveType(node, prim::kPrimTupleGetItem)) { - return input_index + output_num; - } - auto valid_inputs = graph->valid_inputs(); - if (valid_inputs[input_index]) { - SetChildGraphParameter(node, graph->graph_id(), input_index); - } else { - MS_LOG(DEBUG) << "Invalid input arg: " << node->DebugString(); - } - return ++input_index; -} - -size_t AscendSession::SetChildGraphInput(const KernelGraphPtr &graph, const ValuePtr &value, size_t input_index) { - MS_EXCEPTION_IF_NULL(graph); - MS_EXCEPTION_IF_NULL(value); - if (!value->isa()) { - MS_LOG(EXCEPTION) << "Value Node should be a tensor, unexpected value: " << value->ToString(); - } - SetChildGraphParameter(value->cast(), graph->graph_id(), input_index); - return ++input_index; -} - -size_t AscendSession::SetChildGraphInput(const KernelGraphPtr &graph, const VectorRef &vec_args, size_t input_index) { - auto index = input_index; - for (auto &arg : vec_args) { - if (utils::isa(arg)) { - // arg is a anf node - auto node = utils::cast(arg); - index = SetChildGraphInput(graph, node, input_index); - } else if (utils::isa(arg)) { - // arg is a tensor - auto value = utils::cast(arg); - index = SetChildGraphInput(graph, value, input_index); - } else { - MS_LOG(EXCEPTION) << "Unexpected arg type " << arg.ToString(); - } - } - return index; -} - -void AscendSession::SetChildGraphInput(GraphId g, const VectorRef &args) { - MS_LOG(INFO) << "Set input of graph " << g; - auto to_graph = GetGraph(g); - MS_EXCEPTION_IF_NULL(to_graph); - DumpGraphInputArgs(args); - UpdateGraphOrder(g); - auto &graph_inputs = to_graph->inputs(); - auto real_args = GetRealArgs(to_graph, args); - size_t input_index = 0; - for (size_t i = 0; i < real_args.size(); i++) { - if (input_index >= graph_inputs.size()) { - MS_LOG(EXCEPTION) << "Input_index " << input_index << " out of range size " << graph_inputs.size(); - } - auto &real_arg = real_args[i]; - if (utils::isa(real_arg)) { - // arg is a anf node - auto node = utils::cast(real_arg); - input_index = SetChildGraphInput(to_graph, node, input_index); - } else if (utils::isa(real_arg)) { - // arg is a tensor - auto value = utils::cast(real_arg); - input_index = SetChildGraphInput(to_graph, value, input_index); - } else if (utils::isa(real_arg)) { - // arg is a VectorRef - auto vec_args = utils::cast(real_arg); - input_index = SetChildGraphInput(to_graph, vec_args, input_index); - } else { - MS_LOG(EXCEPTION) << "Unexpected arg type " << real_arg.ToString(); - } - } - MS_LOG(INFO) << "Finish!"; -} - GraphId AscendSession::GetGraphIdByNode(const AnfNodePtr &front_anf) const { for (const auto &graph_item : graphs_) { auto graph = graph_item.second; @@ -1487,63 +819,10 @@ void AscendSession::InsertAssignToGraph(GraphId graph_id, const AnfNodePtr &from MS_EXCEPTION_IF_NULL(assign_node); assign_node->set_abstract(to->abstract()); // append the assign at the end of from graph - InsertDependToGraph(graph_id, assign_node); + AscendControlParser::InsertDependToGraph(NOT_NULL(graph), NOT_NULL(assign_node)); } -void AscendSession::InsertMultipleAssignToGraph(GraphId graph_id, const AnfNodePtr &from, const AnfNodePtr &to) { - std::vector from_outputs = AnfAlgo::GetAllOutput(from, {prim::kPrimTupleGetItem}); - std::vector to_outputs = AnfAlgo::GetAllOutput(to, {prim::kPrimTupleGetItem}); - MS_LOG(INFO) << "Insert assigns from [" << AnfAlgo::GetGraphId(from.get()) << "] to [" - << AnfAlgo::GetGraphId(to.get()) << "]"; - if (from_outputs.size() != to_outputs.size()) { - MS_LOG(INFO) << "From[" << from->DebugString(5) << "] to[" << to->DebugString(5) << "]"; - MS_LOG(EXCEPTION) << "From outputs size[" << from_outputs.size() << "] is not equal to to outputs size[" - << to_outputs.size() << "]"; - } - for (size_t i = 0; i < from_outputs.size(); i++) { - InsertAssignToGraph(graph_id, from_outputs[i], to_outputs[i]); - } -} - -void AscendSession::InsertStreamActiveToGraph(GraphId graph_id, uint32_t actived_stream) { - MS_LOG(INFO) << "Insert stream_active from " << graph_id << " to " << actived_stream; - auto from_graph = GetGraph(graph_id); - MS_EXCEPTION_IF_NULL(from_graph); - std::vector inputs = {NewValueNode(std::make_shared("StreamActive"))}; - auto active_node = from_graph->NewCNode(inputs); - MS_EXCEPTION_IF_NULL(active_node); - active_node->set_abstract(std::make_shared()); - // set the active stream id into the attr of active node - std::vector active_index_value = {}; - active_index_value.push_back(actived_stream); - AnfAlgo::SetNodeAttr(kAttrActiveStreamList, MakeValue>(active_index_value), active_node); - // append the active node at the end of from graph - auto return_node = from_graph->get_return(); - MS_EXCEPTION_IF_NULL(return_node); - InsertControlDependToGraph(graph_id, return_node->input(kReturnDataIndex), active_node); -} - -void AscendSession::InsertDependToGraph(GraphId graph_id, const AnfNodePtr &attch_node) { - AscendControlParser::InsertDependToGraph(NOT_NULL(GetGraph(graph_id)), NOT_NULL(attch_node)); -} - -void AscendSession::InsertControlDependToGraph(GraphId graph_id, const AnfNodePtr &first_node, - const AnfNodePtr &second_node) { - AscendControlParser::InsertControlDependToGraph(NOT_NULL(GetGraph(graph_id)), NOT_NULL(first_node), - NOT_NULL(second_node)); -} - -size_t AscendSession::ExecOrderOfChildGraph(GraphId final_graph, GraphId child_graph) { - auto &graph_order = GetGraphOrder(final_graph); - for (size_t i = 0; i < graph_order.size(); i++) { - if (child_graph == graph_order[i]) { - return i; - } - } - return kInvalidIndex; -} - -std::vector &AscendSession::GetGraphOrder(GraphId final_graph_id) { +const std::vector &AscendSession::GetGraphOrder(GraphId final_graph_id) const { auto graph_order_iter = graph_execute_orders_.find(final_graph_id); if (graph_order_iter == graph_execute_orders_.end()) { MS_LOG(EXCEPTION) << "Final graph" << final_graph_id << "has no child graph"; @@ -1551,8 +830,7 @@ std::vector &AscendSession::GetGraphOrder(GraphId final_graph_id) { return graph_order_iter->second; } -// get graph order type vector by graph id -std::vector &AscendSession::GetGraphOrderType(GraphId final_graph_id) { +const std::vector &AscendSession::GetGraphOrderType(GraphId final_graph_id) const { auto graph_type_iter = graph_order_types_.find(final_graph_id); if (graph_type_iter == graph_order_types_.end()) { MS_LOG(EXCEPTION) << "Final graph" << final_graph_id << "has no graph_order_types_"; @@ -1584,85 +862,6 @@ void AscendSession::SyncInitialTenosrToDevice() { } } -static void ConstructSplitedGraphOutput(const KernelGraphPtr &new_kernel_graph, const std::vector &list) { - // count the output of every anf node - std::set has_output_nodes; - for (auto &anf_node : list) { - MS_EXCEPTION_IF_NULL(anf_node); - for (auto &input : anf_node->inputs()) { - (void)has_output_nodes.insert(input); - } - } - - auto make_tuple_primitve = NewValueNode(std::make_shared(prim::kPrimMakeTuple->name())); - std::vector make_tuple_inputs = {make_tuple_primitve}; - int output_idx = 0; - MS_EXCEPTION_IF_NULL(new_kernel_graph); - for (auto &anf_node : list) { - if (AnfAlgo::CheckPrimitiveType(anf_node, prim::kPrimReturn)) { - new_kernel_graph->set_return(anf_node); - } - if (has_output_nodes.find(anf_node) == has_output_nodes.end()) { - MS_EXCEPTION_IF_NULL(anf_node); - MS_LOG(INFO) << "Output[" << output_idx++ << "]:" << anf_node->DebugString(); - make_tuple_inputs.push_back(anf_node); - } - } - if (new_kernel_graph->get_return() == nullptr) { - new_kernel_graph->set_output(new_kernel_graph->NewCNode(make_tuple_inputs)); - } -} - -std::vector AscendSession::ConstructSplitedGraph(const KernelGraphPtr &new_kernel_graph, - const std::vector &list) { - MS_EXCEPTION_IF_NULL(new_kernel_graph); - MS_LOG(INFO) << "Start contruct splited kernel graph:" << new_kernel_graph->graph_id(); - MS_LOG(INFO) << "Construct input of kernel graph:" << new_kernel_graph->graph_id(); - std::vector call_node_inputs; - std::vector new_graph_inputs; - // create new parameter from cnode - for (auto &anf_node : list) { - MS_EXCEPTION_IF_NULL(anf_node); - auto cnode = anf_node->cast(); - for (size_t input_idx = 1; input_idx < cnode->inputs().size(); input_idx++) { - auto input = cnode->inputs()[input_idx]; - MS_EXCEPTION_IF_NULL(input); - AnfNodePtr new_parameter = nullptr; - // check whether input has been put into args of call, if mulptiple use of one parameter or cnode, only set one - // parameter in graph inputs and one arg in call node - auto call_input_it = std::find(call_node_inputs.begin(), call_node_inputs.end(), input); - if (call_input_it != call_node_inputs.end()) { - cnode->set_input(input_idx, new_graph_inputs[std::distance(call_node_inputs.begin(), call_input_it)]); - continue; - } - // value node consider move to new graph - if (input->isa()) { - cnode->set_input(input_idx, input); - continue; - } else if (AnfAlgo::GetGraphId(input.get()) != new_kernel_graph->graph_id()) { - // if is cnode and not in current child graph - new_parameter = CreateNewParameterFromCNode(input, true, new_kernel_graph.get()); - cnode->set_input(input_idx, new_parameter); - } else { - // if is a cnode and in current graph - continue; - } - new_graph_inputs.push_back(new_parameter); - call_node_inputs.push_back(input); - } - } - // set graph inputs of new graph - auto graph_inputs = new_kernel_graph->MutableInputs(); - MS_EXCEPTION_IF_NULL(graph_inputs); - graph_inputs->clear(); - std::copy(new_graph_inputs.begin(), new_graph_inputs.end(), std::back_inserter(*graph_inputs)); - - MS_LOG(INFO) << "Construct output of kernel graph:" << new_kernel_graph->graph_id(); - ConstructSplitedGraphOutput(new_kernel_graph, list); - MS_LOG(INFO) << "End"; - return call_node_inputs; -} - void AscendSession::BackendOptimization(const std::vector &all_graphs) { MS_LOG(INFO) << "Start BackendCommonOptimization"; for (auto &graph : all_graphs) { @@ -1671,134 +870,12 @@ void AscendSession::BackendOptimization(const std::vector &all_g MS_LOG(INFO) << "End."; } -void AscendSession::SplitGraphs(NotNull root_graph) { - std::set memo; - // if output of graph is nullptr,no need insert maketuple at the end of graph - if (root_graph->output() == nullptr) { - return; - } - // if root graph output is a call node ,the root graph is condition graph of 'if' sentence - auto root_graph_output = AnfAlgo::VisitKernelWithReturnType(root_graph->output(), 0).first; - if (AnfAlgo::CheckPrimitiveType(root_graph_output, prim::kPrimCall)) { - SplitGraph(root_graph, {prim::kPrimReturn}, NOT_NULL(&memo)); - for (auto &child_graph : root_graph->child_graph_order()) { - RecurseSplitGraph(NOT_NULL(child_graph), NOT_NULL(&memo)); - } - } else { - RecurseSplitGraph(root_graph, NOT_NULL(&memo)); - } - memo.clear(); - // add maketuple to the end of the last child graph to suit old process - auto output_graph = root_graph->child_graph_order().empty() ? root_graph : root_graph->child_graph_order().back(); - auto make_tuple = output_graph->NewCNode( - {NewValueNode(std::make_shared(prim::kPrimMakeTuple->name())), output_graph->output()}); - output_graph->set_output(make_tuple); - // replace the real input if the real input is a call - RecurseToUpdateCallRealInput(root_graph, NOT_NULL(&memo)); -} - -AnfNodePtr AscendSession::BindNewCallToNewGraph(NotNull graph, - const std::vector &child_graph_list) { - // if child graph list only has a call ,then return the exist call - if (child_graph_list.size() == 1 && AnfAlgo::CheckPrimitiveType(child_graph_list[0], prim::kPrimCall)) { - return child_graph_list[0]; - } - // create new child graph - auto child_graph = NewKernelGraph(); - MS_EXCEPTION_IF_NULL(child_graph); - // create new value node to bind child graph - auto graph_value_node = graph->NewValueNode(NewValueNode(child_graph)); - std::vector new_call_input = {NewValueNode(std::make_shared(prim::kPrimCall->name())), - graph_value_node}; - // set the graph id of all node of child graph - for (auto &child_graph_node : child_graph_list) { - AnfAlgo::SetGraphId(child_graph->graph_id(), child_graph_node.get()); - } - auto call_node_args = ConstructSplitedGraph(child_graph, child_graph_list); - std::copy(call_node_args.begin(), call_node_args.end(), std::back_inserter(new_call_input)); - auto new_call = graph->NewCNode(new_call_input); - AnfAlgo::SetNodeAttr("graph_id", MakeValue(graph->graph_id()), new_call); - return new_call; -} - -void AscendSession::SplitGraph(NotNull graph, const std::set &cut_prims, - const NotNull *> memo) { - MS_LOG(INFO) << "Start,graph_id:" << graph->graph_id(); - bool split_flag = false; - auto apply_list = GetCNodes(TopoSort(graph->get_return())); - // update the root graph child graph order - graph->UpdateChildGraphOrder(); - // get child list from current graph - std::vector> child_graph_lists = GetChildList(apply_list, cut_prims); - if (child_graph_lists.size() > 1) { - std::list depend_input = {}; - for (size_t call_index = 0; call_index < child_graph_lists.size(); call_index++) { - auto call_node = BindNewCallToNewGraph(graph, child_graph_lists[call_index]); - MS_EXCEPTION_IF_NULL(call_node); - // if call node is the last call of true graph,no need create child graph after that - auto child_graphs = AnfAlgo::GetCallNodeKernelGraph(call_node->cast()); - depend_input.push_front(call_node); - if (child_graphs.size() == 1 && child_graphs[0] == graph->parent_graph()) { - break; - } - } - depend_input.push_front(graph->NewValueNode(NewValueNode(std::make_shared(prim::kPrimDepend->name())))); - auto depend = graph->NewCNode(std::vector(depend_input.begin(), depend_input.end())); - auto new_return_primitive = - graph->NewValueNode(NewValueNode(std::make_shared(prim::kPrimReturn->name()))); - graph->set_return(graph->NewCNode({new_return_primitive, depend})); - AnfNodePtr pre_call_node = nullptr; - AnfNodePtr cur_call_node = nullptr; - auto iter = depend_input.begin(); - for (++iter; iter != depend_input.end(); ++iter) { - pre_call_node = cur_call_node; - cur_call_node = *iter; - if (pre_call_node != nullptr && cur_call_node != nullptr) { - AscendControlParser::InsertControlDependToGraph(graph, NOT_NULL(cur_call_node), NOT_NULL(pre_call_node)); - } - } - split_flag = true; - } - graph->UpdateChildGraphOrder(); - UpdateRealInput(graph, split_flag, memo); - MS_LOG(INFO) << "Split graph[" << graph->graph_id() << "] end"; -} - -void AscendSession::RecurseSplitGraph(NotNull graph, const NotNull *> memo) { - memo->insert(graph.get()); - SplitGraph(graph, {prim::kPrimCall}, memo); - for (auto &child_graph : graph->child_graph_order()) { - if (memo->find(child_graph) == memo->end()) { - RecurseSplitGraph(NOT_NULL(child_graph), memo); - } - } -} - void AscendSession::LinkChildGraphs(NotNull graph) { AscendControlParser::LinkGraph(graph); } void AscendSession::RootGraphExecutorValidate(NotNull graph) { AscendControlParser::ExecutorValidate(graph); } -void AscendSession::RecurseCompileGraph(NotNull graph, const NotNull *> memo) { - memo->insert(graph.get()); - CompileChildGraph(graph); - for (auto child_graph : graph->child_graph_order()) { - if (memo->find(child_graph) != memo->end()) { - continue; - } - RecurseCompileGraph(NOT_NULL(child_graph), memo); - // copy ref map to final graph - auto child_ref_map = child_graph->GetRefMap(); - for (auto &item : child_ref_map) { - if (graph->IsInRefOutputMap(item.first)) { - MS_LOG(EXCEPTION) << "The ref pair is already in final graph!"; - } - graph->AddRefCorrespondPairs(item.first, item.second); - } - } -} - void AscendSession::CreateMultiBranchOutput(NotNull graph, NotNull *> memo) { if (memo->find(graph.get()) != memo->end()) { return; diff --git a/mindspore/ccsrc/backend/session/ascend_session.h b/mindspore/ccsrc/backend/session/ascend_session.h index ddd9f8d7aa4..a42377bbaaf 100755 --- a/mindspore/ccsrc/backend/session/ascend_session.h +++ b/mindspore/ccsrc/backend/session/ascend_session.h @@ -51,26 +51,16 @@ class AscendSession : public SessionBasic { py::tuple RunOp(const OpRunInfo &op_run_info, const GraphInfo &graph_info, const std::vector &input_tensors) override; - // set parameters of final graph - GraphId SetFinalGraphInput(const std::vector &args) override; - // set output of final graph - void SetFinalGraphOutput(const BaseRef &output) override; - // insert switch and set the relative active ops - void SwitchCompile(GraphId cond_g, GraphId true_g, GraphId false_g, const AnfNodePtr &condition_output) override; - // set args of child graph.the arg maybe come from a output of other child graphs,or from final graph's parameter - void SetChildGraphInput(GraphId g, const VectorRef &args) override; // get graph id in child graphs by ME front anf node pointer GraphId GetGraphIdByNode(const AnfNodePtr &front_anf) const override; // get graph id of final graph GraphId GetFinalRunGraph() const override { return final_graph_id_; } - // insert active to graph - void SetActive(GraphId, GraphId) override; // compile child graph when session have multiple child graphs void CompileChildGraph(const KernelGraphPtr &child_graph); - void RecurseGetSummaryNodes(KernelGraph *graph, std::map> *summary); - void GetSummaryNodes(KernelGraph *graph); private: + void RecurseSetSummaryNodes(KernelGraph *graph, std::map> *summary); + void SetSummaryNodes(KernelGraph *graph) override; void InitRuntimeResource(); void SelectKernel(const KernelGraph &kernel_graph) const; void HardwareOptimize(const std::shared_ptr &kernel_graph) const; @@ -92,63 +82,21 @@ class AscendSession : public SessionBasic { void RunOpHardwareOptimize(const std::shared_ptr &kernel_graph) const; void RunOpExecTask(const std::shared_ptr &kernel_graph) const; - size_t SetChildGraphInput(const KernelGraphPtr &graph, const AnfNodePtr &node, size_t input_index); - size_t SetChildGraphInput(const KernelGraphPtr &graph, const ValuePtr &value, size_t input_index); - size_t SetChildGraphInput(const KernelGraphPtr &graph, const VectorRef &vec_args, size_t input_index); - - void SetFinalGraphOutput(const AnfNodePtr &node); - void SetFinalGraphOutput(const ValuePtr &value); - void SetFinalGraphOutput(const VectorRef &vec_output); - - void SplitGraph(NotNull graph, const std::set &cut_prims, - const NotNull *> memo); - // split graphs with recurse from root graph - void SplitGraphs(NotNull root_graph); - void BackendOptimization(const std::vector &all_graphs); - void LinkChildGraphs(NotNull graph); + static void BackendOptimization(const std::vector &all_graphs); + static void LinkChildGraphs(NotNull graph); void RootGraphExecutorValidate(NotNull graph); - std::vector ConstructSplitedGraph(const KernelGraphPtr &new_kernel_graph, - const std::vector &list); - void RecurseCompileGraph(NotNull graph, const NotNull *> memo); - void RecurseSplitGraph(NotNull graph, const NotNull *> memo); - AnfNodePtr BindNewCallToNewGraph(NotNull graph, const std::vector &child_graph_list); - // merge execution order list of child graphs void MergeGraphExecOrder(); // insert assion op to sync data bettween different graphs void InsertAssignToGraph(GraphId graph_id, const AnfNodePtr &from, const AnfNodePtr &to); - // insert mutiple assigns to graph - void InsertMultipleAssignToGraph(GraphId graph_id, const AnfNodePtr &from, const AnfNodePtr &to); - // insert active op to graph - void InsertStreamActiveToGraph(GraphId graph_id, uint32_t actived_stream); - // get execute index of graph - size_t ExecOrderOfChildGraph(GraphId final_graph, GraphId child_graph); - // handle condition graph from vm - void InsertSwitchToGraph(GraphId condition_graph_id, GraphId true_graph_id); - // insert depend to graph, used to attch control nodes to graph - void InsertDependToGraph(GraphId graph_id, const AnfNodePtr &attch_node); - // insert depend to graph, used to attch control nodes to graph - void InsertControlDependToGraph(GraphId graph_id, const AnfNodePtr &first_node, const AnfNodePtr &second_node); - // set child graph parameter if front arg is a anf - void SetChildGraphParameter(const AnfNodePtr &front_anf, GraphId to_graph_id, size_t input_idx); - // set child graph parameter if front arg is a tensor - void SetChildGraphParameter(const tensor::TensorPtr &front_tensor, GraphId to_graph_id, size_t input_idx); - // update the execution order of all child graphs - void UpdateGraphOrder(GraphId to_graph); - // handle switch when merge - void MergeSwitchCompile(); // get graph order vector by graph id - std::vector &GetGraphOrder(GraphId final_graph_id); + const std::vector &GetGraphOrder(GraphId final_graph_id) const; // get graph order type vector by graph id - std::vector &GetGraphOrderType(GraphId final_graph_id); - // copy output of if and else - void CopyOutputOfIf(GraphId false_graph_id); + const std::vector &GetGraphOrderType(GraphId final_graph_id) const; // check if graph cache exist bool GraphCacheExist(const GraphInfo &graph_info) const; // insert all assign to child graph void InsertAllAssigns(); - // create fake output of final graph - AnfNodePtr CreateFakeOutput(GraphId final_graph_id, const AnfNodePtr &true_output); // sync intial tensors' data to device void SyncInitialTenosrToDevice(); void SetFinalGraphSummaryFlag(const std::shared_ptr &kernel_graph); @@ -162,16 +110,10 @@ class AscendSession : public SessionBasic { void AssignStaticMemory(const NotNull graph, NotNull *> memo) const; void UpdateRefOutputMap(const NotNull graph, NotNull *> memo) const; - // member variables // key is final_graph_id,value is child graph execute order of final graph std::unordered_map> graph_execute_orders_; // key is final_graph_id,value is the graph types of child graphs std::unordered_map> graph_order_types_; - // record condition graph of while - std::unordered_map while_condition_graphs_; - // record all conditions - std::unordered_map> switches_; - std::unordered_map condition_output_; // share parameters std::vector> assigns_; // initial tensors, these tensor will sync data to device before run graph diff --git a/mindspore/ccsrc/backend/session/cpu_session.cc b/mindspore/ccsrc/backend/session/cpu_session.cc index a15827fa8a6..94862a0a59d 100644 --- a/mindspore/ccsrc/backend/session/cpu_session.cc +++ b/mindspore/ccsrc/backend/session/cpu_session.cc @@ -108,7 +108,7 @@ void CPUSession::RunGraph(const GraphId &graph_id, const std::vectorset_execution_order(execution_order); NamedSummaryOutputs summary_outputs; if (enable_summary) { - GetSummaryNodes(kernel_graph.get()); + SetSummaryNodes(kernel_graph.get()); summary_outputs = kernel_graph->summary_nodes(); runtime_.IncreaseSummaryRefCount(summary_outputs); } diff --git a/mindspore/ccsrc/backend/session/gpu_session.cc b/mindspore/ccsrc/backend/session/gpu_session.cc index 8462664f67f..b3b6844e884 100644 --- a/mindspore/ccsrc/backend/session/gpu_session.cc +++ b/mindspore/ccsrc/backend/session/gpu_session.cc @@ -217,7 +217,7 @@ GraphId GPUSession::CompileGraph(const AnfNodePtrList &lst, const AnfNodePtrList Reorder(&execution_order); graph->set_execution_order(execution_order); // Get summary nodes. - GetSummaryNodes(graph.get()); + SetSummaryNodes(graph.get()); // Remove NoOp from execution graph opt::RemoveNopNode(graph.get()); // Set graph manager. diff --git a/mindspore/ccsrc/backend/session/kernel_graph.cc b/mindspore/ccsrc/backend/session/kernel_graph.cc index aa5a62e7e4e..d8183c1b2bb 100644 --- a/mindspore/ccsrc/backend/session/kernel_graph.cc +++ b/mindspore/ccsrc/backend/session/kernel_graph.cc @@ -898,27 +898,6 @@ void KernelGraph::ReplaceNode(NotNull old_anf_node, NotNull seed_nodes; UpdateNodeEdgeList(&seed_nodes); } - // update graph inputs in child graph - auto it_real_inputs = std::find_if(real_inputs_.begin(), real_inputs_.end(), - [&old_anf_node](const std::pair> &n) -> bool { - return n.first == old_anf_node.get(); - }); - if (it_real_inputs != real_inputs_.end()) { - // erase old parameter in map - auto old_args = it_real_inputs->second; - real_inputs_.erase(it_real_inputs); - // insert new parameter to map - auto iter = std::find_if(real_inputs_.begin(), real_inputs_.end(), - [&new_anf_node](const std::pair> &n) -> bool { - return n.first == new_anf_node.get(); - }); - if (iter != real_inputs_.end()) { - MS_LOG(WARNING) << new_anf_node->DebugString() << " Already exist in real inputs, will be rewrited."; - iter->second = old_args; - } else { - real_inputs_.emplace_back(new_anf_node, old_args); - } - } } void KernelGraph::UpdateExecuteKernelStreamLabel() { @@ -953,56 +932,6 @@ std::vector KernelGraph::FindNodeByPrimitive(const PrimitivePtr &primi return result; } -void KernelGraph::SetRealInput(const AnfNodePtr ¶meter, const AnfNodePtr &arg) { - MS_EXCEPTION_IF_NULL(parameter); - MS_EXCEPTION_IF_NULL(arg); - MS_LOG(INFO) << "Parameter: " << parameter->DebugString() << ", real input : " << arg->DebugString(); - MS_EXCEPTION_IF_NULL(parameter); - MS_EXCEPTION_IF_NULL(arg); - auto iter = std::find_if( - real_inputs_.begin(), real_inputs_.end(), - [¶meter](const std::pair> &n) -> bool { return n.first == parameter; }); - if (iter != real_inputs_.end()) { - auto &args = iter->second; - args.push_back(arg); - } else { - real_inputs_.emplace_back(parameter, std::vector(1, arg)); - } -} - -void KernelGraph::AddUnreuseArgs(const AnfNodePtr &arg, const std::shared_ptr &from_graph) { - unreuse_args_[arg] = from_graph; -} - -void KernelGraph::UpdateCallRealInput() { - MS_LOG(INFO) << "Update graph id: " << graph_id_; - std::vector>> real_inputs_map; - for (auto &it : real_inputs_) { - auto parameter = it.first; - MS_EXCEPTION_IF_NULL(parameter); - auto real_inputs = it.second; - std::vector new_real_inputs; - for (auto &real_input : real_inputs) { - // if real input is a call node ,find the child graph output act as the new real input - auto tmp_real_input = GetCallRealOutputs(real_input); - std::copy(tmp_real_input.begin(), tmp_real_input.end(), std::back_inserter(new_real_inputs)); - // replace the call in unreuse_args_ - auto unreuse_arg_it = unreuse_args_.find(real_input); - if (unreuse_arg_it != unreuse_args_.end()) { - auto old_graph = unreuse_arg_it->second; - for (auto new_real_input : new_real_inputs) { - // if call reference graph output is parameter, it will be allowed to reuse - if (!new_real_input->isa()) { - unreuse_args_[new_real_input] = old_graph; - } - } - } - } - real_inputs_map.emplace_back(parameter, new_real_inputs); - } - real_inputs_ = real_inputs_map; -} - void KernelGraph::PrintGraphExecuteOrder() const { MS_LOG(INFO) << "Graph:" << graph_id_ << "execution order"; for (size_t i = 0; i < execution_order_.size(); i++) { diff --git a/mindspore/ccsrc/backend/session/kernel_graph.h b/mindspore/ccsrc/backend/session/kernel_graph.h index 7e3988e11bc..1576a4c31d7 100644 --- a/mindspore/ccsrc/backend/session/kernel_graph.h +++ b/mindspore/ccsrc/backend/session/kernel_graph.h @@ -131,16 +131,8 @@ class KernelGraph : public FuncGraph { void set_parent_graph(const std::shared_ptr &parent_graph) { parent_graph_ = parent_graph; } // find anf node in graph std::vector FindNodeByPrimitive(const PrimitivePtr &primitive) const; - // get real inputs - const std::vector>> &real_inputs() const { return real_inputs_; } - void SetRealInput(const AnfNodePtr ¶meter, const AnfNodePtr &arg); - // mark unreused args - void AddUnreuseArgs(const AnfNodePtr &arg, const std::shared_ptr &from_graph); - const std::map> &unreuse_args() const { return unreuse_args_; } // used to dump ir std::string ToString() const override; - // update the real input if the node is a call - void UpdateCallRealInput(); void set_start_label(const CNodePtr &start_label) { start_label_ = start_label; } CNodePtr get_start_label() { return start_label_; } @@ -212,9 +204,6 @@ class KernelGraph : public FuncGraph { // valid inputs std::vector valid_inputs_; - // new members for control sink process - // all child grahs refers to partial node - std::map> node_to_child_graphs_; // child graph execute order in root graph std::vector> child_graph_order_; @@ -223,9 +212,6 @@ class KernelGraph : public FuncGraph { // parameter graph std::shared_ptr parent_graph_; - // record real parameters,inputs_ is the formal parameters - std::vector>> real_inputs_; - std::map> unreuse_args_; CNodePtr start_label_; CNodePtr end_goto_; diff --git a/mindspore/ccsrc/backend/session/session_basic.cc b/mindspore/ccsrc/backend/session/session_basic.cc index 79efb26088b..ee33ff39fc2 100644 --- a/mindspore/ccsrc/backend/session/session_basic.cc +++ b/mindspore/ccsrc/backend/session/session_basic.cc @@ -890,7 +890,7 @@ void SessionBasic::RegisterSummaryCallBackFunc(const CallBackFunc &callback) { void SessionBasic::Reorder(std::vector *node_list) { AnfAlgo::ReorderExecList(NOT_NULL(node_list)); } -void SessionBasic::GetSummaryNodes(KernelGraph *graph) { +void SessionBasic::SetSummaryNodes(KernelGraph *graph) { MS_LOG(DEBUG) << "Update summary Start"; MS_EXCEPTION_IF_NULL(graph); if (!graph->summary_node_exist()) { @@ -930,7 +930,7 @@ void SessionBasic::Summary(KernelGraph *graph) { if (!exist_summary) { return; } - GetSummaryNodes(graph); + SetSummaryNodes(graph); auto summary_outputs = graph->summary_nodes(); std::map params_list; // fetch outputs apply kernel in session & run callback functions diff --git a/mindspore/ccsrc/backend/session/session_basic.h b/mindspore/ccsrc/backend/session/session_basic.h index 838a8807aed..427c49bdbb4 100755 --- a/mindspore/ccsrc/backend/session/session_basic.h +++ b/mindspore/ccsrc/backend/session/session_basic.h @@ -92,19 +92,9 @@ class SessionBasic { CNodePtr HandleSwitchInputs(const AnfNodePtr &anf_node, KernelGraph *graph); std::vector CreateSwitchOrPartialNode(const CNodePtr &cnode, KernelGraph *graph); - // set parameters of final graph - virtual GraphId SetFinalGraphInput(const std::vector &) { return kInvalidGraphId; } - // set output of final graph - virtual void SetFinalGraphOutput(const BaseRef &) {} - // insert switch and set the relative active ops - virtual void SwitchCompile(GraphId, GraphId, GraphId, const AnfNodePtr &) {} - // set args of child graph.the arg maybe come from a output of other child graphs,or from final graph's parameter - virtual void SetChildGraphInput(GraphId, const VectorRef &) {} // get graph id in child graphs by ME front anf node pointer virtual GraphId GetGraphIdByNode(const AnfNodePtr &) const { return kInvalidGraphId; } virtual GraphId GetFinalRunGraph() const { return kInvalidGraphId; } - virtual void SetActive(GraphId, GraphId) {} - virtual void GetSummaryNodes(KernelGraph *graph); void AssignParamKey(const KernelGraphPtr &kernel_graph); void InitPSParamAndOptim(const KernelGraphPtr &kernel_graph, const std::vector &inputs_const); virtual bool CheckModelInputs(uint32_t graph_id, const std::vector &inputs) const { return true; } @@ -120,6 +110,7 @@ class SessionBasic { #endif protected: + virtual void SetSummaryNodes(KernelGraph *graph); // Get graph by graph id ,if not exist return null ptr KernelGraphPtr GetGraph(GraphId graph_id) const; virtual void LoadInputData(const std::shared_ptr &kernel_graph, diff --git a/mindspore/ccsrc/pipeline/pynative/CMakeLists.txt b/mindspore/ccsrc/pipeline/pynative/CMakeLists.txt index c15928ee768..661b62ca61a 100644 --- a/mindspore/ccsrc/pipeline/pynative/CMakeLists.txt +++ b/mindspore/ccsrc/pipeline/pynative/CMakeLists.txt @@ -1,4 +1,4 @@ -file(GLOB_RECURSE _PYNATIVE_SRC_LIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "base.cc" "pynative_execute.cc") +file(GLOB_RECURSE _PYNATIVE_SRC_LIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "pynative_execute.cc") if (ENABLE_GE) file(GLOB_RECURSE _GE_SRC_LIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "pynative_execute_ge.cc") diff --git a/mindspore/ccsrc/vm/backend.cc b/mindspore/ccsrc/vm/backend.cc index 0290ee57fc2..654e546e3ca 100644 --- a/mindspore/ccsrc/vm/backend.cc +++ b/mindspore/ccsrc/vm/backend.cc @@ -21,7 +21,6 @@ #include "utils/log_adapter.h" #include "ir/anf.h" #include "utils/callbacks.h" -#include "utils/graph_utils.h" #include "utils/base_ref_extends.h" #include "backend/session/session_factory.h" #include "common/utils.h" @@ -34,19 +33,6 @@ namespace compile { bool Backend::GetCond(const BaseRef &c, bool *const value) { return BaseRefToBool(c, value); } bool Backend::GetIndex(const BaseRef &c, int *const value) { return BaseRefToInt(utils::cast(c), value); } -LinConvertResult MsBackend::GetMultiGraphRun(const FuncGraphPtr &g) { - // multi_graph merge to one, big graph have paramters in begin and only have one output - MS_LOG(DEBUG) << "graph:" << g->ToString() << " parameter size:" << g->parameters().size(); - multi_result_.inputs = g->parameters(); - final_output_ = NewValueNode("fake_output"); - multi_result_.outputs = {final_output_}; - GraphId final_g = target_sess_->GetFinalRunGraph(); - - multi_result_.run = std::make_shared( - [final_g, this](const VectorRef &args) -> VectorRef { return MsRunGraph(final_g, args, ""); }); - return multi_result_; -} - LinConvertResult MsBackend::MsConvert(const AnfNodePtrList &lst, const std::string &target) { MS_LOG(DEBUG) << "MsConvert"; MS_EXCEPTION_IF_NULL(MsContext::GetInstance()); @@ -96,149 +82,9 @@ LinConvertResult MsBackend::MsConvert(const AnfNodePtrList &lst, const std::stri return result; } -void MsBackend::SetSwitchActive(const BaseRef &c, bool cond) { - GraphId active_g = simu_cond_map_[c].cond_graph_map[cond]; - - GraphId cond_g = kInvalidGraphId; - if (utils::isa(c)) { - cond_g = target_sess_->GetGraphIdByNode(utils::cast(c)); - } else { - MS_LOG(EXCEPTION) << "cond not a anf node:" << c.ToString(); - } - auto before_cond = curr_switch_; - if (curr_switch_.hash() != c.hash()) { - // invoke while false->before true call - if (simu_cond_map_[before_cond].cond_graph_map.count(false)) { - active_g = simu_cond_map_[before_cond].cond_graph_map[false]; - } else { - active_g = kInvalidGraphId; - } - // while x < y: - // z = y + 1 - // while z < c2: - // out = out + 1 - // z = z + 1 - if (active_g == cond_g) { - active_g = kInvalidGraphId; - simu_cond_map_[before_cond].cond_graph_map[false] = kInvalidGraphId; - } - MS_LOG(DEBUG) << "invoke set active:" << active_g; - } - MS_LOG(DEBUG) << "switch set active:" << active_g << ", " << cond_g; - target_sess_->SetActive(active_g, cond_g); -} - -void MsBackend::SetSwitchGraph() { - MS_LOG(DEBUG) << "SetSwitchGraph curr_switch:" << curr_switch_.ToString(); - - if (is_switch_call_) { - GraphId false_g = kInvalidGraphId; - GraphId true_g = kInvalidGraphId; - MS_LOG(DEBUG) << "start SetSwitchGraph"; - true_g = simu_cond_map_[curr_switch_].cond_graph_map[true]; - bool curr_cond = simu_cond_map_[curr_switch_].curr_cond; - if (!curr_cond) { - if (simu_cond_map_[curr_switch_].cond_graph_map.count(curr_cond)) { - // has false branch - false_g = simu_cond_map_[curr_switch_].cond_graph_map[false]; - } - GraphId cond_g = kInvalidGraphId; - if (utils::isa(curr_switch_)) { - cond_g = target_sess_->GetGraphIdByNode(utils::cast(curr_switch_)); - } else { - MS_LOG(EXCEPTION) << "cond not a anf node:" << curr_switch_.ToString(); - } - MS_LOG(DEBUG) << "switch compile:" << cond_g << ", " << true_g << ", " << false_g; - target_sess_->SwitchCompile(cond_g, true_g, false_g, utils::cast(curr_switch_)); - } - is_switch_call_ = false; - MS_LOG(DEBUG) << "end SetSwitchGraph:" << curr_cond << ", " << is_switch_call_; - } -} - -// convert node from formal parameter to actual parameter, -// and actual parameter is graph user's formal parameter. -// get top while graph's parameter in recall while. -AnfNodePtr MsBackend::ConvertGraphInput(const FuncGraphPtr &func_graph, const AnfNodePtr &node) { - std::unordered_map params_index; - auto result = node; - auto graph = result->func_graph(); - while (func_graph != graph) { - auto iter = graph_user_inputs_.find(graph); - if (iter == graph_user_inputs_.end()) { - break; - } - - params_index.clear(); - auto ¶ms = graph->parameters(); - for (size_t i = 0; i < params.size(); ++i) { - params_index[params[i]] = i; - } - - graph = iter->second.first; - auto &inputs = iter->second.second; - result = inputs[params_index[result]]; - } - return result; -} - -void MsBackend::SetGraphUserInputs(const FuncGraphPtr &func_graph, const FuncGraphPtr &user, - const AnfNodePtrList &inputs) { - if (graph_user_inputs_.find(func_graph) != graph_user_inputs_.end()) { - return; - } - graph_user_inputs_[func_graph] = {user, inputs}; -} - -void MsBackend::RecallGraphInput(const FuncGraphPtr &func_graph, const VectorRef &args, const BaseRef &c) { - std::unordered_map params_index; - auto ¶ms = func_graph->parameters(); - for (size_t i = 0; i < params.size(); ++i) { - params_index[params[i]] = i; - } - - // recall all child graphs in this while - auto &graph_inputs = graph_inputs_[c]; - for (auto &iter : graph_inputs) { - auto &graph = iter.first; - auto &old_args = iter.second; - auto &result = graph_id_map_[graph]; - auto &inputs = result.inputs; - for (size_t i = 0; i < inputs.size(); ++i) { - auto input = ConvertGraphInput(func_graph, inputs[i]); - auto it = params_index.find(input); - if (it != params_index.end()) { - old_args[i] = args[it->second]; - } - } - target_sess_->SetChildGraphInput(graph, old_args); - } - graph_inputs_.erase(c); -} - // compile set input output VectorRef MsBackend::MsSimuRunGraph(const GraphId &g, const VectorRef &args) { MS_LOG(DEBUG) << "set graph input:" << g; - // switch maybe twice - target_sess_->SetChildGraphInput(g, args); - - if (is_switch_call_) { - if (!curr_switch_.is_null()) { - // push this {g, args} to all user while graph_inputs for nest while, - // when current condition recall over delete this cond in graph_inputs. - for (auto &iter : graph_inputs_) { - iter.second.push_back({g, args}); - } - if (graph_inputs_.find(curr_switch_) == graph_inputs_.end()) { - graph_inputs_[curr_switch_].push_back({g, args}); - } - } - bool curr_cond = simu_cond_map_[curr_switch_].curr_cond; - MS_LOG(DEBUG) << "switch call MsSimuRunGraph:" << curr_cond << ", " << g; - simu_cond_map_[curr_switch_].cond_graph_map[curr_cond] = g; - SetSwitchGraph(); - } - std::vector outputs; (void)std::transform(graph_id_map_[g].outputs.begin(), graph_id_map_[g].outputs.end(), std::back_inserter(outputs), [](const AnfNodePtr &v) { return v; }); @@ -290,36 +136,6 @@ VectorRef MsBackend::MsRunGraph(const GraphId &g, const VectorRef &args, const s return outputs; } -SwitchCondStatus MsBackend::SetSimuCond(const BaseRef &c, bool value) { - MS_LOG(DEBUG) << "set cond :" << c.ToString() << ", " << simu_cond_map_.size(); - - CondGraph cond_graph; - cond_graph.curr_cond = value; - if (simu_cond_map_.find(c) == simu_cond_map_.end()) { - simu_cond_map_[c] = cond_graph; - } - - if (simu_cond_map_[c].cond_graph_map.count(value)) { - return kCondAlreadyRun; - } - simu_cond_map_[c].curr_cond = value; - MS_LOG(DEBUG) << "end set cond "; - return kCondOk; -} - -void MsBackend::SimulateRun(FinalVMPtr rt, FuncGraphPtr root) { - MS_LOG(DEBUG) << "Simulate run,root:" << root->ToString() << ", " << root->parameters().size(); - std::vector args; - auto parameters = root->parameters(); - (void)std::transform(parameters.begin(), parameters.end(), std::back_inserter(args), - [](const AnfNodePtr &v) { return v; }); - MS_LOG(DEBUG) << "Simulate start"; - (void)target_sess_->SetFinalGraphInput(parameters); - BaseRef output = rt->Eval(VectorRef(args)); - target_sess_->SetFinalGraphOutput(output); - MS_LOG(DEBUG) << "Simulate Eval end"; -} - void MsBackend::Link(GraphId graph_id) { if (graph_id == kInvalidGraphId) { graph_id = target_sess_->GetFinalRunGraph(); @@ -330,9 +146,6 @@ void MsBackend::Link(GraphId graph_id) { Backend::Backend(const std::string &name) : name_(name) { MS_LOG(DEBUG) << "select backend:" << name; convert_fn_ = backends[name_]; - is_switch_call_ = false; - is_multi_graph_sink_ = false; - simu_flag_ = false; } MsBackend::MsBackend(const std::string &name, const std::string &target, uint32_t device_id) : Backend(name) { diff --git a/mindspore/ccsrc/vm/backend.h b/mindspore/ccsrc/vm/backend.h index 208c4010fb5..1bb7c2e406a 100644 --- a/mindspore/ccsrc/vm/backend.h +++ b/mindspore/ccsrc/vm/backend.h @@ -43,50 +43,19 @@ class Backend { LinkFuncType convert_fn() { return convert_fn_; } std::string name() { return name_; } - virtual void SimulateRun(FinalVMPtr, FuncGraphPtr) {} - virtual SwitchCondStatus SetSimuCond(const BaseRef &, bool) { return kCondOk; } virtual bool GetCond(const BaseRef &c, bool *value); virtual bool GetIndex(const BaseRef &c, int *value); - virtual void SetSwitchGraph() {} - virtual void SetSwitchActive(const BaseRef &, bool) {} - virtual void RecallGraphInput(const FuncGraphPtr &, const VectorRef &, const BaseRef &) {} - virtual void SetGraphUserInputs(const FuncGraphPtr &, const FuncGraphPtr &, const AnfNodePtrList &) {} virtual GraphId CompileGraph(NotNull fg) { return kInvalidGraphId; } - void set_curr_switch(const BaseRef &value) { - curr_switch_ = value; - is_switch_call_ = true; - } - - BaseRef curr_switch() { return curr_switch_; } virtual void Link(GraphId) {} - virtual LinConvertResult GetMultiGraphRun(const FuncGraphPtr &) { return LinConvertResult(); } + virtual void SetDebugger() {} - LinConvertResult multi_result() { return multi_result_; } - void set_multi_result(const LinConvertResult &value) { multi_result_ = value; } - AnfNodePtr final_output() const { return final_output_; } bool is_multi_graph_sink() const { return is_multi_graph_sink_; } void set_is_multi_graph_sink(bool flag) { is_multi_graph_sink_ = flag; } - bool simu_flag() const { return simu_flag_; } - bool is_switch_call() const { return is_switch_call_; } - void set_simu_flag(bool simu) { simu_flag_ = simu; } - - virtual void SetDebugger() {} protected: std::string name_; LinkFuncType convert_fn_; - BaseRef curr_switch_; // curr switch node bool is_multi_graph_sink_; - bool is_switch_call_; - bool simu_flag_; - LinConvertResult multi_result_; - AnfNodePtr final_output_; - std::unordered_map> graph_user_inputs_; -}; - -struct CondGraph { - bool curr_cond; - std::unordered_map cond_graph_map; }; class MsBackend : public Backend { @@ -98,16 +67,7 @@ class MsBackend : public Backend { VectorRef MsRunGraph(const GraphId &g, const VectorRef &args, const std::string &target = ""); VectorRef MsSimuRunGraph(const GraphId &g, const VectorRef &args); - void SimulateRun(FinalVMPtr rt, FuncGraphPtr root) override; - SwitchCondStatus SetSimuCond(const BaseRef &c, bool value) override; - - void SetSwitchGraph() override; - void SetSwitchActive(const BaseRef &c, bool cond) override; - void RecallGraphInput(const FuncGraphPtr &, const VectorRef &, const BaseRef &) override; - void SetGraphUserInputs(const FuncGraphPtr &, const FuncGraphPtr &, const AnfNodePtrList &) override; void Link(GraphId) override; - AnfNodePtr ConvertGraphInput(const FuncGraphPtr &, const AnfNodePtr &); - LinConvertResult GetMultiGraphRun(const FuncGraphPtr &g) override; GraphId CompileGraph(NotNull fg) override; VectorRef RunGraph(GraphId graph_id, const VectorRef &args); void CreateOtherSession(const std::string &target); @@ -121,9 +81,7 @@ class MsBackend : public Backend { session::SessionPtr other_sess_; std::string target_device_; std::string other_device_; - std::unordered_map simu_cond_map_; std::unordered_map graph_id_map_; - std::unordered_map>, BaseRefHash> graph_inputs_; }; } // namespace compile } // namespace mindspore diff --git a/mindspore/ccsrc/vm/transform.cc b/mindspore/ccsrc/vm/transform.cc index 0b96f2feb90..495d5c4af72 100644 --- a/mindspore/ccsrc/vm/transform.cc +++ b/mindspore/ccsrc/vm/transform.cc @@ -515,11 +515,7 @@ int CompileGraph::LinConvert(const FuncGraphPtr &graph, const AnfNodePtrList &no MS_LOG(DEBUG) << "LinConvert start"; LinConvertResult result; - if (backend_->simu_flag()) { - result = backend_->GetMultiGraphRun(graph); - } else { - result = lin_convert_(node_list, target); - } + result = lin_convert_(node_list, target); if (result.run == nullptr) { MS_LOG(ERROR) << "LinConvert failed"; @@ -546,27 +542,6 @@ int CompileGraph::LinConvert(const FuncGraphPtr &graph, const AnfNodePtrList &no return RET_SUCCESS; } -void CompileGraph::AddSinkSwitch(const CNodePtr &node) { - MS_LOG(DEBUG) << "AddSinkSwitch:" << node->ToString(); - if (backend_->is_multi_graph_sink()) { - VectorRef args; - args.emplace_back(-1); - MS_LOG(DEBUG) << "call::" << height_; - AddInst(Instruction::kCall, args); - - args.clear(); - args.emplace_back(node->input(1)); - AddInst(Instruction::kSwitchReturn, args); - - args.clear(); - args.emplace_back(false); - args.emplace_back(Ref(node->input(1))); - args.emplace_back(Ref(node->input(2))); - args.emplace_back(Ref(node->input(3))); - AddInst(Instruction::kSwitch, args); - } -} - int CompileGraph::InterpretNode(const FuncGraphPtr &graph, const CNodePtr &node) { MS_EXCEPTION_IF_NULL(node); MS_LOG(DEBUG) << "Interpret node: " << node->DebugString(true); @@ -589,7 +564,6 @@ int CompileGraph::InterpretNode(const FuncGraphPtr &graph, const CNodePtr &node) AddPartial(node); } else if (IsPrimitive(fn, prim::kPrimSwitch)) { AddSwitch(node); - AddSinkSwitch(node); } else if (IsPrimitive(fn, prim::kPrimSwitchLayer)) { AddSwitchLayer(node); } else if (IsPrimitive(fn, prim::kPrimMakeTuple)) { @@ -607,14 +581,6 @@ int CompileGraph::InterpretNode(const FuncGraphPtr &graph, const CNodePtr &node) return RET_SUCCESS; } -void CompileGraph::GenMultiGraphsRun(const FuncGraphPtr &graph) { - auto ret = LinConvert(graph, {}); - if (ret == RET_FAILED) { - MS_LOG(EXCEPTION) << "MultiGraphRun failed."; - } - AddReturn(nullptr); -} - bool CompileGraph::SplitGraph(const FuncGraphPtr &graph) { MS_LOG(DEBUG) << "Start split graph"; MS_EXCEPTION_IF_NULL(graph); @@ -659,11 +625,6 @@ bool CompileGraph::SplitGraph(const FuncGraphPtr &graph) { return true; } -InstSet CompileGraph::GenMultiGraphsSinkInst(const FuncGraphPtr &graph) { - InstSet inst = Run(graph); - return inst; -} - InstSet CompileGraph::Run(const FuncGraphPtr &graph) { MS_EXCEPTION_IF_NULL(graph); @@ -672,12 +633,8 @@ InstSet CompileGraph::Run(const FuncGraphPtr &graph) { int param_height = height_; MS_LOG(DEBUG) << "'param_height': " << height_ << " to split graph: " << graph->get_return()->DebugString(true); - if (backend_->simu_flag()) { - GenMultiGraphsRun(graph); - } else { - if (!SplitGraph(graph)) { - return inst_; - } + if (!SplitGraph(graph)) { + return inst_; } AddPadStack(param_height); @@ -712,12 +669,6 @@ void CompileGraph::AddPartial(const CNodePtr &node) { if (!IsValueNode(fn)) { MS_LOG(EXCEPTION) << "The type of 1st input of node must be FuncGraph"; } - if (backend_->is_multi_graph_sink()) { - auto func_graph = GetValueNode(fn); - args.emplace_back(func_graph); - AnfNodePtrList outs(inputs.begin() + 2, inputs.end()); - backend_->SetGraphUserInputs(func_graph, node->func_graph(), outs); - } for (size_t i = 1; i < inputs.size(); i++) { args.emplace_back(Ref(inputs[i])); } @@ -739,9 +690,6 @@ void CompileGraph::AddSwitch(const CNodePtr &node) { MS_LOG(EXCEPTION) << "Length of inputs of primitive " << prim::kPrimSwitch->name() << " is less than 4"; } VectorRef args; - if (backend_->is_multi_graph_sink()) { - args.emplace_back(true); - } args.emplace_back(Ref(inputs[1])); args.emplace_back(Ref(inputs[2])); args.emplace_back(Ref(inputs[3])); @@ -761,11 +709,7 @@ void CompileGraph::AddSwitchLayer(const CNodePtr &node) { void CompileGraph::AddReturn(const CNodePtr &node) { VectorRef args; - if (backend_->simu_flag()) { - args.emplace_back(Ref(backend_->final_output())); - } else { - args.emplace_back(Ref(node->input(1))); - } + args.emplace_back(Ref(node->input(1))); args.emplace_back(height_); AddInst(Instruction::kReturn, args); } @@ -783,11 +727,6 @@ void CompileGraph::AddPrimitive(const CNodePtr &node, const PrimitivePtr &prim) int CompileGraph::AddCall(const FuncGraphPtr &graph, const CNodePtr &node) { auto inputs = node->inputs(); AnfNodePtr fn = inputs[0]; - if (backend_->is_multi_graph_sink() && IsValueNode(fn)) { - auto func_graph = GetValueNode(fn); - AnfNodePtrList outs(inputs.begin() + 1, inputs.end()); - backend_->SetGraphUserInputs(func_graph, node->func_graph(), outs); - } (void)Ref(fn); size_t size = inputs.size(); for (size_t i = size - 1; i > 0; i--) { @@ -929,17 +868,6 @@ FinalVMPtr CompileGraphs::Link(const FuncGraphPtr &graph) { } FinalVMPtr rt = std::make_shared(insts_, backend_); - if (backend_->is_multi_graph_sink()) { - backend_->set_simu_flag(true); - MS_LOG(DEBUG) << "Start simulate"; - backend_->SimulateRun(rt, graph); - MS_LOG(DEBUG) << "Link graphs"; - insts_ = transform_->GenMultiGraphsSinkInst(graph); - rt->set_insts(insts_); - backend_->set_simu_flag(false); - MS_LOG(DEBUG) << "End start simulate"; - backend_->Link(kInvalidGraphId); - } MS_LOG(DEBUG) << "End"; return rt; } diff --git a/mindspore/ccsrc/vm/transform.h b/mindspore/ccsrc/vm/transform.h index d08a24d188f..819ee07eb71 100644 --- a/mindspore/ccsrc/vm/transform.h +++ b/mindspore/ccsrc/vm/transform.h @@ -54,12 +54,10 @@ class CompileGraph { ~CompileGraph() = default; InstSet Run(const FuncGraphPtr &func_graph); - InstSet GenMultiGraphsSinkInst(const FuncGraphPtr &graph); bool IsCut(const AnfNodePtr &node); void Push(const AnfNodePtr &node); void Tie(const AnfNodePtr &n1, const AnfNodePtr &n2) { slots_[n2] = slots_[n1]; } void Ret(int nargs); - void GenMultiGraphsRun(const FuncGraphPtr &graph); int Ref(const AnfNodePtr &node); VectorRef SplitNodes(const FuncGraphPtr &func_graph); @@ -84,7 +82,6 @@ class CompileGraph { int LinConvert(const FuncGraphPtr &func_graph, const AnfNodePtrList &node_list, const std::string &target = ""); int InterpretNode(const FuncGraphPtr &func_graph, const CNodePtr &node); int AddCall(const FuncGraphPtr &graph, const CNodePtr &node); - void AddSinkSwitch(const CNodePtr &node); void AddPadStack(int param_height); void AddTailCall(const AnfNodePtr &fn, size_t size); void AddPartial(const CNodePtr &node); diff --git a/mindspore/ccsrc/vm/vm.cc b/mindspore/ccsrc/vm/vm.cc index baa5b0ea118..091e7af7bc5 100644 --- a/mindspore/ccsrc/vm/vm.cc +++ b/mindspore/ccsrc/vm/vm.cc @@ -17,12 +17,9 @@ */ #include "vm/vm.h" - #include - #include "vm/vmimpl.h" #include "vm/backend.h" -#include "vm/transform.h" #include "pipeline/jit/parse/data_converter.h" #include "utils/base_ref_extends.h" @@ -142,33 +139,10 @@ void FinalVM::Popsp() { } } -void FinalVM::PushStatus(bool is_switch_call) { ret_status_.push(is_switch_call); } - -bool FinalVM::PopStatus() { - if (ret_status_.empty()) { - return false; - } - bool status = ret_status_.top(); - ret_status_.pop(); - return status; -} - void FinalVM::DoJmp(const BaseRef &jmp_orig) { MS_LOG(DEBUG) << "Start"; BaseRef jmp = jmp_orig; - if (backend_->simu_flag()) { - bool is_switch_call = false; - if (utils::isa(jmp)) { // need to inherit from Base - MS_LOG(DEBUG) << "Start jump StructSwitch"; - auto simu_value = utils::cast>(jmp); - jmp = simu_value->fn_; - backend_->set_curr_switch(simu_value->value_); - is_switch_call = true; - } - PushStatus(is_switch_call); - } - if (utils::isa(jmp)) { // need to inherit from Base MS_LOG(DEBUG) << "Start jump StructPartial"; auto new_jmp = utils::cast>(jmp); @@ -270,13 +244,6 @@ void FinalVM::InstSwitchReturn(const VectorRef &args) { MS_LOG(ERROR) << __FUNCTION__ << " requires one parameter, while the input size is " << args.size() << "."; return; } - - auto rv = Ref(-1); - if (utils::isa(rv) || utils::isa(rv)) { - auto &c = args[0]; - cond_out_[c] = rv; - } - Pop(1); Popsp(); } @@ -294,51 +261,12 @@ void FinalVM::InstReturn(const VectorRef &args) { int height = utils::cast(args[1]); auto rv = Ref(rpos); - if (backend_->simu_flag()) { - auto c = backend_->curr_switch(); - auto status = PopStatus(); - if (status) { - auto iter = cond_out_.find(c); - if (iter != cond_out_.end()) { - rv = MergeArgs(rv, iter->second); - cond_out_.erase(iter); - } - } - - if (backend_->is_switch_call()) { - backend_->SetSwitchGraph(); - } - } - Pop(height); Push(rv); Popp(); MS_LOG(DEBUG) << "End"; } -void FinalVM::InstSimuPartial(const VectorRef &args) { - const size_t args_size = 2; - if (args.size() < args_size) { - MS_LOG(ERROR) << __FUNCTION__ << " requires " << args_size << " or more parameters, while the input size is " - << args.size() << "."; - return; - } - - auto &node = args[0]; - if (!utils::isa(node)) { - MS_LOG(ERROR) << "The type of 1st input of node must be FuncGraph"; - return; - } - auto fg = utils::cast(node); - int fn_ = utils::cast(args[1]); - auto fn = utils::cast(Ref(fn_)); - MS_LOG(DEBUG) << "Partial argssize:" << args.size(); - std::vector outs(args.size() - 2); - (void)std::transform(args.begin() + 2, args.end(), outs.begin(), - [&, this](const BaseRef &a) { return Ref(utils::cast(a)); }); - Push(std::make_shared(fn, VectorRef(outs), fg)); -} - void FinalVM::InstRealPartial(const VectorRef &args) { const size_t args_size = 1; if (args.size() < args_size) { @@ -358,91 +286,10 @@ void FinalVM::InstRealPartial(const VectorRef &args) { void FinalVM::InstPartial(const VectorRef &args) { MS_LOG(DEBUG) << "Start"; - if (backend_->is_multi_graph_sink()) { - InstSimuPartial(args); - } else { - InstRealPartial(args); - } + InstRealPartial(args); MS_LOG(DEBUG) << "End"; } -void FinalVM::InstSimuSwitch(const VectorRef &args) { - const size_t args_size = 4; - if (args.size() != args_size) { - MS_LOG(ERROR) << __FUNCTION__ << " requires " << args_size << " parameters, while the input size is " << args.size() - << "."; - return; - } - bool cond = utils::cast(args[0]); - int cond_node = utils::cast(args[1]); - int vtrue = utils::cast(args[2]); - int vfalse = utils::cast(args[3]); - - MS_LOG(DEBUG) << "Simu switch cond:" << cond; - BaseRef c = Ref(cond_node); - bool bool_value = cond; - SwitchCondStatus cond_stat = backend_->SetSimuCond(c, bool_value); - - if (cond_stat == kCondAlreadyRun) { - MS_LOG(DEBUG) << "switch alreay run bool while true jmp"; - BaseRef jmp = Ref(vtrue); - if (utils::isa(jmp)) { - auto new_jmp = utils::cast>(jmp); - backend_->RecallGraphInput(new_jmp->fg_, new_jmp->args_, c); - } - cond_jmp_[c] = Ref(vfalse); - Push(static_cast(cond_stat)); - Popp(); - backend_->SetSwitchActive(c, bool_value); - return; - } - if (bool_value) { - Push(std::make_shared(Ref(vtrue), c)); - Pushsp(); - } else { - MergeJmpArgs(Ref(vfalse), c); - Push(std::make_shared(Ref(vfalse), c)); - } -} - -void FinalVM::MergeJmpArgs(const BaseRef &jmp, const BaseRef &c) { - auto iter = cond_jmp_.find(c); - if (iter == cond_jmp_.end()) { - return; - } - auto old_jmp = utils::cast>(iter->second); - auto new_jmp = utils::cast>(jmp); - auto &old_args = old_jmp->args_; - auto &new_args = new_jmp->args_; - for (size_t i = 0; i < new_args.size(); ++i) { - auto &old_arg = old_args[i]; - auto &new_arg = new_args[i]; - new_arg = MergeArgs(old_arg, new_arg); - } -} - -BaseRef FinalVM::MergeArgs(const BaseRef &first, const BaseRef &second) { - MS_LOG(DEBUG) << __FUNCTION__ << ": " << first.ToString() << ", " << second.ToString(); - if (utils::isa(first)) { - auto old_vec_ref = utils::cast(first); - if (utils::isa(second)) { - auto new_vec_ref = utils::cast(second); - std::copy(new_vec_ref.begin(), new_vec_ref.end(), std::back_inserter(old_vec_ref)); - } else { - old_vec_ref.push_back(second); - } - return old_vec_ref; - } - - if (utils::isa(second)) { - auto new_vec_ref = utils::cast(second); - new_vec_ref.push_back(first); - return new_vec_ref; - } - - return VectorRef({first, second}); -} - void FinalVM::InstRealSwitch(const VectorRef &args) { const size_t args_size = 3; if (args.size() != args_size) { @@ -472,11 +319,7 @@ void FinalVM::InstRealSwitch(const VectorRef &args) { void FinalVM::InstSwitch(const VectorRef &args) { MS_LOG(DEBUG) << "Start"; - if (backend_->is_multi_graph_sink()) { - InstSimuSwitch(args); - } else { - InstRealSwitch(args); - } + InstRealSwitch(args); MS_LOG(DEBUG) << "End"; } @@ -580,14 +423,6 @@ void FinalVM::InstExternal(const VectorRef &args) { VectorRef tuple; RunFunctionRef run_ref = utils::cast(args[0]); compile::RunFuncPtr fn = run_ref.func_; - if (backend_->simu_flag()) { - MS_LOG(DEBUG) << "Simu run"; - if (args.size() == 1) { - MS_LOG(EXCEPTION) << "The number of args should be greater than 1, but got 1"; - } - auto simu_run_ref = utils::cast(args[1]); - fn = simu_run_ref.func_; - } for (size_t i = 2; i < args.size(); ++i) { auto index = utils::cast(args[i]); tuple.push_back(Ref(index)); diff --git a/mindspore/ccsrc/vm/vm.h b/mindspore/ccsrc/vm/vm.h index 02a1ad4ddb1..9986a3a34fb 100644 --- a/mindspore/ccsrc/vm/vm.h +++ b/mindspore/ccsrc/vm/vm.h @@ -96,7 +96,6 @@ class FinalVM { public: // Create a VM with the specified instructions and backend. explicit FinalVM(const InstSet &insts, const BackendPtr &backend); - virtual ~FinalVM() = default; BaseRef Eval(const VectorRef &args); @@ -104,10 +103,8 @@ class FinalVM { void InstTailCall(const VectorRef &args); void InstReturn(const VectorRef &args); void InstPartial(const VectorRef &args); - void InstSimuPartial(const VectorRef &args); void InstRealPartial(const VectorRef &args); void InstSwitch(const VectorRef &args); - void InstSimuSwitch(const VectorRef &args); void InstRealSwitch(const VectorRef &args); void InstTuple(const VectorRef &args); void InstPush(const VectorRef &args); @@ -129,23 +126,16 @@ class FinalVM { void Popp(); void Pushsp(); void Popsp(); - void PushStatus(bool is_switch_call); - bool PopStatus(); void DoJmp(const BaseRef &jmp); void SyncData(const py::object &args); - void MergeJmpArgs(const BaseRef &jmp, const BaseRef &c); - BaseRef MergeArgs(const BaseRef &first, const BaseRef &second); private: InstSet insts_; std::deque insts_stack_; std::stack retp_; std::stack retsp_; - std::stack ret_status_; int pc_; int sp_; - std::unordered_map cond_jmp_; - std::unordered_map cond_out_; BackendPtr backend_; const InstFunctionMap inst_function_map = { {Instruction::kCall, [this](const VectorRef &args) { InstCall(args); }},