blob: f68747b076a07cd39f9a94ba8e8176ff0f0c2524 [file] [log] [blame]
telsoa015307bc12018-03-09 13:51:08 +00001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
David Beck93e48982018-09-05 13:05:09 +01003// SPDX-License-Identifier: MIT
telsoa015307bc12018-03-09 13:51:08 +00004//
5
6#pragma once
telsoa015307bc12018-03-09 13:51:08 +00007#include <armnn/ArmNN.hpp>
arovir01b0717b52018-09-05 17:03:25 +01008
telsoa015307bc12018-03-09 13:51:08 +00009#include <CpuExecutor.h>
arovir01b0717b52018-09-05 17:03:25 +010010#include <HalInterfaces.h>
11#include <NeuralNetworks.h>
Sadik Armagan188675f2021-02-12 17:16:42 +000012#include <Utils.h>
telsoa015307bc12018-03-09 13:51:08 +000013
14#include <vector>
15#include <string>
Matteo Martincighe48bdff2018-09-03 13:50:50 +010016#include <fstream>
17#include <iomanip>
telsoa015307bc12018-03-09 13:51:08 +000018
Matthew Bentham912b3622019-05-03 15:49:14 +010019namespace V1_0 = ::android::hardware::neuralnetworks::V1_0;
Kevin May42477c12020-03-26 13:34:14 +000020namespace V1_1 = ::android::hardware::neuralnetworks::V1_1;
Matthew Bentham912b3622019-05-03 15:49:14 +010021
Kevin May42477c12020-03-26 13:34:14 +000022#if defined(ARMNN_ANDROID_NN_V1_2) || defined(ARMNN_ANDROID_NN_V1_3)
Mike Kellyb5fdf382019-06-11 16:35:25 +010023namespace V1_2 = ::android::hardware::neuralnetworks::V1_2;
24#endif
25
Kevin May42477c12020-03-26 13:34:14 +000026#ifdef ARMNN_ANDROID_NN_V1_3
27namespace V1_3 = ::android::hardware::neuralnetworks::V1_3;
28#endif
29
telsoa015307bc12018-03-09 13:51:08 +000030namespace armnn_driver
31{
32
Kevin Mayec1e5b82020-02-26 17:00:39 +000033#ifdef ARMNN_ANDROID_R
34using DataLocation = ::android::nn::hal::DataLocation;
35#endif
36
Kevin May42477c12020-03-26 13:34:14 +000037inline const V1_0::Model& getMainModel(const V1_0::Model& model) { return model; }
38inline const V1_1::Model& getMainModel(const V1_1::Model& model) { return model; }
39
40#if defined (ARMNN_ANDROID_NN_V1_2) || defined (ARMNN_ANDROID_NN_V1_3)
41inline const V1_2::Model& getMainModel(const V1_2::Model& model) { return model; }
42#endif
43
44#ifdef ARMNN_ANDROID_NN_V1_3
45inline const V1_3::Subgraph& getMainModel(const V1_3::Model& model) { return model.main; }
46#endif
47
telsoa015307bc12018-03-09 13:51:08 +000048extern const armnn::PermutationVector g_DontPermute;
49
Mike Kellyb5fdf382019-06-11 16:35:25 +010050template <typename OperandType>
telsoa015307bc12018-03-09 13:51:08 +000051class UnsupportedOperand: public std::runtime_error
52{
53public:
Mike Kellyb5fdf382019-06-11 16:35:25 +010054 UnsupportedOperand(const OperandType type)
telsoa015307bc12018-03-09 13:51:08 +000055 : std::runtime_error("Operand type is unsupported")
56 , m_type(type)
57 {}
58
Mike Kellyb5fdf382019-06-11 16:35:25 +010059 OperandType m_type;
telsoa015307bc12018-03-09 13:51:08 +000060};
61
62/// Swizzles tensor data in @a input according to the dimension mappings.
63void SwizzleAndroidNn4dTensorToArmNn(const armnn::TensorInfo& tensor, const void* input, void* output,
64 const armnn::PermutationVector& mappings);
65
66/// Returns a pointer to a specific location in a pool
Sadik Armagan188675f2021-02-12 17:16:42 +000067void* GetMemoryFromPool(V1_0::DataLocation location,
telsoa015307bc12018-03-09 13:51:08 +000068 const std::vector<android::nn::RunTimePoolInfo>& memPools);
69
70/// Can throw UnsupportedOperand
Matthew Bentham912b3622019-05-03 15:49:14 +010071armnn::TensorInfo GetTensorInfoForOperand(const V1_0::Operand& operand);
telsoa015307bc12018-03-09 13:51:08 +000072
Kevin May42477c12020-03-26 13:34:14 +000073#if defined(ARMNN_ANDROID_NN_V1_2) || defined(ARMNN_ANDROID_NN_V1_3) // Using ::android::hardware::neuralnetworks::V1_2
Mike Kellyb5fdf382019-06-11 16:35:25 +010074armnn::TensorInfo GetTensorInfoForOperand(const V1_2::Operand& operand);
75#endif
76
Kevin May42477c12020-03-26 13:34:14 +000077#ifdef ARMNN_ANDROID_NN_V1_3 // Using ::android::hardware::neuralnetworks::V1_3
78armnn::TensorInfo GetTensorInfoForOperand(const V1_3::Operand& operand);
79#endif
80
Matthew Bentham912b3622019-05-03 15:49:14 +010081std::string GetOperandSummary(const V1_0::Operand& operand);
kevmay01bc5f7842018-08-30 12:34:39 +010082
Kevin May42477c12020-03-26 13:34:14 +000083#if defined(ARMNN_ANDROID_NN_V1_2) || defined(ARMNN_ANDROID_NN_V1_3) // Using ::android::hardware::neuralnetworks::V1_2
Mike Kellyb5fdf382019-06-11 16:35:25 +010084std::string GetOperandSummary(const V1_2::Operand& operand);
85#endif
86
Kevin May42477c12020-03-26 13:34:14 +000087#ifdef ARMNN_ANDROID_NN_V1_3 // Using ::android::hardware::neuralnetworks::V1_3
88std::string GetOperandSummary(const V1_3::Operand& operand);
89#endif
90
Matteo Martincighe48bdff2018-09-03 13:50:50 +010091template <typename HalModel>
92std::string GetModelSummary(const HalModel& model)
kevmay01bc5f7842018-08-30 12:34:39 +010093{
94 std::stringstream result;
95
Kevin May42477c12020-03-26 13:34:14 +000096 result << getMainModel(model).inputIndexes.size() << " input(s), "
97 << getMainModel(model).operations.size() << " operation(s), "
98 << getMainModel(model).outputIndexes.size() << " output(s), "
99 << getMainModel(model).operands.size() << " operand(s) "
100 << std::endl;
kevmay01bc5f7842018-08-30 12:34:39 +0100101
102 result << "Inputs: ";
Kevin May42477c12020-03-26 13:34:14 +0000103 for (uint32_t i = 0; i < getMainModel(model).inputIndexes.size(); i++)
kevmay01bc5f7842018-08-30 12:34:39 +0100104 {
Kevin May42477c12020-03-26 13:34:14 +0000105 result << GetOperandSummary(getMainModel(model).operands[getMainModel(model).inputIndexes[i]]) << ", ";
kevmay01bc5f7842018-08-30 12:34:39 +0100106 }
107 result << std::endl;
108
109 result << "Operations: ";
Kevin May42477c12020-03-26 13:34:14 +0000110 for (uint32_t i = 0; i < getMainModel(model).operations.size(); i++)
kevmay01bc5f7842018-08-30 12:34:39 +0100111 {
Kevin May42477c12020-03-26 13:34:14 +0000112 result << toString(getMainModel(model).operations[i].type).c_str() << ", ";
kevmay01bc5f7842018-08-30 12:34:39 +0100113 }
114 result << std::endl;
115
116 result << "Outputs: ";
Kevin May42477c12020-03-26 13:34:14 +0000117 for (uint32_t i = 0; i < getMainModel(model).outputIndexes.size(); i++)
kevmay01bc5f7842018-08-30 12:34:39 +0100118 {
Kevin May42477c12020-03-26 13:34:14 +0000119 result << GetOperandSummary(getMainModel(model).operands[getMainModel(model).outputIndexes[i]]) << ", ";
kevmay01bc5f7842018-08-30 12:34:39 +0100120 }
121 result << std::endl;
122
123 return result.str();
124}
telsoa015307bc12018-03-09 13:51:08 +0000125
126void DumpTensor(const std::string& dumpDir,
telsoa01ce3e84a2018-08-31 09:31:35 +0100127 const std::string& requestName,
128 const std::string& tensorName,
129 const armnn::ConstTensor& tensor);
130
131void DumpJsonProfilingIfRequired(bool gpuProfilingEnabled,
132 const std::string& dumpDir,
133 armnn::NetworkId networkId,
134 const armnn::IProfiler* profiler);
telsoa015307bc12018-03-09 13:51:08 +0000135
Jim Flynn829ad302019-12-13 14:43:24 +0000136std::string ExportNetworkGraphToDotFile(const armnn::IOptimizedNetwork& optimizedNetwork,
137 const std::string& dumpDir);
telsoa01ce3e84a2018-08-31 09:31:35 +0100138
Sadik Armaganb3021432021-01-13 15:56:51 +0000139std::string SerializeNetwork(const armnn::INetwork& network, const std::string& dumpDir);
140
141void RenameExportedFiles(const std::string& existingSerializedFileName,
142 const std::string& existingDotFileName,
143 const std::string& dumpDir,
144 const armnn::NetworkId networkId);
145
146void RenameFile(const std::string& existingName,
147 const std::string& extension,
148 const std::string& dumpDir,
149 const armnn::NetworkId networkId);
Matteo Martincighe48bdff2018-09-03 13:50:50 +0100150
Aron Virginas-Tar573a8fa2019-07-23 14:01:37 +0100151/// Checks if a tensor info represents a dynamic tensor
152bool IsDynamicTensor(const armnn::TensorInfo& outputInfo);
153
Finn Williamsa4983ce2020-07-23 12:55:12 +0100154/// Checks for ArmNN support of dynamic tensors.
155bool AreDynamicTensorsSupported(void);
156
Jim Flynn829ad302019-12-13 14:43:24 +0000157std::string GetFileTimestamp();
158
Kevin May42477c12020-03-26 13:34:14 +0000159#if defined(ARMNN_ANDROID_NN_V1_2) || defined(ARMNN_ANDROID_NN_V1_3)
160inline V1_2::OutputShape ComputeShape(const armnn::TensorInfo& info)
161{
162 V1_2::OutputShape shape;
163
Kevin May42477c12020-03-26 13:34:14 +0000164 armnn::TensorShape tensorShape = info.GetShape();
Finn Williamsfc884b42020-06-11 17:35:44 +0100165 // Android will expect scalars as a zero dimensional tensor
166 if(tensorShape.GetDimensionality() == armnn::Dimensionality::Scalar)
Kevin May42477c12020-03-26 13:34:14 +0000167 {
Finn Williamsfc884b42020-06-11 17:35:44 +0100168 shape.dimensions = android::hardware::hidl_vec<uint32_t>{};
169 }
170 else
171 {
172 android::hardware::hidl_vec<uint32_t> dimensions;
173 const unsigned int numDims = tensorShape.GetNumDimensions();
174 dimensions.resize(numDims);
175 for (unsigned int outputIdx = 0u; outputIdx < numDims; ++outputIdx)
176 {
177 dimensions[outputIdx] = tensorShape[outputIdx];
178 }
179 shape.dimensions = dimensions;
Kevin May42477c12020-03-26 13:34:14 +0000180 }
181
Kevin May42477c12020-03-26 13:34:14 +0000182 shape.isSufficient = true;
183
184 return shape;
185}
186#endif
187
188void CommitPools(std::vector<::android::nn::RunTimePoolInfo>& memPools);
189
Matthew Bentham912b3622019-05-03 15:49:14 +0100190} // namespace armnn_driver