Imported Upstream version 1.25.0
[platform/core/ml/nnfw.git] / runtime / onert / core / src / ir / OperationDumper.cc
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
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 "OperationDumper.h"
18
19 #include <string>
20
21 #include "util/logging.h"
22
23 namespace onert
24 {
25 namespace ir
26 {
27
28 using namespace operation;
29
30 namespace
31 {
32
33 // Dump all input and output.
34 // Use this function when there is no special input or(and) output.
35 void dumpOpGeneric(const Operation &node, const std::string &adding_input = "")
36 {
37   VERBOSE(LIR) << "* " << node.name() << std::endl;
38   VERBOSE(LIR) << "  - Inputs : Input(" << node.getInputs() << ") " << adding_input << std::endl;
39   VERBOSE(LIR) << "  - Output : Output(" << node.getOutputs() << ")" << std::endl;
40 }
41
42 void dumpUnaryInputOp(const Operation &node, const std::string &adding_input = "")
43 {
44   VERBOSE(LIR) << "* " << node.name() << std::endl;
45   VERBOSE(LIR) << "  - Inputs : Input(" << node.getInputs().at(0) << ") " << adding_input
46                << std::endl;
47   VERBOSE(LIR) << "  - Output : Output(" << node.getOutputs().at(0) << ")" << std::endl;
48 }
49
50 void dumpConvOp(const Operation &node, const std::string &padding_type)
51 {
52   VERBOSE(LIR) << "* " << node.name() << "(" << padding_type << ")" << std::endl;
53   VERBOSE(LIR) << "  - Inputs : IFM(" << node.getInputs().at(Conv2D::Input::INPUT) << ") Kernel("
54                << node.getInputs().at(Conv2D::Input::KERNEL) << ") Bias("
55                << node.getInputs().at(Conv2D::Input::BIAS) << ")" << std::endl;
56   VERBOSE(LIR) << "  - Output : OFM(" << node.getOutputs().at(0) << ")" << std::endl;
57 }
58 } // namespace
59
60 OperationDumper::OperationDumper(const std::string &start_msg)
61 {
62   VERBOSE(LIR) << start_msg << std::endl;
63 }
64
65 void OperationDumper::visit(const ArgMinMax &node)
66 {
67   std::string min_max = node.param().is_arg_max ? "(Max)" : "(Min)";
68   VERBOSE(LIR) << "* " << node.name() << min_max << std::endl;
69   VERBOSE(LIR) << "  - Inputs : Input(" << node.getInputs().at(ArgMinMax::INPUT) << ") Axis("
70                << node.getInputs().at(ArgMinMax::AXIS) << ") " << std::endl;
71   VERBOSE(LIR) << "  - Output : Output(" << node.getOutputs().at(0) << ")" << std::endl;
72 }
73
74 void OperationDumper::visit(const BatchToSpaceND &node)
75 {
76   std::string block_size =
77     "BlockSize(" + std::to_string(node.getInputs().at(BatchToSpaceND::Input::BLOCK_SIZE).value()) +
78     ")";
79   dumpOpGeneric(node, block_size);
80 }
81
82 void OperationDumper::visit(const BCQFullyConnected &node)
83 {
84   VERBOSE(LIR) << "* " << node.name() << std::endl;
85   VERBOSE(LIR) << "  - Inputs : IFM(" << node.getInputs().at(BCQFullyConnected::Input::INPUT)
86                << ") WeightsBinary("
87                << node.getInputs().at(BCQFullyConnected::Input::WEIGHTS_BINARY)
88                << ") WeightsScales("
89                << node.getInputs().at(BCQFullyConnected::Input::WEIGHTS_SCALES)
90                << ") WeightsClusters("
91                << node.getInputs().at(BCQFullyConnected::Input::WEIGHTS_CLUSTERS) << ") Bias("
92                << node.getInputs().at(BCQFullyConnected::Input::BIAS) << ")" << std::endl;
93   VERBOSE(LIR) << "  - Output : OFM(" << node.getOutputs().at(0) << ")" << std::endl;
94 }
95
96 void OperationDumper::visit(const BinaryArithmetic &node) { dumpOpGeneric(node); }
97
98 void OperationDumper::visit(const operation::BroadcastTo &node) { dumpOpGeneric(node); }
99
100 void OperationDumper::visit(const Comparison &node) { dumpOpGeneric(node); }
101
102 void OperationDumper::visit(const Concat &node) { dumpOpGeneric(node); }
103
104 void OperationDumper::visit(const Conv2D &node)
105 {
106   std::string padding_type =
107     node.param().padding.type == PaddingType::EXPLICIT ? "Explicit" : "Implicit";
108   dumpConvOp(node, padding_type);
109 }
110
111 void OperationDumper::visit(const ConvertFp16ToFp32 &node) { dumpOpGeneric(node); }
112
113 void OperationDumper::visit(const ConvertFp32ToFp16 &node) { dumpOpGeneric(node); }
114
115 void OperationDumper::visit(const DepthToSpace &node) { dumpOpGeneric(node); }
116
117 void OperationDumper::visit(const DepthwiseConv2D &node)
118 {
119   std::string padding_type =
120     node.param().padding.type == PaddingType::EXPLICIT ? "Explicit" : "Implicit";
121   dumpConvOp(node, padding_type);
122 }
123
124 void OperationDumper::visit(const ElementwiseActivation &node)
125 {
126   std::string params;
127   if (node.param().op_type == ElementwiseActivation::Type::RELU)
128   {
129     params = " lower value(" + std::to_string(node.param().alpha) + ") upper value(" +
130              std::to_string(node.param().beta) + ")";
131   }
132   else if (node.param().op_type == ElementwiseActivation::Type::LEAKY_RELU)
133   {
134     params = " alpha value(" + std::to_string(node.param().alpha) + ")";
135   }
136   dumpOpGeneric(node, params);
137 }
138
139 void OperationDumper::visit(const ElementwiseBinary &node) { dumpOpGeneric(node); }
140
141 void OperationDumper::visit(const ElementwiseUnary &node) { dumpOpGeneric(node); }
142
143 void OperationDumper::visit(const EmbeddingLookup &node)
144 {
145   VERBOSE(LIR) << "* " << node.name() << std::endl;
146   VERBOSE(LIR) << "  - Inputs : Lookups(" << node.getInputs().at(EmbeddingLookup::Input::LOOKUPS)
147                << ") VALUES(" << node.getInputs().at(EmbeddingLookup::Input::VALUES) << ")"
148                << std::endl;
149   VERBOSE(LIR) << "  - Output : Output(" << node.getOutputs().at(0) << ")" << std::endl;
150 }
151
152 void OperationDumper::visit(const ExpandDims &node)
153 {
154   std::string axis =
155     "AXIS(" + std::to_string(node.getInputs().at(ExpandDims::Input::AXIS).value()) + ")";
156   dumpUnaryInputOp(node, axis);
157 }
158
159 void OperationDumper::visit(const Fill &node)
160 {
161   VERBOSE(LIR) << "* " << node.name() << std::endl;
162   VERBOSE(LIR) << "  - Inputs : Shape(" << node.getInputs().at(Fill::Input::SHAPE) << ") Value("
163                << node.getInputs().at(Fill::Input::VALUE) << ")" << std::endl;
164   VERBOSE(LIR) << "  - Output : Output(" << node.getOutputs().at(0) << ")" << std::endl;
165 }
166
167 void OperationDumper::visit(const FullyConnected &node)
168 {
169   std::string inputs =
170     "Weight(" + std::to_string(node.getInputs().at(FullyConnected::Input::WEIGHT).value()) +
171     ") Bias(" + std::to_string(node.getInputs().at(FullyConnected::Input::BIAS).value()) + ")";
172   dumpUnaryInputOp(node, inputs);
173 }
174
175 void OperationDumper::visit(const Gather &node)
176 {
177   std::string indices =
178     "Indices(" + std::to_string(node.getInputs().at(Gather::Input::INDICES).value()) + ")";
179   dumpUnaryInputOp(node, indices);
180 }
181
182 void OperationDumper::visit(const HashtableLookup &node)
183 {
184   VERBOSE(LIR) << "* HashTableLookup" << std::endl;
185   VERBOSE(LIR) << "  - Inputs : Lookups(" << node.getInputs().at(HashtableLookup::Input::LOOKUPS)
186                << ") Keys(" << node.getInputs().at(HashtableLookup::Input::KEYS) << ") Values("
187                << node.getInputs().at(HashtableLookup::Input::VALUES) << ")" << std::endl;
188   VERBOSE(LIR) << "  - Outputs : Output(" << node.getInputs().at(HashtableLookup::Output::OUTPUT)
189                << ") Hits(" << node.getInputs().at(HashtableLookup::Output::HITS) << ")"
190                << std::endl;
191 }
192
193 void OperationDumper::visit(const InstanceNorm &node)
194 {
195   std::string inputs =
196     "Gamma(" + std::to_string(node.getInputs().at(InstanceNorm::Input::GAMMA).value()) + ") Beta(" +
197     std::to_string(node.getInputs().at(InstanceNorm::Input::BETA).value()) + ")";
198   dumpUnaryInputOp(node, inputs);
199 }
200
201 void OperationDumper::visit(const L2Normalization &node) { dumpOpGeneric(node); }
202
203 void OperationDumper::visit(const LocalResponseNormalization &node) { dumpOpGeneric(node); }
204
205 void OperationDumper::visit(const Loss &node)
206 {
207   VERBOSE(LIR) << "* " << node.name() << std::endl;
208   VERBOSE(LIR) << " - Inputs : Prediction(" << node.getInputs().at(Loss::Input::Y_PRED) << ") True("
209                << node.getInputs().at(Loss::Input::Y_TRUE) << ")" << std::endl;
210   VERBOSE(LIR) << " - Outputs : Output(" << node.getOutputs().at(0) << ")" << std::endl;
211 }
212
213 void OperationDumper::visit(const LSTM &node)
214 {
215   VERBOSE(LIR) << "* " << node.name() << std::endl;
216   VERBOSE(LIR)
217     << "  - Inputs : Input(" << node.getInputs().at(LSTM::Input::INPUT)
218     << ") Input To Input Weights(" << node.getInputs().at(LSTM::Input::INPUT_TO_INPUT_WEIGHTS)
219     << ") Input To Forget Weights(" << node.getInputs().at(LSTM::Input::INPUT_TO_FORGET_WEIGHTS)
220     << ") Input To Cell Weights(" << node.getInputs().at(LSTM::Input::INPUT_TO_CELL_WEIGHTS)
221     << ") Input To Output Weights(" << node.getInputs().at(LSTM::Input::INPUT_TO_OUTPUT_WEIGHTS)
222     << ") Recurrent To Input Weights("
223     << node.getInputs().at(LSTM::Input::RECURRENT_TO_INPUT_WEIGHTS)
224     << ") Recurrent To Forget Weights("
225     << node.getInputs().at(LSTM::Input::RECURRENT_TO_FORGET_WEIGHTS)
226     << ") Recurrent To Cell Weights(" << node.getInputs().at(LSTM::Input::RECURRENT_TO_CELL_WEIGHTS)
227     << ") Recurrent To Output Weights("
228     << node.getInputs().at(LSTM::Input::RECURRENT_TO_OUTPUT_WEIGHTS) << ") Cell To Input Weights("
229     << node.getInputs().at(LSTM::Input::CELL_TO_INPUT_WEIGHTS) << ") Cell To Forget Weights("
230     << node.getInputs().at(LSTM::Input::CELL_TO_FORGET_WEIGHTS) << ") Cell To OUTPUT Weights("
231     << node.getInputs().at(LSTM::Input::CELL_TO_OUTPUT_WEIGHTS) << ") Input Gate Bias("
232     << node.getInputs().at(LSTM::Input::INPUT_GATE_BIAS) << ") Forget Gate Bias("
233     << node.getInputs().at(LSTM::Input::FORGET_GATE_BIAS) << ") Cell Bias("
234     << node.getInputs().at(LSTM::Input::CELL_BIAS) << ") Output Gate Bias("
235     << node.getInputs().at(LSTM::Input::OUTPUT_GATE_BIAS) << ") Projection Weights("
236     << node.getInputs().at(LSTM::Input::PROJECTION_WEIGHTS) << ") Projection Bias("
237     << node.getInputs().at(LSTM::Input::PROJECTION_BIAS) << ") Output State In("
238     << node.getInputs().at(LSTM::Input::OUTPUT_STATE_IN) << ") Cell State In("
239     << node.getInputs().at(LSTM::Input::CELL_STATE_IN);
240   if (node.getInputs().size() == 24)
241   {
242     VERBOSE(LIR) << ") Input Layer Normalization Weights("
243                  << node.getInputs().at(LSTM::Input::INPUT_LAYER_NORMALIZATION_WEIGHTS)
244                  << ") Forget Layer Normalization Weights("
245                  << node.getInputs().at(LSTM::Input::FORGET_LAYER_NORMALIZATION_WEIGHTS)
246                  << ") Cell Layer Normalization Weights("
247                  << node.getInputs().at(LSTM::Input::CELL_LAYER_NORMALIZATION_WEIGHTS)
248                  << ") Ouput Layer Normalization Weights("
249                  << node.getInputs().at(LSTM::Input::OUTPUT_LAYER_NORMALIZATION_WEIGHTS);
250   }
251   VERBOSE(LIR) << ")" << std::endl;
252   VERBOSE(LIR) << "  - Output : Scratch Buffer("
253                << node.getOutputs().at(LSTM::Output::SCRATCH_BUFFER) << ") Output State Out("
254                << node.getOutputs().at(LSTM::Output::OUTPUT_STATE_OUT) << ") Cell State Out("
255                << node.getOutputs().at(LSTM::Output::CELL_STATE_OUT) << ") Output("
256                << node.getOutputs().at(LSTM::Output::OUTPUT) << ")" << std::endl;
257 }
258
259 void OperationDumper::visit(const Pack &node) { dumpOpGeneric(node); }
260
261 void OperationDumper::visit(const Pad &node)
262 {
263   std::string pad = "Pad(" + std::to_string(node.getInputs().at(Pad::Input::PAD).value()) + ")";
264   dumpUnaryInputOp(node, pad);
265 }
266
267 void OperationDumper::visit(const Permute &node)
268 {
269   std::string permute_type = "Unknown";
270   switch (node.getPermuteType())
271   {
272     case Permute::Type::COPY:
273       permute_type = "Copy";
274       break;
275     case Permute::Type::NHWC_TO_NCHW:
276       permute_type = "NHWC to NCHW";
277       break;
278     case Permute::Type::NCHW_TO_NHWC:
279       permute_type = "NCHW to NHWC";
280       break;
281   }
282
283   VERBOSE(LIR) << "* Permute(" + permute_type + ")" << std::endl;
284   VERBOSE(LIR) << "  - Inputs : Input(" << node.getInputs().at(0) << ")" << std::endl;
285   VERBOSE(LIR) << "  - Output : Output(" << node.getOutputs().at(0) << ")" << std::endl;
286 }
287
288 void OperationDumper::visit(const Pool2D &node)
289 {
290   std::string padding_type =
291     node.param().padding.type == PaddingType::EXPLICIT ? "Explicit" : "Implicit";
292   VERBOSE(LIR) << "* " << node.name() << "(" << padding_type << ")" << std::endl;
293   VERBOSE(LIR) << "  - Inputs : IFM(" << node.getInputs().at(Pool2D::Input::INPUT) << ")"
294                << std::endl;
295   VERBOSE(LIR) << "  - Output : OFM(" << node.getOutputs().at(0) << ")" << std::endl;
296 }
297
298 void OperationDumper::visit(const Pow &node) { dumpOpGeneric(node); }
299
300 void OperationDumper::visit(const PReLU &node)
301 {
302   std::string alpha =
303     "Alpha(" + std::to_string(node.getInputs().at(PReLU::Input::ALPHA).value()) + ")";
304   dumpOpGeneric(node, alpha);
305 }
306
307 void OperationDumper::visit(const Rank &node) { dumpOpGeneric(node); }
308
309 void OperationDumper::visit(const Reduce &node) { dumpUnaryInputOp(node); }
310
311 void OperationDumper::visit(const Reshape &node)
312 {
313   // optional param
314   std::string shape =
315     node.getInputs().size() == 2
316       ? "Shape(" + std::to_string(node.getInputs().at(Reshape::Input::SHAPE).value()) + ")"
317       : "Shape(not provided)";
318   dumpUnaryInputOp(node, shape);
319 }
320
321 void OperationDumper::visit(const ResizeBilinear &node) { dumpOpGeneric(node); }
322
323 void OperationDumper::visit(const ResizeNearestNeighbor &node) { dumpOpGeneric(node); }
324
325 void OperationDumper::visit(const Reverse &node)
326 {
327   std::string axis =
328     "Axis(" + std::to_string(node.getInputs().at(Reverse::Input::AXIS).value()) + ")";
329   dumpUnaryInputOp(node, axis);
330 }
331
332 void OperationDumper::visit(const RNN &node)
333 {
334   VERBOSE(LIR) << "* RNN" << std::endl;
335   VERBOSE(LIR) << "  - Inputs : Input(" << node.getInputs().at(RNN::Input::INPUT) << ") Weights("
336                << node.getInputs().at(RNN::Input::WEIGHTS) << ") Recurrent Weights("
337                << node.getInputs().at(RNN::Input::RECURRENT_WEIGHTS) << ") Bias("
338                << node.getInputs().at(RNN::Input::BIAS) << ") Hidden State("
339                << node.getInputs().at(RNN::Input::HIDDEN_STATE_IN) << ")" << std::endl;
340   VERBOSE(LIR) << "  - Output : Output(" << node.getOutputs().at(RNN::Output::OUTPUT)
341                << ") Hidden State(" << node.getInputs().at(RNN::Output::HIDDEN_STATE_OUT) << ")"
342                << std::endl;
343 }
344
345 void OperationDumper::visit(const Range &node)
346 {
347   VERBOSE(LIR) << "* Range" << std::endl;
348   VERBOSE(LIR) << "  - Inputs : Start(" << node.getInputs().at(Range::Input::START) << ")"
349                << " Limit(" << node.getInputs().at(Range::Input::LIMIT) << ")"
350                << " Delta(" << node.getInputs().at(Range::Input::DELTA) << ")" << std::endl;
351   VERBOSE(LIR) << "  - Output : Output(" << node.getOutputs().at(0) << ")" << std::endl;
352 }
353
354 void OperationDumper::visit(const Select &node)
355 {
356   VERBOSE(LIR) << "* Select" << std::endl;
357   VERBOSE(LIR) << "  - Inputs : Condition(" << node.getInputs().at(Select::Input::CONDITION) << ")"
358                << " Input_X(" << node.getInputs().at(Select::Input::INPUT_TRUE) << ")"
359                << " Input_Y(" << node.getInputs().at(Select::Input::INPUT_FALSE) << ")"
360                << std::endl;
361   VERBOSE(LIR) << "  - Output : Output(" << node.getOutputs().at(0) << ")" << std::endl;
362 }
363
364 void OperationDumper::visit(const ir::operation::Shape &node) { dumpOpGeneric(node); }
365
366 void OperationDumper::visit(const Softmax &node) { dumpOpGeneric(node); }
367
368 void OperationDumper::visit(const SpaceToBatchND &node)
369 {
370   std::string inputs =
371     "BlockSize(" + std::to_string(node.getInputs().at(SpaceToBatchND::Input::BLOCK_SIZE).value()) +
372     ") Paddings(" + std::to_string(node.getInputs().at(SpaceToBatchND::Input::PADDINGS).value()) +
373     ")";
374   dumpUnaryInputOp(node, inputs);
375 }
376
377 void OperationDumper::visit(const SpaceToDepth &node) { dumpOpGeneric(node); }
378
379 void OperationDumper::visit(const Split &node) { dumpOpGeneric(node); }
380
381 void OperationDumper::visit(const SquaredDifference &node) { dumpOpGeneric(node); }
382
383 void OperationDumper::visit(const StatelessRandomUniform &node)
384 {
385   VERBOSE(LIR) << "* StatelessRandomUniform" << std::endl;
386   VERBOSE(LIR) << "  - Inputs : Shape(" << node.getInputs().at(StatelessRandomUniform::Input::SHAPE)
387                << " Seed(" << node.getInputs().at(StatelessRandomUniform::Input::SEED) << ")"
388                << std::endl;
389   VERBOSE(LIR) << "  - Output : Output(" << node.getOutputs().at(0) << ")" << std::endl;
390 }
391
392 void OperationDumper::visit(const Squeeze &node) { dumpOpGeneric(node); }
393
394 void OperationDumper::visit(const Slice &node) { dumpUnaryInputOp(node); }
395
396 void OperationDumper::visit(const StridedSlice &node) { dumpUnaryInputOp(node); }
397
398 void OperationDumper::visit(const Tile &node)
399 {
400   std::string multiples =
401     "Multiples(" + std::to_string(node.getInputs().at(Tile::Input::MULTIPLES).value()) + ")";
402   dumpUnaryInputOp(node, multiples);
403 }
404
405 void OperationDumper::visit(const TopKV2 &node)
406 {
407   VERBOSE(LIR) << "* TopKV2" << std::endl;
408   VERBOSE(LIR) << "  - Inputs : Input(" << node.getInputs().at(TopKV2::Input::INPUT) << ")"
409                << std::endl;
410   VERBOSE(LIR) << "  - Outputs : Values(" << node.getOutputs().at(TopKV2::Output::OUTPUT_VALUES)
411                << ") Indices(" << node.getOutputs().at(TopKV2::Output::OUTPUT_INDICES) << ")"
412                << std::endl;
413 }
414
415 void OperationDumper::visit(const TransposeConv &node)
416 {
417   std::string padding_type =
418     node.param().padding.type == PaddingType::EXPLICIT ? "Explicit" : "Implicit";
419   VERBOSE(LIR) << "* TransposeConv(" << padding_type << ")" << std::endl;
420   VERBOSE(LIR) << "  - Inputs : Output Shape("
421                << node.getInputs().at(TransposeConv::Input::OUTPUT_SHAPE) << ") KERNEL("
422                << node.getInputs().at(TransposeConv::Input::KERNEL) << ") IFM("
423                << node.getInputs().at(TransposeConv::Input::INPUT) << ")" << std::endl;
424   VERBOSE(LIR) << "  - Output : OFM(" << node.getOutputs().at(0) << ")" << std::endl;
425 }
426
427 void OperationDumper::visit(const Transpose &node) { dumpOpGeneric(node); }
428
429 void OperationDumper::visit(const Unpack &node)
430 {
431   VERBOSE(LIR) << "* " << node.name() << std::endl;
432   VERBOSE(LIR) << "  - Inputs : Input(" << node.getInputs().at(Unpack::Input::INPUT) << ")"
433                << std::endl;
434   VERBOSE(LIR) << "  - Output : Outputs(" << node.getOutputs() << ")" << std::endl;
435 }
436
437 void OperationDumper::visit(const OneHot &node)
438 {
439   VERBOSE(LIR) << "* " << node.name() << std::endl;
440   VERBOSE(LIR) << "  - Inputs : "
441                << "Indices(" << node.getInputs().at(OneHot::Input::INDICES) << ") " << std::endl;
442   VERBOSE(LIR) << "  - Output : Output(" << node.getOutputs().at(0) << ")" << std::endl;
443 }
444
445 void OperationDumper::visit(const If &node)
446 {
447   VERBOSE(LIR) << "* " << node.name() << std::endl;
448   VERBOSE(LIR) << "  - Inputs : "
449                << "Then subgraph (" << node.param().then_subg_index << ") Else subgraph ("
450                << node.param().else_subg_index << ") Inputs(" << node.getInputs() << ")"
451                << std::endl;
452   VERBOSE(LIR) << "  - Output : Outputs(" << node.getOutputs() << ")" << std::endl;
453 }
454
455 void OperationDumper::visit(const While &node)
456 {
457   VERBOSE(LIR) << "* " << node.name() << std::endl;
458   VERBOSE(LIR) << "  - Inputs : "
459                << "Cond subgraph (" << node.param().cond_subg_index << ") Body subgraph ("
460                << node.param().body_subg_index << ") Inputs(" << node.getInputs() << ")"
461                << std::endl;
462   VERBOSE(LIR) << "  - Output : Outputs(" << node.getOutputs() << ")" << std::endl;
463 }
464
465 } // namespace ir
466 } // namespace onert