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.

func_graph.cc 20 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620
  1. /**
  2. * This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/).
  3. *
  4. * Copyright 2019-2020 Huawei Technologies Co., Ltd
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. #include "ir/func_graph.h"
  19. #include <algorithm>
  20. #include <sstream>
  21. #include <utility>
  22. #include "debug/trace.h"
  23. #include "ir/manager.h"
  24. #include "operator/ops.h"
  25. #include "pybind_api/export_flags.h"
  26. #include "utils/ordered_set.h"
  27. #include "utils/convert_utils_base.h"
  28. namespace mindspore {
  29. /*
  30. * Methods of Graph
  31. */
  32. FuncGraph::FuncGraph()
  33. : flags_(),
  34. transforms_(),
  35. parameter_default_value_(),
  36. seen_(0),
  37. parameters_(),
  38. has_vararg_(false),
  39. has_kwarg_(false),
  40. kwonlyargs_count_(0),
  41. hyper_param_count_(0),
  42. is_generated_(false),
  43. return_(nullptr),
  44. manager_(std::weak_ptr<FuncGraphManager>()) {
  45. debug_info_ = std::make_shared<GraphDebugInfo>();
  46. }
  47. AnfNodePtr FuncGraph::output() const {
  48. // If return value is set, return should have two inputs.
  49. if (return_ != nullptr && return_->inputs().size() == 2) {
  50. return return_->input(1);
  51. } else {
  52. // If not set yet, return nullptr.
  53. return nullptr;
  54. }
  55. }
  56. ParameterPtr FuncGraph::add_parameter() {
  57. FuncGraphPtr this_func_graph = shared_from_base<FuncGraph>();
  58. ParameterPtr p = std::make_shared<Parameter>(this_func_graph);
  59. add_parameter(p);
  60. return p;
  61. }
  62. void FuncGraph::add_parameter(const ParameterPtr &p) {
  63. if (manager_.lock()) {
  64. std::vector<AnfNodePtr> new_params = parameters_;
  65. new_params.push_back(p);
  66. manager_.lock()->SetParameters(shared_from_base<FuncGraph>(), new_params);
  67. } else {
  68. parameters_.push_back(p);
  69. }
  70. }
  71. ParameterPtr FuncGraph::AddWeightParameter(const std::string &name) {
  72. FuncGraphPtr this_graph = shared_from_base<FuncGraph>();
  73. ParameterPtr p = std::make_shared<Parameter>(this_graph);
  74. p->set_name(name);
  75. p->debug_info()->set_name(name);
  76. std::vector<AnfNodePtr> new_params = parameters_;
  77. // append parameter
  78. new_params.push_back(p);
  79. if (manager_.lock()) {
  80. manager_.lock()->SetParameters(shared_from_base<FuncGraph>(), new_params);
  81. } else {
  82. parameters_.push_back(p);
  83. }
  84. hyper_param_count_++;
  85. return p;
  86. }
  87. bool FuncGraph::has_flag(const std::string &flag) {
  88. if (flags_.count(flag)) {
  89. return flags_[flag];
  90. }
  91. return false;
  92. }
  93. CNodePtr FuncGraph::NewCNode(const std::vector<AnfNodePtr> &inputs) {
  94. CNodePtr cnode = std::make_shared<CNode>(inputs, shared_from_base<FuncGraph>());
  95. if (has_flag(GRAPH_FLAG_HAS_EFFECT)) {
  96. order_.push_back(cnode);
  97. MS_LOG(INFO) << "Graph: " << ToString() << ", push back " << cnode->DebugString() << " in order.";
  98. }
  99. return cnode;
  100. }
  101. CNodePtr FuncGraph::NewCNodeWithScope(const std::vector<AnfNodePtr> &inputs, const ScopePtr &scope) {
  102. CNodePtr app = NewCNode(inputs);
  103. app->set_scope(scope);
  104. return app;
  105. }
  106. void FuncGraph::DumpCNodeList() {
  107. MS_LOG(INFO) << "FuncGraph " << ToString() << " has following CNode in code order:";
  108. for (const auto &cnode : order_) {
  109. MS_LOG(INFO) << cnode->DebugString();
  110. }
  111. }
  112. std::string FuncGraph::ToString() const {
  113. return mindspore::label_manage::Label(const_cast<FuncGraph *>(this)->shared_from_base<FuncGraph>()->debug_info());
  114. }
  115. GraphDebugInfoPtr FuncGraph::debug_info() {
  116. MS_EXCEPTION_IF_NULL(this->debug_info_);
  117. if (this->debug_info_->get_graph() == nullptr) {
  118. this->debug_info_->set_graph(shared_from_base<FuncGraph>());
  119. }
  120. return this->debug_info_;
  121. }
  122. const AnfNodeSet &FuncGraph::nodes() { return nodes_; }
  123. void FuncGraph::CopyNodes(const FuncGraphPtr &source) { nodes_ = source->nodes(); }
  124. void FuncGraph::ClearNodes() { nodes_.clear(); }
  125. void FuncGraph::AddNode(AnfNodePtr node) { nodes_.add(node); }
  126. void FuncGraph::DropNode(AnfNodePtr node) {
  127. nodes_.erase(node);
  128. auto graph = node->func_graph();
  129. // Remove the node from order list.
  130. if (graph) {
  131. graph->EraseUnusedNodeInOrder(node);
  132. }
  133. }
  134. const AnfNodeCounterMap &FuncGraph::value_nodes() { return value_nodes_; }
  135. void FuncGraph::CopyValueNodes(const FuncGraphPtr &source) {
  136. auto &others = source->value_nodes();
  137. for (auto it = others.begin(); it != others.end(); it++) {
  138. AddValueNode(it->first, it->second);
  139. }
  140. }
  141. void FuncGraph::ClearValueNodes() { value_nodes_.clear(); }
  142. void FuncGraph::AddValueNode(AnfNodePtr node, int count) {
  143. if (value_nodes_.count(node) == 0) {
  144. value_nodes_[node] = count;
  145. } else {
  146. value_nodes_[node] += count;
  147. }
  148. }
  149. void FuncGraph::DropValueNode(AnfNodePtr node) {
  150. if (value_nodes_.count(node) != 0) {
  151. if (value_nodes_[node] == 1) {
  152. (void)value_nodes_.erase(node);
  153. } else {
  154. value_nodes_[node]--;
  155. if (value_nodes_[node] < 0) {
  156. MS_LOG(EXCEPTION) << "Count of ValueNode '" << node
  157. << "' dec from 0. NodeInfo: " << trace::GetDebugInfo(debug_info());
  158. }
  159. }
  160. }
  161. }
  162. const AnfNodeCounterMap &FuncGraph::free_variables() { return free_variables_; }
  163. void FuncGraph::CopyFreeVariables(const FuncGraphPtr &source) {
  164. auto &others = source->free_variables();
  165. for (auto it = others.begin(); it != others.end(); it++) {
  166. if (it->first->func_graph().get() != this) {
  167. (void)AddFreeVariable(it->first, it->second);
  168. }
  169. }
  170. }
  171. void FuncGraph::ClearFreeVariables() { free_variables_.clear(); }
  172. bool FuncGraph::AddFreeVariable(AnfNodePtr node, int count) {
  173. if (free_variables_.count(node) == 0) {
  174. free_variables_[node] = count;
  175. return true;
  176. } else {
  177. free_variables_[node] += count;
  178. return false;
  179. }
  180. }
  181. bool FuncGraph::DropFreeVariable(AnfNodePtr node) {
  182. if (free_variables_.count(node) != 0) {
  183. if (free_variables_[node] == 1) {
  184. (void)free_variables_.erase(node);
  185. return true;
  186. } else {
  187. free_variables_[node]--;
  188. if (free_variables_[node] < 0) {
  189. MS_LOG(EXCEPTION) << "Count of free variable '" << node
  190. << "' dec from 0. NodeInfo: " << trace::GetDebugInfo(debug_info());
  191. }
  192. }
  193. }
  194. return false;
  195. }
  196. const BaseRefCounterMap &FuncGraph::free_variables_total() {
  197. auto mng = manager_.lock();
  198. MS_EXCEPTION_IF_NULL(mng);
  199. auto &fv_total = mng->free_variables_total();
  200. return fv_total[shared_from_base<FuncGraph>()];
  201. }
  202. std::vector<AnfNodePtr> FuncGraph::free_variables_nodes() {
  203. std::vector<AnfNodePtr> nodes;
  204. const auto &fv_total = this->free_variables_total();
  205. for (auto &p : fv_total) {
  206. auto key = p.first;
  207. if (utils::isa<AnfNodePtr>(key)) {
  208. nodes.push_back(utils::cast<AnfNodePtr>(key));
  209. }
  210. }
  211. return nodes;
  212. }
  213. std::vector<FuncGraphPtr> FuncGraph::free_variables_func_graphs() {
  214. std::vector<FuncGraphPtr> func_graphs;
  215. const auto &fv_total = this->free_variables_total();
  216. for (auto &p : fv_total) {
  217. auto key = p.first;
  218. if (utils::isa<FuncGraphPtr>(key)) {
  219. func_graphs.push_back(utils::cast<FuncGraphPtr>(key));
  220. }
  221. }
  222. return func_graphs;
  223. }
  224. const FuncGraphCounterMap &FuncGraph::func_graphs_used() { return func_graphs_used_; }
  225. void FuncGraph::CopyFuncGraphsUsed(const FuncGraphPtr &source) {
  226. auto &others = source->func_graphs_used();
  227. for (auto it = others.begin(); it != others.end(); it++) {
  228. (void)AddFuncGraphUsed(it->first, it->second);
  229. }
  230. func_graphs_used_.erase(source);
  231. }
  232. void FuncGraph::ClearFuncGraphsUsed() { func_graphs_used_.clear(); }
  233. bool FuncGraph::AddFuncGraphUsed(FuncGraphPtr fg, int count) {
  234. if (func_graphs_used_.count(fg) == 0) {
  235. func_graphs_used_[fg] = count;
  236. return true;
  237. } else {
  238. func_graphs_used_[fg] += count;
  239. return false;
  240. }
  241. }
  242. bool FuncGraph::DropFuncGraphUsed(FuncGraphPtr fg) {
  243. if (func_graphs_used_.count(fg) != 0) {
  244. if (func_graphs_used_[fg] == 1) {
  245. (void)func_graphs_used_.erase(fg);
  246. return true;
  247. } else {
  248. func_graphs_used_[fg]--;
  249. if (func_graphs_used_[fg] < 0) {
  250. MS_LOG(EXCEPTION) << "Count of FuncGraph '" << fg
  251. << "' dec from 0. NodeInfo: " << trace::GetDebugInfo(debug_info());
  252. }
  253. }
  254. }
  255. return false;
  256. }
  257. const FuncGraphSet &FuncGraph::func_graphs_used_total() {
  258. auto mng = manager_.lock();
  259. MS_EXCEPTION_IF_NULL(mng);
  260. auto &used = mng->func_graphs_used_total(shared_from_base<FuncGraph>());
  261. return used;
  262. }
  263. const CNodeIndexCounterMap &FuncGraph::func_graph_cnodes_index() { return func_graph_cnodes_index_; }
  264. void FuncGraph::CopyFuncGraphCNodesIndex(const FuncGraphPtr &source) {
  265. auto &others = source->func_graph_cnodes_index();
  266. for (auto it = others.begin(); it != others.end(); it++) {
  267. // Ignore the user graph who may own itself.
  268. auto fg = it->first->first->func_graph();
  269. MS_EXCEPTION_IF_NULL(fg);
  270. if (fg.get() != this) {
  271. AddFuncGraphCNodeIndex(it->first, it->second);
  272. }
  273. }
  274. }
  275. void FuncGraph::ClearFuncGraphCNodesIndex() { func_graph_cnodes_index_.clear(); }
  276. void FuncGraph::AddFuncGraphCNodeIndex(CNodeIndexPairPtr pair, int count) {
  277. if (func_graph_cnodes_index_.count(pair) == 0) {
  278. func_graph_cnodes_index_[pair] = count;
  279. } else {
  280. func_graph_cnodes_index_[pair] += count;
  281. }
  282. }
  283. void FuncGraph::DropFuncGraphCNodeIndex(CNodeIndexPairPtr pair) {
  284. if (func_graph_cnodes_index_.count(pair) != 0) {
  285. if (func_graph_cnodes_index_[pair] == 1) {
  286. (void)func_graph_cnodes_index_.erase(pair);
  287. } else {
  288. func_graph_cnodes_index_[pair]--;
  289. if (func_graph_cnodes_index_[pair] < 0) {
  290. MS_LOG(EXCEPTION) << "Count of CNode/Index '" << pair->first << "/" << pair->second
  291. << "' dec from 0. NodeInfo: " << trace::GetDebugInfo(debug_info());
  292. }
  293. }
  294. }
  295. }
  296. const FuncGraphCounterMap &FuncGraph::j_func_graphs() { return j_func_graphs_; }
  297. void FuncGraph::CopyJFuncGraphs(const FuncGraphPtr &source) {
  298. auto &others = source->j_func_graphs();
  299. for (auto it = others.begin(); it != others.end(); it++) {
  300. AddJFuncGraph(it->first, it->second);
  301. }
  302. }
  303. void FuncGraph::ClearJFuncGraphs() { j_func_graphs_.clear(); }
  304. void FuncGraph::AddJFuncGraph(FuncGraphPtr fg, int count) {
  305. if (j_func_graphs_.count(fg) == 0) {
  306. j_func_graphs_[fg] = count;
  307. } else {
  308. j_func_graphs_[fg] += count;
  309. }
  310. }
  311. void FuncGraph::DropJFuncGraph(FuncGraphPtr fg) {
  312. if (j_func_graphs_.count(fg) != 0) {
  313. if (j_func_graphs_[fg] == 1) {
  314. (void)j_func_graphs_.erase(fg);
  315. } else {
  316. j_func_graphs_[fg]--;
  317. if (j_func_graphs_[fg] < 0) {
  318. MS_LOG(EXCEPTION) << "Count of J FuncGraph '" << fg
  319. << "' dec from 0. NodeInfo: " << trace::GetDebugInfo(debug_info());
  320. }
  321. }
  322. }
  323. }
  324. FuncGraphPtr FuncGraph::parent() {
  325. // report the bug early.
  326. if (manager_.lock() == nullptr) {
  327. MS_LOG(EXCEPTION) << "BUG: no manager for this func graph: " << ToString()
  328. << " NodeInfo: " << trace::GetDebugInfo(debug_info());
  329. }
  330. auto mng = manager_.lock();
  331. MS_EXCEPTION_IF_NULL(mng);
  332. return mng->parent(shared_from_base<FuncGraph>());
  333. }
  334. const FuncGraphSet &FuncGraph::children() {
  335. auto mng = manager_.lock();
  336. MS_EXCEPTION_IF_NULL(mng);
  337. return mng->children(shared_from_base<FuncGraph>());
  338. }
  339. const FuncGraphSet &FuncGraph::scope() {
  340. auto mng = manager_.lock();
  341. MS_EXCEPTION_IF_NULL(mng);
  342. return mng->scopes(shared_from_base<FuncGraph>());
  343. }
  344. bool FuncGraph::recursive() {
  345. auto mng = manager_.lock();
  346. MS_EXCEPTION_IF_NULL(mng);
  347. return mng->recursive(shared_from_base<FuncGraph>());
  348. }
  349. std::shared_ptr<std::list<FuncGraphPtr>> FuncGraph::recursive_graphs() {
  350. auto mng = manager_.lock();
  351. MS_EXCEPTION_IF_NULL(mng);
  352. return mng->recursive_graphs(shared_from_base<FuncGraph>());
  353. }
  354. AnfNodePtr FuncGraph::GetDefaultValueByName(const std::string &name) {
  355. auto itr = this->parameter_default_value_.find(name);
  356. if (itr == parameter_default_value_.end()) {
  357. return nullptr;
  358. }
  359. auto default_value = itr->second;
  360. if (default_value == nullptr) {
  361. MS_LOG(EXCEPTION) << "Graph parameter " << name << " not exist";
  362. }
  363. if (IsValueNode<NullObj>(default_value)) {
  364. return nullptr;
  365. }
  366. return default_value;
  367. }
  368. // set the default values
  369. void FuncGraph::SetDefaultValues(const std::vector<std::string> &name_list, const std::vector<AnfNodePtr> &value_list) {
  370. auto all_is_null = std::all_of(value_list.begin(), value_list.end(),
  371. [](const AnfNodePtr &node) { return IsValueNode<NullObj>(node); });
  372. if (value_list.empty()) {
  373. all_is_null = true;
  374. }
  375. for (size_t i = 0; i < name_list.size(); ++i) {
  376. if (!all_is_null) {
  377. this->parameter_default_value_[name_list[i]] = value_list[i];
  378. }
  379. }
  380. }
  381. void FuncGraph::ClearDefaultValues() { parameter_default_value_.clear(); }
  382. size_t FuncGraph::GetDefaultValueCount() {
  383. int null_count =
  384. std::count_if(parameter_default_value_.begin(), parameter_default_value_.end(),
  385. [](const std::pair<std::string, AnfNodePtr> &pair) { return IsValueNode<NullObj>(pair.second); });
  386. return parameter_default_value_.size() - IntToSize(null_count);
  387. }
  388. AnfNodePtr FuncGraph::GetVariableArgParameter() {
  389. if (!has_vararg_) {
  390. return nullptr;
  391. }
  392. if (has_kwarg_) {
  393. if (parameters_.size() < hyper_param_count_ + 2) {
  394. MS_LOG(EXCEPTION) << "Length of parameters is " << parameters_.size() << ", hyper_param_count is "
  395. << hyper_param_count_ << ", parameters is less than 2 + hyper_param_count";
  396. }
  397. return parameters_[parameters_.size() - hyper_param_count_ - 2];
  398. }
  399. if (parameters_.size() < hyper_param_count_ + 1) {
  400. MS_LOG(EXCEPTION) << "Length of parameters is " << parameters_.size() << ", hyper_param_count is "
  401. << hyper_param_count_ << ", parameters is less than 1 + hyper_param_count";
  402. }
  403. return parameters_[parameters_.size() - hyper_param_count_ - 1];
  404. }
  405. std::string FuncGraph::GetVariableArgName() {
  406. if (!has_vararg_) {
  407. return "";
  408. }
  409. if (has_kwarg_) {
  410. if (parameters_.size() < hyper_param_count_ + 2) {
  411. MS_LOG(EXCEPTION) << "Length of parameters is " << parameters_.size() << ", hyper_param_count is "
  412. << hyper_param_count_ << ", parameters is less than 2 + hyper_param_count";
  413. }
  414. return parameters_[parameters_.size() - hyper_param_count_ - 2]->cast<ParameterPtr>()->name();
  415. }
  416. if (parameters_.size() < hyper_param_count_ + 1) {
  417. MS_LOG(EXCEPTION) << "Length of parameters is " << parameters_.size() << ", hyper_param_count is "
  418. << hyper_param_count_ << ", parameters is less than 1 + hyper_param_count";
  419. }
  420. return parameters_[parameters_.size() - hyper_param_count_ - 1]->cast<ParameterPtr>()->name();
  421. }
  422. AnfNodePtr FuncGraph::GetVariableKwargParameter() {
  423. if (has_kwarg_) {
  424. if (parameters_.size() < hyper_param_count_ + 1) {
  425. MS_LOG(EXCEPTION) << "Length of parameters is " << parameters_.size() << ", hyper_param_count is "
  426. << hyper_param_count_ << ", parameters is less than 1 + hyper_param_count";
  427. }
  428. return parameters_[parameters_.size() - hyper_param_count_ - 1];
  429. }
  430. return nullptr;
  431. }
  432. std::string FuncGraph::GetVariableKwargName() {
  433. if (has_kwarg_) {
  434. if (parameters_.size() < hyper_param_count_ + 1) {
  435. MS_LOG(EXCEPTION) << "Length of parameters is " << parameters_.size() << ", hyper_param_count is "
  436. << hyper_param_count_ << ", parameters is less than 1 + hyper_param_count";
  437. }
  438. return parameters_[parameters_.size() - hyper_param_count_ - 1]->cast<ParameterPtr>()->name();
  439. }
  440. return "";
  441. }
  442. int FuncGraph::GetPositionalArgsCount() const {
  443. int count = SizeToInt(parameters_.size());
  444. if (has_kwarg_) {
  445. count--;
  446. }
  447. if (has_vararg_) {
  448. count--;
  449. }
  450. return count - kwonlyargs_count_ - SizeToInt(hyper_param_count_);
  451. }
  452. AnfNodePtr FuncGraph::GetParameterByName(const std::string &name) {
  453. for (size_t i = 0; i < parameters_.size(); ++i) {
  454. MS_EXCEPTION_IF_NULL(parameters_[i]);
  455. auto param_cast = parameters_[i]->cast<ParameterPtr>();
  456. MS_EXCEPTION_IF_NULL(param_cast);
  457. if (param_cast->name() == name) {
  458. return parameters_[i];
  459. }
  460. }
  461. return nullptr;
  462. }
  463. void FuncGraph::add_parameter_obj_node(const AnfNodePtr &p) { paramter_obj_nodes_.push_back(p); }
  464. std::list<CNodePtr> FuncGraph::GetOrderedCnodes() {
  465. if (has_flag(GRAPH_FLAG_HAS_EFFECT)) {
  466. MS_LOG(DEBUG) << "Return ordered cnodes.";
  467. return order_;
  468. } else {
  469. auto this_ptr = shared_from_base<FuncGraph>();
  470. auto BelongSameGraph = std::bind(IncludeBelongGraph, this_ptr, std::placeholders::_1);
  471. auto SuccDepends = std::bind(SuccIncludeFV, this_ptr, std::placeholders::_1);
  472. std::list<CNodePtr> cnodes;
  473. auto nodes = TopoSort(get_return(), SuccDepends, BelongSameGraph);
  474. for (const auto &node : nodes) {
  475. auto cnode = dyn_cast<CNode>(node);
  476. if (cnode) {
  477. cnodes.push_back(cnode);
  478. }
  479. }
  480. return cnodes;
  481. }
  482. }
  483. void FuncGraph::EraseUnusedNodeInOrder() {
  484. if (has_flag(GRAPH_FLAG_HAS_EFFECT)) {
  485. auto mng = manager_.lock();
  486. if (mng) {
  487. auto &all_nodes = nodes();
  488. // Erase unused cnode.
  489. for (auto it = order_.begin(); it != order_.end();) {
  490. if (all_nodes.count(*it)) {
  491. (void)it++;
  492. } else {
  493. MS_LOG(DEBUG) << "Remove node " << (*it)->ToString() << " in graph " << ToString() << " order.";
  494. it = order_.erase(it);
  495. }
  496. }
  497. }
  498. }
  499. }
  500. void FuncGraph::EraseUnusedNodeInOrder(const AnfNodePtr &n) {
  501. if (has_flag(GRAPH_FLAG_HAS_EFFECT) && n && n->isa<CNode>()) {
  502. order_.remove(n->cast<CNodePtr>());
  503. MS_LOG(DEBUG) << "Remove the node" << n->DebugString() << " from order list.";
  504. }
  505. }
  506. void FuncGraph::CheckOrder() {
  507. if (has_flag(GRAPH_FLAG_HAS_EFFECT)) {
  508. MS_LOG(DEBUG) << "Check graph " << ToString();
  509. for (auto it = order_.begin(); it != order_.end(); (void)it++) {
  510. for (const auto &input_node : (*it)->inputs()) {
  511. if (input_node && input_node->isa<CNode>() && input_node->func_graph() == shared_from_base<FuncGraph>()) {
  512. // Need to reorder the wrong order node.
  513. auto found = std::find(order_.begin(), it, input_node);
  514. if (found == it) {
  515. DumpCNodeList();
  516. MS_LOG(EXCEPTION) << "The cnode " << (*it)->DebugString() << " order in " << ToString()
  517. << " doesn't obey the input dependency, "
  518. << "as input " << input_node->DebugString() << " is not ahead of itself.";
  519. }
  520. }
  521. }
  522. }
  523. auto mng = manager_.lock();
  524. if (mng != nullptr) {
  525. const auto &all_nodes = nodes();
  526. if (all_nodes.size() != (order_.size() + parameters_.size())) {
  527. DumpCNodeList();
  528. MS_LOG(EXCEPTION) << "CNode order size " << order_.size() << " is not equal to managed node size "
  529. << all_nodes.size() - parameters_.size() << ".";
  530. }
  531. }
  532. MS_LOG(DEBUG) << "Check order okay.";
  533. }
  534. }
  535. size_t NewFgSeenGeneration() {
  536. static size_t fg_seen_generation = 0;
  537. return ++fg_seen_generation;
  538. }
  539. const PrimitivePtr FuncGraphTransform::func_graph_prim_ = std::make_shared<Primitive>("FuncGraph");
  540. const char kFuncGraphFlagUndetermined[] = "Undeterminate";
  541. } // namespace mindspore