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.

anf_ir_dump.cc 23 kB

5 years ago
5 years ago
5 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
5 years ago
5 years ago
5 years ago
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  1. /**
  2. * Copyright 2019-2021 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 "debug/anf_ir_dump.h"
  17. #if defined(_WIN32) || defined(_WIN64)
  18. #include <stdlib.h>
  19. #endif
  20. #include <fstream>
  21. #include <iomanip>
  22. #include <memory>
  23. #include <unordered_map>
  24. #include "ir/primitive.h"
  25. #include "ir/func_graph.h"
  26. #include "runtime/device/kernel_info.h"
  27. #include "ir/graph_utils.h"
  28. #include "backend/session/anf_runtime_algorithm.h"
  29. #include "frontend/parallel/ops_info/operator_info.h"
  30. #include "pipeline/jit/base.h"
  31. #include "debug/trace.h"
  32. #include "utils/trace_base.h"
  33. namespace mindspore {
  34. const std::string ToShortString(const TypeId &typeId) {
  35. std::string label = TypeIdLabel(typeId);
  36. std::string prefix = "kNumberType";
  37. if (prefix.length() > label.length()) {
  38. return label;
  39. }
  40. auto position = label.find(prefix);
  41. // position is 0 when label begins with prefix
  42. if (position != 0) {
  43. return label;
  44. }
  45. auto sub_position = position + prefix.length();
  46. if (sub_position >= label.length()) {
  47. return label;
  48. }
  49. return label.substr(sub_position);
  50. }
  51. void PrintKernelFormatAndType(std::ostringstream &buffer, const std::string &fmt, const TypeId &type,
  52. const std::vector<size_t> &shape) {
  53. buffer << "<" << ToShortString(type);
  54. if (!fmt.empty()) {
  55. buffer << "x" << fmt << shape;
  56. }
  57. buffer << ">";
  58. }
  59. void PrintNodeOutputType(std::ostringstream &buffer, const AnfNodePtr &nd) {
  60. if (nd == nullptr) {
  61. return;
  62. }
  63. ValuePtr tensor_value = nullptr;
  64. auto abstract = nd->abstract();
  65. if (abstract != nullptr && abstract->isa<abstract::AbstractTensor>()) {
  66. tensor_value = abstract->BuildValue();
  67. }
  68. abstract::ShapePtr shape = dyn_cast<abstract::Shape>(nd->Shape());
  69. TypePtr type = dyn_cast<Type>(nd->Type());
  70. if ((shape != nullptr) && (type != nullptr)) {
  71. buffer << "<" << type << ", " << shape->ToString();
  72. if (tensor_value != nullptr && tensor_value != kAnyValue) {
  73. buffer << ", value=...";
  74. }
  75. buffer << ">";
  76. } else if (type != nullptr) {
  77. buffer << "<" << type;
  78. if (tensor_value != nullptr && tensor_value != kAnyValue) {
  79. buffer << ", value=...";
  80. }
  81. buffer << ">";
  82. } else {
  83. buffer << "<null>";
  84. }
  85. }
  86. void PrintNodeInputType(std::ostringstream &buffer, const AnfNodePtr &nd) {
  87. if (nd == nullptr) {
  88. return;
  89. }
  90. const auto &inputs = GetInputs(nd);
  91. size_t len = inputs.size();
  92. if (len > 1) {
  93. // skip inputs[0] which is Primitive value node
  94. for (size_t i = 1; i < len; ++i) {
  95. AnfNodePtr in = inputs[i];
  96. if (i != 1) {
  97. buffer << ", ";
  98. }
  99. PrintNodeOutputType(buffer, in);
  100. }
  101. }
  102. }
  103. void PrintInputAndOutputInferType(std::ostringstream &buffer, const AnfNodePtr &nd) {
  104. buffer << " : (";
  105. PrintNodeInputType(buffer, nd);
  106. buffer << ") -> (";
  107. PrintNodeOutputType(buffer, nd);
  108. buffer << ")";
  109. }
  110. struct SubGraphIRInfo {
  111. int32_t local_var;
  112. std::ostringstream buffer;
  113. OrderedMap<AnfNodePtr, int32_t> local_var_map;
  114. };
  115. void DumpGlobalInfoEntry(const FuncGraphPtr &graph, std::ostringstream &buffer) {
  116. if (graph == nullptr) {
  117. return;
  118. }
  119. buffer << "#IR entry : @" << graph->ToString() << std::endl;
  120. buffer << "#attrs :" << std::endl;
  121. for (const auto &attr : graph->attrs()) {
  122. buffer << attr.first << " : ";
  123. if (attr.second->isa<BoolImm>()) {
  124. buffer << GetValue<bool>(attr.second);
  125. } else if (attr.second->isa<StringImm>()) {
  126. buffer << GetValue<std::string>(attr.second);
  127. }
  128. buffer << std::endl;
  129. }
  130. }
  131. void DumpKernelInfo(const CNodePtr &node, const std::shared_ptr<SubGraphIRInfo> &gsub) {
  132. if (node == nullptr || gsub == nullptr) {
  133. return;
  134. }
  135. auto kernel_info = node->kernel_info();
  136. if (kernel_info == nullptr || !kernel_info->has_build_info()) {
  137. return;
  138. }
  139. gsub->buffer << " : (";
  140. size_t input_num = AnfAlgo::GetInputTensorNum(node);
  141. for (size_t i = 0; i < input_num; ++i) {
  142. if (i != 0) {
  143. gsub->buffer << ", ";
  144. }
  145. auto format = AnfAlgo::GetInputFormat(node, i);
  146. auto type = AnfAlgo::GetInputDeviceDataType(node, i);
  147. auto shape = AnfAlgo::GetInputDeviceShape(node, i);
  148. PrintKernelFormatAndType(gsub->buffer, format, type, shape);
  149. }
  150. gsub->buffer << ") -> (";
  151. size_t output_num = AnfAlgo::GetOutputTensorNum(node);
  152. for (size_t i = 0; i < output_num; ++i) {
  153. if (i != 0) {
  154. gsub->buffer << ", ";
  155. }
  156. auto format = AnfAlgo::GetOutputFormat(node, i);
  157. auto type = AnfAlgo::GetOutputDeviceDataType(node, i);
  158. auto shape = AnfAlgo::GetOutputDeviceShape(node, i);
  159. PrintKernelFormatAndType(gsub->buffer, format, type, shape);
  160. }
  161. gsub->buffer << ")";
  162. gsub->buffer << std::endl;
  163. }
  164. int32_t DumpParams(const FuncGraphPtr &graph, std::ostringstream &buffer, OrderedMap<AnfNodePtr, int32_t> *para_map) {
  165. if (graph == nullptr) {
  166. MS_LOG(INFO) << "Param graph is nullptr.";
  167. return 0;
  168. }
  169. std::vector<AnfNodePtr> parameters = graph->parameters();
  170. buffer << "#Total params : " << parameters.size() << std::endl;
  171. buffer << std::endl;
  172. // dump parameters
  173. int32_t para = 1;
  174. for (const auto &p : parameters) {
  175. if (p == nullptr) {
  176. continue;
  177. }
  178. auto parameter_ptr = p->cast<ParameterPtr>();
  179. if (parameter_ptr == nullptr) {
  180. MS_LOG(EXCEPTION) << "p cannot cast to ParameterPtr";
  181. }
  182. buffer << "%para" << para << "_" << parameter_ptr->name() << " : ";
  183. // print parameters' type and shape
  184. PrintNodeOutputType(buffer, p);
  185. auto kernel_info = p->kernel_info();
  186. if (kernel_info != nullptr && kernel_info->has_build_info()) {
  187. buffer << " : ";
  188. auto type = AnfAlgo::GetOutputDeviceDataType(p, 0);
  189. auto format = AnfAlgo::GetOutputFormat(p, 0);
  190. auto shape = AnfAlgo::GetOutputDeviceShape(p, 0);
  191. PrintKernelFormatAndType(buffer, format, type, shape);
  192. buffer << " : IsWeight:" << std::boolalpha << AnfAlgo::IsParameterWeight(parameter_ptr);
  193. }
  194. buffer << std::endl;
  195. if (para_map != nullptr) {
  196. (*para_map)[p] = para++;
  197. }
  198. MS_LOG(DEBUG) << "Record param: " << p->ToString() << " graph belong : " << p->func_graph()->ToString();
  199. }
  200. return para;
  201. }
  202. void DumpOperator(const AnfNodePtr &op, const std::shared_ptr<SubGraphIRInfo> &gsub) {
  203. if (op == nullptr) {
  204. MS_LOG(INFO) << "Param op is nullptr";
  205. return;
  206. }
  207. if (gsub == nullptr) {
  208. MS_LOG(INFO) << "Param gsub is nullptr";
  209. return;
  210. }
  211. if (IsValueNode<FuncGraph>(op)) {
  212. FuncGraphPtr fg = GetValueNode<FuncGraphPtr>(op);
  213. if (fg != nullptr) {
  214. gsub->buffer << "call @" << fg->ToString();
  215. }
  216. } else if (op->isa<CNode>()) {
  217. if (gsub->local_var_map.find(op) != gsub->local_var_map.end()) {
  218. gsub->buffer << "%" << gsub->local_var_map[op];
  219. } else {
  220. auto node = op->cast<CNodePtr>();
  221. auto fg = node->func_graph();
  222. gsub->buffer << "$(" << fg->ToString() << ":" << node->ToString() << ")";
  223. }
  224. } else if (op->isa<ValueNode>()) {
  225. gsub->buffer << GetValueNode(op)->ToString();
  226. } else {
  227. gsub->buffer << op->ToString();
  228. }
  229. }
  230. void DumpOperands(const AnfNodePtr &nd, OrderedMap<AnfNodePtr, int32_t> *para_map,
  231. const std::shared_ptr<SubGraphIRInfo> &gsub) {
  232. if (nd == nullptr || para_map == nullptr || gsub == nullptr) {
  233. return;
  234. }
  235. gsub->buffer << "(";
  236. const auto &inputs = GetInputs(nd);
  237. size_t len = inputs.size();
  238. if (len > 1) {
  239. // skip inputs[0] which is Primitive valuenode
  240. for (size_t i = 1; i < len; ++i) {
  241. AnfNodePtr in = inputs[i];
  242. MS_EXCEPTION_IF_NULL(in);
  243. if (i != 1) {
  244. gsub->buffer << ", ";
  245. }
  246. if (in->isa<Parameter>()) {
  247. if (!(*para_map)[in]) {
  248. gsub->buffer << "%para_" << in->ToString();
  249. } else {
  250. gsub->buffer << "%para" << (*para_map)[in] << "_" << in->ToString();
  251. }
  252. } else if (in->isa<CNode>()) {
  253. if (gsub->local_var_map.find(in) != gsub->local_var_map.end()) {
  254. gsub->buffer << "%" << gsub->local_var_map[in];
  255. } else {
  256. auto node = in->cast<CNodePtr>();
  257. auto fg = node->func_graph();
  258. gsub->buffer << "$(" << fg->ToString() << ":" << node->ToString() << ")";
  259. }
  260. } else if (in->isa<ValueNode>() && !IsValueNode<FuncGraph>(in)) {
  261. // non Primitive valuenode
  262. gsub->buffer << GetValueNode(in)->ToString();
  263. } else if (IsValueNode<FuncGraph>(in)) {
  264. FuncGraphPtr fg = GetValueNode<FuncGraphPtr>(in);
  265. gsub->buffer << "@" << fg->ToString();
  266. } else {
  267. gsub->buffer << in->ToString();
  268. }
  269. }
  270. }
  271. gsub->buffer << ")";
  272. }
  273. void DumpParallelInfo(const CNodePtr &node, const std::shared_ptr<SubGraphIRInfo> &gsub) {
  274. if ((node == nullptr) || (gsub == nullptr)) {
  275. return;
  276. }
  277. auto operator_info = node->user_data<parallel::OperatorInfo>();
  278. if (operator_info == nullptr) {
  279. return;
  280. }
  281. auto strategy = operator_info->strategy();
  282. if (strategy == nullptr) {
  283. return;
  284. }
  285. ValuePtr temp = MakeValue(strategy->GetInputDim());
  286. gsub->buffer << " { strategy: ";
  287. gsub->buffer << temp->ToString();
  288. gsub->buffer << " }";
  289. }
  290. void DumpAttrs(const std::unordered_map<std::string, ValuePtr> &attrs, const std::shared_ptr<SubGraphIRInfo> &gsub,
  291. bool check_strategy = false) {
  292. int i = 0;
  293. for (const auto &attr : attrs) {
  294. if (check_strategy && attr.first == PARALLEL_STRATEGY) {
  295. continue; // skip the strategy
  296. }
  297. if (i++ != 0) {
  298. gsub->buffer << ", ";
  299. }
  300. gsub->buffer << attr.first << ": ";
  301. if (attr.second == nullptr) {
  302. gsub->buffer << "null";
  303. } else {
  304. gsub->buffer << attr.second->ToString();
  305. }
  306. }
  307. }
  308. void DumpOperateAttrs(const AnfNodePtr &op, const std::shared_ptr<SubGraphIRInfo> &gsub) {
  309. if (op == nullptr || gsub == nullptr) {
  310. return;
  311. }
  312. if (IsValueNode<Primitive>(op)) {
  313. PrimitivePtr primitive = GetValueNode<PrimitivePtr>(op);
  314. if (!primitive->instance_name().empty()) {
  315. gsub->buffer << " {";
  316. gsub->buffer << "instance name"
  317. << ": ";
  318. gsub->buffer << primitive->instance_name();
  319. gsub->buffer << "}";
  320. }
  321. auto attrs = primitive->attrs();
  322. if (!attrs.empty()) {
  323. gsub->buffer << " primitive_attrs: {";
  324. DumpAttrs(attrs, gsub, true);
  325. gsub->buffer << "}";
  326. }
  327. }
  328. }
  329. void DumpCNodeAttrs(const CNodePtr &op, const std::shared_ptr<SubGraphIRInfo> &gsub) {
  330. if (op == nullptr || gsub == nullptr) {
  331. return;
  332. }
  333. if (op->attrs().empty()) {
  334. return;
  335. }
  336. auto attrs = op->attrs();
  337. gsub->buffer << " cnode_attrs: {";
  338. DumpAttrs(attrs, gsub);
  339. gsub->buffer << "}";
  340. }
  341. void DumpCNodePrimalAttrs(const CNodePtr &op, const std::shared_ptr<SubGraphIRInfo> &gsub) {
  342. if (op == nullptr || gsub == nullptr) {
  343. return;
  344. }
  345. if (op->primal_attrs().empty()) {
  346. gsub->buffer << std::endl;
  347. return;
  348. }
  349. auto primal_attrs = op->primal_attrs();
  350. gsub->buffer << " cnode_primal_attrs: {";
  351. int i = 0;
  352. for (const auto &attr : primal_attrs) {
  353. if (i++ != 0) {
  354. gsub->buffer << ", ";
  355. }
  356. gsub->buffer << attr.first << ": ";
  357. if (attr.second == nullptr) {
  358. gsub->buffer << "null";
  359. } else {
  360. gsub->buffer << attr.second->ToString();
  361. }
  362. }
  363. gsub->buffer << "}";
  364. gsub->buffer << std::endl;
  365. }
  366. void DumpShape(const AnfNodePtr &nd, const FuncGraphPtr &sub_graph, const std::shared_ptr<SubGraphIRInfo> &gsub) {
  367. if (nd == nullptr || sub_graph == nullptr || gsub == nullptr) {
  368. return;
  369. }
  370. if (nd != sub_graph->get_return()) {
  371. gsub->buffer << " : (";
  372. PrintNodeInputType(gsub->buffer, nd);
  373. gsub->buffer << ") -> (";
  374. PrintNodeOutputType(gsub->buffer, nd);
  375. gsub->buffer << ")";
  376. } else {
  377. gsub->buffer << " : (";
  378. PrintNodeInputType(gsub->buffer, nd);
  379. gsub->buffer << ")";
  380. }
  381. gsub->buffer << std::endl;
  382. }
  383. void DumpCNode(const CNodePtr &nd, const FuncGraphPtr &sub_graph, OrderedMap<AnfNodePtr, int32_t> *const para_map,
  384. const std::shared_ptr<SubGraphIRInfo> &gsub, bool dump_full_name = false,
  385. LocDumpMode dump_location = kOff) {
  386. if (nd == nullptr || sub_graph == nullptr || para_map == nullptr || gsub == nullptr) {
  387. return;
  388. }
  389. if (nd != sub_graph->get_return()) {
  390. gsub->buffer << " %" << gsub->local_var << "(" << nd->ToString() << ")"
  391. << " = ";
  392. gsub->local_var_map[nd] = gsub->local_var++;
  393. } else {
  394. gsub->buffer << " ";
  395. }
  396. if (nd->inputs().empty()) {
  397. MS_LOG(EXCEPTION) << "Input of apply node is empty";
  398. }
  399. // print operator
  400. AnfNodePtr op = nd->input(0);
  401. DumpOperator(op, gsub);
  402. // print operands
  403. DumpOperands(nd, para_map, gsub);
  404. // print operator attrs
  405. DumpOperateAttrs(op, gsub);
  406. // print cnode attrs
  407. DumpCNodeAttrs(nd, gsub);
  408. // print cnode primal attrs
  409. DumpCNodePrimalAttrs(nd, gsub);
  410. // print parallel info
  411. DumpParallelInfo(nd, gsub);
  412. // print shape info
  413. DumpShape(nd, sub_graph, gsub);
  414. // print kernel info
  415. DumpKernelInfo(nd, gsub);
  416. if (dump_full_name) {
  417. gsub->buffer << " : (" << nd->fullname_with_scope() << ")" << std::endl;
  418. }
  419. if (dump_location == kTopStack) {
  420. if (label_manage::GetGlobalTraceLabelType() == label_manage::TraceLabelType::kWithUniqueId) {
  421. gsub->buffer << trace::GetDebugInfo(nd->debug_info(), " # ", kSourceLineTipDiscard) << "#"
  422. << label_manage::Label(nd->debug_info()) << "\n";
  423. auto primal_debug_infos = nd->primal_debug_infos();
  424. if (!primal_debug_infos.empty()) {
  425. gsub->buffer << " # Corresponding forward node candidate:\n";
  426. for (auto &primal_debug_info : primal_debug_infos) {
  427. gsub->buffer << trace::GetDebugInfo(primal_debug_info, " # ", kSourceLineTipDiscard) << "#"
  428. << label_manage::Label(primal_debug_info) << "\n";
  429. }
  430. }
  431. } else {
  432. gsub->buffer << trace::GetDebugInfo(nd->debug_info(), " # ", kSourceLineTipDiscard) << "\n";
  433. auto primal_debug_infos = nd->primal_debug_infos();
  434. if (!primal_debug_infos.empty()) {
  435. gsub->buffer << " # Corresponding forward node candidate:\n";
  436. for (auto &primal_debug_info : primal_debug_infos) {
  437. gsub->buffer << trace::GetDebugInfo(primal_debug_info, " # ", kSourceLineTipDiscard) << "\n";
  438. }
  439. }
  440. }
  441. } else if (dump_location == kWholeStack) {
  442. auto traces = mindspore::trace::GetSourceLineList(nd);
  443. for (auto &trace : traces) {
  444. gsub->buffer << " # " << trace;
  445. }
  446. }
  447. }
  448. void DumpIRInSubgraph(const std::vector<AnfNodePtr> &nodes, OrderedMap<AnfNodePtr, int32_t> *para_map,
  449. OrderedMap<FuncGraphPtr, std::shared_ptr<SubGraphIRInfo>> *const sub_graphs, int32_t total_para,
  450. bool dump_full_name = false, LocDumpMode dump_location = kOff) {
  451. if (para_map == nullptr || sub_graphs == nullptr) {
  452. return;
  453. }
  454. for (const auto &nd : nodes) {
  455. MS_EXCEPTION_IF_NULL(nd);
  456. FuncGraphPtr sub_graph = nd->func_graph();
  457. if (sub_graph == nullptr) {
  458. MS_LOG(DEBUG) << "Node[" << nd->ToString() << "] belongs to no graph!";
  459. continue;
  460. }
  461. std::shared_ptr<SubGraphIRInfo> gsub = (*sub_graphs)[sub_graph];
  462. if (gsub == nullptr) {
  463. gsub = std::make_shared<SubGraphIRInfo>();
  464. gsub->local_var = 0;
  465. (*sub_graphs)[sub_graph] = gsub;
  466. }
  467. std::vector<AnfNodePtr> parameters = sub_graph->parameters();
  468. for (size_t idx = 0; idx < parameters.size(); idx++) {
  469. MS_EXCEPTION_IF_NULL(parameters[idx]);
  470. if ((*para_map).count(parameters[idx]) == 0) {
  471. (*para_map)[parameters[idx]] = total_para++;
  472. }
  473. }
  474. if (!nd->isa<Parameter>()) {
  475. if (nd->isa<CNode>()) {
  476. // print and record output of operator if it is not 'Return'
  477. DumpCNode(nd->cast<CNodePtr>(), sub_graph, para_map, gsub, dump_full_name, dump_location);
  478. } else {
  479. gsub->buffer << " " << nd->ToString() << std::endl;
  480. }
  481. }
  482. }
  483. }
  484. void DumpSubgraph(const OrderedMap<FuncGraphPtr, std::shared_ptr<SubGraphIRInfo>> *sub_graphs,
  485. const FuncGraphPtr &graph, OrderedMap<AnfNodePtr, int32_t> *para_map, std::ofstream &fout) {
  486. if (sub_graphs == nullptr || graph == nullptr) {
  487. return;
  488. }
  489. fout << "#Total subgraph : " << sub_graphs->size() << std::endl;
  490. fout << std::endl;
  491. for (const auto &sg : *sub_graphs) {
  492. fout << "subgraph attr:" << std::endl;
  493. MS_EXCEPTION_IF_NULL(sg.first);
  494. for (const auto &attr : sg.first->attrs()) {
  495. fout << attr.first << " : ";
  496. if (attr.second->isa<BoolImm>()) {
  497. fout << GetValue<bool>(attr.second);
  498. } else if (attr.second->isa<StringImm>()) {
  499. fout << (GetValue<std::string>(attr.second));
  500. }
  501. fout << std::endl;
  502. }
  503. fout << "subgraph @" << sg.first->ToString() << "(";
  504. if (sg.first != graph) {
  505. std::vector<AnfNodePtr> parameters = sg.first->parameters();
  506. if (parameters.size() == 1) {
  507. MS_EXCEPTION_IF_NULL(parameters[0]);
  508. fout << "%para" << (*para_map)[parameters[0]] << "_" << parameters[0]->ToString();
  509. } else if (parameters.size() > 1) {
  510. for (size_t idx = 0; idx < parameters.size() - 1; idx++) {
  511. MS_EXCEPTION_IF_NULL(parameters[idx]);
  512. fout << "%para" << (*para_map)[parameters[idx]] << "_" << parameters[idx]->ToString();
  513. fout << ", ";
  514. }
  515. MS_EXCEPTION_IF_NULL(parameters[parameters.size() - 1]);
  516. fout << "%para" << (*para_map)[parameters[parameters.size() - 1]] << "_"
  517. << parameters[parameters.size() - 1]->ToString();
  518. }
  519. }
  520. fout << ") {" << std::endl;
  521. MS_EXCEPTION_IF_NULL(sg.second);
  522. fout << sg.second->buffer.str();
  523. fout << "}" << std::endl;
  524. fout << std::endl;
  525. }
  526. }
  527. void GetEnvDumpIrLineLevel(LocDumpMode *dump_location) {
  528. static std::unordered_map<std::string, enum LocDumpMode> dump_level_map = {
  529. {std::to_string(kOff), kOff}, {std::to_string(kTopStack), kTopStack}, {std::to_string(kWholeStack), kWholeStack}};
  530. static const auto dump_level_in_env = common::GetEnv("ENV_DUMP_IR_LINE_LEVEL");
  531. auto it = dump_level_map.find(dump_level_in_env);
  532. if (it == dump_level_map.end()) {
  533. return;
  534. }
  535. // Use the env setting instead parameter setting.
  536. *dump_location = it->second;
  537. }
  538. #ifdef ENABLE_DUMP_IR
  539. void DumpIR(const std::string &filename, const FuncGraphPtr &graph, bool dump_full_name, LocDumpMode dump_location,
  540. const std::string &target_file) {
  541. GetEnvDumpIrLineLevel(&dump_location);
  542. if (graph == nullptr) {
  543. return;
  544. }
  545. auto path = GetSaveGraphsPathName(Common::AddId(filename, ".ir"));
  546. if (!target_file.empty()) {
  547. path = target_file;
  548. }
  549. auto realpath = Common::CreatePrefixPath(path);
  550. if (!realpath.has_value()) {
  551. MS_LOG(ERROR) << "Get real path failed, path=" << path;
  552. return;
  553. }
  554. ChangeFileMode(realpath.value(), S_IWUSR);
  555. std::ofstream fout(realpath.value());
  556. std::ostringstream buffer;
  557. if (!fout.is_open()) {
  558. MS_LOG(ERROR) << "Open dump file '" << realpath.value() << "' failed!"
  559. << " Errno:" << errno << " ErrInfo:" << strerror(errno);
  560. return;
  561. }
  562. auto nodes = TopoSort(graph->get_return(), SuccDeeperSimple, AlwaysInclude);
  563. OrderedMap<AnfNodePtr, int32_t> para_map;
  564. // dump global info
  565. DumpGlobalInfoEntry(graph, buffer);
  566. int32_t total_para = DumpParams(graph, buffer, &para_map);
  567. OrderedMap<FuncGraphPtr, std::shared_ptr<SubGraphIRInfo>> sub_graphs;
  568. // dump ir in each sub graph
  569. DumpIRInSubgraph(nodes, &para_map, &sub_graphs, total_para, dump_full_name, dump_location);
  570. // output global info
  571. fout << buffer.str() << std::endl;
  572. // output each sub graph
  573. DumpSubgraph(&sub_graphs, graph, &para_map, fout);
  574. fout.close();
  575. // set file mode to read only by user
  576. ChangeFileMode(realpath.value(), S_IRUSR);
  577. }
  578. void DumpIRForRDR(const std::string &filename, const FuncGraphPtr &graph, bool dump_full_name,
  579. LocDumpMode dump_location) {
  580. GetEnvDumpIrLineLevel(&dump_location);
  581. if (graph == nullptr) {
  582. return;
  583. }
  584. auto path = Common::AddId(filename, ".ir");
  585. auto realpath = Common::CreatePrefixPath(path);
  586. if (!realpath.has_value()) {
  587. MS_LOG(ERROR) << "Get real path failed. path=" << path;
  588. return;
  589. }
  590. ChangeFileMode(realpath.value(), S_IWUSR);
  591. std::ofstream fout(realpath.value());
  592. std::ostringstream buffer;
  593. if (!fout.is_open()) {
  594. MS_LOG(ERROR) << "Open dump file '" << realpath.value() << "' failed!"
  595. << " Errno:" << errno << " ErrInfo:" << strerror(errno);
  596. return;
  597. }
  598. auto nodes = TopoSort(graph->get_return(), SuccDeeperSimple, AlwaysInclude);
  599. OrderedMap<AnfNodePtr, int32_t> para_map;
  600. // dump global info
  601. DumpGlobalInfoEntry(graph, buffer);
  602. int32_t total_para = DumpParams(graph, buffer, &para_map);
  603. OrderedMap<FuncGraphPtr, std::shared_ptr<SubGraphIRInfo>> sub_graphs;
  604. // dump ir in each sub graph
  605. DumpIRInSubgraph(nodes, &para_map, &sub_graphs, total_para, dump_full_name, dump_location);
  606. // output global info
  607. fout << buffer.str() << std::endl;
  608. // output each sub graph
  609. DumpSubgraph(&sub_graphs, graph, &para_map, fout);
  610. fout.close();
  611. // set file mode to read only by user
  612. ChangeFileMode(realpath.value(), S_IRUSR);
  613. }
  614. #else
  615. void DumpIR(const std::string &, const FuncGraphPtr &, bool, LocDumpMode, const std::string &) {
  616. static bool already_printed = false;
  617. if (already_printed) {
  618. return;
  619. }
  620. already_printed = true;
  621. MS_LOG(WARNING) << "The functionality of dumping function graph IR is disabled, "
  622. << "please recompile source to enable it. See help of building script.";
  623. }
  624. void DumpIRForRDR(const std::string &, const FuncGraphPtr &, bool, LocDumpMode) {
  625. static bool already_printed = false;
  626. if (already_printed) {
  627. return;
  628. }
  629. already_printed = true;
  630. MS_LOG(WARNING) << "The functionality of dumping function graph IR is disabled, "
  631. << "please recompile source to enable it. See help of building script.";
  632. }
  633. #endif
  634. } // namespace mindspore