1 /**
2 * Copyright 2021-2022 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
17 #include "runtime/graph_scheduler/actor/actor_dump.h"
18 #include <map>
19 #include <utility>
20 #include <deque>
21
22 #include "runtime/graph_scheduler/scheduler_helper.h"
23 namespace mindspore {
24 namespace runtime {
25 namespace {
GetSplitName(const std::string & name)26 std::string GetSplitName(const std::string &name) {
27 auto index = name.rfind('/');
28 if ((index != std::string::npos) && (index < name.size() - 1)) {
29 return name.substr(index + 1);
30 }
31 return name;
32 }
33
DumpBaseInputInfo(const AbstractActor * actor,std::ofstream & ofs)34 void DumpBaseInputInfo(const AbstractActor *actor, std::ofstream &ofs) {
35 MS_EXCEPTION_IF_NULL(actor);
36 // Dump device tensor store.
37 if (actor->device_tensor_store_keys().size() > 0) {
38 ofs << "\t\tdevice_tensor_store_keys:" << actor->device_tensor_store_keys().size() << "\n ";
39 for (const auto &device_tensor_store_key : actor->device_tensor_store_keys()) {
40 MS_EXCEPTION_IF_NULL(device_tensor_store_key.second);
41 ofs << "\t\t\tto_input_index:" << device_tensor_store_key.first
42 << "\tfrom_node_name:" << device_tensor_store_key.second->fullname_with_scope() << "\n";
43 }
44 }
45
46 // Dump input data arrow.
47 if (actor->input_data_arrow_aids().size() > 0) {
48 ofs << "\t\tinput_data_arrow_actors:" << actor->input_data_arrow_aids().size() << "\n ";
49 for (const auto &input_data_arrow_aid : actor->input_data_arrow_aids()) {
50 ofs << "\t\t\tfrom_actor_name:" << input_data_arrow_aid.first.Name() << "\n";
51 }
52 }
53
54 // Dump input control arrow.
55 if (actor->input_control_arrow_aids().size() > 0) {
56 ofs << "\t\tinput_control_arrow_actors:" << actor->input_control_arrow_aids().size() << "\n ";
57 for (const auto &input_control_arrow_aid : actor->input_control_arrow_aids()) {
58 ofs << "\t\t\tfrom_actor_name:" << input_control_arrow_aid.first.Name() << "\n";
59 }
60 }
61 }
62
DumpBaseOutputInfo(const AbstractActor * actor,std::ofstream & ofs)63 void DumpBaseOutputInfo(const AbstractActor *actor, std::ofstream &ofs) {
64 MS_EXCEPTION_IF_NULL(actor);
65 // Dump batch output data arrow.
66 size_t batch_output_data_size = 0;
67 if (actor->batch_output_data_arrows().size() > 0) {
68 ofs << "\t\tbatch_output_data_arrows:" << actor->batch_output_data_arrows().size() << "\n ";
69 for (const auto &batch_output_data_arrow : actor->batch_output_data_arrows()) {
70 batch_output_data_size += batch_output_data_arrow.second.size();
71 ofs << "\t\t\tbatch_to_actor_name:" << batch_output_data_arrow.first
72 << "\tbatch_size:" << batch_output_data_arrow.second.size() << "\n";
73 for (const auto &data_arrow : batch_output_data_arrow.second) {
74 MS_EXCEPTION_IF_NULL(data_arrow);
75 ofs << "\t\t\t\tfrom_output_index:" << data_arrow->from_output_index_
76 << "\tto_actor_name:" << data_arrow->to_op_id_.Name() << "\tto_input_index:" << data_arrow->to_input_index_
77 << "\tflag:" << data_arrow->flag_ << "\n";
78 }
79 }
80 }
81
82 // Dump output data arrow.
83 if (actor->output_data_arrows().size() != actor->output_data_nodes().size()) {
84 MS_LOG(EXCEPTION) << "The size of output data arrows is not equal to the output nodes, arrow num:"
85 << actor->output_data_arrows().size() << " node num:" << actor->output_data_nodes().size()
86 << " for actor:" << actor->GetAID().Name();
87 }
88 if (actor->output_data_arrows().size() > 0) {
89 ofs << "\t\toutput_data_arrows:" << actor->output_data_arrows().size() - batch_output_data_size << "\n ";
90 size_t batch_count = 0;
91 for (size_t i = 0; i < actor->output_data_arrows().size(); ++i) {
92 auto data_arrow = actor->output_data_arrows()[i];
93 auto output_node = actor->output_data_nodes()[i];
94 MS_EXCEPTION_IF_NULL(data_arrow);
95 if (!TEST_FLAG(data_arrow->flag_, kOutputDataFlagBatch)) {
96 std::string node_name = (output_node != nullptr) ? GetSplitName(output_node->fullname_with_scope()) : "";
97 ofs << "\t\t\tfrom_output_node:" << node_name << "\tfrom_output_index:" << data_arrow->from_output_index_
98 << "\tto_actor_name:" << data_arrow->to_op_id_.Name() << "\tto_input_index:" << data_arrow->to_input_index_
99 << "\tflag:" << data_arrow->flag_ << "\n";
100 } else {
101 ++batch_count;
102 }
103 }
104 if (batch_count != batch_output_data_size) {
105 MS_LOG(EXCEPTION) << "Check batch output data error, the expect num:" << batch_output_data_size
106 << ", but get num:" << batch_count << " for " << actor->GetAID().Name();
107 }
108 }
109
110 // Dump output control arrow.
111 const auto &output_control_arrows = actor->output_control_arrows();
112 if (output_control_arrows.size() > 0) {
113 ofs << "\t\toutput_control_arrows:" << output_control_arrows.size() << "\n ";
114 for (const auto &output_control_arrow : output_control_arrows) {
115 MS_EXCEPTION_IF_NULL(output_control_arrow);
116 ofs << "\t\t\tto_actor_name:" << output_control_arrow->to_op_id_.Name()
117 << "\tflag:" << output_control_arrow->flag_ << "\n";
118 }
119 }
120 }
121
DumpAbstractActor(const AbstractActor * actor,std::ofstream & ofs)122 void DumpAbstractActor(const AbstractActor *actor, std::ofstream &ofs) {
123 MS_EXCEPTION_IF_NULL(actor);
124 if (actor->parent_fusion_actor() != nullptr) {
125 ofs << "\t\tparent_fusion_actor:" << actor->parent_fusion_actor()->GetAID().Name() << "\n ";
126 }
127 // Dump device context.
128 if (actor->device_contexts().size() > 0) {
129 ofs << "\t\tdevice_contexts:" << actor->device_contexts().size() << "\n ";
130 for (const auto &device_context : actor->device_contexts()) {
131 if (device_context == nullptr) {
132 ofs << "\t\t\tdevice_context:" << device_context << "\n";
133 continue;
134 }
135 ofs << "\t\t\tdevice_context:" << device_context->device_context_key().ToString() << "\n";
136 }
137 }
138
139 DumpBaseInputInfo(actor, ofs);
140 DumpBaseOutputInfo(actor, ofs);
141
142 // Dump internal parameters.
143 if (actor->internal_parameters().size() > 0) {
144 ofs << "\t\tinternal_parameters:" << actor->internal_parameters().size() << "\n ";
145 for (auto &internal_parameter_iter : actor->internal_parameters()) {
146 MS_EXCEPTION_IF_NULL(internal_parameter_iter.first.first);
147 for (auto &internal_parameter_weakptr : internal_parameter_iter.second) {
148 auto internal_parameter = internal_parameter_weakptr.lock();
149 MS_EXCEPTION_IF_NULL(internal_parameter);
150 ofs << "\t\t\toutput_node:" << internal_parameter_iter.first.first->fullname_with_scope()
151 << "\toutput_index:" << internal_parameter_iter.first.second
152 << "\tinternal_parameter:" << internal_parameter->DebugString() << "\n";
153 }
154 }
155 }
156
157 // Dump dependent actors.
158 if (actor->dependent_actors().size() > 0) {
159 ofs << "\t\tdependent_actors:" << actor->dependent_actors().size() << "\n ";
160 for (auto &dependent_actor : actor->dependent_actors()) {
161 ofs << "\t\t\tdependent_actor_name:" << dependent_actor << "\n ";
162 }
163 }
164
165 // Dump the memory actor insert position.
166 if (actor->memory_alloc_insert_position() != nullptr) {
167 ofs << "\t\tmemory_alloc_insert_from_position:" << actor->memory_alloc_insert_position()->GetAID().Name() << "\n";
168 }
169 if (actor->memory_free_insert_position() != nullptr) {
170 ofs << "\t\tmemory_free_insert_to_position:" << actor->memory_free_insert_position()->GetAID().Name() << "\n";
171 }
172 }
173
DumpDSActor(const DataSourceActor * actor,std::ofstream & ofs)174 void DumpDSActor(const DataSourceActor *actor, std::ofstream &ofs) {
175 MS_EXCEPTION_IF_NULL(actor);
176 const auto &actor_name = actor->GetAID().Name();
177 ofs << "\tactor_name:" << actor_name << "\tactor_id:" << actor->actor_id() << "\n";
178
179 if (actor->type() == KernelTransformType::kDeviceDataSourceActor) {
180 // Dump the member info of device queue data source actor.
181 const auto &device_queue_ds_actor = dynamic_cast<const DeviceQueueDataSourceActor *>(actor);
182 MS_EXCEPTION_IF_NULL(device_queue_ds_actor);
183 const auto &data_kernel = device_queue_ds_actor->data_kernel();
184 MS_EXCEPTION_IF_NULL(data_kernel);
185 ofs << "\t\tdata_kernel_name:" << data_kernel->fullname_with_scope()
186 << "\tinput_number:" << common::AnfAlgo::GetInputTensorNum(data_kernel)
187 << "\toutput_number:" << AnfAlgo::GetOutputTensorNum(data_kernel) << "\n";
188 for (size_t i = 0; i < AnfAlgo::GetOutputTensorNum(data_kernel); ++i) {
189 const auto &device_tensor = AnfAlgo::GetMutableOutputAddr(data_kernel, i, false);
190 MS_EXCEPTION_IF_NULL(device_tensor);
191 ofs << "\t\t\toutput_index:" << i << "\tptr:" << device_tensor->GetPtr() << "\tsize:" << device_tensor->GetSize()
192 << "\tstream id:" << device_tensor->stream_id()
193 << "\toriginal_ref_count:" << device_tensor->original_ref_count()
194 << "\tdynamic_ref_count:" << device_tensor->dynamic_ref_count() << "\tflag:" << device_tensor->flag()
195 << "\n ";
196 }
197 } else if (actor->type() == KernelTransformType::kHostDataSourceActor) {
198 // Dump the member info of host queue data source actor.
199 const auto &host_queue_ds_actor = dynamic_cast<const HostQueueDataSourceActor *>(actor);
200 MS_EXCEPTION_IF_NULL(host_queue_ds_actor);
201 ofs << "\t\tdata_nodes:" << host_queue_ds_actor->data_nodes().size() << "\n";
202 for (size_t i = 0; i < host_queue_ds_actor->data_nodes().size(); ++i) {
203 const auto &data_node = host_queue_ds_actor->data_nodes()[i];
204 MS_EXCEPTION_IF_NULL(data_node.first);
205 const auto &device_tensor = AnfAlgo::GetMutableOutputAddr(data_node.first, data_node.second, false);
206 MS_EXCEPTION_IF_NULL(device_tensor);
207 ofs << "\t\t\tnode_order_number:" << i << "\tnode_name:" << data_node.first->fullname_with_scope()
208 << "\tdebug_name:" << data_node.first->DebugString() << "\tindex:" << data_node.second
209 << "\tptr:" << device_tensor->GetPtr() << "\tsize:" << device_tensor->GetSize()
210 << "\tstream id:" << device_tensor->stream_id()
211 << "\toriginal_ref_count:" << device_tensor->original_ref_count()
212 << "\tdynamic_ref_count:" << device_tensor->dynamic_ref_count() << "\tflag:" << device_tensor->flag()
213 << "\n ";
214 }
215 }
216
217 DumpAbstractActor(actor, ofs);
218 ofs << "\n";
219 }
220
DumpKernelActor(const KernelActor * actor,std::ofstream & ofs)221 void DumpKernelActor(const KernelActor *actor, std::ofstream &ofs) {
222 MS_EXCEPTION_IF_NULL(actor);
223 ofs << "\tactor_name:" << actor->GetAID().Name() << "\tactor_id:" << actor->actor_id() << "\n";
224
225 const auto &kernel = actor->kernel();
226 MS_EXCEPTION_IF_NULL(kernel);
227 auto kernel_info = dynamic_cast<KernelInfo *>(kernel->kernel_info());
228 MS_EXCEPTION_IF_NULL(kernel_info);
229 ofs << "\t\tkernel_name:" << kernel->fullname_with_scope() << "\tstream id:" << kernel_info->stream_id()
230 << "\tinputs_num:" << common::AnfAlgo::GetInputTensorNum(kernel)
231 << "\tignored_input_addresses_num:" << SchedulerHelper::GetIgnoredInputAddressCount(kernel)
232 << "\toutputs_num:" << AnfAlgo::GetOutputTensorNum(kernel) << "\tis_dynamic_shape:" << actor->is_dynamic_shape()
233 << "\tis_launch_skipped:" << actor->is_launch_skipped() << "\n";
234 const auto &somas_outputs = kernel_info->somas_output_result();
235 const auto &somas_graph_output_indexes = actor->somas_graph_output_indexes();
236 for (size_t i = 0; i < AnfAlgo::GetOutputTensorNum(kernel); ++i) {
237 const auto &device_tensor = AnfAlgo::GetMutableOutputAddr(kernel, i, false);
238 MS_EXCEPTION_IF_NULL(device_tensor);
239 ofs << "\t\t\toutput_index:" << i << "\tptr:" << device_tensor->GetPtr() << "\tsize:" << device_tensor->GetSize()
240 << "\tstream id:" << device_tensor->stream_id()
241 << "\toriginal_ref_count:" << device_tensor->original_ref_count()
242 << "\tdynamic_ref_count:" << device_tensor->dynamic_ref_count() << "\tflag:" << device_tensor->flag()
243 << "\tis_somas_enable:" << kernel_info->IsTensorEnableSomas(somas_outputs, i)
244 << "\tsomas_offset:" << kernel_info->GetTensorSomasOffset(somas_outputs, i)
245 << "\tsomas_aligned_size:" << kernel_info->GetTensorSomasAlignedSize(somas_outputs, i)
246 << "\tsoams_whether_graph_output:" << somas_graph_output_indexes.count(i) << "\n ";
247 }
248 const auto &somas_workspace = kernel_info->somas_workspace_result();
249 const auto &workspace_addresses = kernel_info->workspace_address_list();
250 for (size_t i = 0; i < workspace_addresses.size(); ++i) {
251 auto &device_tensor = workspace_addresses[i];
252 MS_EXCEPTION_IF_NULL(device_tensor);
253 ofs << "\t\t\tworkspace_index:" << i << "\tptr:" << device_tensor->GetPtr() << "\tsize:" << device_tensor->GetSize()
254 << "\tstream id:" << device_tensor->stream_id()
255 << "\toriginal_ref_count:" << device_tensor->original_ref_count()
256 << "\tdynamic_ref_count:" << device_tensor->dynamic_ref_count() << "\tflag:" << device_tensor->flag()
257 << "\tis_somas_enable:" << kernel_info->IsTensorEnableSomas(somas_workspace, i)
258 << "\tsomas_offset:" << kernel_info->GetTensorSomasOffset(somas_workspace, i)
259 << "\tsomas_aligned_size:" << kernel_info->GetTensorSomasAlignedSize(somas_workspace, i) << "\n ";
260 }
261
262 DumpAbstractActor(actor, ofs);
263
264 if (actor->modifiable_ref_input_indexes().size() != 0) {
265 ofs << "\t\tmodifiable_ref_input_indexes:" << actor->modifiable_ref_input_indexes().size() << "\n";
266 for (auto &ref_input_index : actor->modifiable_ref_input_indexes()) {
267 ofs << "\t\t\tmodifiable_ref_input_index:" << ref_input_index << "\n ";
268 }
269 }
270 if (actor->modifiable_ref_output_indexes().size() != 0) {
271 ofs << "\t\tmodifiable_ref_output_indexes:" << actor->modifiable_ref_output_indexes().size() << "\n";
272 for (auto &ref_output_index : actor->modifiable_ref_output_indexes()) {
273 ofs << "\t\t\tmodifiable_ref_output_index:" << ref_output_index << "\n ";
274 }
275 }
276
277 ofs << "\n";
278 }
279
DumpCustomActor(const CustomActor * actor,std::ofstream & ofs)280 void DumpCustomActor(const CustomActor *actor, std::ofstream &ofs) {
281 MS_EXCEPTION_IF_NULL(actor);
282 ofs << "\tactor_name:" << actor->GetAID().Name() << "\tactor_id:" << actor->actor_id() << "\n";
283 DumpAbstractActor(actor, ofs);
284 ofs << "\n";
285 }
286
DumpSwapActor(const MemorySwapActor * actor,std::ofstream & ofs)287 void DumpSwapActor(const MemorySwapActor *actor, std::ofstream &ofs) {
288 MS_EXCEPTION_IF_NULL(actor);
289 ofs << "\tactor_name:" << actor->GetAID().Name() << "\tactor_id:" << actor->actor_id() << "\n";
290 DumpAbstractActor(actor, ofs);
291 ofs << "\n";
292 }
293
DumpSuperKernelActor(const SuperKernelActor * actor,std::ofstream & ofs)294 void DumpSuperKernelActor(const SuperKernelActor *actor, std::ofstream &ofs) {
295 MS_EXCEPTION_IF_NULL(actor);
296 ofs << "\tactor_name:" << actor->GetAID().Name() << "\tactor_id:" << actor->actor_id() << "\n";
297
298 const auto &graph = actor->graph();
299 MS_EXCEPTION_IF_NULL(graph);
300
301 ofs << "\t\tgraph_id:" << graph->graph_id() << "\tgraphl_name:" << graph->ToString()
302 << "\tis_graph_run_mode:" << graph->is_graph_run_mode() << "\tis_loop_count_sink:" << graph->is_loop_count_sink()
303 << "\tinputs_num:" << (graph->input_nodes()).size() << "\tkernels_num:" << (graph->execution_order()).size()
304 << "\tis enable zero copy:" << graph->has_flag(kFlagEnableZeroCopyInGraph) << "\n";
305
306 DumpAbstractActor(actor, ofs);
307 ofs << "\n";
308 }
309
DumpAnyTypeKernelActor(const AnyTypeKernelActor * actor,std::ofstream & ofs)310 void DumpAnyTypeKernelActor(const AnyTypeKernelActor *actor, std::ofstream &ofs) {
311 MS_EXCEPTION_IF_NULL(actor);
312 ofs << "\tactor_name:" << actor->GetAID().Name() << "\tactor_id:" << actor->actor_id() << "\n";
313 const auto &graph = actor->graph();
314 MS_EXCEPTION_IF_NULL(graph);
315 ofs << "\t\tgraph_id:" << graph->graph_id() << "\tgraphl_name:" << graph->ToString()
316 << "\tis_graph_run_mode:" << graph->is_graph_run_mode() << "\tis_loop_count_sink:" << graph->is_loop_count_sink()
317 << "\tinputs_num:" << (graph->input_nodes()).size() << "\tkernels_num:" << (graph->execution_order()).size()
318 << "\tis enable zero copy:" << graph->has_flag(kFlagEnableZeroCopyInGraph) << "\n";
319
320 DumpAbstractActor(actor, ofs);
321 ofs << "\n";
322 }
323
DumpMemoryActor(const MemoryAwareActor * actor,std::ofstream & ofs)324 void DumpMemoryActor(const MemoryAwareActor *actor, std::ofstream &ofs) {
325 MS_EXCEPTION_IF_NULL(actor);
326 ofs << "\tactor_name:" << actor->GetAID().Name() << "\tactor_id:" << actor->actor_id() << "\n";
327
328 SomasInfo *somas_info = nullptr;
329 if (actor->type() == KernelTransformType::kMemoryAllocActor) {
330 auto alloc_actor = dynamic_cast<const MemoryAllocActor *>(actor);
331 MS_EXCEPTION_IF_NULL(alloc_actor);
332 somas_info = alloc_actor->somas_info();
333 } else {
334 auto free_actor = dynamic_cast<const MemoryFreeActor *>(actor);
335 MS_EXCEPTION_IF_NULL(free_actor);
336 somas_info = free_actor->somas_info();
337 }
338
339 MS_EXCEPTION_IF_NULL(somas_info);
340 ofs << "\t\tgraph_id:" << somas_info->graph_id_ << "\twhole_block_size:" << somas_info->whole_block_size_ << "\n ";
341
342 DumpAbstractActor(actor, ofs);
343
344 ofs << "\n";
345 }
346
DumpCopyActor(const CopyActor * actor,std::ofstream & ofs)347 void DumpCopyActor(const CopyActor *actor, std::ofstream &ofs) {
348 MS_EXCEPTION_IF_NULL(actor);
349 ofs << "\tactor_name:" << actor->GetAID().Name() << "\tactor_id:" << actor->actor_id() << "\n";
350
351 auto &device_tensor = actor->output();
352 if (device_tensor != nullptr) {
353 ofs << "\t\toutput_index:" << 0 << "\tptr:" << device_tensor->GetPtr() << "\tsize:" << device_tensor->GetSize()
354 << "\tstream id:" << device_tensor->stream_id()
355 << "\toriginal_ref_count:" << device_tensor->original_ref_count()
356 << "\tdynamic_ref_count:" << device_tensor->dynamic_ref_count() << "\tflag:" << device_tensor->flag() << "\n ";
357 }
358
359 DumpAbstractActor(actor, ofs);
360
361 ofs << "\t\tis_need_update_output_size:" << actor->is_need_update_output_size() << "\n ";
362 ofs << "\n";
363 }
364
DumpFusionActor(const FusionActor * actor,std::ofstream & ofs)365 void DumpFusionActor(const FusionActor *actor, std::ofstream &ofs) {
366 MS_EXCEPTION_IF_NULL(actor);
367 ofs << "\tactor_name:" << actor->GetAID().Name() << "\tactor_id:" << actor->actor_id() << "\n";
368 ofs << "\t\tsub actors:" << actor->sub_actors().size() << "\n";
369 for (auto &sub_actor : actor->sub_actors()) {
370 ofs << "\t\t\tsub_actor_name:" << sub_actor.first << "\n";
371 }
372
373 DumpAbstractActor(actor, ofs);
374
375 if (actor->real_input_data().size() > 0) {
376 ofs << "\t\treal_input_data:" << actor->real_input_data().size() << "\n";
377 for (auto &real_input_data : actor->real_input_data()) {
378 MS_EXCEPTION_IF_NULL(real_input_data.first);
379 ofs << "\t\t\treal_input_data_actor:" << real_input_data.first->GetAID().Name()
380 << "\tinput_index:" << real_input_data.second << "\n";
381 }
382 }
383
384 if (actor->real_input_controls().size() > 0) {
385 ofs << "\t\treal_input_controls:" << actor->real_input_controls().size() << "\n";
386 for (auto &batch_real_input_control : actor->real_input_controls()) {
387 ofs << "\t\t\torigin_input_control_actor:" << batch_real_input_control.first << "\n";
388 for (auto &real_input_control : batch_real_input_control.second) {
389 MS_EXCEPTION_IF_NULL(real_input_control);
390 ofs << "\t\t\t\tto_real_control_actor:" << real_input_control->GetAID().Name() << "\n";
391 }
392 }
393 }
394
395 ofs << "\n";
396 }
397
DumpFormalParameterDeviceTensor(const ControlActor * actor,std::ofstream & ofs)398 void DumpFormalParameterDeviceTensor(const ControlActor *actor, std::ofstream &ofs) {
399 MS_EXCEPTION_IF_NULL(actor);
400 const auto &formal_parameter_device_tensors = actor->ref_formal_parameter_device_tensors();
401 if (!formal_parameter_device_tensors.empty()) {
402 ofs << "\t\tref_formal_parameter_device_tensors:" << formal_parameter_device_tensors.size() << "\n ";
403 for (const auto &formal_parameter_device_tensor : formal_parameter_device_tensors) {
404 for (const auto &device_tensor : formal_parameter_device_tensor.second) {
405 MS_EXCEPTION_IF_NULL(device_tensor);
406 auto ref_node = device_tensor->GetNodeIndex();
407 MS_EXCEPTION_IF_NULL(ref_node.first);
408 ofs << "\t\t\tref_position:" << formal_parameter_device_tensor.first
409 << "\tref_node_name:" << ref_node.first->fullname_with_scope()
410 << "\tref_node_debug_name:" << ref_node.first->DebugString() << "\n";
411 }
412 }
413 }
414
415 const auto &ref_node_formal_parameter_device_tensors = actor->ref_node_formal_parameter_device_tensors();
416 if (!ref_node_formal_parameter_device_tensors.empty()) {
417 ofs << "\t\tref_node_formal_parameter_device_tensors:" << ref_node_formal_parameter_device_tensors.size() << "\n ";
418 for (const auto &ref_node_formal_parameter_device_tensor : ref_node_formal_parameter_device_tensors) {
419 for (const auto &device_tensor : ref_node_formal_parameter_device_tensor.second) {
420 MS_EXCEPTION_IF_NULL(device_tensor);
421 auto ref_node = device_tensor->GetNodeIndex();
422 MS_EXCEPTION_IF_NULL(ref_node.first);
423 ofs << "\t\t\tref_position:" << ref_node_formal_parameter_device_tensor.first
424 << "\tref_node_name:" << ref_node.first->fullname_with_scope()
425 << "\tref_node_debug_name:" << ref_node.first->DebugString() << "\n";
426 }
427 }
428 }
429 }
430
DumpControlActor(const ControlActor * actor,std::ofstream & ofs)431 void DumpControlActor(const ControlActor *actor, std::ofstream &ofs) {
432 MS_EXCEPTION_IF_NULL(actor);
433 DumpAbstractActor(actor, ofs);
434 const auto &local_partials = actor->local_partials();
435 if (local_partials.size() > 0) {
436 ofs << "\t\tlocal partial num:" << local_partials.size() << "\n ";
437 for (const auto &local_partial : local_partials) {
438 // Skip the dead node partial.
439 MS_EXCEPTION_IF_NULL(local_partial.second);
440 if (local_partial.second->func_graph_ == nullptr) {
441 continue;
442 }
443 ofs << "\t\t\tlocal partial index:" << local_partial.first
444 << "\tgraph:" << local_partial.second->func_graph_->ToString()
445 << "\tparameter num:" << local_partial.second->device_tensors_.size() << "\n";
446 }
447 }
448
449 if (actor->input_partial_arrow_aids().size() > 0) {
450 ofs << "\t\tinput_partial_arrow_actor:" << actor->input_partial_arrow_aids().size() << "\n ";
451 for (const auto &input_partial_arrow_aid : actor->input_partial_arrow_aids()) {
452 ofs << "\t\t\tfrom_actor_name:" << input_partial_arrow_aid.Name() << "\n";
453 }
454 }
455
456 if (actor->input_branch_id_arrow_aids().size() > 0) {
457 ofs << "\t\tinput_branch_id_arrow_actor:" << actor->input_branch_id_arrow_aids().size() << "\n ";
458 for (const auto &input_branch_id_arrow_aid : actor->input_branch_id_arrow_aids()) {
459 ofs << "\t\t\tfrom_actor_name:" << input_branch_id_arrow_aid.Name() << "\n";
460 }
461 }
462
463 const auto &output_partial_arrows = actor->output_partial_arrows();
464 if (output_partial_arrows.size() > 0) {
465 ofs << "\t\toutput_partial_arrows:" << output_partial_arrows.size() << "\n ";
466 for (const auto &partial_arrow : output_partial_arrows) {
467 MS_EXCEPTION_IF_NULL(partial_arrow);
468 ofs << "\t\t\tfrom_output_index:" << partial_arrow->from_output_index_
469 << "\tto_actor_name:" << partial_arrow->to_op_id_.Name()
470 << "\tto_input_index:" << partial_arrow->to_input_index_ << "\n";
471 }
472 }
473
474 const auto &output_branch_id_arrows = actor->output_branch_id_arrows();
475 if (output_branch_id_arrows.size() > 0) {
476 ofs << "\t\toutput_branch_id_arrows:" << output_branch_id_arrows.size() << "\n ";
477 for (const auto &aid : output_branch_id_arrows) {
478 ofs << "\t\t\tto_actor_name:" << aid.Name() << "\n";
479 }
480 }
481
482 DumpFormalParameterDeviceTensor(actor, ofs);
483 }
484
DumpSwitchActor(const SwitchActor * actor,std::ofstream & ofs)485 void DumpSwitchActor(const SwitchActor *actor, std::ofstream &ofs) {
486 MS_EXCEPTION_IF_NULL(actor);
487 ofs << "\tactor_name:" << actor->GetAID().Name() << "\tactor_id:" << actor->actor_id() << '\n';
488 DumpControlActor(actor, ofs);
489 }
490
DumpGatherActor(const GatherActor * actor,std::ofstream & ofs)491 void DumpGatherActor(const GatherActor *actor, std::ofstream &ofs) {
492 MS_EXCEPTION_IF_NULL(actor);
493 ofs << "\tactor_name:" << actor->GetAID().Name() << "\tactor_id:" << actor->actor_id() << '\n';
494 ofs << "\t\tbranch id:" << actor->branch_id() << '\n';
495 DumpControlActor(actor, ofs);
496
497 ofs << "\t\toutput index:" << '\n';
498 const auto &dynamic_len_index = actor->dynamic_len_index();
499 for (const auto &func_to_index : dynamic_len_index) {
500 const auto &func_graph = func_to_index.first;
501 MS_EXCEPTION_IF_NULL(func_graph);
502 ofs << "\t\t\tfunc_graph:" << func_graph->ToString() << '\n';
503 const auto &index_list = func_to_index.second;
504 for (size_t i = 0; i < index_list.size(); ++i) {
505 ofs << "\t\t\t\treal index:" << i << " is dynamic len:" << index_list[i].second << " relative index:";
506 for (const auto &index : index_list[i].first) {
507 ofs << index << " ";
508 }
509 ofs << '\n';
510 }
511 }
512
513 const auto &output_data_with_branch_id_arrows = actor->output_data_with_branch_id_arrows();
514 if (output_data_with_branch_id_arrows.size() > 0) {
515 ofs << "\t\toutput_data_with_branch_id_arrows:" << output_data_with_branch_id_arrows.size() << "\n ";
516 for (const auto &output_data_with_branch_id_arrow : output_data_with_branch_id_arrows) {
517 MS_EXCEPTION_IF_NULL(output_data_with_branch_id_arrow.first);
518 ofs << "\t\t\tbranch funcgraph:" << output_data_with_branch_id_arrow.first->ToString() << "\n";
519 for (const auto &arrow : output_data_with_branch_id_arrow.second) {
520 ofs << "\t\t\t\tto actor:" << arrow << "\n";
521 }
522 }
523 }
524 }
525
DumpEntranceActor(const EntranceActor * actor,std::ofstream & ofs)526 void DumpEntranceActor(const EntranceActor *actor, std::ofstream &ofs) {
527 MS_EXCEPTION_IF_NULL(actor);
528 ofs << "\tactor_name:" << actor->GetAID().Name() << "\tactor_id:" << actor->actor_id() << '\n';
529 DumpControlActor(actor, ofs);
530
531 if (actor->loop_body_input_control_arrow_aids().size() > 0) {
532 ofs << "\t\tinput_loop_body_control_arrow_actors:" << actor->loop_body_input_control_arrow_aids().size() << "\n ";
533 for (const auto &loop_body_input_control_arrow_aid : actor->loop_body_input_control_arrow_aids()) {
534 ofs << "\t\t\tfrom_actor_name:" << loop_body_input_control_arrow_aid.Name() << "\n";
535 }
536 }
537 }
538
DumpExitActor(const ExitActor * actor,std::ofstream & ofs)539 void DumpExitActor(const ExitActor *actor, std::ofstream &ofs) {
540 MS_EXCEPTION_IF_NULL(actor);
541 ofs << "\tactor_name:" << actor->GetAID().Name() << "\tactor_id:" << actor->actor_id() << '\n';
542 DumpControlActor(actor, ofs);
543
544 ofs << "\t\toutput index:" << '\n';
545 const auto &dynamic_len_index = actor->output_branch_dynamic_len_index();
546 for (const auto &func_to_index : dynamic_len_index) {
547 const auto &branch_id = func_to_index.first;
548 ofs << "\t\t\tbranch_id:" << branch_id << '\n';
549 const auto &index_list = func_to_index.second;
550 for (size_t i = 0; i < index_list.size(); ++i) {
551 ofs << "\t\t\t\treal index:" << i << " is dynamic len:" << index_list[i].second << " relative index:";
552 for (const auto &index : index_list[i].first) {
553 ofs << index << " ";
554 }
555 ofs << '\n';
556 }
557 }
558
559 const auto &output_branch_data_arrows = actor->output_branch_data_arrows();
560 if (output_branch_data_arrows.size() > 0) {
561 ofs << "\t\toutput_branch_data_arrows:" << output_branch_data_arrows.size() << "\n ";
562 for (const auto &output_branch_data_arrow : output_branch_data_arrows) {
563 ofs << "\t\t\tbranch id:" << output_branch_data_arrow.first << "\n";
564 for (const auto &arrow : output_branch_data_arrow.second) {
565 MS_EXCEPTION_IF_NULL(arrow);
566 ofs << "\t\t\t\tfrom_output_index:" << arrow->from_output_index_
567 << "\tto_actor_name:" << arrow->to_op_id_.Name() << "\tto_input_index:" << arrow->to_input_index_ << "\n";
568 }
569 }
570 }
571
572 const auto &output_branch_partial_arrows = actor->output_branch_partial_arrows();
573 if (output_branch_partial_arrows.size() > 0) {
574 ofs << "\t\toutput_branch_partial_arrows:" << output_branch_partial_arrows.size() << "\n ";
575 for (const auto &output_branch_partial_arrow : output_branch_partial_arrows) {
576 ofs << "\t\t\tbranch id:" << output_branch_partial_arrow.first << "\n";
577 for (const auto &arrow : output_branch_partial_arrow.second) {
578 MS_EXCEPTION_IF_NULL(arrow);
579 ofs << "\t\t\t\tfrom_output_index:" << arrow->from_output_index_
580 << "\tto_actor_name:" << arrow->to_op_id_.Name() << "\tto_input_index:" << arrow->to_input_index_ << "\n";
581 }
582 }
583 }
584
585 const auto &output_branch_control_arrows = actor->output_branch_control_arrows();
586 if (output_branch_control_arrows.size() > 0) {
587 ofs << "\t\toutput_branch_control_arrows:" << output_branch_control_arrows.size() << "\n ";
588 for (const auto &output_branch_control_arrow : output_branch_control_arrows) {
589 ofs << "\t\t\tbranch id:" << output_branch_control_arrow.first << "\n";
590 for (const auto &arrow : output_branch_control_arrow.second) {
591 ofs << "\t\t\t\tto actor:" << arrow << "\n";
592 }
593 }
594 }
595
596 const auto &is_need_copy_device_tensors = actor->is_need_copy_device_tensors();
597 if (is_need_copy_device_tensors.size() > 0) {
598 ofs << "\t\twhether_need_copy_device_tensors:" << is_need_copy_device_tensors.size() << "\n ";
599 for (size_t i = 0; i < is_need_copy_device_tensors.size(); ++i) {
600 ofs << "\t\t\tdevice_tensor_position:" << i << "\tis_need_copy:" << is_need_copy_device_tensors[i] << "\n";
601 }
602 }
603 }
604
DumpStackActor(const StackActor * actor,std::ofstream & ofs)605 void DumpStackActor(const StackActor *actor, std::ofstream &ofs) {
606 MS_EXCEPTION_IF_NULL(actor);
607 ofs << "\tactor_name:" << actor->GetAID().Name() << "\tactor_id:" << actor->actor_id() << '\n';
608 ofs << "\t\tinput stack data num:" << actor->input_stack_data_num() << '\n';
609 ofs << "\t\tinput stack partial num:" << actor->input_stack_partials_num() << '\n';
610 ofs << "\t\tinput stack control num:" << actor->input_stack_controls_num() << '\n';
611 DumpControlActor(actor, ofs);
612 }
613
DumpSwitchActors(const std::vector<SwitchActorPtr> & actors,std::ofstream & ofs)614 void DumpSwitchActors(const std::vector<SwitchActorPtr> &actors, std::ofstream &ofs) {
615 ofs << "\n\n[Switch actors:" << actors.size() << "]\n";
616 for (const auto &switch_actor : actors) {
617 DumpSwitchActor(switch_actor.get(), ofs);
618 ofs << "\n";
619 }
620 }
621
DumpGatherActors(const std::vector<GatherActorPtr> & actors,std::ofstream & ofs)622 void DumpGatherActors(const std::vector<GatherActorPtr> &actors, std::ofstream &ofs) {
623 ofs << "\n\n[Gather actors:" << actors.size() << "]\n";
624 for (const auto &gather_actor : actors) {
625 DumpGatherActor(gather_actor.get(), ofs);
626 ofs << "\n";
627 }
628 }
629
DumpEntranceActors(const std::vector<EntranceActorPtr> & actors,std::ofstream & ofs)630 void DumpEntranceActors(const std::vector<EntranceActorPtr> &actors, std::ofstream &ofs) {
631 ofs << "\n\n[Entrance actors:" << actors.size() << "]\n";
632 for (const auto &entrance_actor : actors) {
633 DumpEntranceActor(entrance_actor.get(), ofs);
634 ofs << "\n";
635 }
636 }
637
DumpExitActors(const std::vector<ExitActorPtr> & actors,std::ofstream & ofs)638 void DumpExitActors(const std::vector<ExitActorPtr> &actors, std::ofstream &ofs) {
639 ofs << "\n\n[Exit actors:" << actors.size() << "]\n";
640 for (const auto &exit_actor : actors) {
641 DumpExitActor(exit_actor.get(), ofs);
642 ofs << "\n";
643 }
644 }
645
DumpStackActors(const std::vector<StackActorPtr> & actors,std::ofstream & ofs)646 void DumpStackActors(const std::vector<StackActorPtr> &actors, std::ofstream &ofs) {
647 ofs << "\n\n[Stack actors:" << actors.size() << "]\n";
648 for (const auto &stack_actor : actors) {
649 DumpStackActor(stack_actor.get(), ofs);
650 ofs << "\n";
651 }
652 }
653 } // namespace
654
DumpDataPrepareActor(const DataPrepareActorPtr & actor,std::ofstream & ofs)655 void DumpDataPrepareActor(const DataPrepareActorPtr &actor, std::ofstream &ofs) {
656 ofs << "\n\n[Data prepare actor:" << (actor != nullptr ? 1 : 0) << "]\n";
657 if (actor == nullptr) {
658 return;
659 }
660
661 ofs << "\tactor_name:" << actor->GetAID().Name() << "\tactor_id:" << actor->actor_id() << "\n";
662 DumpAbstractActor(actor.get(), ofs);
663
664 ofs << "\t\tcontinuous_memory_nodes:" << actor->continuous_memory_nodes().size() << "\n ";
665 for (const auto &iter : actor->continuous_memory_nodes()) {
666 MS_EXCEPTION_IF_NULL(iter.first.first);
667 MS_EXCEPTION_IF_NULL(iter.first.second);
668 ofs << "\t\t\tnode_name:" << iter.first.first->fullname_with_scope()
669 << "\tdevice_context:" << iter.first.second->device_context_key().ToString()
670 << "\tis_input_need:" << iter.second.first << "\tis_output_need:" << iter.second.second << "\n";
671 }
672 }
673
DumpLoopCountActor(const LoopCountActorPtr & actor,std::ofstream & ofs)674 void DumpLoopCountActor(const LoopCountActorPtr &actor, std::ofstream &ofs) {
675 ofs << "\n\n[Loop count actor:" << (actor != nullptr ? 1 : 0) << "]\n";
676 if (actor == nullptr) {
677 return;
678 }
679
680 ofs << "\tactor_name:" << actor->GetAID().Name() << "\tactor_id:" << actor->actor_id()
681 << "\tloop_count:" << actor->loop_count() << "\n";
682 DumpAbstractActor(actor.get(), ofs);
683
684 ofs << "\t\t\tto_data_prepare_actor:" << actor->data_prepare_aid().Name() << "\n";
685 for (auto &entrance_aid : actor->entrance_aids()) {
686 ofs << "\t\t\tto_entrance_actor:" << entrance_aid.Name() << "\n";
687 }
688 }
689
DumpOutputActor(const OutputActorPtr & actor,std::ofstream & ofs)690 void DumpOutputActor(const OutputActorPtr &actor, std::ofstream &ofs) {
691 ofs << "\n\n[Output actor:" << (actor != nullptr ? 1 : 0) << "]\n";
692 if (actor == nullptr) {
693 return;
694 }
695
696 ofs << "\tactor_name:" << actor->GetAID().Name() << "\tactor_id:" << actor->actor_id()
697 << "\tloop_count:" << actor->loop_count() << "\toutputs_num:" << actor->outputs_num() << "\n";
698
699 DumpAbstractActor(actor.get(), ofs);
700 }
701
DumpDSActors(const std::vector<DataSourceActorPtr> & actors,std::ofstream & ofs)702 void DumpDSActors(const std::vector<DataSourceActorPtr> &actors, std::ofstream &ofs) {
703 ofs << "\n\n[Data source actors:" << actors.size() << "]\n";
704 for (const auto &data_source_actor : actors) {
705 DumpDSActor(data_source_actor.get(), ofs);
706 }
707 }
708
DumpKernelActors(const std::vector<KernelActorPtr> & actors,std::ofstream & ofs)709 void DumpKernelActors(const std::vector<KernelActorPtr> &actors, std::ofstream &ofs) {
710 ofs << "\n\n[Kernel actors:" << actors.size() << "]\n";
711 for (const auto &kernel_actor : actors) {
712 DumpKernelActor(kernel_actor.get(), ofs);
713 }
714 }
715
DumpKernelInferActors(const std::vector<KernelInferActorPtr> & actors,std::ofstream & ofs)716 void DumpKernelInferActors(const std::vector<KernelInferActorPtr> &actors, std::ofstream &ofs) {
717 ofs << "\n\n[Kernel infer actors:" << actors.size() << "]\n";
718 for (const auto &kernel_infer_actor : actors) {
719 DumpKernelActor(kernel_infer_actor.get(), ofs);
720 }
721 }
722
DumpKernelResizeActors(const std::vector<KernelResizeActorPtr> & actors,std::ofstream & ofs)723 void DumpKernelResizeActors(const std::vector<KernelResizeActorPtr> &actors, std::ofstream &ofs) {
724 ofs << "\n\n[Kernel resize actors:" << actors.size() << "]\n";
725 for (const auto &kernel_resize_actor : actors) {
726 DumpKernelActor(kernel_resize_actor.get(), ofs);
727 }
728 }
729
DumpCustomActors(const std::vector<CustomActorPtr> & actors,std::ofstream & ofs)730 void DumpCustomActors(const std::vector<CustomActorPtr> &actors, std::ofstream &ofs) {
731 ofs << "\n\n[Custom actors:" << actors.size() << "]\n";
732 for (const auto &custom_actor : actors) {
733 DumpCustomActor(custom_actor.get(), ofs);
734 }
735 }
736
DumpSwapActors(const std::vector<std::vector<MemSwapActorPtr>> & actors,std::ofstream & ofs)737 void DumpSwapActors(const std::vector<std::vector<MemSwapActorPtr>> &actors, std::ofstream &ofs) {
738 size_t swap_actor_num = 0;
739 (void)std::for_each(actors.cbegin(), actors.cend(),
740 [&swap_actor_num](const std::vector<MemSwapActorPtr> &actor) { swap_actor_num += actor.size(); });
741 ofs << "\n\n[Swap actors:" << swap_actor_num << "]\n";
742 for (const auto &as : actors) {
743 for (const auto &swap_actor : as) {
744 if (swap_actor == nullptr) {
745 continue;
746 }
747 DumpSwapActor(swap_actor.get(), ofs);
748 }
749 }
750 }
751
DumpSuperKernelActors(const std::vector<SuperKernelActorPtr> & actors,std::ofstream & ofs)752 void DumpSuperKernelActors(const std::vector<SuperKernelActorPtr> &actors, std::ofstream &ofs) {
753 ofs << "\n\n[Super kernel actors:" << actors.size() << "]\n";
754 for (const auto &super_kernel_actor : actors) {
755 DumpSuperKernelActor(super_kernel_actor.get(), ofs);
756 }
757 }
758
DumpAnyTypeKernelActors(const std::vector<AnyTypeKernelActorPtr> & actors,std::ofstream & ofs)759 void DumpAnyTypeKernelActors(const std::vector<AnyTypeKernelActorPtr> &actors, std::ofstream &ofs) {
760 ofs << "\n\n[Any Type kernel actors:" << actors.size() << "]\n";
761 for (const auto &actor : actors) {
762 DumpAnyTypeKernelActor(actor.get(), ofs);
763 }
764 }
765
DumpNoInputKernelActors(const std::vector<AbstractActorPtr> & actors,std::ofstream & ofs)766 void DumpNoInputKernelActors(const std::vector<AbstractActorPtr> &actors, std::ofstream &ofs) {
767 ofs << "\n\n[No input kernel actors:" << actors.size() << "]\n";
768 for (const auto &actor : actors) {
769 MS_EXCEPTION_IF_NULL(actor);
770 if (actor->type() == KernelTransformType::kKernelActor) {
771 auto kernel_actor = dynamic_cast<const KernelActor *>(actor.get());
772 MS_EXCEPTION_IF_NULL(kernel_actor);
773 DumpKernelActor(kernel_actor, ofs);
774 } else if (actor->type() == KernelTransformType::kSuperKernelActor) {
775 auto super_kernel_actor = dynamic_cast<const SuperKernelActor *>(actor.get());
776 MS_EXCEPTION_IF_NULL(super_kernel_actor);
777 DumpSuperKernelActor(super_kernel_actor, ofs);
778 } else if (actor->type() == KernelTransformType::kCustomActor) {
779 auto custom_actor = dynamic_cast<const CustomActor *>(actor.get());
780 MS_EXCEPTION_IF_NULL(custom_actor);
781 DumpCustomActor(custom_actor, ofs);
782 }
783 }
784 }
785
DumpMemoryActors(const std::vector<MemoryAwareActorPtr> & actors,std::ofstream & ofs)786 void DumpMemoryActors(const std::vector<MemoryAwareActorPtr> &actors, std::ofstream &ofs) {
787 ofs << "\n\n[Memory actors:" << actors.size() << "]\n";
788 for (const auto &memory_actor : actors) {
789 DumpMemoryActor(memory_actor.get(), ofs);
790 }
791 }
792
DumpCopyActors(const std::vector<CopyActorPtr> & actors,std::ofstream & ofs)793 void DumpCopyActors(const std::vector<CopyActorPtr> &actors, std::ofstream &ofs) {
794 ofs << "\n\n[Copy actors:" << actors.size() << "]\n";
795 for (const auto ©_actor : actors) {
796 DumpCopyActor(copy_actor.get(), ofs);
797 }
798 }
799
DumpFusionActors(const std::vector<FusionActorPtr> & actors,std::ofstream & ofs)800 void DumpFusionActors(const std::vector<FusionActorPtr> &actors, std::ofstream &ofs) {
801 ofs << "\n\n[Fusion actors:" << actors.size() << "]\n";
802 for (const auto &fusion_actor : actors) {
803 DumpFusionActor(fusion_actor.get(), ofs);
804 }
805 }
806
DumpControlActors(const ControlActorSetPtr & control_actor_set,std::ofstream & ofs)807 void DumpControlActors(const ControlActorSetPtr &control_actor_set, std::ofstream &ofs) {
808 if (control_actor_set == nullptr) {
809 return;
810 }
811
812 ofs << "\n\n[Control actors]\n";
813 DumpEntranceActors(control_actor_set->entrance_actors_, ofs);
814 DumpSwitchActors(control_actor_set->switch_actors_, ofs);
815 DumpGatherActors(control_actor_set->gather_actors_, ofs);
816 DumpStackActors(control_actor_set->stack_actors_, ofs);
817 DumpExitActors(control_actor_set->exit_actors_, ofs);
818 }
819
820 namespace {
GetActorSubName(AbstractActor * actor)821 std::string GetActorSubName(AbstractActor *actor) {
822 MS_EXCEPTION_IF_NULL(actor);
823 if (actor->type() == KernelTransformType::kCopyActor) {
824 return std::string("CopyActor");
825 } else if (actor->type() == KernelTransformType::kEntranceActor) {
826 return std::string("EntranceActor");
827 }
828 const auto &name = actor->GetAID().Name();
829 std::string kernel_graph_name;
830 if (actor->type() == KernelTransformType::kKernelActor) {
831 const auto &kernel_actor = dynamic_cast<KernelActor *>(actor);
832 if (kernel_actor != nullptr && kernel_actor->kernel() != nullptr &&
833 kernel_actor->kernel()->func_graph() != nullptr) {
834 kernel_graph_name = kernel_actor->kernel()->func_graph()->ToString() + ":";
835 }
836 }
837 if (name.find("/") == std::string::npos) {
838 return kernel_graph_name + name;
839 }
840 const auto &pos = name.find_last_of("/");
841 return kernel_graph_name + name.substr(pos + 1);
842 }
843 using ActorInputMap = std::map<size_t, std::tuple<std::string, BaseShapePtr, TypePtr>>;
AddInputActorInfo(ActorInputMap * actor_inputs,AbstractActor * input_actor,const AbstractActor * const actor,const ActorInfoMap & actor_info,size_t from_index,size_t to_index)844 void AddInputActorInfo(ActorInputMap *actor_inputs, AbstractActor *input_actor, const AbstractActor *const actor,
845 const ActorInfoMap &actor_info, size_t from_index, size_t to_index) {
846 MS_EXCEPTION_IF_NULL(actor_inputs);
847 MS_EXCEPTION_IF_NULL(actor);
848 if (actor_inputs->find(to_index) != actor_inputs->end()) {
849 MS_LOG(INFO) << "Invalid index:" << to_index << " for actor:" << actor->GetAID()
850 << " input aid:" << input_actor->GetAID() << " same to:" << std::get<0>((*actor_inputs)[to_index]);
851 return;
852 }
853 const auto &input_iter = actor_info.find(input_actor);
854 if (input_iter != actor_info.end()) {
855 const auto &input_name =
856 "%" + std::to_string(std::get<0>(input_iter->second)) + "[" + std::to_string(from_index) + "]";
857 const auto &input_shapes = std::get<1>(input_iter->second);
858 const auto &input_types = std::get<2>(input_iter->second);
859 auto shape =
860 ((from_index < input_shapes.size() && input_shapes[from_index] != nullptr) ? input_shapes[from_index] : nullptr);
861 auto type =
862 ((from_index < input_types.size() && input_types[from_index] != nullptr) ? input_types[from_index] : nullptr);
863 (*actor_inputs)[to_index] = {input_name, shape, type};
864 } else {
865 (*actor_inputs)[to_index] = {input_actor->GetAID().Name() + "[" + std::to_string(from_index) + "]", nullptr,
866 nullptr};
867 }
868 }
869
GetFromIndexInHostQueueDataSourceActor(AbstractActor * input_actor,const DataArrow * const data_arrow)870 size_t GetFromIndexInHostQueueDataSourceActor(AbstractActor *input_actor, const DataArrow *const data_arrow) {
871 MS_EXCEPTION_IF_NULL(input_actor);
872 MS_EXCEPTION_IF_NULL(data_arrow);
873 const auto &host_ds_actor = dynamic_cast<HostQueueDataSourceActor *>(input_actor);
874 MS_EXCEPTION_IF_NULL(host_ds_actor);
875 const auto &iter =
876 std::find_if(host_ds_actor->output_data_arrows().begin(), host_ds_actor->output_data_arrows().end(),
877 [data_arrow](const auto &arrow) { return arrow.get() == data_arrow; });
878 if (iter == host_ds_actor->output_data_arrows().end()) {
879 MS_LOG(INFO) << "Failed to find output data arrow from index" << data_arrow->from_output_index_
880 << " to aid:" << data_arrow->to_op_id_ << " to index:" << data_arrow->to_op_id_
881 << " in host data source actor:" << input_actor->GetAID();
882 return IntToSize(data_arrow->from_output_index_);
883 }
884 size_t node_index = LongToSize(iter - host_ds_actor->output_data_arrows().begin());
885 if (node_index >= host_ds_actor->output_data_nodes().size()) {
886 MS_LOG(INFO) << "Invalid node index:" << node_index << " total:" << host_ds_actor->output_data_nodes().size()
887 << " for actor:" << input_actor->GetAID();
888 return IntToSize(data_arrow->from_output_index_);
889 }
890 return host_ds_actor->FetchNodePosition(
891 {host_ds_actor->output_data_nodes()[node_index], IntToSize(data_arrow->from_output_index_)});
892 }
893
GetFromIndexInSuperKernelActor(AbstractActor * input_actor,const AbstractActor * const actor,const DataArrow * const data_arrow)894 size_t GetFromIndexInSuperKernelActor(AbstractActor *input_actor, const AbstractActor *const actor,
895 const DataArrow *const data_arrow) {
896 MS_EXCEPTION_IF_NULL(input_actor);
897 MS_EXCEPTION_IF_NULL(data_arrow);
898 if (input_actor->output_data_arrows().size() != input_actor->output_data_nodes().size()) {
899 MS_LOG(INFO) << "For actor:" << input_actor->GetAID()
900 << " output arrow size:" << input_actor->output_data_arrows().size()
901 << " not equal to node size:" << input_actor->output_data_nodes().size();
902 return IntToSize(data_arrow->from_output_index_);
903 }
904 const auto &super_kernel_actor = dynamic_cast<SuperKernelActor *>(input_actor);
905 MS_EXCEPTION_IF_NULL(super_kernel_actor);
906 const auto &graph = super_kernel_actor->graph();
907 if (graph == nullptr) {
908 MS_LOG(INFO) << "Failed to get graph in actor:" << input_actor->GetAID();
909 return IntToSize(data_arrow->from_output_index_);
910 }
911 const auto &output_pairs = common::AnfAlgo::GetAllOutputWithIndex(graph->output());
912 const auto &data_iter =
913 std::find_if(input_actor->output_data_arrows().begin(), input_actor->output_data_arrows().end(),
914 [data_arrow](const auto &arrow) { return arrow.get() == data_arrow; });
915 if (data_iter == input_actor->output_data_arrows().end()) {
916 MS_LOG(INFO) << "Failed to find output data arrow from index" << data_arrow->from_output_index_
917 << " to aid:" << data_arrow->to_op_id_ << " to index:" << data_arrow->to_op_id_
918 << " in host data source actor:" << input_actor->GetAID();
919 return IntToSize(data_arrow->from_output_index_);
920 }
921 size_t node_index = LongToSize(data_iter - input_actor->output_data_arrows().begin());
922 if (node_index >= input_actor->output_data_nodes().size() ||
923 input_actor->output_data_nodes()[node_index] == nullptr) {
924 MS_LOG(INFO) << "Invalid node index:" << node_index << " total:" << input_actor->output_data_nodes().size()
925 << " for actor:" << input_actor->GetAID() << " graph:" << graph->ToString();
926 return IntToSize(data_arrow->from_output_index_);
927 }
928 const auto &output_iter =
929 std::find(output_pairs.begin(), output_pairs.end(),
930 std::make_pair(input_actor->output_data_nodes()[node_index], IntToSize(data_arrow->from_output_index_)));
931 if (output_iter == output_pairs.end()) {
932 MS_LOG(INFO) << "Failed to find output node:" << input_actor->output_data_nodes()[node_index]->fullname_with_scope()
933 << " in graph:" << graph->ToString() << " for actor:" << actor->GetAID();
934 return IntToSize(data_arrow->from_output_index_);
935 }
936 return output_iter - output_pairs.begin();
937 }
938
FetchInputActor(std::string input_aid,ActorInputMap * actor_inputs,const AbstractActor * const actor,const ActorInfoMap & actor_info,const DataArrow * const data_arrow)939 void FetchInputActor(std::string input_aid, ActorInputMap *actor_inputs, const AbstractActor *const actor,
940 const ActorInfoMap &actor_info, const DataArrow *const data_arrow) {
941 MS_EXCEPTION_IF_NULL(data_arrow);
942 size_t to_index = IntToSize(data_arrow->to_input_index_);
943 size_t from_index = IntToSize(data_arrow->from_output_index_);
944 auto input_actor = FetchActor(input_aid);
945 if (input_actor == nullptr) {
946 MS_LOG(INFO) << "Failed to fetch input actor:" << input_aid;
947 return;
948 }
949 if (input_actor->type() == KernelTransformType::kHostDataSourceActor) {
950 from_index = GetFromIndexInHostQueueDataSourceActor(input_actor, data_arrow);
951 } else if (input_actor->type() == KernelTransformType::kSuperKernelActor) {
952 from_index = GetFromIndexInSuperKernelActor(input_actor, actor, data_arrow);
953 } else if (actor->type() != KernelTransformType::kFusionActor &&
954 data_arrow->to_op_id_.Name().find(kFusionActorNameSuffix) != std::string::npos) {
955 const auto &fusion_aid = data_arrow->to_op_id_.Name();
956 const auto &from_actor = FetchActor(fusion_aid);
957 if (from_actor == nullptr) {
958 MS_LOG(INFO) << "Failed to fetch actor:" << fusion_aid;
959 return;
960 }
961 input_actor = from_actor;
962 from_index = to_index;
963 const auto &fusion_actor = dynamic_cast<FusionActor *>(from_actor);
964 MS_EXCEPTION_IF_NULL(fusion_actor);
965 const auto &real_input_data = fusion_actor->real_input_data();
966 if (to_index >= real_input_data.size()) {
967 MS_LOG(INFO) << "Failed to find to index in fusion actor:" << input_aid << " for actor:" << actor->GetAID()
968 << " to index:" << to_index;
969 return;
970 }
971 to_index = real_input_data[to_index].second;
972 }
973 AddInputActorInfo(actor_inputs, input_actor, actor, actor_info, from_index, to_index);
974 }
975
FetchInputDeviceTensorStore(const AnfNodePtr & key,size_t index,const AbstractActor * const actor,ActorInputMap * actor_inputs)976 void FetchInputDeviceTensorStore(const AnfNodePtr &key, size_t index, const AbstractActor *const actor,
977 ActorInputMap *actor_inputs) {
978 MS_EXCEPTION_IF_NULL(key);
979 MS_EXCEPTION_IF_NULL(actor_inputs);
980 std::string input_name = "%";
981 if (key->isa<Parameter>()) {
982 input_name += key->DebugString(0);
983 } else if (key->isa<ValueNode>()) {
984 const auto &value_node = key->cast<ValueNodePtr>();
985 MS_EXCEPTION_IF_NULL(value_node);
986 if (value_node->value() == nullptr) {
987 input_name += value_node->DebugString();
988 } else {
989 if (value_node->value()->isa<Scalar>()) {
990 input_name = value_node->value()->DumpText();
991 } else {
992 input_name = value_node->value()->ToString();
993 }
994 }
995 } else {
996 input_name += key->DebugString();
997 }
998 if (actor_inputs->find(index) != actor_inputs->end()) {
999 MS_LOG(INFO) << "Invalid index:" << index << " for actor:" << actor->GetAID() << " input aid:" << key->DebugString()
1000 << " same to:" << std::get<0>((*actor_inputs)[index]);
1001 return;
1002 }
1003 (*actor_inputs)[index] = {input_name, key->Shape() == nullptr ? nullptr : key->Shape(),
1004 key->Type() == nullptr ? nullptr : key->Type()};
1005 }
1006
FetchInputForHostQueueDSActor(AbstractActor * actor,ActorInputMap * actor_inputs)1007 void FetchInputForHostQueueDSActor(AbstractActor *actor, ActorInputMap *actor_inputs) {
1008 MS_EXCEPTION_IF_NULL(actor);
1009 MS_EXCEPTION_IF_NULL(actor_inputs);
1010 const auto &ds_actor = dynamic_cast<HostQueueDataSourceActor *>(actor);
1011 MS_EXCEPTION_IF_NULL(ds_actor);
1012 for (size_t i = 0; i < ds_actor->data_nodes().size(); ++i) {
1013 const auto &node_pair = ds_actor->data_nodes()[i];
1014 if (node_pair.first == nullptr) {
1015 (*actor_inputs)[i] = {"null", nullptr, nullptr};
1016 continue;
1017 }
1018 auto device_address = AnfAlgo::GetMutableOutputAddr(node_pair.first, node_pair.second, false);
1019 if (device_address == nullptr || device_address->kernel_tensor() == nullptr) {
1020 (*actor_inputs)[i] = {"null", nullptr, nullptr};
1021 continue;
1022 }
1023 const auto &kernel_tensor = device_address->kernel_tensor();
1024 (*actor_inputs)[i] = {node_pair.first->DebugString(0),
1025 kernel_tensor->GetShape() == nullptr ? nullptr : kernel_tensor->GetShape(),
1026 kernel_tensor->GetType() == nullptr ? nullptr : kernel_tensor->GetType()};
1027 }
1028 }
1029
FetchInputData(AbstractActor * actor,ActorInputMap * actor_inputs,ActorInfoMap * actor_info)1030 void FetchInputData(AbstractActor *actor, ActorInputMap *actor_inputs, ActorInfoMap *actor_info) {
1031 MS_EXCEPTION_IF_NULL(actor);
1032 MS_EXCEPTION_IF_NULL(actor_info);
1033 MS_EXCEPTION_IF_NULL(actor_inputs);
1034 for (const auto &pair : actor->input_data_arrow_aids()) {
1035 if (pair.second == nullptr) {
1036 MS_LOG(INFO) << "Invalid input data arrow for actor:" << actor->GetAID() << " input actor:" << pair.first;
1037 continue;
1038 }
1039 FetchInputActor(pair.first.Name(), actor_inputs, actor, *actor_info, pair.second);
1040 }
1041
1042 for (const auto &pair : actor->device_tensor_store_keys()) {
1043 MS_EXCEPTION_IF_NULL(pair.second);
1044 FetchInputDeviceTensorStore(pair.second, pair.first, actor, actor_inputs);
1045 }
1046
1047 if (actor->type() == KernelTransformType::kHostDataSourceActor) {
1048 FetchInputForHostQueueDSActor(actor, actor_inputs);
1049 }
1050 }
1051
FetchOutputInfo(AbstractActor * actor,std::vector<BaseShapePtr> * output_shapes,std::vector<TypePtr> * output_types,const ActorInputMap & actor_inputs)1052 void FetchOutputInfo(AbstractActor *actor, std::vector<BaseShapePtr> *output_shapes, std::vector<TypePtr> *output_types,
1053 const ActorInputMap &actor_inputs) {
1054 MS_EXCEPTION_IF_NULL(actor);
1055 MS_EXCEPTION_IF_NULL(output_shapes);
1056 MS_EXCEPTION_IF_NULL(output_types);
1057 if (actor->type() == KernelTransformType::kKernelActor) {
1058 const auto &kernel_actor = dynamic_cast<KernelActor *>(actor);
1059 if (kernel_actor != nullptr && kernel_actor->kernel() != nullptr &&
1060 kernel_actor->kernel()->kernel_info() != nullptr) {
1061 const auto &kernel_info = dynamic_cast<KernelInfo *>(kernel_actor->kernel()->kernel_info());
1062 MS_EXCEPTION_IF_NULL(kernel_info);
1063 const auto &device_addresses = kernel_info->output_address_list();
1064 for (const auto &device_address : device_addresses) {
1065 if (device_address != nullptr && device_address->kernel_tensor() != nullptr) {
1066 output_shapes->emplace_back(device_address->kernel_tensor()->GetShape());
1067 output_types->emplace_back(device_address->kernel_tensor()->GetType());
1068 }
1069 }
1070 }
1071 } else if (actor->type() == KernelTransformType::kSuperKernelActor) {
1072 if (actor->output_data_arrows().size() != actor->output_data_nodes().size()) {
1073 MS_LOG(INFO) << "For actor:" << actor->GetAID() << " output arrow size:" << actor->output_data_arrows().size()
1074 << " not equal to node size:" << actor->output_data_nodes().size();
1075 return;
1076 }
1077 const auto &super_kernel_actor = dynamic_cast<SuperKernelActor *>(actor);
1078 MS_EXCEPTION_IF_NULL(super_kernel_actor);
1079 const auto &graph = super_kernel_actor->graph();
1080 if (graph == nullptr) {
1081 MS_LOG(INFO) << "Failed to get graph in actor:" << actor->GetAID();
1082 return;
1083 }
1084 const auto &output_pairs = common::AnfAlgo::GetAllOutputWithIndex(graph->output());
1085 for (size_t i = 0; i < output_pairs.size(); ++i) {
1086 const auto &output_pair = output_pairs[i];
1087 MS_EXCEPTION_IF_NULL(output_pair.first);
1088 const auto &node_index = common::AnfAlgo::VisitKernelWithReturnType(output_pair.first, output_pair.second, false);
1089 MS_EXCEPTION_IF_NULL(node_index.first);
1090 device::DeviceAddressPtr device_address = nullptr;
1091 if (AnfAlgo::OutputAddrExist(node_index.first, node_index.second, false)) {
1092 device_address = AnfAlgo::GetMutableOutputAddr(node_index.first, node_index.second, false);
1093 }
1094 if (device_address == nullptr || device_address->kernel_tensor() == nullptr) {
1095 MS_LOG(INFO) << "For actor:" << actor->GetAID() << " output node:" << node_index.first->fullname_with_scope()
1096 << " has invalid device address:" << device_address;
1097 output_shapes->emplace_back(nullptr);
1098 output_types->emplace_back(nullptr);
1099 continue;
1100 }
1101 output_shapes->emplace_back(device_address->kernel_tensor()->GetShape());
1102 output_types->emplace_back(device_address->kernel_tensor()->GetType());
1103 }
1104 } else {
1105 for_each(actor_inputs.begin(), actor_inputs.end(), [output_shapes, output_types](const auto &pair) {
1106 output_shapes->emplace_back(std::get<1>(pair.second));
1107 output_types->emplace_back(std::get<2>(pair.second));
1108 });
1109 }
1110 }
1111
DumpActorInfo(AbstractActor * actor,std::ofstream & ofs)1112 void DumpActorInfo(AbstractActor *actor, std::ofstream &ofs) {
1113 MS_EXCEPTION_IF_NULL(actor);
1114 if (actor->type() == KernelTransformType::kKernelActor || actor->type() == KernelTransformType::kSuperKernelActor ||
1115 actor->type() == KernelTransformType::kOutputActor) {
1116 ofs << "\t# device context: ";
1117 std::for_each(actor->device_contexts().begin(), actor->device_contexts().end(), [&ofs](const auto &device_context) {
1118 ofs << (device_context == nullptr ? "null" : device_context->device_context_key().ToString()) << " ";
1119 });
1120 ofs << "\n";
1121 } else if (actor->type() == KernelTransformType::kCopyActor) {
1122 if (actor->device_contexts().size() >= 2 && actor->device_contexts()[0] != nullptr &&
1123 actor->device_contexts()[1] != nullptr) {
1124 ofs << "\t# device context: " << actor->device_contexts()[0]->device_context_key().ToString() << " -> "
1125 << actor->device_contexts()[1]->device_context_key().ToString() << "\n";
1126 }
1127 }
1128 }
1129
IsTopActorType(AbstractActor * actor)1130 bool IsTopActorType(AbstractActor *actor) {
1131 return actor->type() != KernelTransformType::kStackActor && actor->type() != KernelTransformType::kEntranceActor;
1132 }
1133 } // namespace
1134
TopoSortForActor(AbstractActor * root)1135 std::vector<AbstractActor *> TopoSortForActor(AbstractActor *root) {
1136 std::vector<AbstractActor *> actors;
1137 auto seen = NewSeenGeneration();
1138 std::deque<AbstractActor *> todo;
1139 (void)todo.emplace_back(root);
1140
1141 mindspore::HashMap<AbstractActor *, SeenNum> seen_map;
1142 mindspore::HashMap<AbstractActor *, SeenNum> extra_seen_map;
1143 seen_map[root] = 0;
1144 extra_seen_map[root] = 0;
1145 while (!todo.empty()) {
1146 AbstractActor *actor = todo.back();
1147
1148 if (extra_seen_map[actor] == seen) {
1149 todo.pop_back();
1150 continue;
1151 }
1152 if (seen_map[actor] == seen) {
1153 extra_seen_map[actor] = seen;
1154 (void)actors.emplace_back(actor);
1155 todo.pop_back();
1156 continue;
1157 }
1158 seen_map[actor] = seen;
1159 std::vector<std::string> input_aids;
1160
1161 if (IsTopActorType(actor)) {
1162 std::for_each(
1163 actor->input_data_arrow_aids().begin(), actor->input_data_arrow_aids().end(),
1164 [&input_aids, actor](const auto &pair) {
1165 input_aids.emplace_back((actor->type() != KernelTransformType::kFusionActor && pair.second != nullptr &&
1166 pair.second->to_op_id_.Name().find(kFusionActorNameSuffix) != std::string::npos)
1167 ? pair.second->to_op_id_.Name()
1168 : pair.first.Name());
1169 });
1170 std::for_each(
1171 actor->input_control_arrow_aids().begin(), actor->input_control_arrow_aids().end(),
1172 [&input_aids, actor](const auto &pair) {
1173 input_aids.emplace_back((actor->type() != KernelTransformType::kFusionActor && pair.second != nullptr &&
1174 pair.second->to_op_id_.Name().find(kFusionActorNameSuffix) != std::string::npos)
1175 ? pair.second->to_op_id_.Name()
1176 : pair.first.Name());
1177 });
1178 }
1179 for (auto aid : input_aids) {
1180 const auto &input_actor = FetchActor(aid);
1181 if (input_actor == nullptr) {
1182 MS_LOG(INFO) << "Failed to get actor:" << aid;
1183 continue;
1184 }
1185 if (seen_map.find(input_actor) == seen_map.end()) {
1186 seen_map[input_actor] = 0;
1187 }
1188 if (extra_seen_map.find(input_actor) == extra_seen_map.end()) {
1189 extra_seen_map[input_actor] = 0;
1190 }
1191 if (extra_seen_map[input_actor] == seen) {
1192 continue;
1193 }
1194 if (seen_map[input_actor] != seen) {
1195 (void)todo.emplace_back(input_actor);
1196 continue;
1197 }
1198 // Loop count has a cycle input and skip it.
1199 if (input_actor != root && input_actor->type() != KernelTransformType::kLoopCountActor) {
1200 MS_LOG(EXCEPTION) << "Actor cycle exists in actor:" << input_actor->GetAID();
1201 }
1202 }
1203 }
1204 return actors;
1205 }
1206
DumpActorInfo(AbstractActor * actor,size_t index,ActorInfoMap * actor_info,std::ofstream & ofs)1207 void DumpActorInfo(AbstractActor *actor, size_t index, ActorInfoMap *actor_info, std::ofstream &ofs) {
1208 MS_EXCEPTION_IF_NULL(actor);
1209 MS_EXCEPTION_IF_NULL(actor_info);
1210 ActorInputMap actor_inputs;
1211 FetchInputData(actor, &actor_inputs, actor_info);
1212
1213 std::vector<BaseShapePtr> output_shapes;
1214 std::vector<TypePtr> output_types;
1215 FetchOutputInfo(actor, &output_shapes, &output_types, actor_inputs);
1216 (*actor_info)[actor] = {index, output_shapes, output_types};
1217
1218 // Dump input data.
1219 ofs << "%" << index << " = " << GetActorSubName(actor) << "(";
1220 for (const auto &pair : actor_inputs) {
1221 ofs << std::get<0>(pair.second);
1222 if (pair.first < actor_inputs.size() - 1) {
1223 ofs << ", ";
1224 }
1225 }
1226
1227 // Dump input control.
1228 if (!actor->input_control_arrow_aids().empty()) {
1229 ofs << ") op control(";
1230 for (const auto &pair : actor->input_control_arrow_aids()) {
1231 auto aid = pair.first.Name();
1232 if (actor->type() != KernelTransformType::kFusionActor && pair.second != nullptr &&
1233 pair.second->to_op_id_.Name().find(kFusionActorNameSuffix) != std::string::npos) {
1234 aid = pair.second->to_op_id_.Name();
1235 }
1236 const auto &input_actor = FetchActor(aid);
1237 ofs << "%";
1238 if ((*actor_info).find(input_actor) != (*actor_info).end()) {
1239 ofs << std::get<0>((*actor_info)[input_actor]);
1240 } else {
1241 ofs << aid;
1242 }
1243 if (pair != actor->input_control_arrow_aids().back()) {
1244 ofs << ", ";
1245 }
1246 }
1247 }
1248 ofs << ")\n";
1249
1250 if (actor->type() == KernelTransformType::kDataPrepareActor) {
1251 return;
1252 }
1253 // Dump device context;
1254 DumpActorInfo(actor, ofs);
1255
1256 // Dump output info.
1257 std::string shape = "\t# shape : ";
1258 std::string type = "\t# type : ";
1259 for (const auto &pair : actor_inputs) {
1260 shape = shape + "<" + (std::get<1>(pair.second) == nullptr ? "null" : std::get<1>(pair.second)->ToString()) + "> ";
1261 type = type + "<" + (std::get<2>(pair.second) == nullptr ? "null" : std::get<2>(pair.second)->ToString()) + "> ";
1262 }
1263 shape += "-> ";
1264 type += "-> ";
1265 for_each(output_shapes.begin(), output_shapes.end(), [&shape](const auto &shape_ptr) {
1266 shape = shape + "<" + (shape_ptr == nullptr ? "null" : shape_ptr->ToString()) + "> ";
1267 });
1268 for_each(output_types.begin(), output_types.end(), [&type](const auto &type_ptr) {
1269 type = type + "<" + (type_ptr == nullptr ? "null" : type_ptr->ToString()) + "> ";
1270 });
1271 ofs << shape << "\n" << type << "\n";
1272 }
1273 } // namespace runtime
1274 } // namespace mindspore
1275