xref: /aosp_15_r20/external/armnn/src/armnn/ProfilingDetails.hpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1 //
2 // Copyright © 2022 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #pragma once
7 
8 #include <iomanip>
9 
10 #include "armnn/Types.hpp"
11 #include "armnn/TypesUtils.hpp"
12 #include "armnn/backends/WorkloadInfo.hpp"
13 
14 #include "SerializeLayerParameters.hpp"
15 #include "JsonUtils.hpp"
16 
17 namespace armnn
18 {
19 
20 /// ProfilingDetails class records any details associated with the operator and passes on for outputting to the user
21 class ProfilingDetails : public JsonUtils
22 {
23 public:
24     /// Constructor
ProfilingDetails()25     ProfilingDetails() : JsonUtils(m_ProfilingDetails), m_DetailsExist(false)
26     {}
27 
28     /// Destructor
~ProfilingDetails()29     ~ProfilingDetails() noexcept
30     {}
31 
32     /// Add to the ProfilingDetails
33     template <typename DescriptorType>
AddDetailsToString(const std::string & workloadName,const DescriptorType & desc,const WorkloadInfo & infos,const arm::pipe::ProfilingGuid guid)34     void AddDetailsToString(const std::string& workloadName,
35                             const DescriptorType& desc,
36                             const WorkloadInfo& infos,
37                             const arm::pipe::ProfilingGuid guid)
38     {
39         // Once details exist, we can assume we're on the second iteration of details
40         if (m_DetailsExist)
41         {
42             PrintSeparator();
43             PrintNewLine();
44         }
45 
46         PrintHeader();
47         PrintTabs();
48         m_ProfilingDetails << std::quoted("Name") << ": " << std::quoted(workloadName);
49         PrintSeparator();
50         PrintNewLine();
51         PrintTabs();
52         m_ProfilingDetails << std::quoted("GUID") << ": " << std::quoted(std::to_string(guid));
53 
54         // From this point onwards everything is potentially optional so we must be careful of separators and new lines.
55 
56         // Print tensor infos and related data types
57         if (!infos.m_InputTensorInfos.empty())
58         {
59             PrintSeparator();
60             PrintNewLine();
61             // Only add separator and new line if there is an output tensor info.
62             PrintInfos(infos.m_InputTensorInfos, "Input", !infos.m_OutputTensorInfos.empty());
63         }
64 
65         if (!infos.m_OutputTensorInfos.empty())
66         {
67             // Don't add a separator as we don't know what's next.
68             PrintInfos(infos.m_OutputTensorInfos, "Output", false);
69         }
70 
71         if (infos.m_BiasTensorInfo.has_value())
72         {
73             PrintSeparator();
74             PrintNewLine();
75             PrintInfo(infos.m_BiasTensorInfo.value(), "Bias", false);
76         }
77 
78         if (infos.m_WeightsTensorInfo.has_value())
79         {
80             PrintSeparator();
81             PrintNewLine();
82             PrintInfo(infos.m_WeightsTensorInfo.value(), "Weights", false);
83         }
84 
85         if (infos.m_ConvolutionMethod.has_value())
86         {
87             PrintSeparator();
88             PrintNewLine();
89             PrintTabs();
90 
91             m_ProfilingDetails << std::quoted("Convolution Method") << ": "
92                                << std::quoted(infos.m_ConvolutionMethod.value());
93         }
94 
95         ParameterStringifyFunction extractParams = [this](const std::string& name, const std::string& value) {
96             // Always begin with a separator and new line.
97             PrintSeparator();
98             PrintNewLine();
99             PrintTabs();
100             m_ProfilingDetails << std::quoted(name) << " : " << std::quoted(value);
101         };
102 
103         StringifyLayerParameters<DescriptorType>::Serialize(extractParams, desc);
104 
105         PrintNewLine();
106         PrintFooter();
107 
108         m_DetailsExist = true;
109     }
110 
111     /// Get the ProfilingDetails
112     /// \return the ProfilingDetails
GetProfilingDetails() const113     std::string GetProfilingDetails() const
114     {
115         return m_ProfilingDetails.str();
116     }
117 
DetailsExist()118     bool DetailsExist()
119     {
120         return m_DetailsExist;
121     }
122 
123 private:
124     // Print tensor infos and related data types
PrintInfo(const TensorInfo & info,const std::string & ioString,bool addSeparator=true)125     void PrintInfo(const TensorInfo& info, const std::string& ioString, bool addSeparator = true)
126     {
127         const std::vector<TensorInfo> infoVect{ info };
128         PrintInfos(infoVect, ioString, addSeparator);
129     }
130 
PrintInfos(const std::vector<TensorInfo> & infos,const std::string & ioString,bool addSeparator=true)131     void PrintInfos(const std::vector<TensorInfo>& infos, const std::string& ioString, bool addSeparator = true)
132     {
133         for ( size_t i = 0; i < infos.size(); i++ )
134         {
135             auto shape = infos[i].GetShape();
136             PrintTabs();
137 
138             m_ProfilingDetails << std::quoted(ioString + " " + std::to_string(i)) << ": ";
139 
140             PrintHeader();
141             PrintTabs();
142 
143             // Shape
144             m_ProfilingDetails << std::quoted("Shape") << ": \"[";
145             for ( unsigned int dim = 0; dim < shape.GetNumDimensions(); dim++ )
146             {
147                 shape.GetNumDimensions() == dim + 1 ?
148                 m_ProfilingDetails << shape[dim] << "]\"" : // true
149                 m_ProfilingDetails << shape[dim] << ",";    // false
150             }
151 
152             PrintSeparator();
153             PrintNewLine();
154 
155             // Data Type
156             PrintTabs();
157             m_ProfilingDetails << std::quoted("DataType") << ": "
158                                << std::quoted(GetDataTypeName(infos[i].GetDataType()));
159 
160             PrintSeparator();
161             PrintNewLine();
162 
163             // Number of Dimensions
164             PrintTabs();
165             m_ProfilingDetails << std::quoted("Num Dims") << ": "
166                                << std::quoted(std::to_string(shape.GetNumDimensions()));
167 
168 
169             // Close out the scope
170             PrintNewLine();
171             PrintFooter();
172             // For the last element we will consider the value of addSeparator.
173             if ((i < infos.size() - 1) || (addSeparator))
174             {
175                 PrintSeparator();
176                 PrintNewLine();
177             }
178         }
179     }
180 
181     /// Stores ProfilingDetails
182     std::ostringstream m_ProfilingDetails;
183     bool m_DetailsExist;
184 
185 };
186 
187 } // namespace armnn
188