You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

flow_ctrl_pass.cc 39 kB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
4 years ago
4 years ago
5 years ago
4 years ago
5 years ago
5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
5 years ago
4 years ago
5 years ago
4 years ago
4 years ago
5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
4 years ago
5 years ago
4 years ago
4 years ago
5 years ago
5 years ago
4 years ago
4 years ago
5 years ago
4 years ago
4 years ago
5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
4 years ago
5 years ago
4 years ago
5 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
4 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
4 years ago
4 years ago
5 years ago
5 years ago
4 years ago
4 years ago
5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
5 years ago
4 years ago
4 years ago
5 years ago
4 years ago
4 years ago
5 years ago
4 years ago
5 years ago
4 years ago
4 years ago
5 years ago
4 years ago
4 years ago
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  1. /**
  2. * Copyright 2020 Huawei Technologies Co., Ltd
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "graph/passes/flow_ctrl_pass.h"
  17. #include <memory>
  18. #include <string>
  19. #include <vector>
  20. #include "framework/common/debug/ge_log.h"
  21. #include "graph/debug/ge_attr_define.h"
  22. #include "graph/common/omg_util.h"
  23. #include "common/ge/ge_util.h"
  24. #include "graph/manager/graph_var_manager.h"
  25. #include "graph/passes/pass_utils.h"
  26. namespace ge {
  27. // when namespace change to ge, please delete the using code.
  28. Status FlowCtrlPass::Run(ComputeGraphPtr compute_graph) {
  29. GE_CHECK_NOTNULL(compute_graph);
  30. if (!PassUtils::IsNeedTrainIteFlowCtrl(compute_graph)) {
  31. GELOGI("No need FlowCtrl for graph %u.", compute_graph->GetGraphID());
  32. return NOT_CHANGED;
  33. }
  34. GELOGI("FlowCtrl pass begin.graph is [%s].", compute_graph->GetName().c_str());
  35. bool graph_change = false;
  36. // 1. Add FP/BP flow ctrl (big cycle)
  37. for (auto &node : compute_graph->GetDirectNode()) {
  38. GE_IF_BOOL_EXEC(node == nullptr, continue);
  39. GE_IF_BOOL_EXEC(node->GetOpDesc() == nullptr, continue);
  40. uint32_t true_stream_id = 0;
  41. bool is_found = AttrUtils::GetInt(node->GetOpDesc(), ATTR_NAME_TRUE_BRANCH_STREAM, true_stream_id);
  42. // FP/BP cycle flag is true_stream_id == 0
  43. if (is_found && (true_stream_id == TRUE_STREAM_ID)) {
  44. // Add big cycle
  45. Status ret = AddFpBpIteratorCtrl(compute_graph, node);
  46. if (ret != SUCCESS) {
  47. GELOGE(ret, "[Add][FpBpIteratorCtrl] failed, node:%s, graph:%s.",
  48. node->GetName().c_str(), compute_graph->GetName().c_str());
  49. return ret;
  50. }
  51. graph_change = true;
  52. // only one big cycle, so break.
  53. break;
  54. }
  55. }
  56. // 2. Add special node flow ctrl. eg, IteratorGetNext. (small cycle)
  57. // NOTE: Small cycle share the variables with big cycle.
  58. for (auto &node : compute_graph->GetDirectNode()) {
  59. GE_IF_BOOL_EXEC(node == nullptr, continue);
  60. GE_IF_BOOL_EXEC(node->GetOpDesc() == nullptr, continue);
  61. bool need_cycle_flag = false;
  62. bool is_found = AttrUtils::GetBool(node->GetOpDesc(), ATTR_NAME_STREAM_CYCLE_EVENT_FLAG, need_cycle_flag);
  63. // small cycle flag is need_stream_cycle_event == true
  64. if (is_found && need_cycle_flag) {
  65. Status ret = AddSpecialNodeIteratorCtrl(compute_graph, node);
  66. if (ret != SUCCESS) {
  67. GELOGE(ret, "[Add][SpecialNodeIteratorCtrl] failed, node:%s, graph:%s.",
  68. node->GetName().c_str(), compute_graph->GetName().c_str());
  69. return ret;
  70. }
  71. graph_change = true;
  72. }
  73. }
  74. // add edge operation below depends on memcpy node in itertor loop set single stream,or may cause block
  75. for (auto &active_node : active_nodes_in_iter_loop_) {
  76. auto ret = GraphUtils::AddEdge(active_node->GetOutControlAnchor(),
  77. assign_add_node_in_fpbp_loop_->GetInControlAnchor());
  78. if (ret != GRAPH_SUCCESS) {
  79. GELOGW("add control edge between iter_loop_node:%s and fpbp_loop_node:%s fail, may cause block",
  80. active_node->GetName().c_str(), assign_add_node_in_fpbp_loop_->GetName().c_str());
  81. }
  82. }
  83. GELOGI("FlowCtrl pass end, graph is %s.", graph_change ? "changed" : "not changed");
  84. return graph_change ? SUCCESS : NOT_CHANGED;
  85. }
  86. bool FlowCtrlPass::CheckMultiDataSet(ComputeGraphPtr &compute_graph) {
  87. int data_set_num = 0;
  88. for (auto &node : compute_graph->GetDirectNode()) {
  89. if (node == nullptr) {
  90. continue;
  91. }
  92. string type;
  93. bool is_found = AttrUtils::GetStr(node->GetOpDesc(), ATTR_NAME_FRAMEWORK_ORIGINAL_TYPE, type);
  94. if (is_found && type == "IteratorV2") {
  95. data_set_num++;
  96. }
  97. }
  98. GELOGI("The ComputeGraph contain %d dataSet.", data_set_num);
  99. return (data_set_num > 1) ? true : false;
  100. }
  101. NodePtr FlowCtrlPass::InsertOp(ComputeGraphPtr &compute_graph, const string &node_type, const string &node_name,
  102. const std::vector<GeTensorDesc> &input_list,
  103. const std::vector<GeTensorDesc> &output_list) {
  104. OpDescPtr op_desc = MakeShared<OpDesc>(node_name, node_type);
  105. if (op_desc == nullptr) {
  106. REPORT_CALL_ERROR("E19999", "New OpDesc failed");
  107. GELOGE(FAILED, "[New][OpDesc] failed, name:%s, type:%s.", node_name.c_str(), node_type.c_str());
  108. return nullptr;
  109. }
  110. for (auto &input_desc : input_list) {
  111. graphStatus graph_status = op_desc->AddInputDesc(input_desc);
  112. if (graph_status != GRAPH_SUCCESS) {
  113. REPORT_CALL_ERROR("E19999", "Add input desc to op:%s(%s) failed",
  114. op_desc->GetName().c_str(), op_desc->GetType().c_str());
  115. GELOGE(FAILED, "[Add][InputDesc] to op:%s(%s) failed", op_desc->GetName().c_str(), op_desc->GetType().c_str());
  116. return nullptr;
  117. }
  118. }
  119. for (auto &output_desc : output_list) {
  120. graphStatus graph_status = op_desc->AddOutputDesc(output_desc);
  121. if (graph_status != GRAPH_SUCCESS) {
  122. REPORT_CALL_ERROR("E19999", "Add output desc to op:%s(%s) failed",
  123. op_desc->GetName().c_str(), op_desc->GetType().c_str());
  124. GELOGE(FAILED, "[Add][OutputDesc] to op:%s(%s) failed",
  125. op_desc->GetName().c_str(), op_desc->GetType().c_str());
  126. return nullptr;
  127. }
  128. }
  129. GE_IF_BOOL_EXEC(compute_graph == nullptr,
  130. REPORT_INNER_ERROR("E19999", "Param compute_graph is nullptr, check invalid");
  131. DOMI_LOGE("[Check][Param] compute_graph is nullptr");
  132. return nullptr);
  133. NodePtr node = compute_graph->AddNode(op_desc);
  134. if (node == nullptr) {
  135. REPORT_CALL_ERROR("E19999", "Add node:%s(%s) to graph:%s failed",
  136. op_desc->GetName().c_str(), op_desc->GetType().c_str(), compute_graph->GetName().c_str());
  137. GELOGE(FAILED, "[Add][Node] %s(%s) to graph:%s failed",
  138. op_desc->GetName().c_str(), op_desc->GetType().c_str(), compute_graph->GetName().c_str());
  139. return nullptr;
  140. }
  141. GELOGI("Insert op success, name:%s, type:%s.", node_name.c_str(), node_type.c_str());
  142. return node;
  143. }
  144. NodePtr FlowCtrlPass::InsertStreamSwitchOp(ComputeGraphPtr &compute_graph, const string &switch_name,
  145. const NodePtr &loop_cond, const NodePtr &iter_per_loop) {
  146. GE_IF_BOOL_EXEC(loop_cond == nullptr || loop_cond->GetOpDesc() == nullptr,
  147. REPORT_INNER_ERROR("E19999", "Param loop_cond or its op_desc is nullptr, check invalid");
  148. GELOGE(FAILED, "[Check][Param] Param loop_cond or its op_desc is nullptr");
  149. return nullptr);
  150. GE_IF_BOOL_EXEC(iter_per_loop == nullptr || iter_per_loop->GetOpDesc() == nullptr,
  151. REPORT_INNER_ERROR("E19999", "Param iter_per_loop or its op_desc is nullptr, check invalid");
  152. GELOGE(FAILED, "[Check][Param] Param iter_per_loop or its op_desc is nullptr");
  153. return nullptr);
  154. std::vector<GeTensorDesc> input_desc_list = {loop_cond->GetOpDesc()->GetOutputDesc(0),
  155. iter_per_loop->GetOpDesc()->GetOutputDesc(0)};
  156. std::vector<GeTensorDesc> output_desc_list;
  157. NodePtr stream_switch = InsertOp(compute_graph, STREAMSWITCH, switch_name, input_desc_list, output_desc_list);
  158. if (stream_switch == nullptr) {
  159. GELOGE(FAILED, "[Insert][StreamSwitchOp] failed, name:%s.", switch_name.c_str());
  160. return nullptr;
  161. }
  162. // set input 0
  163. graphStatus add_ret = GraphUtils::AddEdge(loop_cond->GetOutDataAnchor(0), stream_switch->GetInDataAnchor(0));
  164. if (add_ret != GRAPH_SUCCESS) {
  165. REPORT_CALL_ERROR("E19999", "Add edge between op:%s(%s)(index:0) and op:%s(%s)(index:0) failed",
  166. loop_cond->GetName().c_str(), loop_cond->GetType().c_str(),
  167. stream_switch->GetName().c_str(), stream_switch->GetType().c_str());
  168. GELOGE(FAILED, "[Add][Edge] between op:%s(%s)(index:0) and op:%s(%s)(index:0) failed",
  169. loop_cond->GetName().c_str(), loop_cond->GetType().c_str(),
  170. stream_switch->GetName().c_str(), stream_switch->GetType().c_str());
  171. return nullptr;
  172. }
  173. // set input 1
  174. add_ret = GraphUtils::AddEdge(iter_per_loop->GetOutDataAnchor(0), stream_switch->GetInDataAnchor(1));
  175. if (add_ret != GRAPH_SUCCESS) {
  176. REPORT_CALL_ERROR("E19999", "Add edge between op:%s(%s)(index:0) and op:%s(%s)(index:1) failed",
  177. iter_per_loop->GetName().c_str(), iter_per_loop->GetType().c_str(),
  178. stream_switch->GetName().c_str(), stream_switch->GetType().c_str());
  179. GELOGE(FAILED, "[Add][Edge] between op:%s(%s)(index:0) and op:%s(%s)(index:1) failed",
  180. iter_per_loop->GetName().c_str(), iter_per_loop->GetType().c_str(),
  181. stream_switch->GetName().c_str(), stream_switch->GetType().c_str());
  182. return nullptr;
  183. }
  184. // stream switch op need switch cond by attr.
  185. GE_IF_BOOL_EXEC(!AttrUtils::SetInt(stream_switch->GetOpDesc(), ATTR_NAME_STREAM_SWITCH_COND,
  186. static_cast<int64_t>(RT_LESS)),
  187. REPORT_CALL_ERROR("E19999", "Set Attr:%s to op:%s(%s) failed", ATTR_NAME_STREAM_SWITCH_COND.c_str(),
  188. stream_switch->GetName().c_str(), stream_switch->GetType().c_str());
  189. DOMI_LOGE("[Set][Attr] %s to op:%s(%s) failed", ATTR_NAME_STREAM_SWITCH_COND.c_str(),
  190. stream_switch->GetName().c_str(), stream_switch->GetType().c_str());
  191. return nullptr);
  192. return stream_switch;
  193. }
  194. NodePtr FlowCtrlPass::AddVariableNode(ComputeGraphPtr &compute_graph, const string &name) {
  195. GE_IF_BOOL_EXEC(compute_graph == nullptr,
  196. REPORT_INNER_ERROR("E19999", "Param compute_graph is nullptr, check invalid");
  197. DOMI_LOGE("[Check][Param] compute_graph is nullptr");
  198. return nullptr);
  199. NodePtr exist_node = compute_graph->FindNode(name);
  200. if (exist_node != nullptr) {
  201. GELOGD("Node %s already exist, no need add.", name.c_str());
  202. return exist_node;
  203. }
  204. // fetch and set tensor desc
  205. GeTensorDesc tensor_desc;
  206. if (ge::VarManager::Instance(compute_graph->GetSessionID()) == nullptr) {
  207. REPORT_INNER_ERROR("E19999", "Get VarManager by session_id:%lu failed", compute_graph->GetSessionID());
  208. return nullptr;
  209. }
  210. Status ret = ge::VarManager::Instance(compute_graph->GetSessionID())->GetCurVarDesc(name, tensor_desc);
  211. if (ret != SUCCESS) {
  212. REPORT_INNER_ERROR("E19999", "Get var tensor from VarManager by name:%s failed, session_id:%lu",
  213. name.c_str(), compute_graph->GetSessionID());
  214. GELOGE(FAILED, "[Get][CurVarDesc] failed, name:%s, session_id:%lu", name.c_str(), compute_graph->GetSessionID());
  215. return nullptr;
  216. }
  217. std::vector<GeTensorDesc> input_desc_list;
  218. std::vector<GeTensorDesc> output_desc_list = {tensor_desc};
  219. // insert node
  220. return InsertOp(compute_graph, VARIABLE, name, input_desc_list, output_desc_list);
  221. }
  222. Status FlowCtrlPass::AddGlobalStepVariableNode(ComputeGraphPtr &compute_graph) {
  223. NodePtr output_node = compute_graph->FindFirstNodeMatchType(NETOUTPUT);
  224. if (output_node == nullptr) {
  225. GELOGD("Node type %s can't be found in graph %u", NETOUTPUT, compute_graph->GetGraphID());
  226. return SUCCESS;
  227. }
  228. // Global step just add to main graph's netoutput node.And the main graph must be known shape
  229. if ((compute_graph->GetParentGraph() != nullptr) ||
  230. ((compute_graph->GetParentGraph() == nullptr) && (GraphUtils::IsUnknownShapeGraph(compute_graph)))) {
  231. GELOGD("Subgraph %s no need global step variable.", compute_graph->GetName().c_str());
  232. return SUCCESS;
  233. }
  234. NodePtr exist_node = compute_graph->FindNode(NODE_NAME_GLOBAL_STEP);
  235. if (exist_node != nullptr) {
  236. GELOGD("Node %s already exist, no need add.", NODE_NAME_GLOBAL_STEP.c_str());
  237. return SUCCESS;
  238. }
  239. // set global step tensor desc
  240. GeTensorDesc tensor_desc(GeShape({1}), FORMAT_ND, DT_UINT64);
  241. std::vector<GeTensorDesc> input_desc_list = {};
  242. std::vector<GeTensorDesc> output_desc_list = {tensor_desc};
  243. NodePtr global_step = InsertOp(compute_graph, VARIABLE, NODE_NAME_GLOBAL_STEP,
  244. input_desc_list, output_desc_list);
  245. if (global_step == nullptr) {
  246. GELOGE(FAILED, "[Insert][Op] in graph:%s failed, global_step is null.", compute_graph->GetName().c_str());
  247. return FAILED;
  248. }
  249. // add ctrl edges
  250. graphStatus add_ret = GraphUtils::AddEdge(global_step->GetOutControlAnchor(), output_node->GetInControlAnchor());
  251. if (add_ret != GRAPH_SUCCESS) {
  252. REPORT_CALL_ERROR("E19999", "Add control edge between op:%s(%s) and op:%s(%s) failed",
  253. global_step->GetName().c_str(), global_step->GetType().c_str(),
  254. output_node->GetName().c_str(), output_node->GetType().c_str());
  255. GELOGE(FAILED, "[Add][ControlEdge] between op:%s(%s) and op:%s(%s) failed",
  256. global_step->GetName().c_str(), global_step->GetType().c_str(),
  257. output_node->GetName().c_str(), output_node->GetType().c_str());
  258. return FAILED;
  259. }
  260. GELOGD("Add global_step to netoutput edge in graph %u success", compute_graph->GetGraphID());
  261. return SUCCESS;
  262. }
  263. NodePtr FlowCtrlPass::InsertAssignOp(ge::ComputeGraphPtr &compute_graph, const string &node_type,
  264. const string &node_name, const NodePtr &ref_node, const NodePtr &value_node) {
  265. GE_IF_BOOL_EXEC(ref_node == nullptr || value_node == nullptr ||
  266. ref_node->GetOpDesc() == nullptr || value_node->GetOpDesc() == nullptr,
  267. REPORT_INNER_ERROR("E19999", "Param ref_node or value_node or their op_desc is nullptr, "
  268. "check invalid");
  269. GELOGE(FAILED, "[Check][Param] Param ref_node or value_node or their op_desc is nullptr");
  270. return nullptr);
  271. GeTensorDesc ref_tensor_desc = ref_node->GetOpDesc()->GetOutputDesc(0);
  272. GeTensorDesc val_tensor_desc = value_node->GetOpDesc()->GetOutputDesc(0);
  273. std::vector<GeTensorDesc> input_desc_list = {ref_tensor_desc, val_tensor_desc};
  274. std::vector<GeTensorDesc> output_desc_list = {ref_tensor_desc};
  275. NodePtr assign_node = InsertOp(compute_graph, node_type, node_name, input_desc_list, output_desc_list);
  276. if (assign_node == nullptr) {
  277. GELOGE(FAILED, "[Insert][node] %s(%s) failed.", node_name.c_str(), node_type.c_str());
  278. return nullptr;
  279. }
  280. // assign node input 0 = ref_node
  281. graphStatus add_ret = GraphUtils::AddEdge(ref_node->GetOutDataAnchor(0), assign_node->GetInDataAnchor(0));
  282. if (add_ret != GRAPH_SUCCESS) {
  283. REPORT_CALL_ERROR("E19999", "Add edge between op:%s(%s)(index:0) and op:%s(%s)(index:0) failed",
  284. ref_node->GetName().c_str(), ref_node->GetType().c_str(),
  285. assign_node->GetName().c_str(), assign_node->GetType().c_str());
  286. GELOGE(FAILED, "[Add][Edge] between op:%s(%s)(index:0) and op:%s(%s)(index:0) failed",
  287. ref_node->GetName().c_str(), ref_node->GetType().c_str(),
  288. assign_node->GetName().c_str(), assign_node->GetType().c_str());
  289. return nullptr;
  290. }
  291. // assign input 1 = value_node
  292. add_ret = GraphUtils::AddEdge(value_node->GetOutDataAnchor(0), assign_node->GetInDataAnchor(1));
  293. if (add_ret != GRAPH_SUCCESS) {
  294. REPORT_CALL_ERROR("E19999", "Add edge between op:%s(%s)(index:0) and op:%s(%s)(index:1) failed",
  295. value_node->GetName().c_str(), value_node->GetType().c_str(),
  296. assign_node->GetName().c_str(), assign_node->GetType().c_str());
  297. GELOGE(FAILED, "[Add][Edge] between op:%s(%s)(index:0) and op:%s(%s)(index:1) failed",
  298. value_node->GetName().c_str(), value_node->GetType().c_str(),
  299. assign_node->GetName().c_str(), assign_node->GetType().c_str());
  300. return nullptr;
  301. }
  302. (void)ge::AttrUtils::SetBool(assign_node->GetOpDesc(), ATTR_NEED_COMPILE, true);
  303. return assign_node;
  304. }
  305. Status FlowCtrlPass::CreateIterCtrlTrueBranch(ComputeGraphPtr &compute_graph, const NodePtr &loop_cond_node,
  306. const NodePtr &loop_inc_node, NodePtr &switch_node) {
  307. /*
  308. * loopCond
  309. * |
  310. * v
  311. * switch --> AssignAdd --> active
  312. * ^
  313. * |
  314. * loopIncrement
  315. */
  316. // Insert AssignAdd node
  317. assign_add_node_in_fpbp_loop_ =
  318. InsertAssignOp(compute_graph, ASSIGNADD, NODE_NAME_FLOWCTRL_LOOP_ASSIGNADD, loop_cond_node, loop_inc_node);
  319. if (assign_add_node_in_fpbp_loop_ == nullptr || switch_node == nullptr) {
  320. GELOGE(PARAM_INVALID, "[Check][Param] assign add node or switch node is null");
  321. return FAILED;
  322. }
  323. string active_name = switch_node->GetName() + "_StreamActive";
  324. // add attr for stream assign model to break branch.
  325. auto status = SetStreamLabel(assign_add_node_in_fpbp_loop_, active_name);
  326. if (status != ge::SUCCESS) {
  327. REPORT_CALL_ERROR("E19999", "Set stream_label:%s to op:%s(%s) failed",
  328. active_name.c_str(), assign_add_node_in_fpbp_loop_->GetName().c_str(),
  329. assign_add_node_in_fpbp_loop_->GetType().c_str());
  330. GELOGE(status, "[Set][StreamLabel] %s to op:%s(%s) failed",
  331. active_name.c_str(), assign_add_node_in_fpbp_loop_->GetName().c_str(),
  332. assign_add_node_in_fpbp_loop_->GetType().c_str());
  333. return status;
  334. }
  335. // used for stream assign to find true branch
  336. status = SetActiveLabelList(switch_node, { active_name });
  337. if (status != ge::SUCCESS) {
  338. REPORT_CALL_ERROR("E19999", "Set active label list:%s to op:%s(%s) failed",
  339. active_name.c_str(), switch_node->GetName().c_str(), switch_node->GetType().c_str());
  340. GELOGE(status, "[Set][ActiveLabelList] %s to op:%s(%s) failed",
  341. active_name.c_str(), switch_node->GetName().c_str(), switch_node->GetType().c_str());
  342. return status;
  343. }
  344. // 2. Insert active node
  345. NodePtr active_node = InsertOp(compute_graph, STREAMACTIVE, active_name, {}, {});
  346. if (active_node == nullptr) {
  347. GELOGE(FAILED, "[Insert][StreamActiveNode] %s for IterCtrlTrueStream failed.", active_name.c_str());
  348. return FAILED;
  349. }
  350. status = SetStreamLabel(active_node, active_name);
  351. if (status != ge::SUCCESS) {
  352. REPORT_CALL_ERROR("E19999", "Set stream_label:%s to op:%s(%s) failed",
  353. active_name.c_str(), active_node->GetName().c_str(), active_node->GetType().c_str());
  354. GELOGE(status, "[Set][StreamLabel] %s to op:%s(%s) failed",
  355. active_name.c_str(), active_node->GetName().c_str(), active_node->GetType().c_str());
  356. return status;
  357. }
  358. GE_IF_BOOL_EXEC(!AttrUtils::SetBool(active_node->GetOpDesc(), ATTR_NAME_IS_LOOP_ACTIVE, true),
  359. REPORT_CALL_ERROR("E19999", "Set Attr:%s to op:%s(%s) failed",
  360. ATTR_NAME_IS_LOOP_ACTIVE.c_str(),
  361. active_node->GetName().c_str(), active_node->GetType().c_str());
  362. DOMI_LOGE("[Set][Attr] %s to op:%s(%s) failed", ATTR_NAME_IS_LOOP_ACTIVE.c_str(),
  363. active_node->GetName().c_str(), active_node->GetType().c_str());
  364. return FAILED);
  365. // add ctrl edges
  366. graphStatus add_ret = GraphUtils::AddEdge(switch_node->GetOutControlAnchor(),
  367. assign_add_node_in_fpbp_loop_->GetInControlAnchor());
  368. if (add_ret != GRAPH_SUCCESS) {
  369. REPORT_CALL_ERROR("E19999", "Add control edge between op:%s(%s) and op:%s(%s) failed",
  370. switch_node->GetName().c_str(), switch_node->GetType().c_str(),
  371. assign_add_node_in_fpbp_loop_->GetName().c_str(),
  372. assign_add_node_in_fpbp_loop_->GetType().c_str());
  373. GELOGE(FAILED, "[Add][ControlEdge] between op:%s(%s) and op:%s(%s) failed",
  374. switch_node->GetName().c_str(), switch_node->GetType().c_str(),
  375. assign_add_node_in_fpbp_loop_->GetName().c_str(), assign_add_node_in_fpbp_loop_->GetType().c_str());
  376. return FAILED;
  377. }
  378. add_ret = GraphUtils::AddEdge(assign_add_node_in_fpbp_loop_->GetOutControlAnchor(),
  379. active_node->GetInControlAnchor());
  380. if (add_ret != GRAPH_SUCCESS) {
  381. REPORT_CALL_ERROR("E19999", "Add control edge between op:%s(%s) and op:%s(%s) failed",
  382. assign_add_node_in_fpbp_loop_->GetName().c_str(),
  383. assign_add_node_in_fpbp_loop_->GetType().c_str(),
  384. active_node->GetName().c_str(), active_node->GetType().c_str());
  385. GELOGE(FAILED, "[Add][ControlEdge] between op:%s(%s) and op:%s(%s) failed",
  386. assign_add_node_in_fpbp_loop_->GetName().c_str(), assign_add_node_in_fpbp_loop_->GetType().c_str(),
  387. active_node->GetName().c_str(), active_node->GetType().c_str());
  388. return FAILED;
  389. }
  390. GELOGI("CreateIterCtrlTrueBranch success. StreamActive op:%s.", active_node->GetName().c_str());
  391. return SUCCESS;
  392. }
  393. Status FlowCtrlPass::CreateIterCtrlFalseBranch(ComputeGraphPtr &compute_graph, const NodePtr &loop_cond_node,
  394. const NodePtr &loop_reset_node, NodePtr &switch_node) {
  395. /*
  396. * loopCond
  397. * |
  398. * v
  399. * switch --> Assign --> active --> ModelExit
  400. * ^
  401. * |
  402. * loopReset
  403. */
  404. // Insert Assign node and ctrl edge
  405. NodePtr assign_node =
  406. InsertAssignOp(compute_graph, ASSIGN, NODE_NAME_FLOWCTRL_LOOP_ASSIGN, loop_cond_node, loop_reset_node);
  407. if (assign_node == nullptr || switch_node == nullptr) {
  408. GELOGE(PARAM_INVALID, "[Check][Param] assign_node or switch node is null.");
  409. return FAILED;
  410. }
  411. auto status = SetStreamLabel(assign_node, switch_node->GetName());
  412. if (status != ge::SUCCESS) {
  413. REPORT_CALL_ERROR("E19999", "Set stream_label:%s to op:%s(%s) failed",
  414. switch_node->GetName().c_str(), assign_node->GetName().c_str(), assign_node->GetType().c_str());
  415. GELOGE(status, "[Set][StreamLabel] %s to op:%s(%s) failed",
  416. switch_node->GetName().c_str(), assign_node->GetName().c_str(), assign_node->GetType().c_str());
  417. return status;
  418. }
  419. graphStatus add_ret = GraphUtils::AddEdge(switch_node->GetOutControlAnchor(), assign_node->GetInControlAnchor());
  420. if (add_ret != GRAPH_SUCCESS) {
  421. REPORT_CALL_ERROR("E19999", "Add control edge between op:%s(%s) and op:%s(%s) failed",
  422. switch_node->GetName().c_str(), switch_node->GetType().c_str(),
  423. assign_node->GetName().c_str(), assign_node->GetType().c_str());
  424. GELOGE(FAILED, "[Add][ControlEdge] between op:%s(%s) and op:%s(%s) failed",
  425. switch_node->GetName().c_str(), switch_node->GetType().c_str(),
  426. assign_node->GetName().c_str(), assign_node->GetType().c_str());
  427. return FAILED;
  428. }
  429. if (CheckMultiDataSet(compute_graph)) {
  430. GELOGI("Multi dataSae exist, model_exit node is need.");
  431. // 2. Insert active node and add ctrl edge
  432. string active_name = switch_node->GetName() + "_StreamExitActive";
  433. NodePtr active_node = InsertOp(compute_graph, STREAMACTIVE, active_name, {}, {});
  434. if (active_node == nullptr) {
  435. GELOGE(FAILED, "[Insert][StreamActiveNode] %s for IterCtrlTrueStream failed.", active_name.c_str());
  436. return FAILED;
  437. }
  438. status = SetStreamLabel(active_node, switch_node->GetName());
  439. if (status != ge::SUCCESS) {
  440. REPORT_CALL_ERROR("E19999", "Set stream_label:%s to op:%s(%s) failed", switch_node->GetName().c_str(),
  441. active_node->GetName().c_str(), active_node->GetType().c_str());
  442. GELOGE(status, "[Set][StreamLabel] %s to op:%s(%s) failed", switch_node->GetName().c_str(),
  443. active_node->GetName().c_str(), active_node->GetType().c_str());
  444. return status;
  445. }
  446. GE_CHK_STATUS_RET(SetSwitchBranchNodeLabel(active_node, switch_node->GetName()),
  447. "[Set][SwitchBranchNodeLabel] %s to op:%s(%s) failed", switch_node->GetName().c_str(),
  448. active_node->GetName().c_str(), active_node->GetType().c_str());
  449. string model_exit_name = switch_node->GetName() + "_ModelExit";
  450. status = SetActiveLabelList(active_node, { model_exit_name });
  451. if (status != ge::SUCCESS) {
  452. REPORT_CALL_ERROR("E19999", "Set active label list:%s to op:%s(%s) failed",
  453. model_exit_name.c_str(), active_node->GetName().c_str(), active_node->GetType().c_str());
  454. GELOGE(status, "[Set][ActiveLabelList] %s to op:%s(%s) failed",
  455. model_exit_name.c_str(), active_node->GetName().c_str(), active_node->GetType().c_str());
  456. return status;
  457. }
  458. add_ret = GraphUtils::AddEdge(assign_node->GetOutControlAnchor(), active_node->GetInControlAnchor());
  459. if (add_ret != GRAPH_SUCCESS) {
  460. REPORT_CALL_ERROR("E19999", "Add control edge between op:%s(%s) and op:%s(%s) failed",
  461. assign_node->GetName().c_str(), assign_node->GetType().c_str(),
  462. active_node->GetName().c_str(), active_node->GetType().c_str());
  463. GELOGE(FAILED, "[Add][ControlEdge] between op:%s(%s) and op:%s(%s) failed",
  464. assign_node->GetName().c_str(), assign_node->GetType().c_str(),
  465. active_node->GetName().c_str(), active_node->GetType().c_str());
  466. return FAILED;
  467. }
  468. // 3. Insert model exit node and add ctrl edge
  469. NodePtr model_exit_node = InsertOp(compute_graph, MODELEXIT, model_exit_name, {}, {});
  470. if (model_exit_node == nullptr) {
  471. GELOGE(FAILED, "[Insert][ModelExitNode] %s for IterCtrlTrueStream failed.", model_exit_name.c_str());
  472. return FAILED;
  473. }
  474. status = SetStreamLabel(model_exit_node, model_exit_name);
  475. if (status != ge::SUCCESS) {
  476. REPORT_CALL_ERROR("E19999", "Set stream_label:%s to op:%s(%s) failed",
  477. model_exit_name.c_str(), model_exit_node->GetName().c_str(),
  478. model_exit_node->GetType().c_str());
  479. GELOGE(status, "[Set][StreamLabel] %s to op:%s(%s) failed", model_exit_name.c_str(),
  480. model_exit_node->GetName().c_str(), model_exit_node->GetType().c_str());
  481. return status;
  482. }
  483. add_ret = GraphUtils::AddEdge(active_node->GetOutControlAnchor(), model_exit_node->GetInControlAnchor());
  484. if (add_ret != GRAPH_SUCCESS) {
  485. REPORT_CALL_ERROR("E19999", "Add control edge between op:%s(%s) and op:%s(%s) failed",
  486. active_node->GetName().c_str(), assign_node->GetType().c_str(),
  487. model_exit_node->GetName().c_str(), model_exit_node->GetType().c_str());
  488. GELOGE(FAILED, "[Add][ControlEdge] between op:%s(%s) and op:%s(%s) failed",
  489. active_node->GetName().c_str(), assign_node->GetType().c_str(),
  490. model_exit_node->GetName().c_str(), model_exit_node->GetType().c_str());
  491. return FAILED;
  492. }
  493. }
  494. GELOGI("CreateIterCtrlFalseBranch success.");
  495. return SUCCESS;
  496. }
  497. Status FlowCtrlPass::AddFpBpIteratorCtrl(ComputeGraphPtr &compute_graph, NodePtr &pre_node) {
  498. GE_IF_BOOL_EXEC(pre_node == nullptr, DOMI_LOGE("[Check][Param] pre_node is nullptr."); return FAILED);
  499. string pre_node_name = pre_node->GetName();
  500. GELOGI("Add FpBp Iterator ctrl, pre node:%s.", pre_node_name.c_str());
  501. // 1. Get or add variables
  502. NodePtr loop_cond_node = AddVariableNode(compute_graph, NODE_NAME_FLOWCTRL_LOOP_COND);
  503. if (loop_cond_node == nullptr) {
  504. GELOGE(FAILED, "[Add][Variable] %s failed.", NODE_NAME_FLOWCTRL_LOOP_COND.c_str());
  505. return FAILED;
  506. }
  507. NodePtr loop_inc_node = AddVariableNode(compute_graph, NODE_NAME_FLOWCTRL_LOOP_INCREMENT);
  508. if (loop_inc_node == nullptr) {
  509. GELOGE(FAILED, "[Add][Variable] %s failed.", NODE_NAME_FLOWCTRL_LOOP_INCREMENT.c_str());
  510. return FAILED;
  511. }
  512. NodePtr loop_reset_node = AddVariableNode(compute_graph, NODE_NAME_FLOWCTRL_LOOP_RESETVALUE);
  513. if (loop_reset_node == nullptr) {
  514. GELOGE(FAILED, "[Add][Variable] %s failed.", NODE_NAME_FLOWCTRL_LOOP_RESETVALUE.c_str());
  515. return FAILED;
  516. }
  517. NodePtr iter_per_loop_node = AddVariableNode(compute_graph, NODE_NAME_FLOWCTRL_LOOP_PER_ITER);
  518. if (iter_per_loop_node == nullptr) {
  519. GELOGE(FAILED, "[Add][Variable] %s failed.", NODE_NAME_FLOWCTRL_LOOP_PER_ITER.c_str());
  520. return FAILED;
  521. }
  522. // 2. Add StreamSwitch
  523. string switch_name = pre_node_name + "_" + NODE_NAME_STREAM_SWITCH;
  524. NodePtr switch_node = InsertStreamSwitchOp(compute_graph, switch_name, loop_cond_node, iter_per_loop_node);
  525. if (switch_node == nullptr) {
  526. GELOGE(FAILED, "[Insert][StreamSwitchOp] %s failed.", switch_name.c_str());
  527. return FAILED;
  528. }
  529. auto status = SetStreamLabel(switch_node, switch_name);
  530. if (status != ge::SUCCESS) {
  531. REPORT_CALL_ERROR("E19999", "Set stream label:%s to op:%s(%s) failed",
  532. switch_name.c_str(), switch_node->GetName().c_str(), switch_node->GetType().c_str());
  533. GELOGE(status, "[Set][StreamLabel] %s to op:%s(%s) failed",
  534. switch_name.c_str(), switch_node->GetName().c_str(), switch_node->GetType().c_str());
  535. return status;
  536. }
  537. graphStatus add_ret = GraphUtils::AddEdge(pre_node->GetOutControlAnchor(), switch_node->GetInControlAnchor());
  538. if (add_ret != GRAPH_SUCCESS) {
  539. REPORT_CALL_ERROR("E19999", "Add control edge between op:%s(%s) and op:%s(%s) failed",
  540. pre_node->GetName().c_str(), pre_node->GetType().c_str(),
  541. switch_node->GetName().c_str(), switch_node->GetType().c_str());
  542. GELOGE(FAILED, "[Add][ControlEdge] between op:%s(%s) and op:%s(%s) failed",
  543. pre_node->GetName().c_str(), pre_node->GetType().c_str(),
  544. switch_node->GetName().c_str(), switch_node->GetType().c_str());
  545. return FAILED;
  546. }
  547. // 3. Create switch false branch: return results and reset the loopCond
  548. Status ret = CreateIterCtrlFalseBranch(compute_graph, loop_cond_node, loop_reset_node, switch_node);
  549. if (ret != SUCCESS) {
  550. GELOGE(ret, "[Create][IterCtrlFalseBranch] fail, pre node:%s.", pre_node_name.c_str());
  551. return ret;
  552. }
  553. // 4. Create switch true branch:
  554. // active train streams and increase the loopCond
  555. ret = CreateIterCtrlTrueBranch(compute_graph, loop_cond_node, loop_inc_node, switch_node);
  556. if (ret != SUCCESS) {
  557. GELOGE(ret, "[Create][IterCtrlTrueBranch] fail, pre node:%s.", pre_node_name.c_str());
  558. return ret;
  559. }
  560. return SUCCESS;
  561. }
  562. Status FlowCtrlPass::AddSpecialNodeIteratorCtrl(ComputeGraphPtr &compute_graph, NodePtr &loop_after_node) {
  563. /*
  564. * before add:
  565. * iterator
  566. * |
  567. * v
  568. * MemcpyAsync
  569. *
  570. * after add:
  571. * iterator ----------┐
  572. * | ┆c
  573. * v c v c
  574. * MemcpyAsync-----> switch -----> active
  575. * ^
  576. * / \
  577. * itersPerLoop loopCond
  578. */
  579. GE_IF_BOOL_EXEC(loop_after_node == nullptr || compute_graph == nullptr,
  580. REPORT_INNER_ERROR("E19999", "Param loop_after_node or compute_graph is nullptr, check invalid");
  581. DOMI_LOGE("[Check][Param] loop after node or compute graph is null.");
  582. return FAILED);
  583. InDataAnchorPtr in_anchor = loop_after_node->GetInDataAnchor(0);
  584. if (in_anchor == nullptr || in_anchor->GetPeerOutAnchor() == nullptr) {
  585. REPORT_INNER_ERROR("E19999", "Param loop_after_node:%s(%s) no in data node, check invalid",
  586. loop_after_node->GetName().c_str(), loop_after_node->GetType().c_str());
  587. GELOGE(FAILED, "[Check][Param] Param loop_after_node:%s(%s) no in data node.",
  588. loop_after_node->GetName().c_str(), loop_after_node->GetType().c_str());
  589. return FAILED;
  590. }
  591. NodePtr loop_pre_node = in_anchor->GetPeerOutAnchor()->GetOwnerNode();
  592. // 1. Get variables
  593. NodePtr loop_cond_node = compute_graph->FindNode(NODE_NAME_FLOWCTRL_LOOP_COND);
  594. if (loop_cond_node == nullptr) {
  595. REPORT_INNER_ERROR("E19999", "Node:%s not found in graph:%s, check invalid",
  596. NODE_NAME_FLOWCTRL_LOOP_COND.c_str(), compute_graph->GetName().c_str());
  597. GELOGE(FAILED, "[Check][Param] Node:%s not found in graph:%s.",
  598. NODE_NAME_FLOWCTRL_LOOP_COND.c_str(), compute_graph->GetName().c_str());
  599. return FAILED;
  600. }
  601. NodePtr iter_per_loop_node = compute_graph->FindNode(NODE_NAME_FLOWCTRL_LOOP_PER_ITER);
  602. if (iter_per_loop_node == nullptr) {
  603. REPORT_INNER_ERROR("E19999", "Node:%s not found in graph:%s, check invalid",
  604. NODE_NAME_FLOWCTRL_LOOP_PER_ITER.c_str(), compute_graph->GetName().c_str());
  605. GELOGE(FAILED, "[Check][Param] Node:%s not found in graph:%s.",
  606. NODE_NAME_FLOWCTRL_LOOP_PER_ITER.c_str(), compute_graph->GetName().c_str());
  607. return FAILED;
  608. }
  609. // 2. Add StreamSwitch and edges to switch_node.
  610. GE_IF_BOOL_EXEC(loop_pre_node == nullptr,
  611. REPORT_INNER_ERROR("E19999", "Param loop_after_node:%s(%s) no in data node, check invalid",
  612. loop_after_node->GetName().c_str(), loop_after_node->GetType().c_str());
  613. DOMI_LOGE("[Check][Param] Param loop_after_node:%s(%s) no in data node",
  614. loop_after_node->GetName().c_str(), loop_after_node->GetType().c_str());
  615. return FAILED);
  616. string switch_name = loop_pre_node->GetName() + "_" + NODE_NAME_STREAM_SWITCH;
  617. NodePtr switch_node = InsertStreamSwitchOp(compute_graph, switch_name, loop_cond_node, iter_per_loop_node);
  618. if (switch_node == nullptr) {
  619. GELOGE(FAILED, "[Insert][StreamSwitchOp] %s failed.", switch_name.c_str());
  620. return FAILED;
  621. }
  622. auto status = SetStreamLabel(switch_node, switch_name);
  623. if (status != ge::SUCCESS) {
  624. REPORT_CALL_ERROR("E19999", "Set stream label:%s to op:%s(%s) failed",
  625. switch_name.c_str(), switch_node->GetName().c_str(), switch_node->GetType().c_str());
  626. GELOGE(status, "[Set][StreamLabel] %s to op:%s(%s) failed",
  627. switch_name.c_str(), switch_node->GetName().c_str(), switch_node->GetType().c_str());
  628. return status;
  629. }
  630. graphStatus add_ret = GraphUtils::AddEdge(loop_pre_node->GetOutControlAnchor(), switch_node->GetInControlAnchor());
  631. if (add_ret != GRAPH_SUCCESS) {
  632. REPORT_CALL_ERROR("E19999", "Add control edge between op:%s(%s) and op:%s(%s) failed",
  633. loop_pre_node->GetName().c_str(), loop_pre_node->GetType().c_str(),
  634. switch_node->GetName().c_str(), switch_node->GetType().c_str());
  635. GELOGE(FAILED, "[Add][ControlEdge] between op:%s(%s) and op:%s(%s) failed",
  636. loop_pre_node->GetName().c_str(), loop_pre_node->GetType().c_str(),
  637. switch_node->GetName().c_str(), switch_node->GetType().c_str());
  638. return FAILED;
  639. }
  640. add_ret = GraphUtils::AddEdge(loop_after_node->GetOutControlAnchor(), switch_node->GetInControlAnchor());
  641. if (add_ret != GRAPH_SUCCESS) {
  642. REPORT_CALL_ERROR("E19999", "Add control edge between op:%s(%s) and op:%s(%s) failed",
  643. loop_after_node->GetName().c_str(), loop_after_node->GetType().c_str(),
  644. switch_node->GetName().c_str(), switch_node->GetType().c_str());
  645. GELOGE(FAILED, "[Add][ControlEdge] between op:%s(%s) and op:%s(%s) failed",
  646. loop_after_node->GetName().c_str(), loop_after_node->GetType().c_str(),
  647. switch_node->GetName().c_str(), switch_node->GetType().c_str());
  648. return FAILED;
  649. }
  650. // 3. Create switch true branch: only active
  651. string active_name = switch_name + "_StreamActive";
  652. NodePtr active_node = InsertOp(compute_graph, STREAMACTIVE, active_name, {}, {});
  653. if (active_node == nullptr) {
  654. GELOGE(FAILED, "[Insert][StreamActiveNode] %s for SpecialNodeIteratorCtrl failed.", active_name.c_str());
  655. return FAILED;
  656. }
  657. status = SetStreamLabel(active_node, active_name);
  658. if (status != ge::SUCCESS) {
  659. REPORT_CALL_ERROR("E19999", "Set stream label:%s to op:%s(%s) failed",
  660. active_name.c_str(), active_node->GetName().c_str(), active_node->GetType().c_str());
  661. GELOGE(status, "[Set][StreamLabel] %s to op:%s(%s) failed",
  662. active_name.c_str(), active_node->GetName().c_str(), active_node->GetType().c_str());
  663. return status;
  664. }
  665. GE_IF_BOOL_EXEC(!AttrUtils::SetBool(active_node->GetOpDesc(), ATTR_NAME_IS_LOOP_ACTIVE, true),
  666. REPORT_CALL_ERROR("E19999", "Set Attr:%s to op:%s(%s) failed", ATTR_NAME_IS_LOOP_ACTIVE.c_str(),
  667. active_node->GetName().c_str(), active_node->GetType().c_str());
  668. DOMI_LOGE("[Set][Attr] %s to op:%s(%s) failed", ATTR_NAME_IS_LOOP_ACTIVE.c_str(),
  669. active_node->GetName().c_str(), active_node->GetType().c_str());
  670. return FAILED);
  671. add_ret = GraphUtils::AddEdge(switch_node->GetOutControlAnchor(), active_node->GetInControlAnchor());
  672. if (add_ret != GRAPH_SUCCESS) {
  673. REPORT_CALL_ERROR("E19999", "Add control edge between op:%s(%s) and op:%s(%s) failed",
  674. switch_node->GetName().c_str(), switch_node->GetType().c_str(),
  675. active_node->GetName().c_str(), active_node->GetType().c_str());
  676. GELOGE(FAILED, "[Add][ControlEdge] between op:%s(%s) and op:%s(%s) failed",
  677. switch_node->GetName().c_str(), switch_node->GetType().c_str(),
  678. active_node->GetName().c_str(), active_node->GetType().c_str());
  679. return FAILED;
  680. }
  681. // used for stream assign to find true branch
  682. status = SetActiveLabelList(switch_node, { active_name });
  683. if (status != ge::SUCCESS) {
  684. REPORT_CALL_ERROR("E19999", "Set active label list:%s to op:%s(%s) failed",
  685. active_name.c_str(), switch_node->GetName().c_str(), switch_node->GetType().c_str());
  686. GELOGE(status, "[Set][ActiveLabelList] %s to op:%s(%s) failed",
  687. active_name.c_str(), switch_node->GetName().c_str(), switch_node->GetType().c_str());
  688. return status;
  689. }
  690. // used for stream assign to find active stream
  691. status = SetActiveLabelList(active_node, { loop_pre_node->GetName() });
  692. if (status != ge::SUCCESS) {
  693. REPORT_CALL_ERROR("E19999", "Set active label list:%s to op:%s(%s) failed", loop_pre_node->GetName().c_str(),
  694. active_node->GetName().c_str(), active_node->GetType().c_str());
  695. GELOGE(status, "[Set][ActiveLabelList] %s to op:%s(%s) failed",
  696. loop_pre_node->GetName().c_str(), active_node->GetName().c_str(), active_node->GetType().c_str());
  697. return status;
  698. }
  699. active_nodes_in_iter_loop_.push_back(active_node);
  700. return SUCCESS;
  701. }
  702. } // namespace ge

图引擎模块(GE)是MindSpore的一个子模块,其代码由C++实现,位于前端模块ME和底层硬件之间,起到承接作用。图引擎模块以ME下发的图作为输入,然后进行一系列的深度图优化操作,最后输出一张可以在底层硬件上高效运行的图。GE针对昇腾AI处理器的硬件结构特点,做了特定的优化工作,以此来充分发挥出昇腾AI处理器的强大算力。在进行模型训练/推理时,GE会被自动调用而用户并不感知。GE主要由GE API和GE Core两部分组成,详细的架构图如下所示