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