xref: /aosp_15_r20/external/ComputeLibrary/utils/TypePrinter.h (revision c217d954acce2dbc11938adb493fc0abd69584f3)
1 /*
2  * Copyright (c) 2017-2023 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 #ifndef __ARM_COMPUTE_TYPE_PRINTER_H__
25 #define __ARM_COMPUTE_TYPE_PRINTER_H__
26 
27 #ifdef ARM_COMPUTE_OPENCL_ENABLED
28 #include "arm_compute/core/CL/ICLTensor.h"
29 #endif /* ARM_COMPUTE_OPENCL_ENABLED */
30 
31 #include "arm_compute/core/Dimensions.h"
32 #include "arm_compute/core/Error.h"
33 #include "arm_compute/core/GPUTarget.h"
34 #include "arm_compute/core/KernelDescriptors.h"
35 #include "arm_compute/core/Size2D.h"
36 #include "arm_compute/core/Strides.h"
37 #include "arm_compute/core/TensorInfo.h"
38 #include "arm_compute/core/Types.h"
39 #include "arm_compute/core/experimental/IPostOp.h"
40 #include "arm_compute/core/experimental/PostOps.h"
41 #include "arm_compute/dynamic_fusion/sketch/attributes/CastAttributes.h"
42 #include "arm_compute/dynamic_fusion/sketch/attributes/ClampAttributes.h"
43 #include "arm_compute/dynamic_fusion/sketch/attributes/Conv2dAttributes.h"
44 #include "arm_compute/dynamic_fusion/sketch/attributes/DepthwiseConv2dAttributes.h"
45 #include "arm_compute/dynamic_fusion/sketch/attributes/Pool2dAttributes.h"
46 #include "arm_compute/dynamic_fusion/sketch/attributes/ResizeAttributes.h"
47 #include "arm_compute/dynamic_fusion/sketch/attributes/SoftmaxAttributes.h"
48 #include "arm_compute/dynamic_fusion/sketch/gpu/operators/GpuPool2d.h"
49 #include "arm_compute/runtime/CL/CLTunerTypes.h"
50 #include "arm_compute/runtime/CL/CLTypes.h"
51 #include "arm_compute/runtime/FunctionDescriptors.h"
52 #include "arm_compute/runtime/common/LSTMParams.h"
53 #include "support/Cast.h"
54 #include "support/StringSupport.h"
55 #include <ostream>
56 #include <sstream>
57 #include <string>
58 
59 namespace arm_compute
60 {
61 /** Formatted output if arg is not null
62  *
63  * @param[in] arg Object to print
64  *
65  * @return String representing arg.
66  */
67 template <typename T>
to_string_if_not_null(T * arg)68 std::string to_string_if_not_null(T *arg)
69 {
70     if(arg == nullptr)
71     {
72         return "nullptr";
73     }
74     else
75     {
76         return to_string(*arg);
77     }
78 }
79 
80 /** Fallback method: try to use std::to_string:
81  *
82  * @param[in] val Value to convert to string
83  *
84  * @return String representing val.
85  */
86 template <typename T>
to_string(const T & val)87 inline std::string to_string(const T &val)
88 {
89     return support::cpp11::to_string(val);
90 }
91 
92 /** Formatted output of a vector of objects.
93  *
94  * @note: Using the overloaded to_string() instead of overloaded operator<<(), because to_string() functions are
95  *        overloaded for all types, where two or more of them can use the same operator<<(), ITensor is an example.
96  *
97  * @param[out] os   Output stream
98  * @param[in]  args Vector of objects to print
99  *
100  * @return Modified output stream.
101  */
102 template <typename T>
103 ::std::ostream &operator<<(::std::ostream &os, const std::vector<T> &args)
104 {
105     const size_t max_print_size = 5U;
106 
107     os << "[";
108     bool   first = true;
109     size_t i;
110     for(i = 0; i < args.size(); ++i)
111     {
112         if(i == max_print_size)
113         {
114             break;
115         }
116         if(first)
117         {
118             first = false;
119         }
120         else
121         {
122             os << ", ";
123         }
124         os << to_string(args[i]);
125     }
126     if(i < args.size())
127     {
128         os << ", ...";
129     }
130     os << "]";
131     return os;
132 }
133 
134 /** Formatted output of a vector of objects.
135  *
136  * @param[in] args Vector of objects to print
137  *
138  * @return String representing args.
139  */
140 template <typename T>
to_string(const std::vector<T> & args)141 std::string to_string(const std::vector<T> &args)
142 {
143     std::stringstream str;
144     str << args;
145     return str.str();
146 }
147 
148 /** @name (EXPERIMENTAL_POST_OPS)
149  * @{
150  */
151 /** Formmated output of the @ref experimental::PostOpType type
152  *
153  * @param[out] os           Output stream.
154  * @param[in]  post_op_type Type to output.
155  *
156  * @return Modified output stream.
157  */
158 inline ::std::ostream &operator<<(::std::ostream &os, experimental::PostOpType post_op_type)
159 {
160     os << "type=";
161     switch(post_op_type)
162     {
163         case experimental::PostOpType::Activation:
164         {
165             os << "Activation";
166             break;
167         }
168         case experimental::PostOpType::Eltwise_Add:
169         {
170             os << "Eltwise_Add";
171             break;
172         }
173         case experimental::PostOpType::Eltwise_PRelu:
174         {
175             os << "Eltwise_PRelu";
176             break;
177         }
178         default:
179         {
180             ARM_COMPUTE_ERROR("Unsupported PostOpType");
181             break;
182         }
183     }
184     return os;
185 }
186 /** Converts a @ref experimental::PostOpType to string
187  *
188  * @param[in] post_op_type PostOpType value to be converted
189  *
190  * @return String representing the corresponding PostOpType
191  */
to_string(experimental::PostOpType post_op_type)192 inline std::string to_string(experimental::PostOpType post_op_type)
193 {
194     std::stringstream str;
195     str << post_op_type;
196     return str.str();
197 }
198 /** Formatted output of the @ref experimental::IPostOp type.
199  *
200  * @param[out] os      Output stream.
201  * @param[in]  post_op Type to output.
202  *
203  * @return Modified output stream.
204  */
205 template <typename T>
206 inline ::std::ostream &operator<<(::std::ostream &os, const experimental::IPostOp<T> &post_op)
207 {
208     os << "<";
209     os << post_op.type() << ",";
210     os << "prev_dst_pos=" << post_op.prev_dst_pos() << ",";
211     switch(post_op.type())
212     {
213         case experimental::PostOpType::Activation:
214         {
215             const auto _post_op = utils::cast::polymorphic_downcast<const experimental::PostOpAct<T> *>(&post_op);
216             os << "act_info=" << &(_post_op->_act_info);
217             break;
218         }
219         case experimental::PostOpType::Eltwise_Add:
220         {
221             const auto _post_op = utils::cast::polymorphic_downcast<const experimental::PostOpEltwiseAdd<T> *>(&post_op);
222             os << "convert_policy=" << _post_op->_policy;
223             break;
224         }
225         case experimental::PostOpType::Eltwise_PRelu:
226         {
227             const auto _post_op = utils::cast::polymorphic_downcast<const experimental::PostOpEltwisePRelu<T> *>(&post_op);
228             os << "convert_policy=" << _post_op->_policy;
229             break;
230         }
231         default:
232         {
233             ARM_COMPUTE_ERROR("Unsupported PostOpType");
234             break;
235         }
236     }
237     os << ">";
238     return os;
239 }
240 /** Converts an @ref experimental::IPostOp to string
241  *
242  * @param[in] post_op IPostOp value to be converted
243  *
244  * @return String representing the corresponding IPostOp
245  */
246 template <typename T>
to_string(const experimental::IPostOp<T> & post_op)247 inline std::string to_string(const experimental::IPostOp<T> &post_op)
248 {
249     std::stringstream str;
250     str << post_op;
251     return str.str();
252 }
253 /** Formatted output of the @ref experimental::PostOpList type.
254  *
255  * @param[out] os       Output stream.
256  * @param[in]  post_ops Type to output.
257  *
258  * @return Modified output stream.
259  */
260 template <typename T>
261 inline ::std::ostream &operator<<(::std::ostream &os, const experimental::PostOpList<T> &post_ops)
262 {
263     os << "[";
264     for(const auto &post_op : post_ops.get_list())
265     {
266         os << *post_op << ",";
267     }
268     os << "]";
269     return os;
270 }
271 /** Converts a @ref experimental::PostOpList to string
272  *
273  * @param[in] post_ops PostOpList value to be converted
274  *
275  * @return String representing the corresponding PostOpList
276  */
277 template <typename T>
to_string(const experimental::PostOpList<T> & post_ops)278 inline std::string to_string(const experimental::PostOpList<T> &post_ops)
279 {
280     std::stringstream str;
281     str << post_ops;
282     return str.str();
283 }
284 /** @} */ // end of group (EXPERIMENTAL_POST_OPS)
285 
286 /** Formatted output of the Dimensions type.
287  *
288  * @param[out] os         Output stream.
289  * @param[in]  dimensions Type to output.
290  *
291  * @return Modified output stream.
292  */
293 template <typename T>
294 inline ::std::ostream &operator<<(::std::ostream &os, const Dimensions<T> &dimensions)
295 {
296     if(dimensions.num_dimensions() > 0)
297     {
298         os << dimensions[0];
299 
300         for(unsigned int d = 1; d < dimensions.num_dimensions(); ++d)
301         {
302             os << "," << dimensions[d];
303         }
304     }
305 
306     return os;
307 }
308 
309 /** Formatted output of the RoundingPolicy type.
310  *
311  * @param[out] os              Output stream.
312  * @param[in]  rounding_policy Type to output.
313  *
314  * @return Modified output stream.
315  */
316 inline ::std::ostream &operator<<(::std::ostream &os, const RoundingPolicy &rounding_policy)
317 {
318     switch(rounding_policy)
319     {
320         case RoundingPolicy::TO_ZERO:
321             os << "TO_ZERO";
322             break;
323         case RoundingPolicy::TO_NEAREST_UP:
324             os << "TO_NEAREST_UP";
325             break;
326         case RoundingPolicy::TO_NEAREST_EVEN:
327             os << "TO_NEAREST_EVEN";
328             break;
329         default:
330             ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
331     }
332 
333     return os;
334 }
335 
336 /** Formatted output of the WeightsInfo type.
337  *
338  * @param[out] os           Output stream.
339  * @param[in]  weights_info Type to output.
340  *
341  * @return Modified output stream.
342  */
343 inline ::std::ostream &operator<<(::std::ostream &os, const WeightsInfo &weights_info)
344 {
345     os << weights_info.are_reshaped() << ";";
346     os << weights_info.num_kernels() << ";" << weights_info.kernel_size().first << "," << weights_info.kernel_size().second;
347 
348     return os;
349 }
350 
351 /** Formatted output of the ROIPoolingInfo type.
352  *
353  * @param[out] os        Output stream.
354  * @param[in]  pool_info Type to output.
355  *
356  * @return Modified output stream.
357  */
358 inline ::std::ostream &operator<<(::std::ostream &os, const ROIPoolingLayerInfo &pool_info)
359 {
360     os << pool_info.pooled_width() << "x" << pool_info.pooled_height() << "~" << pool_info.spatial_scale();
361     return os;
362 }
363 
364 /** Formatted output of the ROIPoolingInfo type.
365  *
366  * @param[in] pool_info Type to output.
367  *
368  * @return Formatted string.
369  */
to_string(const ROIPoolingLayerInfo & pool_info)370 inline std::string to_string(const ROIPoolingLayerInfo &pool_info)
371 {
372     std::stringstream str;
373     str << pool_info;
374     return str.str();
375 }
376 
377 /** Formatted output of the GEMMKernelInfo type.
378  *
379  * @param[out] os        Output stream.
380  * @param[in]  gemm_info Type to output.
381  *
382  * @return Modified output stream.
383  */
384 inline ::std::ostream &operator<<(::std::ostream &os, const GEMMKernelInfo &gemm_info)
385 {
386     os << "( m=" << gemm_info.m;
387     os << " n=" << gemm_info.n;
388     os << " k=" << gemm_info.k;
389     os << " depth_output_gemm3d=" << gemm_info.depth_output_gemm3d;
390     os << " reinterpret_input_as_3d=" << gemm_info.reinterpret_input_as_3d;
391     os << " broadcast_bias=" << gemm_info.broadcast_bias;
392     os << " fp_mixed_precision=" << gemm_info.fp_mixed_precision;
393     os << " mult_transpose1xW_width=" << gemm_info.mult_transpose1xW_width;
394     os << " mult_interleave4x4_height=" << gemm_info.mult_interleave4x4_height;
395     os << " a_offset=" << gemm_info.a_offset;
396     os << " b_offset=" << gemm_info.b_offset;
397     os << "post_ops=" << gemm_info.post_ops;
398     os << ")";
399     return os;
400 }
401 
402 /** Formatted output of the GEMMLHSMatrixInfo type.
403  *
404  * @param[out] os        Output stream.
405  * @param[in]  gemm_info Type to output.
406  *
407  * @return Modified output stream.
408  */
409 inline ::std::ostream &operator<<(::std::ostream &os, const GEMMLHSMatrixInfo &gemm_info)
410 {
411     os << "( m0=" << (unsigned int)gemm_info.m0 << " k0=" << gemm_info.k0 << "  v0=" << gemm_info.v0 << "  trans=" << gemm_info.transpose << "  inter=" << gemm_info.interleave << "})";
412     return os;
413 }
414 
415 /** Formatted output of the GEMMRHSMatrixInfo type.
416  *
417  * @param[out] os        Output stream.
418  * @param[in]  gemm_info Type to output.
419  *
420  * @return Modified output stream.
421  */
422 inline ::std::ostream &operator<<(::std::ostream &os, const GEMMRHSMatrixInfo &gemm_info)
423 {
424     os << "( n0=" << (unsigned int)gemm_info.n0 << " k0=" << gemm_info.k0 << "  h0=" << gemm_info.h0 << "  trans=" << gemm_info.transpose << "  inter=" << gemm_info.interleave << " exp_img=" << gemm_info.export_to_cl_image << "})";
425     return os;
426 }
427 
428 /** Formatted output of the GEMMRHSMatrixInfo type.
429  *
430  * @param[in] gemm_info GEMMRHSMatrixInfo to output.
431  *
432  * @return Formatted string.
433  */
to_string(const GEMMRHSMatrixInfo & gemm_info)434 inline std::string to_string(const GEMMRHSMatrixInfo &gemm_info)
435 {
436     std::stringstream str;
437     str << gemm_info;
438     return str.str();
439 }
440 
441 /** Formatted output of the GEMMLHSMatrixInfo type.
442  *
443  * @param[in] gemm_info GEMMLHSMatrixInfo to output.
444  *
445  * @return Formatted string.
446  */
to_string(const GEMMLHSMatrixInfo & gemm_info)447 inline std::string to_string(const GEMMLHSMatrixInfo &gemm_info)
448 {
449     std::stringstream str;
450     str << gemm_info;
451     return str.str();
452 }
453 
454 /** Formatted output of the GEMMKernelInfo type.
455  *
456  * @param[in] gemm_info GEMMKernelInfo Type to output.
457  *
458  * @return Formatted string.
459  */
to_string(const GEMMKernelInfo & gemm_info)460 inline std::string to_string(const GEMMKernelInfo &gemm_info)
461 {
462     std::stringstream str;
463     str << gemm_info;
464     return str.str();
465 }
466 
467 /** Formatted output of the BoundingBoxTransformInfo type.
468  *
469  * @param[out] os        Output stream.
470  * @param[in]  bbox_info Type to output.
471  *
472  * @return Modified output stream.
473  */
474 inline ::std::ostream &operator<<(::std::ostream &os, const BoundingBoxTransformInfo &bbox_info)
475 {
476     auto weights = bbox_info.weights();
477     os << "(" << bbox_info.img_width() << "x" << bbox_info.img_height() << ")~" << bbox_info.scale() << "(weights={" << weights[0] << ", " << weights[1] << ", " << weights[2] << ", " << weights[3] << "})";
478     return os;
479 }
480 
481 #if defined(ARM_COMPUTE_ENABLE_BF16)
482 inline ::std::ostream &operator<<(::std::ostream &os, const bfloat16 &v)
483 {
484     std::stringstream str;
485     str << v;
486     os << str.str();
487     return os;
488 }
489 #endif /* defined(ARM_COMPUTE_ENABLE_BF16) */
490 
491 /** Formatted output of the BoundingBoxTransformInfo type.
492  *
493  * @param[in] bbox_info Type to output.
494  *
495  * @return Formatted string.
496  */
to_string(const BoundingBoxTransformInfo & bbox_info)497 inline std::string to_string(const BoundingBoxTransformInfo &bbox_info)
498 {
499     std::stringstream str;
500     str << bbox_info;
501     return str.str();
502 }
503 
504 /** Formatted output of the ComputeAnchorsInfo type.
505  *
506  * @param[out] os           Output stream.
507  * @param[in]  anchors_info Type to output.
508  *
509  * @return Modified output stream.
510  */
511 inline ::std::ostream &operator<<(::std::ostream &os, const ComputeAnchorsInfo &anchors_info)
512 {
513     os << "(" << anchors_info.feat_width() << "x" << anchors_info.feat_height() << ")~" << anchors_info.spatial_scale();
514     return os;
515 }
516 
517 /** Formatted output of the ComputeAnchorsInfo type.
518  *
519  * @param[in] anchors_info Type to output.
520  *
521  * @return Formatted string.
522  */
to_string(const ComputeAnchorsInfo & anchors_info)523 inline std::string to_string(const ComputeAnchorsInfo &anchors_info)
524 {
525     std::stringstream str;
526     str << anchors_info;
527     return str.str();
528 }
529 
530 /** Formatted output of the GenerateProposalsInfo type.
531  *
532  * @param[out] os             Output stream.
533  * @param[in]  proposals_info Type to output.
534  *
535  * @return Modified output stream.
536  */
537 inline ::std::ostream &operator<<(::std::ostream &os, const GenerateProposalsInfo &proposals_info)
538 {
539     os << "(" << proposals_info.im_width() << "x" << proposals_info.im_height() << ")~" << proposals_info.im_scale();
540     return os;
541 }
542 
543 /** Formatted output of the GenerateProposalsInfo type.
544  *
545  * @param[in] proposals_info Type to output.
546  *
547  * @return Formatted string.
548  */
to_string(const GenerateProposalsInfo & proposals_info)549 inline std::string to_string(const GenerateProposalsInfo &proposals_info)
550 {
551     std::stringstream str;
552     str << proposals_info;
553     return str.str();
554 }
555 
556 /** Formatted output of the QuantizationInfo type.
557  *
558  * @param[out] os    Output stream.
559  * @param[in]  qinfo Type to output.
560  *
561  * @return Modified output stream.
562  */
563 inline ::std::ostream &operator<<(::std::ostream &os, const QuantizationInfo &qinfo)
564 {
565     const UniformQuantizationInfo uqinfo = qinfo.uniform();
566     os << "Scale:" << uqinfo.scale << "~";
567     os << "Offset:" << uqinfo.offset;
568     return os;
569 }
570 
571 /** Formatted output of the QuantizationInfo type.
572  *
573  * @param[in] quantization_info Type to output.
574  *
575  * @return Formatted string.
576  */
to_string(const QuantizationInfo & quantization_info)577 inline std::string to_string(const QuantizationInfo &quantization_info)
578 {
579     std::stringstream str;
580     str << quantization_info;
581     return str.str();
582 }
583 
584 /** Formatted output of the activation function type.
585  *
586  * @param[out] os           Output stream.
587  * @param[in]  act_function Type to output.
588  *
589  * @return Modified output stream.
590  */
591 inline ::std::ostream &operator<<(::std::ostream &os, const ActivationLayerInfo::ActivationFunction &act_function)
592 {
593     switch(act_function)
594     {
595         case ActivationLayerInfo::ActivationFunction::ABS:
596             os << "ABS";
597             break;
598         case ActivationLayerInfo::ActivationFunction::LINEAR:
599             os << "LINEAR";
600             break;
601         case ActivationLayerInfo::ActivationFunction::LOGISTIC:
602             os << "LOGISTIC";
603             break;
604         case ActivationLayerInfo::ActivationFunction::RELU:
605             os << "RELU";
606             break;
607         case ActivationLayerInfo::ActivationFunction::BOUNDED_RELU:
608             os << "BOUNDED_RELU";
609             break;
610         case ActivationLayerInfo::ActivationFunction::LEAKY_RELU:
611             os << "LEAKY_RELU";
612             break;
613         case ActivationLayerInfo::ActivationFunction::SOFT_RELU:
614             os << "SOFT_RELU";
615             break;
616         case ActivationLayerInfo::ActivationFunction::SQRT:
617             os << "SQRT";
618             break;
619         case ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU:
620             os << "LU_BOUNDED_RELU";
621             break;
622         case ActivationLayerInfo::ActivationFunction::ELU:
623             os << "ELU";
624             break;
625         case ActivationLayerInfo::ActivationFunction::SQUARE:
626             os << "SQUARE";
627             break;
628         case ActivationLayerInfo::ActivationFunction::TANH:
629             os << "TANH";
630             break;
631         case ActivationLayerInfo::ActivationFunction::IDENTITY:
632             os << "IDENTITY";
633             break;
634         case ActivationLayerInfo::ActivationFunction::HARD_SWISH:
635             os << "HARD_SWISH";
636             break;
637         case ActivationLayerInfo::ActivationFunction::SWISH:
638             os << "SWISH";
639             break;
640         case ActivationLayerInfo::ActivationFunction::GELU:
641             os << "GELU";
642             break;
643 
644         default:
645             ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
646     }
647 
648     return os;
649 }
650 
651 /** Formatted output of the activation function info type.
652  *
653  * @param[in] info ActivationLayerInfo to output.
654  *
655  * @return Formatted string.
656  */
to_string(const arm_compute::ActivationLayerInfo & info)657 inline std::string to_string(const arm_compute::ActivationLayerInfo &info)
658 {
659     std::stringstream str;
660     if(info.enabled())
661     {
662         str << info.activation();
663     }
664     return str.str();
665 }
666 
667 /** Formatted output of the activation function info.
668  *
669  * @param[out] os   Output stream.
670  * @param[in]  info ActivationLayerInfo to output.
671  *
672  * @return Formatted string.
673  */
674 inline ::std::ostream &operator<<(::std::ostream &os, const ActivationLayerInfo *info)
675 {
676     if(info != nullptr)
677     {
678         if(info->enabled())
679         {
680             os << info->activation();
681             os << "(";
682             os << "VAL_A=" << info->a() << ",";
683             os << "VAL_B=" << info->b();
684             os << ")";
685         }
686         else
687         {
688             os << "disabled";
689         }
690     }
691     else
692     {
693         os << "nullptr";
694     }
695     return os;
696 }
697 
698 /** Formatted output of the activation function type.
699  *
700  * @param[in] function Type to output.
701  *
702  * @return Formatted string.
703  */
to_string(const arm_compute::ActivationLayerInfo::ActivationFunction & function)704 inline std::string to_string(const arm_compute::ActivationLayerInfo::ActivationFunction &function)
705 {
706     std::stringstream str;
707     str << function;
708     return str.str();
709 }
710 
711 /** Formatted output of the NormType type.
712  *
713  * @param[out] os        Output stream.
714  * @param[in]  norm_type Type to output.
715  *
716  * @return Modified output stream.
717  */
718 inline ::std::ostream &operator<<(::std::ostream &os, const NormType &norm_type)
719 {
720     switch(norm_type)
721     {
722         case NormType::CROSS_MAP:
723             os << "CROSS_MAP";
724             break;
725         case NormType::IN_MAP_1D:
726             os << "IN_MAP_1D";
727             break;
728         case NormType::IN_MAP_2D:
729             os << "IN_MAP_2D";
730             break;
731         default:
732             ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
733     }
734 
735     return os;
736 }
737 
738 /** Formatted output of @ref NormalizationLayerInfo.
739  *
740  * @param[in] info Type to output.
741  *
742  * @return Formatted string.
743  */
to_string(const arm_compute::NormalizationLayerInfo & info)744 inline std::string to_string(const arm_compute::NormalizationLayerInfo &info)
745 {
746     std::stringstream str;
747     str << info.type() << ":NormSize=" << info.norm_size();
748     return str.str();
749 }
750 
751 /** Formatted output of @ref NormalizationLayerInfo.
752  *
753  * @param[out] os   Output stream.
754  * @param[in]  info Type to output.
755  *
756  * @return Modified output stream.
757  */
758 inline ::std::ostream &operator<<(::std::ostream &os, const NormalizationLayerInfo &info)
759 {
760     os << info.type() << ":NormSize=" << info.norm_size();
761     return os;
762 }
763 
764 /** Formatted output of the PoolingType type.
765  *
766  * @param[out] os        Output stream.
767  * @param[in]  pool_type Type to output.
768  *
769  * @return Modified output stream.
770  */
771 inline ::std::ostream &operator<<(::std::ostream &os, const PoolingType &pool_type)
772 {
773     switch(pool_type)
774     {
775         case PoolingType::AVG:
776             os << "AVG";
777             break;
778         case PoolingType::MAX:
779             os << "MAX";
780             break;
781         case PoolingType::L2:
782             os << "L2";
783             break;
784         default:
785             ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
786     }
787 
788     return os;
789 }
790 
791 /** Formatted output of @ref PoolingLayerInfo.
792  *
793  * @param[out] os   Output stream.
794  * @param[in]  info Type to output.
795  *
796  * @return Modified output stream.
797  */
798 inline ::std::ostream &operator<<(::std::ostream &os, const PoolingLayerInfo &info)
799 {
800     os << info.pool_type;
801 
802     return os;
803 }
804 
805 /** Formatted output of @ref RoundingPolicy.
806  *
807  * @param[in] rounding_policy Type to output.
808  *
809  * @return Formatted string.
810  */
to_string(const RoundingPolicy & rounding_policy)811 inline std::string to_string(const RoundingPolicy &rounding_policy)
812 {
813     std::stringstream str;
814     str << rounding_policy;
815     return str.str();
816 }
817 
818 /** [Print DataLayout type] **/
819 /** Formatted output of the DataLayout type.
820  *
821  * @param[out] os          Output stream.
822  * @param[in]  data_layout Type to output.
823  *
824  * @return Modified output stream.
825  */
826 inline ::std::ostream &operator<<(::std::ostream &os, const DataLayout &data_layout)
827 {
828     switch(data_layout)
829     {
830         case DataLayout::UNKNOWN:
831             os << "UNKNOWN";
832             break;
833         case DataLayout::NHWC:
834             os << "NHWC";
835             break;
836         case DataLayout::NCHW:
837             os << "NCHW";
838             break;
839         case DataLayout::NDHWC:
840             os << "NDHWC";
841             break;
842         case DataLayout::NCDHW:
843             os << "NCDHW";
844             break;
845         default:
846             ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
847     }
848 
849     return os;
850 }
851 
852 /** Formatted output of the DataLayout type.
853  *
854  * @param[in] data_layout Type to output.
855  *
856  * @return Formatted string.
857  */
to_string(const arm_compute::DataLayout & data_layout)858 inline std::string to_string(const arm_compute::DataLayout &data_layout)
859 {
860     std::stringstream str;
861     str << data_layout;
862     return str.str();
863 }
864 /** [Print DataLayout type] **/
865 
866 /** Formatted output of the DataLayoutDimension type.
867  *
868  * @param[out] os              Output stream.
869  * @param[in]  data_layout_dim Data layout dimension to print.
870  *
871  * @return Modified output stream.
872  */
873 inline ::std::ostream &operator<<(::std::ostream &os, const DataLayoutDimension &data_layout_dim)
874 {
875     switch(data_layout_dim)
876     {
877         case DataLayoutDimension::WIDTH:
878             os << "WIDTH";
879             break;
880         case DataLayoutDimension::HEIGHT:
881             os << "HEIGHT";
882             break;
883         case DataLayoutDimension::CHANNEL:
884             os << "CHANNEL";
885             break;
886         case DataLayoutDimension::DEPTH:
887             os << "DEPTH";
888             break;
889         case DataLayoutDimension::BATCHES:
890             os << "BATCHES";
891             break;
892         default:
893             ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
894     }
895     return os;
896 }
897 
898 /** Formatted output of the DataType type.
899  *
900  * @param[out] os        Output stream.
901  * @param[in]  data_type Type to output.
902  *
903  * @return Modified output stream.
904  */
905 inline ::std::ostream &operator<<(::std::ostream &os, const DataType &data_type)
906 {
907     switch(data_type)
908     {
909         case DataType::UNKNOWN:
910             os << "UNKNOWN";
911             break;
912         case DataType::U8:
913             os << "U8";
914             break;
915         case DataType::QSYMM8:
916             os << "QSYMM8";
917             break;
918         case DataType::QASYMM8:
919             os << "QASYMM8";
920             break;
921         case DataType::QASYMM8_SIGNED:
922             os << "QASYMM8_SIGNED";
923             break;
924         case DataType::QSYMM8_PER_CHANNEL:
925             os << "QSYMM8_PER_CHANNEL";
926             break;
927         case DataType::S8:
928             os << "S8";
929             break;
930         case DataType::U16:
931             os << "U16";
932             break;
933         case DataType::S16:
934             os << "S16";
935             break;
936         case DataType::QSYMM16:
937             os << "QSYMM16";
938             break;
939         case DataType::QASYMM16:
940             os << "QASYMM16";
941             break;
942         case DataType::U32:
943             os << "U32";
944             break;
945         case DataType::S32:
946             os << "S32";
947             break;
948         case DataType::U64:
949             os << "U64";
950             break;
951         case DataType::S64:
952             os << "S64";
953             break;
954         case DataType::BFLOAT16:
955             os << "BFLOAT16";
956             break;
957         case DataType::F16:
958             os << "F16";
959             break;
960         case DataType::F32:
961             os << "F32";
962             break;
963         case DataType::F64:
964             os << "F64";
965             break;
966         case DataType::SIZET:
967             os << "SIZET";
968             break;
969         default:
970             ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
971     }
972 
973     return os;
974 }
975 
976 /** Formatted output of the DataType type.
977  *
978  * @param[in] data_type Type to output.
979  *
980  * @return Formatted string.
981  */
to_string(const arm_compute::DataType & data_type)982 inline std::string to_string(const arm_compute::DataType &data_type)
983 {
984     std::stringstream str;
985     str << data_type;
986     return str.str();
987 }
988 
989 /** Formatted output of the Format type.
990  *
991  * @param[out] os     Output stream.
992  * @param[in]  format Type to output.
993  *
994  * @return Modified output stream.
995  */
996 inline ::std::ostream &operator<<(::std::ostream &os, const Format &format)
997 {
998     switch(format)
999     {
1000         case Format::UNKNOWN:
1001             os << "UNKNOWN";
1002             break;
1003         case Format::U8:
1004             os << "U8";
1005             break;
1006         case Format::S16:
1007             os << "S16";
1008             break;
1009         case Format::U16:
1010             os << "U16";
1011             break;
1012         case Format::S32:
1013             os << "S32";
1014             break;
1015         case Format::U32:
1016             os << "U32";
1017             break;
1018         case Format::F16:
1019             os << "F16";
1020             break;
1021         case Format::F32:
1022             os << "F32";
1023             break;
1024         case Format::UV88:
1025             os << "UV88";
1026             break;
1027         case Format::RGB888:
1028             os << "RGB888";
1029             break;
1030         case Format::RGBA8888:
1031             os << "RGBA8888";
1032             break;
1033         case Format::YUV444:
1034             os << "YUV444";
1035             break;
1036         case Format::YUYV422:
1037             os << "YUYV422";
1038             break;
1039         case Format::NV12:
1040             os << "NV12";
1041             break;
1042         case Format::NV21:
1043             os << "NV21";
1044             break;
1045         case Format::IYUV:
1046             os << "IYUV";
1047             break;
1048         case Format::UYVY422:
1049             os << "UYVY422";
1050             break;
1051         default:
1052             ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
1053     }
1054 
1055     return os;
1056 }
1057 
1058 /** Formatted output of the Format type.
1059  *
1060  * @param[in] format Type to output.
1061  *
1062  * @return Formatted string.
1063  */
to_string(const Format & format)1064 inline std::string to_string(const Format &format)
1065 {
1066     std::stringstream str;
1067     str << format;
1068     return str.str();
1069 }
1070 
1071 /** Formatted output of the Channel type.
1072  *
1073  * @param[out] os      Output stream.
1074  * @param[in]  channel Type to output.
1075  *
1076  * @return Modified output stream.
1077  */
1078 inline ::std::ostream &operator<<(::std::ostream &os, const Channel &channel)
1079 {
1080     switch(channel)
1081     {
1082         case Channel::UNKNOWN:
1083             os << "UNKNOWN";
1084             break;
1085         case Channel::C0:
1086             os << "C0";
1087             break;
1088         case Channel::C1:
1089             os << "C1";
1090             break;
1091         case Channel::C2:
1092             os << "C2";
1093             break;
1094         case Channel::C3:
1095             os << "C3";
1096             break;
1097         case Channel::R:
1098             os << "R";
1099             break;
1100         case Channel::G:
1101             os << "G";
1102             break;
1103         case Channel::B:
1104             os << "B";
1105             break;
1106         case Channel::A:
1107             os << "A";
1108             break;
1109         case Channel::Y:
1110             os << "Y";
1111             break;
1112         case Channel::U:
1113             os << "U";
1114             break;
1115         case Channel::V:
1116             os << "V";
1117             break;
1118         default:
1119             ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
1120     }
1121 
1122     return os;
1123 }
1124 
1125 /** Formatted output of the Channel type.
1126  *
1127  * @param[in] channel Type to output.
1128  *
1129  * @return Formatted string.
1130  */
to_string(const Channel & channel)1131 inline std::string to_string(const Channel &channel)
1132 {
1133     std::stringstream str;
1134     str << channel;
1135     return str.str();
1136 }
1137 
1138 /** Formatted output of the BorderMode type.
1139  *
1140  * @param[out] os   Output stream.
1141  * @param[in]  mode Type to output.
1142  *
1143  * @return Modified output stream.
1144  */
1145 inline ::std::ostream &operator<<(::std::ostream &os, const BorderMode &mode)
1146 {
1147     switch(mode)
1148     {
1149         case BorderMode::UNDEFINED:
1150             os << "UNDEFINED";
1151             break;
1152         case BorderMode::CONSTANT:
1153             os << "CONSTANT";
1154             break;
1155         case BorderMode::REPLICATE:
1156             os << "REPLICATE";
1157             break;
1158         default:
1159             ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
1160     }
1161 
1162     return os;
1163 }
1164 
1165 /** Formatted output of the BorderSize type.
1166  *
1167  * @param[out] os     Output stream.
1168  * @param[in]  border Type to output.
1169  *
1170  * @return Modified output stream.
1171  */
1172 inline ::std::ostream &operator<<(::std::ostream &os, const BorderSize &border)
1173 {
1174     os << border.top << ","
1175        << border.right << ","
1176        << border.bottom << ","
1177        << border.left;
1178 
1179     return os;
1180 }
1181 
1182 /** Formatted output of the PaddingList type.
1183  *
1184  * @param[out] os      Output stream.
1185  * @param[in]  padding Type to output.
1186  *
1187  * @return Modified output stream.
1188  */
1189 inline ::std::ostream &operator<<(::std::ostream &os, const PaddingList &padding)
1190 {
1191     os << "{";
1192     for(auto const &p : padding)
1193     {
1194         os << "{" << p.first << "," << p.second << "}";
1195     }
1196     os << "}";
1197     return os;
1198 }
1199 
1200 /** Formatted output of the Multiples type.
1201  *
1202  * @param[out] os        Output stream.
1203  * @param[in]  multiples Type to output.
1204  *
1205  * @return Modified output stream.
1206  */
1207 inline ::std::ostream &operator<<(::std::ostream &os, const Multiples &multiples)
1208 {
1209     os << "(";
1210     for(size_t i = 0; i < multiples.size() - 1; i++)
1211     {
1212         os << multiples[i] << ", ";
1213     }
1214     os << multiples.back() << ")";
1215     return os;
1216 }
1217 
1218 /** Formatted output of the InterpolationPolicy type.
1219  *
1220  * @param[out] os     Output stream.
1221  * @param[in]  policy Type to output.
1222  *
1223  * @return Modified output stream.
1224  */
1225 inline ::std::ostream &operator<<(::std::ostream &os, const InterpolationPolicy &policy)
1226 {
1227     switch(policy)
1228     {
1229         case InterpolationPolicy::NEAREST_NEIGHBOR:
1230             os << "NEAREST_NEIGHBOR";
1231             break;
1232         case InterpolationPolicy::BILINEAR:
1233             os << "BILINEAR";
1234             break;
1235         case InterpolationPolicy::AREA:
1236             os << "AREA";
1237             break;
1238         default:
1239             ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
1240     }
1241 
1242     return os;
1243 }
1244 
1245 /** Formatted output of the SamplingPolicy type.
1246  *
1247  * @param[out] os     Output stream.
1248  * @param[in]  policy Type to output.
1249  *
1250  * @return Modified output stream.
1251  */
1252 inline ::std::ostream &operator<<(::std::ostream &os, const SamplingPolicy &policy)
1253 {
1254     switch(policy)
1255     {
1256         case SamplingPolicy::CENTER:
1257             os << "CENTER";
1258             break;
1259         case SamplingPolicy::TOP_LEFT:
1260             os << "TOP_LEFT";
1261             break;
1262         default:
1263             ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
1264     }
1265 
1266     return os;
1267 }
1268 
1269 /** Formatted output of the ITensorInfo type.
1270  *
1271  * @param[out] os   Output stream.
1272  * @param[in]  info Tensor information.
1273  *
1274  * @return Modified output stream.
1275  */
1276 inline ::std::ostream &operator<<(std::ostream &os, const ITensorInfo *info)
1277 {
1278     const DataType   data_type   = info->data_type();
1279     const DataLayout data_layout = info->data_layout();
1280 
1281     os << "Shape=" << info->tensor_shape() << ","
1282        << "DataLayout=" << string_from_data_layout(data_layout) << ","
1283        << "DataType=" << string_from_data_type(data_type);
1284 
1285     if(is_data_type_quantized(data_type))
1286     {
1287         const QuantizationInfo qinfo   = info->quantization_info();
1288         const auto             scales  = qinfo.scale();
1289         const auto             offsets = qinfo.offset();
1290 
1291         os << ", QuantizationInfo={"
1292            << "scales.size=" << scales.size()
1293            << ", scale(s)=" << scales << ", ";
1294 
1295         os << "offsets.size=" << offsets.size()
1296            << ", offset(s)=" << offsets << "}";
1297     }
1298     return os;
1299 }
1300 
1301 /** Formatted output of the const TensorInfo& type.
1302  *
1303  * @param[out] os   Output stream.
1304  * @param[in]  info Type to output.
1305  *
1306  * @return Modified output stream.
1307  */
1308 inline ::std::ostream &operator<<(::std::ostream &os, const TensorInfo &info)
1309 {
1310     os << &info;
1311     return os;
1312 }
1313 
1314 /** Formatted output of the const TensorInfo& type.
1315  *
1316  * @param[in] info Type to output.
1317  *
1318  * @return Formatted string.
1319  */
to_string(const TensorInfo & info)1320 inline std::string to_string(const TensorInfo &info)
1321 {
1322     std::stringstream str;
1323     str << &info;
1324     return str.str();
1325 }
1326 
1327 /** Formatted output of the const ITensorInfo& type.
1328  *
1329  * @param[in] info Type to output.
1330  *
1331  * @return Formatted string.
1332  */
to_string(const ITensorInfo & info)1333 inline std::string to_string(const ITensorInfo &info)
1334 {
1335     std::stringstream str;
1336     str << &info;
1337     return str.str();
1338 }
1339 
1340 /** Formatted output of the const ITensorInfo* type.
1341  *
1342  * @param[in] info Type to output.
1343  *
1344  * @return Formatted string.
1345  */
to_string(const ITensorInfo * info)1346 inline std::string to_string(const ITensorInfo *info)
1347 {
1348     std::string ret_str = "nullptr";
1349     if(info != nullptr)
1350     {
1351         std::stringstream str;
1352         str << info;
1353         ret_str = str.str();
1354     }
1355     return ret_str;
1356 }
1357 
1358 /** Formatted output of the ITensorInfo* type.
1359  *
1360  * @param[in] info Type to output.
1361  *
1362  * @return Formatted string.
1363  */
to_string(ITensorInfo * info)1364 inline std::string to_string(ITensorInfo *info)
1365 {
1366     return to_string(static_cast<const ITensorInfo *>(info));
1367 }
1368 
1369 /** Formatted output of the ITensorInfo type obtained from const ITensor* type.
1370  *
1371  * @param[in] tensor Type to output.
1372  *
1373  * @return Formatted string.
1374  */
to_string(const ITensor * tensor)1375 inline std::string to_string(const ITensor *tensor)
1376 {
1377     std::string ret_str = "nullptr";
1378     if(tensor != nullptr)
1379     {
1380         std::stringstream str;
1381         str << "ITensor->info(): " << tensor->info();
1382         ret_str = str.str();
1383     }
1384     return ret_str;
1385 }
1386 
1387 /** Formatted output of the ITensorInfo type obtained from the ITensor* type.
1388  *
1389  * @param[in] tensor Type to output.
1390  *
1391  * @return Formatted string.
1392  */
to_string(ITensor * tensor)1393 inline std::string to_string(ITensor *tensor)
1394 {
1395     return to_string(static_cast<const ITensor *>(tensor));
1396 }
1397 
1398 /** Formatted output of the ITensorInfo type obtained from the ITensor& type.
1399  *
1400  * @param[in] tensor Type to output.
1401  *
1402  * @return Formatted string.
1403  */
to_string(ITensor & tensor)1404 inline std::string to_string(ITensor &tensor)
1405 {
1406     std::stringstream str;
1407     str << "ITensor.info(): " << tensor.info();
1408     return str.str();
1409 }
1410 
1411 #ifdef ARM_COMPUTE_OPENCL_ENABLED
1412 /** Formatted output of the ITensorInfo type obtained from the const ICLTensor& type.
1413  *
1414  * @param[in] cl_tensor Type to output.
1415  *
1416  * @return Formatted string.
1417  */
to_string(const ICLTensor * cl_tensor)1418 inline std::string to_string(const ICLTensor *cl_tensor)
1419 {
1420     std::string ret_str = "nullptr";
1421     if(cl_tensor != nullptr)
1422     {
1423         std::stringstream str;
1424         str << "ICLTensor->info(): " << cl_tensor->info();
1425         ret_str = str.str();
1426     }
1427     return ret_str;
1428 }
1429 
1430 /** Formatted output of the ITensorInfo type obtained from the ICLTensor& type.
1431  *
1432  * @param[in] cl_tensor Type to output.
1433  *
1434  * @return Formatted string.
1435  */
to_string(ICLTensor * cl_tensor)1436 inline std::string to_string(ICLTensor *cl_tensor)
1437 {
1438     return to_string(static_cast<const ICLTensor *>(cl_tensor));
1439 }
1440 #endif /* ARM_COMPUTE_OPENCL_ENABLED */
1441 
1442 /** Formatted output of the Dimensions type.
1443  *
1444  * @param[in] dimensions Type to output.
1445  *
1446  * @return Formatted string.
1447  */
1448 template <typename T>
to_string(const Dimensions<T> & dimensions)1449 inline std::string to_string(const Dimensions<T> &dimensions)
1450 {
1451     std::stringstream str;
1452     str << dimensions;
1453     return str.str();
1454 }
1455 
1456 /** Formatted output of the Strides type.
1457  *
1458  * @param[in] stride Type to output.
1459  *
1460  * @return Formatted string.
1461  */
to_string(const Strides & stride)1462 inline std::string to_string(const Strides &stride)
1463 {
1464     std::stringstream str;
1465     str << stride;
1466     return str.str();
1467 }
1468 
1469 /** Formatted output of the TensorShape type.
1470  *
1471  * @param[in] shape Type to output.
1472  *
1473  * @return Formatted string.
1474  */
to_string(const TensorShape & shape)1475 inline std::string to_string(const TensorShape &shape)
1476 {
1477     std::stringstream str;
1478     str << shape;
1479     return str.str();
1480 }
1481 
1482 /** Formatted output of the Coordinates type.
1483  *
1484  * @param[in] coord Type to output.
1485  *
1486  * @return Formatted string.
1487  */
to_string(const Coordinates & coord)1488 inline std::string to_string(const Coordinates &coord)
1489 {
1490     std::stringstream str;
1491     str << coord;
1492     return str.str();
1493 }
1494 
1495 /** Formatted output of the GEMMReshapeInfo type.
1496  *
1497  * @param[out] os   Output stream.
1498  * @param[in]  info Type to output.
1499  *
1500  * @return Modified output stream.
1501  */
1502 inline ::std::ostream &operator<<(::std::ostream &os, const GEMMReshapeInfo &info)
1503 {
1504     os << "{m=" << info.m() << ",";
1505     os << "n=" << info.n() << ",";
1506     os << "k=" << info.k() << ",";
1507     os << "mult_transpose1xW_width=" << info.mult_transpose1xW_width() << ",";
1508     os << "mult_interleave4x4_height=" << info.mult_interleave4x4_height();
1509     os << "}";
1510 
1511     return os;
1512 }
1513 
1514 /** Formatted output of the GEMMInfo type.
1515  *
1516  * @param[out] os   Output stream.
1517  * @param[in]  info Type to output.
1518  *
1519  * @return Modified output stream.
1520  */
1521 inline ::std::ostream &operator<<(::std::ostream &os, const GEMMInfo &info)
1522 {
1523     os << "{is_a_reshaped=" << info.is_a_reshaped() << ",";
1524     os << "is_b_reshaped=" << info.is_b_reshaped() << ",";
1525     os << "reshape_b_only_on_first_run=" << info.reshape_b_only_on_first_run() << ",";
1526     os << "depth_output_gemm3d=" << info.depth_output_gemm3d() << ",";
1527     os << "reinterpret_input_as_3d=" << info.reinterpret_input_as_3d() << ",";
1528     os << "retain_internal_weights=" << info.retain_internal_weights() << ",";
1529     os << "fp_mixed_precision=" << info.fp_mixed_precision() << ",";
1530     os << "broadcast_bias=" << info.broadcast_bias() << ",";
1531     os << "pretranspose_B=" << info.pretranspose_B() << ",";
1532     os << "post_ops=" << info.post_ops() << "}";
1533 
1534     return os;
1535 }
1536 
1537 /** Formatted output of the Window::Dimension type.
1538  *
1539  * @param[out] os  Output stream.
1540  * @param[in]  dim Type to output.
1541  *
1542  * @return Modified output stream.
1543  */
1544 inline ::std::ostream &operator<<(::std::ostream &os, const Window::Dimension &dim)
1545 {
1546     os << "{start=" << dim.start() << ", end=" << dim.end() << ", step=" << dim.step() << "}";
1547 
1548     return os;
1549 }
1550 /** Formatted output of the Window type.
1551  *
1552  * @param[out] os  Output stream.
1553  * @param[in]  win Type to output.
1554  *
1555  * @return Modified output stream.
1556  */
1557 inline ::std::ostream &operator<<(::std::ostream &os, const Window &win)
1558 {
1559     os << "{";
1560     for(unsigned int i = 0; i < Coordinates::num_max_dimensions; i++)
1561     {
1562         if(i > 0)
1563         {
1564             os << ", ";
1565         }
1566         os << win[i];
1567     }
1568     os << "}";
1569 
1570     return os;
1571 }
1572 
1573 /** Formatted output of the WeightsInfo type.
1574  *
1575  * @param[in] info Type to output.
1576  *
1577  * @return Formatted string.
1578  */
to_string(const WeightsInfo & info)1579 inline std::string to_string(const WeightsInfo &info)
1580 {
1581     std::stringstream str;
1582     str << info;
1583     return str.str();
1584 }
1585 
1586 /** Formatted output of the GEMMReshapeInfo type.
1587  *
1588  * @param[in] info Type to output.
1589  *
1590  * @return Formatted string.
1591  */
to_string(const GEMMReshapeInfo & info)1592 inline std::string to_string(const GEMMReshapeInfo &info)
1593 {
1594     std::stringstream str;
1595     str << info;
1596     return str.str();
1597 }
1598 
1599 /** Formatted output of the GEMMInfo type.
1600  *
1601  * @param[in] info Type to output.
1602  *
1603  * @return Formatted string.
1604  */
to_string(const GEMMInfo & info)1605 inline std::string to_string(const GEMMInfo &info)
1606 {
1607     std::stringstream str;
1608     str << info;
1609     return str.str();
1610 }
1611 
1612 /** Formatted output of the Window::Dimension type.
1613  *
1614  * @param[in] dim Type to output.
1615  *
1616  * @return Formatted string.
1617  */
to_string(const Window::Dimension & dim)1618 inline std::string to_string(const Window::Dimension &dim)
1619 {
1620     std::stringstream str;
1621     str << dim;
1622     return str.str();
1623 }
1624 /** Formatted output of the Window& type.
1625  *
1626  * @param[in] win Type to output.
1627  *
1628  * @return Formatted string.
1629  */
to_string(const Window & win)1630 inline std::string to_string(const Window &win)
1631 {
1632     std::stringstream str;
1633     str << win;
1634     return str.str();
1635 }
1636 
1637 /** Formatted output of the Window* type.
1638  *
1639  * @param[in] win Type to output.
1640  *
1641  * @return Formatted string.
1642  */
to_string(Window * win)1643 inline std::string to_string(Window *win)
1644 {
1645     std::string ret_str = "nullptr";
1646     if(win != nullptr)
1647     {
1648         std::stringstream str;
1649         str << *win;
1650         ret_str = str.str();
1651     }
1652     return ret_str;
1653 }
1654 
1655 /** Formatted output of the Rectangle type.
1656  *
1657  * @param[out] os   Output stream.
1658  * @param[in]  rect Type to output.
1659  *
1660  * @return Modified output stream.
1661  */
1662 inline ::std::ostream &operator<<(::std::ostream &os, const Rectangle &rect)
1663 {
1664     os << rect.width << "x" << rect.height;
1665     os << "+" << rect.x << "+" << rect.y;
1666 
1667     return os;
1668 }
1669 
1670 /** Formatted output of the PaddingMode type.
1671  *
1672  * @param[out] os   Output stream.
1673  * @param[in]  mode Type to output.
1674  *
1675  * @return Modified output stream.
1676  */
1677 inline ::std::ostream &operator<<(::std::ostream &os, const PaddingMode &mode)
1678 {
1679     switch(mode)
1680     {
1681         case PaddingMode::CONSTANT:
1682             os << "CONSTANT";
1683             break;
1684         case PaddingMode::REFLECT:
1685             os << "REFLECT";
1686             break;
1687         case PaddingMode::SYMMETRIC:
1688             os << "SYMMETRIC";
1689             break;
1690         default:
1691             ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
1692     }
1693 
1694     return os;
1695 }
1696 
1697 /** Formatted output of the PaddingMode type.
1698  *
1699  * @param[in] mode Type to output.
1700  *
1701  * @return Formatted string.
1702  */
to_string(const PaddingMode & mode)1703 inline std::string to_string(const PaddingMode &mode)
1704 {
1705     std::stringstream str;
1706     str << mode;
1707     return str.str();
1708 }
1709 
1710 /** Formatted output of the PadStrideInfo type.
1711  *
1712  * @param[out] os              Output stream.
1713  * @param[in]  pad_stride_info Type to output.
1714  *
1715  * @return Modified output stream.
1716  */
1717 inline ::std::ostream &operator<<(::std::ostream &os, const PadStrideInfo &pad_stride_info)
1718 {
1719     os << pad_stride_info.stride().first << "," << pad_stride_info.stride().second;
1720     os << ";";
1721     os << pad_stride_info.pad_left() << "," << pad_stride_info.pad_right() << ","
1722        << pad_stride_info.pad_top() << "," << pad_stride_info.pad_bottom();
1723 
1724     return os;
1725 }
1726 
1727 /** Formatted output of the PadStrideInfo type.
1728  *
1729  * @param[in] pad_stride_info Type to output.
1730  *
1731  * @return Formatted string.
1732  */
to_string(const PadStrideInfo & pad_stride_info)1733 inline std::string to_string(const PadStrideInfo &pad_stride_info)
1734 {
1735     std::stringstream str;
1736     str << pad_stride_info;
1737     return str.str();
1738 }
1739 
1740 /** Formatted output of the BorderMode type.
1741  *
1742  * @param[in] mode Type to output.
1743  *
1744  * @return Formatted string.
1745  */
to_string(const BorderMode & mode)1746 inline std::string to_string(const BorderMode &mode)
1747 {
1748     std::stringstream str;
1749     str << mode;
1750     return str.str();
1751 }
1752 
1753 /** Formatted output of the BorderSize type.
1754  *
1755  * @param[in] border Type to output.
1756  *
1757  * @return Formatted string.
1758  */
to_string(const BorderSize & border)1759 inline std::string to_string(const BorderSize &border)
1760 {
1761     std::stringstream str;
1762     str << border;
1763     return str.str();
1764 }
1765 
1766 /** Formatted output of the PaddingList type.
1767  *
1768  * @param[in] padding Type to output.
1769  *
1770  * @return Formatted string.
1771  */
to_string(const PaddingList & padding)1772 inline std::string to_string(const PaddingList &padding)
1773 {
1774     std::stringstream str;
1775     str << padding;
1776     return str.str();
1777 }
1778 
1779 /** Formatted output of the Multiples type.
1780  *
1781  * @param[in] multiples Type to output.
1782  *
1783  * @return Formatted string.
1784  */
to_string(const Multiples & multiples)1785 inline std::string to_string(const Multiples &multiples)
1786 {
1787     std::stringstream str;
1788     str << multiples;
1789     return str.str();
1790 }
1791 
1792 /** Formatted output of the InterpolationPolicy type.
1793  *
1794  * @param[in] policy Type to output.
1795  *
1796  * @return Formatted string.
1797  */
to_string(const InterpolationPolicy & policy)1798 inline std::string to_string(const InterpolationPolicy &policy)
1799 {
1800     std::stringstream str;
1801     str << policy;
1802     return str.str();
1803 }
1804 
1805 /** Formatted output of the SamplingPolicy type.
1806  *
1807  * @param[in] policy Type to output.
1808  *
1809  * @return Formatted string.
1810  */
to_string(const SamplingPolicy & policy)1811 inline std::string to_string(const SamplingPolicy &policy)
1812 {
1813     std::stringstream str;
1814     str << policy;
1815     return str.str();
1816 }
1817 
1818 /** Formatted output of the ConvertPolicy type.
1819  *
1820  * @param[out] os     Output stream.
1821  * @param[in]  policy Type to output.
1822  *
1823  * @return Modified output stream.
1824  */
1825 inline ::std::ostream &operator<<(::std::ostream &os, const ConvertPolicy &policy)
1826 {
1827     switch(policy)
1828     {
1829         case ConvertPolicy::WRAP:
1830             os << "WRAP";
1831             break;
1832         case ConvertPolicy::SATURATE:
1833             os << "SATURATE";
1834             break;
1835         default:
1836             ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
1837     }
1838 
1839     return os;
1840 }
1841 
to_string(const ConvertPolicy & policy)1842 inline std::string to_string(const ConvertPolicy &policy)
1843 {
1844     std::stringstream str;
1845     str << policy;
1846     return str.str();
1847 }
1848 
1849 /** Formatted output of the ArithmeticOperation type.
1850  *
1851  * @param[out] os Output stream.
1852  * @param[in]  op Operation to output.
1853  *
1854  * @return Modified output stream.
1855  */
1856 inline ::std::ostream &operator<<(::std::ostream &os, const ArithmeticOperation &op)
1857 {
1858     switch(op)
1859     {
1860         case ArithmeticOperation::ADD:
1861             os << "ADD";
1862             break;
1863         case ArithmeticOperation::SUB:
1864             os << "SUB";
1865             break;
1866         case ArithmeticOperation::DIV:
1867             os << "DIV";
1868             break;
1869         case ArithmeticOperation::MAX:
1870             os << "MAX";
1871             break;
1872         case ArithmeticOperation::MIN:
1873             os << "MIN";
1874             break;
1875         case ArithmeticOperation::SQUARED_DIFF:
1876             os << "SQUARED_DIFF";
1877             break;
1878         case ArithmeticOperation::POWER:
1879             os << "POWER";
1880             break;
1881         case ArithmeticOperation::PRELU:
1882             os << "PRELU";
1883             break;
1884         default:
1885             ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
1886     }
1887 
1888     return os;
1889 }
1890 
1891 /** Formatted output of the Arithmetic Operation
1892  *
1893  * @param[in] op Type to output.
1894  *
1895  * @return Formatted string.
1896  */
to_string(const ArithmeticOperation & op)1897 inline std::string to_string(const ArithmeticOperation &op)
1898 {
1899     std::stringstream str;
1900     str << op;
1901     return str.str();
1902 }
1903 
1904 /** Formatted output of the Reduction Operations.
1905  *
1906  * @param[out] os Output stream.
1907  * @param[in]  op Type to output.
1908  *
1909  * @return Modified output stream.
1910  */
1911 inline ::std::ostream &operator<<(::std::ostream &os, const ReductionOperation &op)
1912 {
1913     switch(op)
1914     {
1915         case ReductionOperation::SUM:
1916             os << "SUM";
1917             break;
1918         case ReductionOperation::SUM_SQUARE:
1919             os << "SUM_SQUARE";
1920             break;
1921         case ReductionOperation::MEAN_SUM:
1922             os << "MEAN_SUM";
1923             break;
1924         case ReductionOperation::ARG_IDX_MAX:
1925             os << "ARG_IDX_MAX";
1926             break;
1927         case ReductionOperation::ARG_IDX_MIN:
1928             os << "ARG_IDX_MIN";
1929             break;
1930         case ReductionOperation::PROD:
1931             os << "PROD";
1932             break;
1933         case ReductionOperation::MIN:
1934             os << "MIN";
1935             break;
1936         case ReductionOperation::MAX:
1937             os << "MAX";
1938             break;
1939         default:
1940             ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
1941     }
1942 
1943     return os;
1944 }
1945 
1946 /** Formatted output of the Reduction Operations.
1947  *
1948  * @param[in] op Type to output.
1949  *
1950  * @return Formatted string.
1951  */
to_string(const ReductionOperation & op)1952 inline std::string to_string(const ReductionOperation &op)
1953 {
1954     std::stringstream str;
1955     str << op;
1956     return str.str();
1957 }
1958 
1959 /** Formatted output of the Comparison Operations.
1960  *
1961  * @param[out] os Output stream.
1962  * @param[in]  op Type to output.
1963  *
1964  * @return Modified output stream.
1965  */
1966 inline ::std::ostream &operator<<(::std::ostream &os, const ComparisonOperation &op)
1967 {
1968     switch(op)
1969     {
1970         case ComparisonOperation::Equal:
1971             os << "Equal";
1972             break;
1973         case ComparisonOperation::NotEqual:
1974             os << "NotEqual";
1975             break;
1976         case ComparisonOperation::Greater:
1977             os << "Greater";
1978             break;
1979         case ComparisonOperation::GreaterEqual:
1980             os << "GreaterEqual";
1981             break;
1982         case ComparisonOperation::Less:
1983             os << "Less";
1984             break;
1985         case ComparisonOperation::LessEqual:
1986             os << "LessEqual";
1987             break;
1988         default:
1989             ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
1990     }
1991 
1992     return os;
1993 }
1994 
1995 /** Formatted output of the Elementwise unary Operations.
1996  *
1997  * @param[out] os Output stream.
1998  * @param[in]  op Type to output.
1999  *
2000  * @return Modified output stream.
2001  */
2002 inline ::std::ostream &operator<<(::std::ostream &os, const ElementWiseUnary &op)
2003 {
2004     switch(op)
2005     {
2006         case ElementWiseUnary::RSQRT:
2007             os << "RSQRT";
2008             break;
2009         case ElementWiseUnary::EXP:
2010             os << "EXP";
2011             break;
2012         case ElementWiseUnary::NEG:
2013             os << "NEG";
2014             break;
2015         case ElementWiseUnary::LOG:
2016             os << "LOG";
2017             break;
2018         case ElementWiseUnary::SIN:
2019             os << "SIN";
2020             break;
2021         case ElementWiseUnary::ABS:
2022             os << "ABS";
2023             break;
2024         case ElementWiseUnary::ROUND:
2025             os << "ROUND";
2026             break;
2027         case ElementWiseUnary::LOGICAL_NOT:
2028             os << "LOGICAL_NOT";
2029             break;
2030         default:
2031             ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
2032     }
2033 
2034     return os;
2035 }
2036 
2037 /** Formatted output of the Comparison Operations.
2038  *
2039  * @param[in] op Type to output.
2040  *
2041  * @return Formatted string.
2042  */
to_string(const ComparisonOperation & op)2043 inline std::string to_string(const ComparisonOperation &op)
2044 {
2045     std::stringstream str;
2046     str << op;
2047     return str.str();
2048 }
2049 
2050 /** Formatted output of the Elementwise unary Operations.
2051  *
2052  * @param[in] op Type to output.
2053  *
2054  * @return Formatted string.
2055  */
to_string(const ElementWiseUnary & op)2056 inline std::string to_string(const ElementWiseUnary &op)
2057 {
2058     std::stringstream str;
2059     str << op;
2060     return str.str();
2061 }
2062 
2063 /** Formatted output of the Norm Type.
2064  *
2065  * @param[in] type Type to output.
2066  *
2067  * @return Formatted string.
2068  */
to_string(const NormType & type)2069 inline std::string to_string(const NormType &type)
2070 {
2071     std::stringstream str;
2072     str << type;
2073     return str.str();
2074 }
2075 
2076 /** Formatted output of the Pooling Type.
2077  *
2078  * @param[in] type Type to output.
2079  *
2080  * @return Formatted string.
2081  */
to_string(const PoolingType & type)2082 inline std::string to_string(const PoolingType &type)
2083 {
2084     std::stringstream str;
2085     str << type;
2086     return str.str();
2087 }
2088 
2089 /** Formatted output of the Pooling Layer Info.
2090  *
2091  * @param[in] info Type to output.
2092  *
2093  * @return Formatted string.
2094  */
to_string(const PoolingLayerInfo & info)2095 inline std::string to_string(const PoolingLayerInfo &info)
2096 {
2097     std::stringstream str;
2098     str << "{Type=" << info.pool_type << ","
2099         << "DataLayout=" << info.data_layout << ","
2100         << "IsGlobalPooling=" << info.is_global_pooling;
2101     if(!info.is_global_pooling)
2102     {
2103         str << ","
2104             << "PoolSize=" << info.pool_size.width << "," << info.pool_size.height << ","
2105             << "PadStride=" << info.pad_stride_info;
2106     }
2107     str << "}";
2108     return str.str();
2109 }
2110 
2111 /** Formatted output of the Size3D type.
2112  *
2113  * @param[out] os   Output stream
2114  * @param[in]  size Type to output
2115  *
2116  * @return Modified output stream.
2117  */
2118 inline ::std::ostream &operator<<(::std::ostream &os, const Size3D &size)
2119 {
2120     os << size.width << "x" << size.height << "x" << size.depth;
2121 
2122     return os;
2123 }
2124 
2125 /** Formatted output of the Size3D type.
2126  *
2127  * @param[in] type Type to output
2128  *
2129  * @return Formatted string.
2130  */
to_string(const Size3D & type)2131 inline std::string to_string(const Size3D &type)
2132 {
2133     std::stringstream str;
2134     str << type;
2135     return str.str();
2136 }
2137 
2138 /** Formatted output of the Padding3D type.
2139  *
2140  * @param[out] os        Output stream.
2141  * @param[in]  padding3d Padding info for 3D spatial dimension shape.
2142  *
2143  * @return Modified output stream.
2144  */
2145 inline ::std::ostream &operator<<(::std::ostream &os, const Padding3D &padding3d)
2146 {
2147     os << padding3d.left << "," << padding3d.right << ","
2148        << padding3d.top << "," << padding3d.bottom << ","
2149        << padding3d.front << "," << padding3d.back;
2150     return os;
2151 }
2152 
2153 /** Converts a @ref Padding3D to string
2154  *
2155  * @param[in] padding3d Padding3D value to be converted
2156  *
2157  * @return String representing the corresponding Padding3D
2158  */
to_string(const Padding3D & padding3d)2159 inline std::string to_string(const Padding3D &padding3d)
2160 {
2161     std::stringstream str;
2162     str << padding3d;
2163     return str.str();
2164 }
2165 
2166 /** Formatted output of the DimensionRoundingType type.
2167  *
2168  * @param[out] os            Output stream.
2169  * @param[in]  rounding_type DimensionRoundingType Dimension rounding type when down-scaling, or compute output shape of pooling(2D or 3D).
2170  *
2171  * @return Modified output stream.
2172  */
2173 inline ::std::ostream &operator<<(::std::ostream &os, const DimensionRoundingType &rounding_type)
2174 {
2175     switch(rounding_type)
2176     {
2177         case DimensionRoundingType::CEIL:
2178             os << "CEIL";
2179             break;
2180         case DimensionRoundingType::FLOOR:
2181             os << "FLOOR";
2182             break;
2183         default:
2184             ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
2185     }
2186     return os;
2187 }
2188 
2189 /** Formatted output of the Pooling 3d Layer Info.
2190  *
2191  * @param[out] os   Output stream.
2192  * @param[in]  info Pooling 3D layer info to print to output stream.
2193  *
2194  * @return Modified output stream.
2195  */
2196 inline ::std::ostream &operator<<(::std::ostream &os, const Pooling3dLayerInfo &info)
2197 {
2198     os << "{Type=" << info.pool_type << ","
2199        << "IsGlobalPooling=" << info.is_global_pooling;
2200     if(!info.is_global_pooling)
2201     {
2202         os << ","
2203            << "PoolSize=" << info.pool_size << ", "
2204            << "Stride=" << info.stride << ", "
2205            << "Padding=" << info.padding << ", "
2206            << "Exclude Padding=" << info.exclude_padding << ", "
2207            << "fp_mixed_precision=" << info.fp_mixed_precision << ", "
2208            << "DimensionRoundingType=" << info.round_type;
2209     }
2210     os << "}";
2211     return os;
2212 }
2213 
2214 /** Formatted output of the Pooling 3d Layer Info.
2215  *
2216  * @param[in] info Type to output.
2217  *
2218  * @return Formatted string.
2219  */
to_string(const Pooling3dLayerInfo & info)2220 inline std::string to_string(const Pooling3dLayerInfo &info)
2221 {
2222     std::stringstream str;
2223     str << info;
2224     return str.str();
2225 }
2226 
2227 /** Formatted output of the PriorBoxLayerInfo.
2228  *
2229  * @param[in] info Type to output.
2230  *
2231  * @return Formatted string.
2232  */
to_string(const PriorBoxLayerInfo & info)2233 inline std::string to_string(const PriorBoxLayerInfo &info)
2234 {
2235     std::stringstream str;
2236     str << "{";
2237     str << "Clip:" << info.clip()
2238         << "Flip:" << info.flip()
2239         << "StepX:" << info.steps()[0]
2240         << "StepY:" << info.steps()[1]
2241         << "MinSizes:" << info.min_sizes().size()
2242         << "MaxSizes:" << info.max_sizes().size()
2243         << "ImgSizeX:" << info.img_size().x
2244         << "ImgSizeY:" << info.img_size().y
2245         << "Offset:" << info.offset()
2246         << "Variances:" << info.variances().size();
2247     str << "}";
2248     return str.str();
2249 }
2250 
2251 /** Formatted output of the Size2D type.
2252  *
2253  * @param[out] os   Output stream
2254  * @param[in]  size Type to output
2255  *
2256  * @return Modified output stream.
2257  */
2258 inline ::std::ostream &operator<<(::std::ostream &os, const Size2D &size)
2259 {
2260     os << size.width << "x" << size.height;
2261 
2262     return os;
2263 }
2264 
2265 /** Formatted output of the Size2D type.
2266  *
2267  * @param[in] type Type to output
2268  *
2269  * @return Formatted string.
2270  */
to_string(const Size2D & type)2271 inline std::string to_string(const Size2D &type)
2272 {
2273     std::stringstream str;
2274     str << type;
2275     return str.str();
2276 }
2277 
2278 /** Formatted output of the ConvolutionMethod type.
2279  *
2280  * @param[out] os          Output stream
2281  * @param[in]  conv_method Type to output
2282  *
2283  * @return Modified output stream.
2284  */
2285 inline ::std::ostream &operator<<(::std::ostream &os, const ConvolutionMethod &conv_method)
2286 {
2287     switch(conv_method)
2288     {
2289         case ConvolutionMethod::GEMM:
2290             os << "GEMM";
2291             break;
2292         case ConvolutionMethod::DIRECT:
2293             os << "DIRECT";
2294             break;
2295         case ConvolutionMethod::WINOGRAD:
2296             os << "WINOGRAD";
2297             break;
2298         case ConvolutionMethod::FFT:
2299             os << "FFT";
2300             break;
2301         case ConvolutionMethod::GEMM_CONV2D:
2302             os << "GEMM_CONV2D";
2303             break;
2304         default:
2305             ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
2306     }
2307 
2308     return os;
2309 }
2310 
2311 /** Formatted output of the ConvolutionMethod type.
2312  *
2313  * @param[in] conv_method Type to output
2314  *
2315  * @return Formatted string.
2316  */
to_string(const ConvolutionMethod & conv_method)2317 inline std::string to_string(const ConvolutionMethod &conv_method)
2318 {
2319     std::stringstream str;
2320     str << conv_method;
2321     return str.str();
2322 }
2323 
2324 /** Formatted output of the GPUTarget type.
2325  *
2326  * @param[out] os         Output stream
2327  * @param[in]  gpu_target Type to output
2328  *
2329  * @return Modified output stream.
2330  */
2331 inline ::std::ostream &operator<<(::std::ostream &os, const GPUTarget &gpu_target)
2332 {
2333     switch(gpu_target)
2334     {
2335         case GPUTarget::GPU_ARCH_MASK:
2336             os << "GPU_ARCH_MASK";
2337             break;
2338         case GPUTarget::GPU_GENERATION_MASK:
2339             os << "GPU_GENERATION_MASK";
2340             break;
2341         case GPUTarget::MIDGARD:
2342             os << "MIDGARD";
2343             break;
2344         case GPUTarget::BIFROST:
2345             os << "BIFROST";
2346             break;
2347         case GPUTarget::VALHALL:
2348             os << "VALHALL";
2349             break;
2350         case GPUTarget::T600:
2351             os << "T600";
2352             break;
2353         case GPUTarget::T700:
2354             os << "T700";
2355             break;
2356         case GPUTarget::T800:
2357             os << "T800";
2358             break;
2359         case GPUTarget::G71:
2360             os << "G71";
2361             break;
2362         case GPUTarget::G72:
2363             os << "G72";
2364             break;
2365         case GPUTarget::G51:
2366             os << "G51";
2367             break;
2368         case GPUTarget::G51BIG:
2369             os << "G51BIG";
2370             break;
2371         case GPUTarget::G51LIT:
2372             os << "G51LIT";
2373             break;
2374         case GPUTarget::G31:
2375             os << "G31";
2376             break;
2377         case GPUTarget::G76:
2378             os << "G76";
2379             break;
2380         case GPUTarget::G52:
2381             os << "G52";
2382             break;
2383         case GPUTarget::G52LIT:
2384             os << "G52LIT";
2385             break;
2386         case GPUTarget::G77:
2387             os << "G77";
2388             break;
2389         case GPUTarget::G57:
2390             os << "G57";
2391             break;
2392         case GPUTarget::G78:
2393             os << "G78";
2394             break;
2395         case GPUTarget::G68:
2396             os << "G68";
2397             break;
2398         case GPUTarget::G78AE:
2399             os << "G78AE";
2400             break;
2401         case GPUTarget::G710:
2402             os << "G710";
2403             break;
2404         case GPUTarget::G610:
2405             os << "G610";
2406             break;
2407         case GPUTarget::G510:
2408             os << "G510";
2409             break;
2410         case GPUTarget::G310:
2411             os << "G310";
2412             break;
2413         case GPUTarget::G715:
2414             os << "G715";
2415             break;
2416         case GPUTarget::G615:
2417             os << "G615";
2418             break;
2419         default:
2420             ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
2421     }
2422 
2423     return os;
2424 }
2425 
2426 /** Formatted output of the GPUTarget type.
2427  *
2428  * @param[in] gpu_target Type to output
2429  *
2430  * @return Formatted string.
2431  */
to_string(const GPUTarget & gpu_target)2432 inline std::string to_string(const GPUTarget &gpu_target)
2433 {
2434     std::stringstream str;
2435     str << gpu_target;
2436     return str.str();
2437 }
2438 
2439 /** Formatted output of the DetectionWindow type.
2440  *
2441  * @param[out] os               Output stream
2442  * @param[in]  detection_window Type to output
2443  *
2444  * @return Modified output stream.
2445  */
2446 inline ::std::ostream &operator<<(::std::ostream &os, const DetectionWindow &detection_window)
2447 {
2448     os << "{x=" << detection_window.x << ","
2449        << "y=" << detection_window.y << ","
2450        << "width=" << detection_window.width << ","
2451        << "height=" << detection_window.height << ","
2452        << "idx_class=" << detection_window.idx_class << ","
2453        << "score=" << detection_window.score << "}";
2454 
2455     return os;
2456 }
2457 
2458 /** Formatted output of the DetectionOutputLayerCodeType type.
2459  *
2460  * @param[out] os             Output stream
2461  * @param[in]  detection_code Type to output
2462  *
2463  * @return Modified output stream.
2464  */
2465 inline ::std::ostream &operator<<(::std::ostream &os, const DetectionOutputLayerCodeType &detection_code)
2466 {
2467     switch(detection_code)
2468     {
2469         case DetectionOutputLayerCodeType::CENTER_SIZE:
2470             os << "CENTER_SIZE";
2471             break;
2472         case DetectionOutputLayerCodeType::CORNER:
2473             os << "CORNER";
2474             break;
2475         case DetectionOutputLayerCodeType::CORNER_SIZE:
2476             os << "CORNER_SIZE";
2477             break;
2478         case DetectionOutputLayerCodeType::TF_CENTER:
2479             os << "TF_CENTER";
2480             break;
2481         default:
2482             ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
2483     }
2484 
2485     return os;
2486 }
2487 /** Formatted output of the DetectionOutputLayerCodeType type.
2488  *
2489  * @param[in] detection_code Type to output
2490  *
2491  * @return Formatted string.
2492  */
to_string(const DetectionOutputLayerCodeType & detection_code)2493 inline std::string to_string(const DetectionOutputLayerCodeType &detection_code)
2494 {
2495     std::stringstream str;
2496     str << detection_code;
2497     return str.str();
2498 }
2499 
2500 /** Formatted output of the DetectionOutputLayerInfo type.
2501  *
2502  * @param[out] os             Output stream
2503  * @param[in]  detection_info Type to output
2504  *
2505  * @return Modified output stream.
2506  */
2507 inline ::std::ostream &operator<<(::std::ostream &os, const DetectionOutputLayerInfo &detection_info)
2508 {
2509     os << "{Classes=" << detection_info.num_classes() << ","
2510        << "ShareLocation=" << detection_info.share_location() << ","
2511        << "CodeType=" << detection_info.code_type() << ","
2512        << "VarianceEncodedInTarget=" << detection_info.variance_encoded_in_target() << ","
2513        << "KeepTopK=" << detection_info.keep_top_k() << ","
2514        << "NMSThreshold=" << detection_info.nms_threshold() << ","
2515        << "Eta=" << detection_info.eta() << ","
2516        << "BackgroundLabelId=" << detection_info.background_label_id() << ","
2517        << "ConfidenceThreshold=" << detection_info.confidence_threshold() << ","
2518        << "TopK=" << detection_info.top_k() << ","
2519        << "NumLocClasses=" << detection_info.num_loc_classes()
2520        << "}";
2521 
2522     return os;
2523 }
2524 
2525 /** Formatted output of the DetectionOutputLayerInfo type.
2526  *
2527  * @param[in] detection_info Type to output
2528  *
2529  * @return Formatted string.
2530  */
to_string(const DetectionOutputLayerInfo & detection_info)2531 inline std::string to_string(const DetectionOutputLayerInfo &detection_info)
2532 {
2533     std::stringstream str;
2534     str << detection_info;
2535     return str.str();
2536 }
2537 /** Formatted output of the DetectionPostProcessLayerInfo type.
2538  *
2539  * @param[out] os             Output stream
2540  * @param[in]  detection_info Type to output
2541  *
2542  * @return Modified output stream.
2543  */
2544 inline ::std::ostream &operator<<(::std::ostream &os, const DetectionPostProcessLayerInfo &detection_info)
2545 {
2546     os << "{MaxDetections=" << detection_info.max_detections() << ","
2547        << "MaxClassesPerDetection=" << detection_info.max_classes_per_detection() << ","
2548        << "NmsScoreThreshold=" << detection_info.nms_score_threshold() << ","
2549        << "NmsIouThreshold=" << detection_info.iou_threshold() << ","
2550        << "NumClasses=" << detection_info.num_classes() << ","
2551        << "ScaleValue_y=" << detection_info.scale_value_y() << ","
2552        << "ScaleValue_x=" << detection_info.scale_value_x() << ","
2553        << "ScaleValue_h=" << detection_info.scale_value_h() << ","
2554        << "ScaleValue_w=" << detection_info.scale_value_w() << ","
2555        << "UseRegularNms=" << detection_info.use_regular_nms() << ","
2556        << "DetectionPerClass=" << detection_info.detection_per_class()
2557        << "}";
2558 
2559     return os;
2560 }
2561 
2562 /** Formatted output of the DetectionPostProcessLayerInfo type.
2563  *
2564  * @param[in] detection_info Type to output
2565  *
2566  * @return Formatted string.
2567  */
to_string(const DetectionPostProcessLayerInfo & detection_info)2568 inline std::string to_string(const DetectionPostProcessLayerInfo &detection_info)
2569 {
2570     std::stringstream str;
2571     str << detection_info;
2572     return str.str();
2573 }
2574 
2575 /** Formatted output of the DetectionWindow type.
2576  *
2577  * @param[in] detection_window Type to output
2578  *
2579  * @return Formatted string.
2580  */
to_string(const DetectionWindow & detection_window)2581 inline std::string to_string(const DetectionWindow &detection_window)
2582 {
2583     std::stringstream str;
2584     str << detection_window;
2585     return str.str();
2586 }
2587 
2588 /** Formatted output of @ref PriorBoxLayerInfo.
2589  *
2590  * @param[out] os   Output stream.
2591  * @param[in]  info Type to output.
2592  *
2593  * @return Modified output stream.
2594  */
2595 inline ::std::ostream &operator<<(::std::ostream &os, const PriorBoxLayerInfo &info)
2596 {
2597     os << "Clip:" << info.clip()
2598        << "Flip:" << info.flip()
2599        << "StepX:" << info.steps()[0]
2600        << "StepY:" << info.steps()[1]
2601        << "MinSizes:" << info.min_sizes()
2602        << "MaxSizes:" << info.max_sizes()
2603        << "ImgSizeX:" << info.img_size().x
2604        << "ImgSizeY:" << info.img_size().y
2605        << "Offset:" << info.offset()
2606        << "Variances:" << info.variances();
2607 
2608     return os;
2609 }
2610 
2611 /** Formatted output of the WinogradInfo type. */
2612 inline ::std::ostream &operator<<(::std::ostream &os, const WinogradInfo &info)
2613 {
2614     os << "{OutputTileSize=" << info.output_tile_size << ","
2615        << "KernelSize=" << info.kernel_size << ","
2616        << "PadStride=" << info.convolution_info << ","
2617        << "OutputDataLayout=" << info.output_data_layout << "}";
2618 
2619     return os;
2620 }
2621 
to_string(const WinogradInfo & type)2622 inline std::string to_string(const WinogradInfo &type)
2623 {
2624     std::stringstream str;
2625     str << type;
2626     return str.str();
2627 }
2628 
2629 /** Convert a CLTunerMode value to a string
2630  *
2631  * @param val CLTunerMode value to be converted
2632  *
2633  * @return String representing the corresponding CLTunerMode.
2634  */
to_string(const CLTunerMode val)2635 inline std::string to_string(const CLTunerMode val)
2636 {
2637     switch(val)
2638     {
2639         case CLTunerMode::EXHAUSTIVE:
2640         {
2641             return std::string("Exhaustive");
2642         }
2643         case CLTunerMode::NORMAL:
2644         {
2645             return std::string("Normal");
2646         }
2647         case CLTunerMode::RAPID:
2648         {
2649             return std::string("Rapid");
2650         }
2651         default:
2652         {
2653             ARM_COMPUTE_ERROR("Invalid tuner mode.");
2654             return std::string("UNDEFINED");
2655         }
2656     }
2657 }
2658 /** Converts a @ref CLGEMMKernelType to string
2659  *
2660  * @param[in] val CLGEMMKernelType value to be converted
2661  *
2662  * @return String representing the corresponding CLGEMMKernelType
2663  */
to_string(CLGEMMKernelType val)2664 inline std::string to_string(CLGEMMKernelType val)
2665 {
2666     switch(val)
2667     {
2668         case CLGEMMKernelType::NATIVE:
2669         {
2670             return "Native";
2671         }
2672         case CLGEMMKernelType::RESHAPED_ONLY_RHS:
2673         {
2674             return "Reshaped_Only_RHS";
2675         }
2676         case CLGEMMKernelType::RESHAPED:
2677         {
2678             return "Reshaped";
2679         }
2680         default:
2681         {
2682             return "Unknown";
2683         }
2684     }
2685 }
2686 /** [Print CLTunerMode type] **/
2687 /** Formatted output of the CLTunerMode type.
2688  *
2689  * @param[out] os  Output stream.
2690  * @param[in]  val CLTunerMode to output.
2691  *
2692  * @return Modified output stream.
2693  */
2694 inline ::std::ostream &operator<<(::std::ostream &os, const CLTunerMode &val)
2695 {
2696     os << to_string(val);
2697     return os;
2698 }
2699 
2700 /** Formatted output of the ConvolutionInfo type.
2701  *
2702  * @param[out] os        Output stream.
2703  * @param[in]  conv_info ConvolutionInfo to output.
2704  *
2705  * @return Modified output stream.
2706  */
2707 inline ::std::ostream &operator<<(::std::ostream &os, const ConvolutionInfo &conv_info)
2708 {
2709     os << "{PadStrideInfo=" << conv_info.pad_stride_info << ", "
2710        << "depth_multiplier=" << conv_info.depth_multiplier << ", "
2711        << "act_info=" << to_string(conv_info.act_info) << ", "
2712        << "dilation=" << conv_info.dilation << "}";
2713     return os;
2714 }
2715 
2716 /** Converts a @ref ConvolutionInfo to string
2717  *
2718  * @param[in] info ConvolutionInfo value to be converted
2719  *
2720  * @return String  representing the corresponding ConvolutionInfo
2721  */
to_string(const ConvolutionInfo & info)2722 inline std::string to_string(const ConvolutionInfo &info)
2723 {
2724     std::stringstream str;
2725     str << info;
2726     return str.str();
2727 }
2728 
2729 /** Formatted output of the FullyConnectedLayerInfo type.
2730  *
2731  * @param[out] os         Output stream.
2732  * @param[in]  layer_info FullyConnectedLayerInfo to output.
2733  *
2734  * @return Modified output stream.
2735  */
2736 inline ::std::ostream &operator<<(::std::ostream &os, const FullyConnectedLayerInfo &layer_info)
2737 {
2738     os << "{activation_info=" << to_string(layer_info.activation_info) << ", "
2739        << "weights_trained_layout=" << layer_info.weights_trained_layout << ", "
2740        << "transpose_weights=" << layer_info.transpose_weights << ", "
2741        << "are_weights_reshaped=" << layer_info.are_weights_reshaped << ", "
2742        << "retain_internal_weights=" << layer_info.retain_internal_weights << ", "
2743        << "constant_weights=" << layer_info.transpose_weights << ", "
2744        << "fp_mixed_precision=" << layer_info.fp_mixed_precision << "}";
2745     return os;
2746 }
2747 
2748 /** Converts a @ref FullyConnectedLayerInfo to string
2749  *
2750  * @param[in] info FullyConnectedLayerInfo value to be converted
2751  *
2752  * @return String  representing the corresponding FullyConnectedLayerInfo
2753  */
to_string(const FullyConnectedLayerInfo & info)2754 inline std::string to_string(const FullyConnectedLayerInfo &info)
2755 {
2756     std::stringstream str;
2757     str << info;
2758     return str.str();
2759 }
2760 
2761 /** Formatted output of the GEMMLowpOutputStageType type.
2762  *
2763  * @param[out] os        Output stream.
2764  * @param[in]  gemm_type GEMMLowpOutputStageType to output.
2765  *
2766  * @return Modified output stream.
2767  */
2768 inline ::std::ostream &operator<<(::std::ostream &os, const GEMMLowpOutputStageType &gemm_type)
2769 {
2770     switch(gemm_type)
2771     {
2772         case GEMMLowpOutputStageType::NONE:
2773             os << "NONE";
2774             break;
2775         case GEMMLowpOutputStageType::QUANTIZE_DOWN:
2776             os << "QUANTIZE_DOWN";
2777             break;
2778         case GEMMLowpOutputStageType::QUANTIZE_DOWN_FIXEDPOINT:
2779             os << "QUANTIZE_DOWN_FIXEDPOINT";
2780             break;
2781         case GEMMLowpOutputStageType::QUANTIZE_DOWN_FLOAT:
2782             os << "QUANTIZE_DOWN_FLOAT";
2783             break;
2784         default:
2785             ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
2786     }
2787     return os;
2788 }
2789 
2790 /** Converts a @ref GEMMLowpOutputStageType to string
2791  *
2792  * @param[in] gemm_type GEMMLowpOutputStageType value to be converted
2793  *
2794  * @return String       representing the corresponding GEMMLowpOutputStageType
2795  */
to_string(const GEMMLowpOutputStageType & gemm_type)2796 inline std::string to_string(const GEMMLowpOutputStageType &gemm_type)
2797 {
2798     std::stringstream str;
2799     str << gemm_type;
2800     return str.str();
2801 }
2802 
2803 /** Formatted output of the GEMMLowpOutputStageInfo type.
2804  *
2805  * @param[out] os        Output stream.
2806  * @param[in]  gemm_info GEMMLowpOutputStageInfo to output.
2807  *
2808  * @return Modified output stream.
2809  */
2810 inline ::std::ostream &operator<<(::std::ostream &os, const GEMMLowpOutputStageInfo &gemm_info)
2811 {
2812     os << "{type=" << gemm_info.type << ", "
2813        << "gemlowp_offset=" << gemm_info.gemmlowp_offset << ", "
2814        << "gemmlowp_multiplier=" << gemm_info.gemmlowp_multiplier << ", "
2815        << "gemmlowp_shift=" << gemm_info.gemmlowp_shift << ", "
2816        << "gemmlowp_min_bound=" << gemm_info.gemmlowp_min_bound << ", "
2817        << "gemmlowp_max_bound=" << gemm_info.gemmlowp_max_bound << ", "
2818        << "gemmlowp_multipliers=" << gemm_info.gemmlowp_multiplier << ", "
2819        << "gemmlowp_shifts=" << gemm_info.gemmlowp_shift << ", "
2820        << "gemmlowp_real_multiplier=" << gemm_info.gemmlowp_real_multiplier << ", "
2821        << "is_quantized_per_channel=" << gemm_info.is_quantized_per_channel << ", "
2822        << "output_data_type=" << gemm_info.output_data_type << "}";
2823     return os;
2824 }
2825 
2826 /** Converts a @ref GEMMLowpOutputStageInfo to string
2827  *
2828  * @param[in] gemm_info GEMMLowpOutputStageInfo value to be converted
2829  *
2830  * @return String representing the corresponding GEMMLowpOutputStageInfo
2831  */
to_string(const GEMMLowpOutputStageInfo & gemm_info)2832 inline std::string to_string(const GEMMLowpOutputStageInfo &gemm_info)
2833 {
2834     std::stringstream str;
2835     str << gemm_info;
2836     return str.str();
2837 }
2838 
2839 /** Formatted output of the Conv2dInfo type.
2840  *
2841  * @param[out] os        Output stream.
2842  * @param[in]  conv_info Conv2dInfo to output.
2843  *
2844  * @return Modified output stream.
2845  */
2846 inline ::std::ostream &operator<<(::std::ostream &os, const Conv2dInfo &conv_info)
2847 {
2848     os << "{conv_info=" << conv_info.conv_info << ", "
2849        << "dilation=" << conv_info.dilation << ", "
2850        << "act_info=" << to_string(conv_info.act_info) << ", "
2851        << "enable_fast_math=" << conv_info.enable_fast_math << ", "
2852        << "num_groups=" << conv_info.num_groups << ","
2853        << "post_ops=" << conv_info.post_ops << "}";
2854     return os;
2855 }
2856 
2857 /** Converts a @ref Conv2dInfo to string
2858  *
2859  * @param[in] conv_info Conv2dInfo value to be converted
2860  *
2861  * @return String  representing the corresponding Conv2dInfo
2862  */
to_string(const Conv2dInfo & conv_info)2863 inline std::string to_string(const Conv2dInfo &conv_info)
2864 {
2865     std::stringstream str;
2866     str << conv_info;
2867     return str.str();
2868 }
2869 
2870 /** Formatted output of the PixelValue type.
2871  *
2872  * @param[out] os          Output stream.
2873  * @param[in]  pixel_value PixelValue to output.
2874  *
2875  * @return Modified output stream.
2876  */
2877 inline ::std::ostream &operator<<(::std::ostream &os, const PixelValue &pixel_value)
2878 {
2879     os << "{value.u64=" << pixel_value.get<uint64_t>() << "}";
2880     return os;
2881 }
2882 
2883 /** Converts a @ref PixelValue to string
2884  *
2885  * @param[in] pixel_value PixelValue value to be converted
2886  *
2887  * @return String representing the corresponding PixelValue
2888  */
to_string(const PixelValue & pixel_value)2889 inline std::string to_string(const PixelValue &pixel_value)
2890 {
2891     std::stringstream str;
2892     str << pixel_value;
2893     return str.str();
2894 }
2895 
2896 /** Formatted output of the ScaleKernelInfo type.
2897  *
2898  * @param[out] os         Output stream.
2899  * @param[in]  scale_info ScaleKernelInfo to output.
2900  *
2901  * @return Modified output stream.
2902  */
2903 inline ::std::ostream &operator<<(::std::ostream &os, const ScaleKernelInfo &scale_info)
2904 {
2905     os << "{interpolation_policy=" << scale_info.interpolation_policy << ", "
2906        << "BorderMode=" << scale_info.border_mode << ", "
2907        << "PixelValue=" << scale_info.constant_border_value << ", "
2908        << "SamplingPolicy=" << scale_info.sampling_policy << ", "
2909        << "use_padding=" << scale_info.use_padding << ", "
2910        << "align_corners=" << scale_info.align_corners << ", "
2911        << "data_layout=" << scale_info.data_layout << "}";
2912     return os;
2913 }
2914 
2915 /** Converts a @ref ScaleKernelInfo to string
2916  *
2917  * @param[in] scale_info ScaleKernelInfo value to be converted
2918  *
2919  * @return String representing the corresponding ScaleKernelInfo
2920  */
to_string(const ScaleKernelInfo & scale_info)2921 inline std::string to_string(const ScaleKernelInfo &scale_info)
2922 {
2923     std::stringstream str;
2924     str << scale_info;
2925     return str.str();
2926 }
2927 
2928 /** Formatted output of the FFTDirection type.
2929  *
2930  * @param[out] os      Output stream.
2931  * @param[in]  fft_dir FFTDirection to output.
2932  *
2933  * @return Modified output stream.
2934  */
2935 inline ::std::ostream &operator<<(::std::ostream &os, const FFTDirection &fft_dir)
2936 {
2937     switch(fft_dir)
2938     {
2939         case FFTDirection::Forward:
2940             os << "Forward";
2941             break;
2942         case FFTDirection::Inverse:
2943             os << "Inverse";
2944             break;
2945         default:
2946             ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
2947     }
2948     return os;
2949 }
2950 
2951 /** Converts a @ref FFT1DInfo to string
2952  *
2953  * @param[in] fft_dir FFT1DInfo value to be converted
2954  *
2955  * @return String representing the corresponding FFT1DInfo
2956  */
to_string(const FFTDirection & fft_dir)2957 inline std::string to_string(const FFTDirection &fft_dir)
2958 {
2959     std::stringstream str;
2960     str << "{" << fft_dir << "}";
2961     return str.str();
2962 }
2963 
2964 /** Formatted output of the FFT1DInfo type.
2965  *
2966  * @param[out] os         Output stream.
2967  * @param[in]  fft1d_info FFT1DInfo to output.
2968  *
2969  * @return Modified output stream.
2970  */
2971 inline ::std::ostream &operator<<(::std::ostream &os, const FFT1DInfo &fft1d_info)
2972 {
2973     os << "{axis=" << fft1d_info.axis << ", "
2974        << "direction=" << fft1d_info.direction << "}";
2975     return os;
2976 }
2977 
2978 /** Converts a @ref FFT1DInfo to string
2979  *
2980  * @param[in] fft1d_info FFT1DInfo value to be converted
2981  *
2982  * @return String representing the corresponding FFT1DInfo
2983  */
to_string(const FFT1DInfo & fft1d_info)2984 inline std::string to_string(const FFT1DInfo &fft1d_info)
2985 {
2986     std::stringstream str;
2987     str << fft1d_info;
2988     return str.str();
2989 }
2990 
2991 /** Formatted output of the FFT2DInfo type.
2992  *
2993  * @param[out] os         Output stream.
2994  * @param[in]  fft2d_info FFT2DInfo to output.
2995  *
2996  * @return Modified output stream.
2997  */
2998 inline ::std::ostream &operator<<(::std::ostream &os, const FFT2DInfo &fft2d_info)
2999 {
3000     os << "{axis=" << fft2d_info.axis0 << ", "
3001        << "axis=" << fft2d_info.axis1 << ", "
3002        << "direction=" << fft2d_info.direction << "}";
3003     return os;
3004 }
3005 
3006 /** Converts a @ref FFT2DInfo to string
3007  *
3008  * @param[in] fft2d_info FFT2DInfo value to be converted
3009  *
3010  * @return String representing the corresponding FFT2DInfo
3011  */
to_string(const FFT2DInfo & fft2d_info)3012 inline std::string to_string(const FFT2DInfo &fft2d_info)
3013 {
3014     std::stringstream str;
3015     str << fft2d_info;
3016     return str.str();
3017 }
3018 
3019 /** Formatted output of the Coordinates2D type.
3020  *
3021  * @param[out] os       Output stream.
3022  * @param[in]  coord_2d Coordinates2D to output.
3023  *
3024  * @return Modified output stream.
3025  */
3026 inline ::std::ostream &operator<<(::std::ostream &os, const Coordinates2D &coord_2d)
3027 {
3028     os << "{x=" << coord_2d.x << ", "
3029        << "y=" << coord_2d.y << "}";
3030     return os;
3031 }
3032 
3033 /** Converts a @ref Coordinates2D to string
3034  *
3035  * @param[in] coord_2d Coordinates2D value to be converted
3036  *
3037  * @return String representing the corresponding Coordinates2D
3038  */
to_string(const Coordinates2D & coord_2d)3039 inline std::string to_string(const Coordinates2D &coord_2d)
3040 {
3041     std::stringstream str;
3042     str << coord_2d;
3043     return str.str();
3044 }
3045 
3046 /** Formatted output of the FuseBatchNormalizationType type.
3047  *
3048  * @param[out] os        Output stream.
3049  * @param[in]  fuse_type FuseBatchNormalizationType to output.
3050  *
3051  * @return Modified output stream.
3052  */
3053 inline ::std::ostream &operator<<(::std::ostream &os, const FuseBatchNormalizationType &fuse_type)
3054 {
3055     switch(fuse_type)
3056     {
3057         case FuseBatchNormalizationType::CONVOLUTION:
3058             os << "CONVOLUTION";
3059             break;
3060         case FuseBatchNormalizationType::DEPTHWISECONVOLUTION:
3061             os << "DEPTHWISECONVOLUTION";
3062             break;
3063         default:
3064             ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
3065     }
3066     return os;
3067 }
3068 
3069 /** Converts a @ref FuseBatchNormalizationType to string
3070  *
3071  * @param[in] fuse_type FuseBatchNormalizationType value to be converted
3072  *
3073  * @return String representing the corresponding FuseBatchNormalizationType
3074  */
to_string(const FuseBatchNormalizationType & fuse_type)3075 inline std::string to_string(const FuseBatchNormalizationType &fuse_type)
3076 {
3077     std::stringstream str;
3078     str << fuse_type;
3079     return str.str();
3080 }
3081 
3082 /** Formatted output of the SoftmaxKernelInfo type.
3083  *
3084  * @param[out] os   Output stream.
3085  * @param[in]  info SoftmaxKernelInfo to output.
3086  *
3087  * @return Modified output stream.
3088  */
3089 inline ::std::ostream &operator<<(::std::ostream &os, const SoftmaxKernelInfo &info)
3090 {
3091     os << "{beta=" << info.beta << ", "
3092        << "is_log=" << info.is_log << ", "
3093        << "input_data_type=" << info.input_data_type << ", "
3094        << "axis=" << info.axis << "}";
3095     return os;
3096 }
3097 
3098 /** Converts a @ref SoftmaxKernelInfo to string
3099  *
3100  * @param[in] info SoftmaxKernelInfo value to be converted
3101  *
3102  * @return String representing the corresponding SoftmaxKernelInfo
3103  */
to_string(const SoftmaxKernelInfo & info)3104 inline std::string to_string(const SoftmaxKernelInfo &info)
3105 {
3106     std::stringstream str;
3107     str << info;
3108     return str.str();
3109 }
3110 
3111 /** Formatted output of the ScaleKernelInfo type.
3112  *
3113  * @param[out] os          Output stream.
3114  * @param[in]  lstm_params LSTMParams to output.
3115  *
3116  * @return Modified output stream.
3117  */
3118 template <typename T>
3119 ::std::ostream &operator<<(::std::ostream &os, const LSTMParams<T> &lstm_params)
3120 {
3121     os << "{input_to_input_weights=" << to_string(lstm_params.input_to_input_weights()) << ", "
3122        << "recurrent_to_input_weights=" << to_string(lstm_params.recurrent_to_input_weights()) << ", "
3123        << "cell_to_input_weights=" << to_string(lstm_params.cell_to_input_weights()) << ", "
3124        << "input_gate_bias=" << to_string(lstm_params.input_gate_bias()) << ", "
3125        << "cell_to_forget_weights=" << to_string(lstm_params.cell_to_forget_weights()) << ", "
3126        << "cell_to_output_weights=" << to_string(lstm_params.cell_to_output_weights()) << ", "
3127        << "projection_weights=" << to_string(lstm_params.projection_weights()) << ", "
3128        << "projection_bias=" << to_string(lstm_params.projection_bias()) << ", "
3129        << "input_layer_norm_weights=" << to_string(lstm_params.input_layer_norm_weights()) << ", "
3130        << "forget_layer_norm_weights=" << to_string(lstm_params.forget_layer_norm_weights()) << ", "
3131        << "cell_layer_norm_weights=" << to_string(lstm_params.cell_layer_norm_weights()) << ", "
3132        << "output_layer_norm_weights=" << to_string(lstm_params.output_layer_norm_weights()) << ", "
3133        << "cell_clip=" << lstm_params.cell_clip() << ", "
3134        << "projection_clip=" << lstm_params.projection_clip() << ", "
3135        << "input_intermediate_scale=" << lstm_params.input_intermediate_scale() << ", "
3136        << "forget_intermediate_scale=" << lstm_params.forget_intermediate_scale() << ", "
3137        << "cell_intermediate_scale=" << lstm_params.cell_intermediate_scale() << ", "
3138        << "hidden_state_zero=" << lstm_params.hidden_state_zero() << ", "
3139        << "hidden_state_scale=" << lstm_params.hidden_state_scale() << ", "
3140        << "has_peephole_opt=" << lstm_params.has_peephole_opt() << ", "
3141        << "has_projection=" << lstm_params.has_projection() << ", "
3142        << "has_cifg_opt=" << lstm_params.has_cifg_opt() << ", "
3143        << "use_layer_norm=" << lstm_params.use_layer_norm() << "}";
3144     return os;
3145 }
3146 
3147 /** Converts a @ref LSTMParams to string
3148  *
3149  * @param[in] lstm_params LSTMParams<T> value to be converted
3150  *
3151  * @return String representing the corresponding LSTMParams
3152  */
3153 template <typename T>
to_string(const LSTMParams<T> & lstm_params)3154 std::string to_string(const LSTMParams<T> &lstm_params)
3155 {
3156     std::stringstream str;
3157     str << lstm_params;
3158     return str.str();
3159 }
3160 
3161 /** Converts a @ref LSTMParams to string
3162  *
3163  * @param[in] num uint8_t value to be converted
3164  *
3165  * @return String representing the corresponding uint8_t
3166  */
to_string(const uint8_t num)3167 inline std::string to_string(const uint8_t num)
3168 {
3169     // Explicity cast the uint8_t to signed integer and call the corresponding overloaded to_string() function.
3170     return ::std::to_string(static_cast<int>(num));
3171 }
3172 
3173 /** Available non maxima suppression types */
3174 /** Formatted output of the NMSType type.
3175  *
3176  * @param[out] os       Output stream.
3177  * @param[in]  nms_type NMSType to output.
3178  *
3179  * @return Modified output stream.
3180  */
3181 inline ::std::ostream &operator<<(::std::ostream &os, const NMSType &nms_type)
3182 {
3183     switch(nms_type)
3184     {
3185         case NMSType::LINEAR:
3186             os << "LINEAR";
3187             break;
3188         case NMSType::GAUSSIAN:
3189             os << "GAUSSIAN";
3190             break;
3191         case NMSType::ORIGINAL:
3192             os << "ORIGINAL";
3193             break;
3194         default:
3195             ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
3196     }
3197     return os;
3198 }
3199 
3200 /** Converts a @ref NMSType to string
3201  *
3202  * @param[in] nms_type NMSType value to be converted
3203  *
3204  * @return String representing the corresponding NMSType
3205  */
to_string(const NMSType nms_type)3206 inline std::string to_string(const NMSType nms_type)
3207 {
3208     std::stringstream str;
3209     str << nms_type;
3210     return str.str();
3211 }
3212 
3213 /** Formatted output of the BoxNMSLimitInfo type.
3214  *
3215  * @param[out] os   Output stream.
3216  * @param[in]  info BoxNMSLimitInfo to output.
3217  *
3218  * @return Modified output stream.
3219  */
3220 inline ::std::ostream &operator<<(::std::ostream &os, const BoxNMSLimitInfo &info)
3221 {
3222     os << "{score_thresh=" << info.score_thresh() << ", "
3223        << "nms=" << info.nms() << ", "
3224        << "detections_per_im=" << info.detections_per_im() << ", "
3225        << "soft_nms_enabled=" << info.soft_nms_enabled() << ", "
3226        << "soft_nms_min_score_thres=" << info.soft_nms_min_score_thres() << ", "
3227        << "suppress_size=" << info.suppress_size() << ", "
3228        << "min_size=" << info.min_size() << ", "
3229        << "im_width=" << info.im_width() << ", "
3230        << "im_height=" << info.im_height() << "}";
3231     return os;
3232 }
3233 
3234 /** Converts a @ref BoxNMSLimitInfo to string
3235  *
3236  * @param[in] info BoxNMSLimitInfo value to be converted
3237  *
3238  * @return String representing the corresponding BoxNMSLimitInfo
3239  */
to_string(const BoxNMSLimitInfo & info)3240 inline std::string to_string(const BoxNMSLimitInfo &info)
3241 {
3242     std::stringstream str;
3243     str << info;
3244     return str.str();
3245 }
3246 
3247 /** Converts a @ref DimensionRoundingType to string
3248  *
3249  * @param[in] rounding_type DimensionRoundingType value to be converted
3250  *
3251  * @return String representing the corresponding DimensionRoundingType
3252  */
to_string(const DimensionRoundingType & rounding_type)3253 inline std::string to_string(const DimensionRoundingType &rounding_type)
3254 {
3255     std::stringstream str;
3256     str << rounding_type;
3257     return str.str();
3258 }
3259 
3260 /** Formatted output of the Conv3dInfo type.
3261  *
3262  * @param[out] os          Output stream.
3263  * @param[in]  conv3d_info Type to output.
3264  *
3265  * @return Modified output stream.
3266  */
3267 inline ::std::ostream &operator<<(::std::ostream &os, const Conv3dInfo &conv3d_info)
3268 {
3269     os << conv3d_info.stride;
3270     os << ";";
3271     os << conv3d_info.padding;
3272     os << ";";
3273     os << to_string(conv3d_info.act_info);
3274     os << ";";
3275     os << conv3d_info.dilation;
3276     os << ";";
3277     os << conv3d_info.round_type;
3278     os << ";";
3279     os << conv3d_info.enable_fast_math;
3280 
3281     return os;
3282 }
3283 
3284 /** Formatted output of the Conv3dInfo type.
3285  *
3286  * @param[in] conv3d_info Type to output.
3287  *
3288  * @return Formatted string.
3289  */
to_string(const Conv3dInfo & conv3d_info)3290 inline std::string to_string(const Conv3dInfo &conv3d_info)
3291 {
3292     std::stringstream str;
3293     str << conv3d_info;
3294     return str.str();
3295 }
3296 
3297 /** Formatted output of the arm_compute::WeightFormat type.
3298  *
3299  * @param[in] wf arm_compute::WeightFormat Type to output.
3300  *
3301  * @return Formatted string.
3302  */
to_string(const WeightFormat wf)3303 inline std::string to_string(const WeightFormat wf)
3304 {
3305 #define __CASE_WEIGHT_FORMAT(wf) \
3306     case WeightFormat::wf:       \
3307         return #wf;
3308     switch(wf)
3309     {
3310         __CASE_WEIGHT_FORMAT(UNSPECIFIED)
3311         __CASE_WEIGHT_FORMAT(ANY)
3312         __CASE_WEIGHT_FORMAT(OHWI)
3313         __CASE_WEIGHT_FORMAT(OHWIo2)
3314         __CASE_WEIGHT_FORMAT(OHWIo4)
3315         __CASE_WEIGHT_FORMAT(OHWIo8)
3316         __CASE_WEIGHT_FORMAT(OHWIo16)
3317         __CASE_WEIGHT_FORMAT(OHWIo32)
3318         __CASE_WEIGHT_FORMAT(OHWIo64)
3319         __CASE_WEIGHT_FORMAT(OHWIo128)
3320         __CASE_WEIGHT_FORMAT(OHWIo4i2)
3321         __CASE_WEIGHT_FORMAT(OHWIo4i2_bf16)
3322         __CASE_WEIGHT_FORMAT(OHWIo8i2)
3323         __CASE_WEIGHT_FORMAT(OHWIo8i2_bf16)
3324         __CASE_WEIGHT_FORMAT(OHWIo16i2)
3325         __CASE_WEIGHT_FORMAT(OHWIo16i2_bf16)
3326         __CASE_WEIGHT_FORMAT(OHWIo32i2)
3327         __CASE_WEIGHT_FORMAT(OHWIo32i2_bf16)
3328         __CASE_WEIGHT_FORMAT(OHWIo64i2)
3329         __CASE_WEIGHT_FORMAT(OHWIo64i2_bf16)
3330         __CASE_WEIGHT_FORMAT(OHWIo4i4)
3331         __CASE_WEIGHT_FORMAT(OHWIo4i4_bf16)
3332         __CASE_WEIGHT_FORMAT(OHWIo8i4)
3333         __CASE_WEIGHT_FORMAT(OHWIo8i4_bf16)
3334         __CASE_WEIGHT_FORMAT(OHWIo16i4)
3335         __CASE_WEIGHT_FORMAT(OHWIo16i4_bf16)
3336         __CASE_WEIGHT_FORMAT(OHWIo32i4)
3337         __CASE_WEIGHT_FORMAT(OHWIo32i4_bf16)
3338         __CASE_WEIGHT_FORMAT(OHWIo64i4)
3339         __CASE_WEIGHT_FORMAT(OHWIo64i4_bf16)
3340         __CASE_WEIGHT_FORMAT(OHWIo2i8)
3341         __CASE_WEIGHT_FORMAT(OHWIo4i8)
3342         __CASE_WEIGHT_FORMAT(OHWIo8i8)
3343         __CASE_WEIGHT_FORMAT(OHWIo16i8)
3344         __CASE_WEIGHT_FORMAT(OHWIo32i8)
3345         __CASE_WEIGHT_FORMAT(OHWIo64i8)
3346         default:
3347             return "invalid value";
3348     }
3349 #undef __CASE_WEIGHT_FORMAT
3350 }
3351 
3352 /** Formatted output of the arm_compute::WeightFormat type.
3353  *
3354  * @param[out] os Output stream.
3355  * @param[in]  wf WeightFormat to output.
3356  *
3357  * @return Modified output stream.
3358  */
3359 inline ::std::ostream &operator<<(::std::ostream &os, const arm_compute::WeightFormat &wf)
3360 {
3361     os << to_string(wf);
3362     return os;
3363 }
3364 
3365 /** Formatted output of the std::tuple<TensorShape, TensorShape, arm_compute::WeightFormat> tuple.
3366  *
3367  * @param[in] values tuple of input and output tensor shapes and WeightFormat used.
3368  *
3369  * @return Formatted string.
3370  */
to_string(const std::tuple<TensorShape,TensorShape,arm_compute::WeightFormat> values)3371 inline std::string to_string(const std::tuple<TensorShape, TensorShape, arm_compute::WeightFormat> values)
3372 {
3373     std::stringstream str;
3374     str << "[Input shape = " << std::get<0>(values);
3375     str << ", ";
3376     str << "Expected output shape = " << std::get<1>(values);
3377 
3378     str << ", ";
3379     str << "WeightFormat = " << std::get<2>(values) << "]";
3380     return str.str();
3381 }
3382 
3383 /** Formatted output of the Padding2D type.
3384  *
3385  * @param[out] os        Output stream.
3386  * @param[in]  padding2d Padding info for 2D dimension shape.
3387  *
3388  * @return Modified output stream.
3389  */
3390 inline ::std::ostream &operator<<(::std::ostream &os, const Padding2D &padding2d)
3391 {
3392     os << padding2d.left << "," << padding2d.right << ","
3393        << padding2d.top << "," << padding2d.bottom;
3394     return os;
3395 }
3396 
3397 /** Converts a @ref Padding2D to string
3398  *
3399  * @param[in] padding2d Padding2D value to be converted
3400  *
3401  * @return String representing the corresponding Padding2D
3402  */
to_string(const Padding2D & padding2d)3403 inline std::string to_string(const Padding2D &padding2d)
3404 {
3405     std::stringstream str;
3406     str << padding2d;
3407     return str.str();
3408 }
3409 
3410 /** Formatted output of the arm_compute::experimental::dynamic_fusion::Pool2dAttributes type.
3411  *
3412  * @param[out] os          Output stream.
3413  * @param[in]  pool2d_attr arm_compute::experimental::dynamic_fusion::Pool2dAttributes type to output.
3414  *
3415  * @return Modified output stream.
3416  */
3417 inline ::std::ostream &operator<<(::std::ostream &os, const experimental::dynamic_fusion::Pool2dAttributes &pool2d_attr)
3418 {
3419     os << "Pool2dAttributes="
3420        << "["
3421        << "PoolingType=" << pool2d_attr.pool_type() << ","
3422        << "PoolSize=" << pool2d_attr.pool_size() << ","
3423        << "Padding=" << pool2d_attr.pad() << ","
3424        << "Stride=" << pool2d_attr.stride() << ","
3425        << "ExcludePadding" << pool2d_attr.exclude_padding() << "]";
3426 
3427     return os;
3428 }
3429 
3430 /** Formatted output of the arm_compute::experimental::dynamic_fusion::Pool2dAttributes type.
3431  *
3432  * @param[in] pool2d_attr arm_compute::experimental::dynamic_fusion::Pool2dAttributes type to output.
3433  *
3434  * @return Formatted string.
3435  */
to_string(const experimental::dynamic_fusion::Pool2dAttributes & pool2d_attr)3436 inline std::string to_string(const experimental::dynamic_fusion::Pool2dAttributes &pool2d_attr)
3437 {
3438     std::stringstream str;
3439     str << pool2d_attr;
3440     return str.str();
3441 }
3442 
3443 /** Formatted output of the arm_compute::experimental::dynamic_fusion::GpuPool2dSettings type
3444  *
3445  * @param[out] os       Output stream
3446  * @param[in]  settings arm_compute::dynamic_fusion::GpuPool2dSettings type to output
3447  */
3448 inline ::std::ostream &operator<<(::std::ostream &os, const experimental::dynamic_fusion::GpuPool2dSettings &settings)
3449 {
3450     os << "Settings="
3451        << "["
3452        << "FPMixedPrecision=" << settings.mixed_precision() << "]";
3453     return os;
3454 }
3455 
3456 /** Formatted output of the arm_compute::experimental::dynamic_fusion::GpuPool2dSettings type.
3457  *
3458  * @param[in] settings arm_compute::experimental::dynamic_fusion::GpuPool2dSettings type to output.
3459  *
3460  * @return Formatted string.
3461  */
to_string(const experimental::dynamic_fusion::GpuPool2dSettings & settings)3462 inline std::string to_string(const experimental::dynamic_fusion::GpuPool2dSettings &settings)
3463 {
3464     std::stringstream str;
3465     str << settings;
3466     return str.str();
3467 }
3468 
3469 /** Formatted output of the arm_compute::experimental::dynamic_fusion::Conv2dAttributes type.
3470  *
3471  * @param[out] os          Output stream.
3472  * @param[in]  conv2d_attr arm_compute::experimental::dynamic_fusion::Conv2dAttributes type to output.
3473  *
3474  * @return Modified output stream.
3475  */
3476 inline ::std::ostream &operator<<(::std::ostream &os, const experimental::dynamic_fusion::Conv2dAttributes &conv2d_attr)
3477 {
3478     os << "Conv2dAttributes="
3479        << "["
3480        << "Padding=" << conv2d_attr.pad() << ", "
3481        << "Size2D=" << conv2d_attr.stride() << ", "
3482        << "Dialation=" << conv2d_attr.dilation() << "]";
3483 
3484     return os;
3485 }
3486 
3487 /** Formatted output of the arm_compute::experimental::dynamic_fusion::Conv2dAttributes type.
3488  *
3489  * @param[in] conv2d_attr arm_compute::experimental::dynamic_fusion::Conv2dAttributes type to output.
3490  *
3491  * @return Formatted string.
3492  */
to_string(const experimental::dynamic_fusion::Conv2dAttributes & conv2d_attr)3493 inline std::string to_string(const experimental::dynamic_fusion::Conv2dAttributes &conv2d_attr)
3494 {
3495     std::stringstream str;
3496     str << conv2d_attr;
3497     return str.str();
3498 }
3499 
3500 /** Formatted output of the arm_compute::experimental::dynamic_fusion::CastAttributes type.
3501  *
3502  * @param[out] os        Output stream.
3503  * @param[in]  cast_attr arm_compute::experimental::dynamic_fusion::CastAttributes type to output.
3504  *
3505  * @return Modified output stream.
3506  */
3507 inline ::std::ostream &operator<<(::std::ostream &os, const experimental::dynamic_fusion::CastAttributes &cast_attr)
3508 {
3509     os << "CastAttributes="
3510        << "["
3511        << "Data Type=" << cast_attr.data_type() << ", "
3512        << "Convert Policy=" << cast_attr.convert_policy() << "]";
3513 
3514     return os;
3515 }
3516 /** Formatted output of the arm_compute::experimental::dynamic_fusion::CastAttributes type.
3517  *
3518  * @param[in] cast_attr arm_compute::experimental::dynamic_fusion::CastAttributes type to output.
3519  *
3520  * @return Formatted string.
3521  */
to_string(const experimental::dynamic_fusion::CastAttributes & cast_attr)3522 inline std::string to_string(const experimental::dynamic_fusion::CastAttributes &cast_attr)
3523 {
3524     std::stringstream str;
3525     str << cast_attr;
3526     return str.str();
3527 }
3528 
3529 /** Formatted output of the arm_compute::experimental::dynamic_fusion::DepthwiseConv2dAttributes type.
3530  *
3531  * @param[out] os             Output stream.
3532  * @param[in]  dw_conv2d_attr arm_compute::experimental::dynamic_fusion::DepthwiseConv2dAttributes type to output.
3533  *
3534  * @return Modified output stream.
3535  */
3536 inline ::std::ostream &operator<<(::std::ostream &os, const experimental::dynamic_fusion::DepthwiseConv2dAttributes &dw_conv2d_attr)
3537 {
3538     os << "DepthwiseConv2dAttributes="
3539        << "["
3540        << "Padding=" << dw_conv2d_attr.pad() << ", "
3541        << "Size2D=" << dw_conv2d_attr.stride() << ", "
3542        << "Depth Multiplier=" << dw_conv2d_attr.depth_multiplier() << ", "
3543        << "Dilation=" << dw_conv2d_attr.dilation() << ","
3544        << "DimensionRoundingType: " << dw_conv2d_attr.dimension_rounding_type() << "]";
3545 
3546     return os;
3547 }
3548 /** Formatted output of the arm_compute::experimental::dynamic_fusion::DepthwiseConv2dAttributes type.
3549  *
3550  * @param[in] dw_conv2d_attr arm_compute::experimental::dynamic_fusion::DepthwiseConv2dAttributes type to output.
3551  *
3552  * @return Formatted string.
3553  */
to_string(const experimental::dynamic_fusion::DepthwiseConv2dAttributes & dw_conv2d_attr)3554 inline std::string to_string(const experimental::dynamic_fusion::DepthwiseConv2dAttributes &dw_conv2d_attr)
3555 {
3556     std::stringstream str;
3557     str << dw_conv2d_attr;
3558     return str.str();
3559 }
3560 
3561 /** Formatted output of the arm_compute::experimental::dynamic_fusion::ClampAttributes type.
3562  *
3563  * @param[out] os         Output stream.
3564  * @param[in]  clamp_attr arm_compute::experimental::dynamic_fusion::ClampAttributes type to output.
3565  *
3566  * @return Modified output stream.
3567  */
3568 inline ::std::ostream &operator<<(::std::ostream &os, const experimental::dynamic_fusion::ClampAttributes &clamp_attr)
3569 {
3570     os << "ClampAttributes="
3571        << "["
3572        << "Min value=" << clamp_attr.min_val() << ", "
3573        << "Max value=" << clamp_attr.max_val() << "]";
3574     return os;
3575 }
3576 /** Formatted output of the arm_compute::experimental::dynamic_fusion::ClampAttributes type.
3577  *
3578  * @param[in] clamp_attr arm_compute::experimental::dynamic_fusion::ClampAttributes type to output.
3579  *
3580  * @return Formatted string.
3581  */
to_string(const experimental::dynamic_fusion::ClampAttributes & clamp_attr)3582 inline std::string to_string(const experimental::dynamic_fusion::ClampAttributes &clamp_attr)
3583 {
3584     std::stringstream str;
3585     str << clamp_attr;
3586     return str.str();
3587 }
3588 
3589 /** Formatted output of the arm_compute::experimental::dynamic_fusion::ResizeAttributes type.
3590  *
3591  * @param[out] os          Output stream.
3592  * @param[in]  resize_attr arm_compute::experimental::dynamic_fusion::ResizeAttributes type to output.
3593  *
3594  * @return Modified output stream.
3595  */
3596 inline ::std::ostream &operator<<(::std::ostream &os, const experimental::dynamic_fusion::ResizeAttributes &resize_attr)
3597 {
3598     os << "ResizeAttributes="
3599        << "["
3600        << "AlignCorners=" << resize_attr.align_corners() << ", "
3601        << "InterpolationPolicy=" << resize_attr.interpolation_policy() << ", "
3602        << "OutputHeight=" << resize_attr.output_height() << ", "
3603        << "OutputWidth=" << resize_attr.output_width() << ", "
3604        << "SamplingPolicy=" << resize_attr.sampling_policy() << "]";
3605     return os;
3606 }
3607 
3608 /** Formatted output of the arm_compute::experimental::dynamic_fusion::ResizeAttributes type.
3609  *
3610  * @param[in] resize_attr arm_compute::experimental::dynamic_fusion::ResizeAttributes type to output.
3611  *
3612  * @return Formatted string.
3613  */
to_string(const experimental::dynamic_fusion::ResizeAttributes & resize_attr)3614 inline std::string to_string(const experimental::dynamic_fusion::ResizeAttributes &resize_attr)
3615 {
3616     std::stringstream str;
3617     str << resize_attr;
3618     return str.str();
3619 }
3620 
3621 /** Formatted output of the arm_compute::experimental::dynamic_fusion::SoftmaxAttributes type.
3622  *
3623  * @param[out] os           Output stream.
3624  * @param[in]  softmax_attr arm_compute::experimental::dynamic_fusion::SoftmaxAttributes type to output.
3625  *
3626  * @return Modified output stream.
3627  */
3628 inline ::std::ostream &operator<<(::std::ostream &os, const experimental::dynamic_fusion::SoftmaxAttributes &softmax_attr)
3629 {
3630     os << "SoftmaxAttributes="
3631        << "["
3632        << "Beta=" << softmax_attr.beta() << ", "
3633        << "Is Log Softmax=" << softmax_attr.is_log_softmax() << ", "
3634        << "Axis=" << softmax_attr.axis() << "]";
3635     return os;
3636 }
3637 /** Formatted output of the arm_compute::experimental::dynamic_fusion::SoftmaxAttributes type.
3638  *
3639  * @param[in] softmax_attr arm_compute::experimental::dynamic_fusion::SoftmaxAttributes type to output.
3640  *
3641  * @return Formatted string.
3642  */
to_string(const experimental::dynamic_fusion::SoftmaxAttributes & softmax_attr)3643 inline std::string to_string(const experimental::dynamic_fusion::SoftmaxAttributes &softmax_attr)
3644 {
3645     std::stringstream str;
3646     str << softmax_attr;
3647     return str.str();
3648 }
3649 
3650 } // namespace arm_compute
3651 
3652 #endif /* __ARM_COMPUTE_TYPE_PRINTER_H__ */
3653