1*3e777be0SXin Li //
2*3e777be0SXin Li // Copyright © 2017-2021,2023 Arm Ltd and Contributors. All rights reserved.
3*3e777be0SXin Li // SPDX-License-Identifier: MIT
4*3e777be0SXin Li //
5*3e777be0SXin Li
6*3e777be0SXin Li #pragma once
7*3e777be0SXin Li #include <armnn/ArmNN.hpp>
8*3e777be0SXin Li
9*3e777be0SXin Li #include <CpuExecutor.h>
10*3e777be0SXin Li #include <HalInterfaces.h>
11*3e777be0SXin Li #include <NeuralNetworks.h>
12*3e777be0SXin Li #include <Utils.h>
13*3e777be0SXin Li
14*3e777be0SXin Li #include <fmt/format.h>
15*3e777be0SXin Li
16*3e777be0SXin Li #include <vector>
17*3e777be0SXin Li #include <string>
18*3e777be0SXin Li #include <fstream>
19*3e777be0SXin Li #include <iomanip>
20*3e777be0SXin Li
21*3e777be0SXin Li namespace V1_0 = ::android::hardware::neuralnetworks::V1_0;
22*3e777be0SXin Li namespace V1_1 = ::android::hardware::neuralnetworks::V1_1;
23*3e777be0SXin Li
24*3e777be0SXin Li #if defined(ARMNN_ANDROID_NN_V1_2) || defined(ARMNN_ANDROID_NN_V1_3)
25*3e777be0SXin Li namespace V1_2 = ::android::hardware::neuralnetworks::V1_2;
26*3e777be0SXin Li #endif
27*3e777be0SXin Li
28*3e777be0SXin Li #ifdef ARMNN_ANDROID_NN_V1_3
29*3e777be0SXin Li namespace V1_3 = ::android::hardware::neuralnetworks::V1_3;
30*3e777be0SXin Li #endif
31*3e777be0SXin Li
32*3e777be0SXin Li namespace armnn_driver
33*3e777be0SXin Li {
34*3e777be0SXin Li
35*3e777be0SXin Li #ifdef ARMNN_ANDROID_R
36*3e777be0SXin Li using DataLocation = ::android::nn::hal::DataLocation;
37*3e777be0SXin Li #endif
38*3e777be0SXin Li
getMainModel(const V1_0::Model & model)39*3e777be0SXin Li inline const V1_0::Model& getMainModel(const V1_0::Model& model) { return model; }
getMainModel(const V1_1::Model & model)40*3e777be0SXin Li inline const V1_1::Model& getMainModel(const V1_1::Model& model) { return model; }
41*3e777be0SXin Li
42*3e777be0SXin Li #if defined (ARMNN_ANDROID_NN_V1_2) || defined (ARMNN_ANDROID_NN_V1_3)
getMainModel(const V1_2::Model & model)43*3e777be0SXin Li inline const V1_2::Model& getMainModel(const V1_2::Model& model) { return model; }
44*3e777be0SXin Li #endif
45*3e777be0SXin Li
46*3e777be0SXin Li #ifdef ARMNN_ANDROID_NN_V1_3
getMainModel(const V1_3::Model & model)47*3e777be0SXin Li inline const V1_3::Subgraph& getMainModel(const V1_3::Model& model) { return model.main; }
48*3e777be0SXin Li #endif
49*3e777be0SXin Li
50*3e777be0SXin Li extern const armnn::PermutationVector g_DontPermute;
51*3e777be0SXin Li
52*3e777be0SXin Li template <typename OperandType>
53*3e777be0SXin Li class UnsupportedOperand: public std::runtime_error
54*3e777be0SXin Li {
55*3e777be0SXin Li public:
UnsupportedOperand(const OperandType type)56*3e777be0SXin Li UnsupportedOperand(const OperandType type)
57*3e777be0SXin Li : std::runtime_error("Operand type is unsupported")
58*3e777be0SXin Li , m_type(type)
59*3e777be0SXin Li {}
60*3e777be0SXin Li
61*3e777be0SXin Li OperandType m_type;
62*3e777be0SXin Li };
63*3e777be0SXin Li
64*3e777be0SXin Li /// Swizzles tensor data in @a input according to the dimension mappings.
65*3e777be0SXin Li void SwizzleAndroidNn4dTensorToArmNn(armnn::TensorInfo& tensor, const void* input, void* output,
66*3e777be0SXin Li const armnn::PermutationVector& mappings);
67*3e777be0SXin Li
68*3e777be0SXin Li /// Returns a pointer to a specific location in a pool
69*3e777be0SXin Li void* GetMemoryFromPool(V1_0::DataLocation location,
70*3e777be0SXin Li const std::vector<android::nn::RunTimePoolInfo>& memPools);
71*3e777be0SXin Li
72*3e777be0SXin Li /// Can throw UnsupportedOperand
73*3e777be0SXin Li armnn::TensorInfo GetTensorInfoForOperand(const V1_0::Operand& operand);
74*3e777be0SXin Li
75*3e777be0SXin Li std::string GetOperandSummary(const V1_0::Operand& operand);
76*3e777be0SXin Li
77*3e777be0SXin Li // Returns true for any quantized data type, false for the rest.
78*3e777be0SXin Li bool isQuantizedOperand(const V1_0::OperandType& operandType);
79*3e777be0SXin Li
80*3e777be0SXin Li #if defined(ARMNN_ANDROID_NN_V1_2) || defined(ARMNN_ANDROID_NN_V1_3) // Using ::android::hardware::neuralnetworks::V1_2
81*3e777be0SXin Li armnn::TensorInfo GetTensorInfoForOperand(const V1_2::Operand& operand);
82*3e777be0SXin Li
83*3e777be0SXin Li std::string GetOperandSummary(const V1_2::Operand& operand);
84*3e777be0SXin Li
85*3e777be0SXin Li bool isQuantizedOperand(const V1_2::OperandType& operandType);
86*3e777be0SXin Li #endif
87*3e777be0SXin Li
88*3e777be0SXin Li #ifdef ARMNN_ANDROID_NN_V1_3 // Using ::android::hardware::neuralnetworks::V1_3
89*3e777be0SXin Li armnn::TensorInfo GetTensorInfoForOperand(const V1_3::Operand& operand);
90*3e777be0SXin Li
91*3e777be0SXin Li std::string GetOperandSummary(const V1_3::Operand& operand);
92*3e777be0SXin Li
93*3e777be0SXin Li bool isQuantizedOperand(const V1_3::OperandType& operandType);
94*3e777be0SXin Li #endif
95*3e777be0SXin Li
96*3e777be0SXin Li template <typename HalModel>
GetModelSummary(const HalModel & model)97*3e777be0SXin Li std::string GetModelSummary(const HalModel& model)
98*3e777be0SXin Li {
99*3e777be0SXin Li std::stringstream result;
100*3e777be0SXin Li
101*3e777be0SXin Li result << getMainModel(model).inputIndexes.size() << " input(s), "
102*3e777be0SXin Li << getMainModel(model).operations.size() << " operation(s), "
103*3e777be0SXin Li << getMainModel(model).outputIndexes.size() << " output(s), "
104*3e777be0SXin Li << getMainModel(model).operands.size() << " operand(s) "
105*3e777be0SXin Li << std::endl;
106*3e777be0SXin Li
107*3e777be0SXin Li result << "Inputs: ";
108*3e777be0SXin Li for (uint32_t i = 0; i < getMainModel(model).inputIndexes.size(); i++)
109*3e777be0SXin Li {
110*3e777be0SXin Li result << GetOperandSummary(getMainModel(model).operands[getMainModel(model).inputIndexes[i]]) << ", ";
111*3e777be0SXin Li }
112*3e777be0SXin Li result << std::endl;
113*3e777be0SXin Li
114*3e777be0SXin Li result << "Operations: ";
115*3e777be0SXin Li for (uint32_t i = 0; i < getMainModel(model).operations.size(); i++)
116*3e777be0SXin Li {
117*3e777be0SXin Li result << toString(getMainModel(model).operations[i].type).c_str() << ", ";
118*3e777be0SXin Li }
119*3e777be0SXin Li result << std::endl;
120*3e777be0SXin Li
121*3e777be0SXin Li result << "Outputs: ";
122*3e777be0SXin Li for (uint32_t i = 0; i < getMainModel(model).outputIndexes.size(); i++)
123*3e777be0SXin Li {
124*3e777be0SXin Li result << GetOperandSummary(getMainModel(model).operands[getMainModel(model).outputIndexes[i]]) << ", ";
125*3e777be0SXin Li }
126*3e777be0SXin Li result << std::endl;
127*3e777be0SXin Li
128*3e777be0SXin Li return result.str();
129*3e777be0SXin Li }
130*3e777be0SXin Li
131*3e777be0SXin Li template <typename TensorType>
132*3e777be0SXin Li void DumpTensor(const std::string& dumpDir,
133*3e777be0SXin Li const std::string& requestName,
134*3e777be0SXin Li const std::string& tensorName,
135*3e777be0SXin Li const TensorType& tensor);
136*3e777be0SXin Li
137*3e777be0SXin Li void DumpJsonProfilingIfRequired(bool gpuProfilingEnabled,
138*3e777be0SXin Li const std::string& dumpDir,
139*3e777be0SXin Li armnn::NetworkId networkId,
140*3e777be0SXin Li const armnn::IProfiler* profiler);
141*3e777be0SXin Li
142*3e777be0SXin Li std::string ExportNetworkGraphToDotFile(const armnn::IOptimizedNetwork& optimizedNetwork,
143*3e777be0SXin Li const std::string& dumpDir);
144*3e777be0SXin Li
145*3e777be0SXin Li std::string SerializeNetwork(const armnn::INetwork& network,
146*3e777be0SXin Li const std::string& dumpDir,
147*3e777be0SXin Li std::vector<uint8_t>& dataCacheData,
148*3e777be0SXin Li bool dataCachingActive = true);
149*3e777be0SXin Li
150*3e777be0SXin Li void RenameExportedFiles(const std::string& existingSerializedFileName,
151*3e777be0SXin Li const std::string& existingDotFileName,
152*3e777be0SXin Li const std::string& dumpDir,
153*3e777be0SXin Li const armnn::NetworkId networkId);
154*3e777be0SXin Li
155*3e777be0SXin Li void RenameFile(const std::string& existingName,
156*3e777be0SXin Li const std::string& extension,
157*3e777be0SXin Li const std::string& dumpDir,
158*3e777be0SXin Li const armnn::NetworkId networkId);
159*3e777be0SXin Li
160*3e777be0SXin Li /// Checks if a tensor info represents a dynamic tensor
161*3e777be0SXin Li bool IsDynamicTensor(const armnn::TensorInfo& outputInfo);
162*3e777be0SXin Li
163*3e777be0SXin Li /// Checks for ArmNN support of dynamic tensors.
164*3e777be0SXin Li bool AreDynamicTensorsSupported(void);
165*3e777be0SXin Li
166*3e777be0SXin Li std::string GetFileTimestamp();
167*3e777be0SXin Li
168*3e777be0SXin Li #if defined(ARMNN_ANDROID_NN_V1_2) || defined(ARMNN_ANDROID_NN_V1_3)
ComputeShape(const armnn::TensorInfo & info)169*3e777be0SXin Li inline V1_2::OutputShape ComputeShape(const armnn::TensorInfo& info)
170*3e777be0SXin Li {
171*3e777be0SXin Li V1_2::OutputShape shape;
172*3e777be0SXin Li
173*3e777be0SXin Li armnn::TensorShape tensorShape = info.GetShape();
174*3e777be0SXin Li // Android will expect scalars as a zero dimensional tensor
175*3e777be0SXin Li if(tensorShape.GetDimensionality() == armnn::Dimensionality::Scalar)
176*3e777be0SXin Li {
177*3e777be0SXin Li shape.dimensions = android::hardware::hidl_vec<uint32_t>{};
178*3e777be0SXin Li }
179*3e777be0SXin Li else
180*3e777be0SXin Li {
181*3e777be0SXin Li android::hardware::hidl_vec<uint32_t> dimensions;
182*3e777be0SXin Li const unsigned int numDims = tensorShape.GetNumDimensions();
183*3e777be0SXin Li dimensions.resize(numDims);
184*3e777be0SXin Li for (unsigned int outputIdx = 0u; outputIdx < numDims; ++outputIdx)
185*3e777be0SXin Li {
186*3e777be0SXin Li dimensions[outputIdx] = tensorShape[outputIdx];
187*3e777be0SXin Li }
188*3e777be0SXin Li shape.dimensions = dimensions;
189*3e777be0SXin Li }
190*3e777be0SXin Li
191*3e777be0SXin Li shape.isSufficient = true;
192*3e777be0SXin Li
193*3e777be0SXin Li return shape;
194*3e777be0SXin Li }
195*3e777be0SXin Li #endif
196*3e777be0SXin Li
197*3e777be0SXin Li void CommitPools(std::vector<::android::nn::RunTimePoolInfo>& memPools);
198*3e777be0SXin Li
199*3e777be0SXin Li template <typename ErrorStatus, typename Request>
200*3e777be0SXin Li ErrorStatus ValidateRequestArgument(const Request& request,
201*3e777be0SXin Li const armnn::TensorInfo& tensorInfo,
202*3e777be0SXin Li const V1_0::RequestArgument& requestArgument,
203*3e777be0SXin Li std::string descString);
204*3e777be0SXin Li } // namespace armnn_driver
205