blob: 6e733a26335bbec1ea614601972c50e9f667f01b [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.
Jan Eilersa71c0632021-04-12 13:12:19 +010063void SwizzleAndroidNn4dTensorToArmNn(armnn::TensorInfo& tensor, const void* input, void* output,
telsoa015307bc12018-03-09 13:51:08 +000064 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
Teresa Charlind3381d52021-06-02 18:35:16 +010073std::string GetOperandSummary(const V1_0::Operand& operand);
74
75// Returns true for any quantized data type, false for the rest.
76bool isQuantizedOperand(const V1_0::OperandType& operandType);
77
Kevin May42477c12020-03-26 13:34:14 +000078#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 +010079armnn::TensorInfo GetTensorInfoForOperand(const V1_2::Operand& operand);
Teresa Charlind3381d52021-06-02 18:35:16 +010080
81std::string GetOperandSummary(const V1_2::Operand& operand);
82
83bool isQuantizedOperand(const V1_2::OperandType& operandType);
Mike Kellyb5fdf382019-06-11 16:35:25 +010084#endif
85
Kevin May42477c12020-03-26 13:34:14 +000086#ifdef ARMNN_ANDROID_NN_V1_3 // Using ::android::hardware::neuralnetworks::V1_3
87armnn::TensorInfo GetTensorInfoForOperand(const V1_3::Operand& operand);
Kevin May42477c12020-03-26 13:34:14 +000088
Kevin May42477c12020-03-26 13:34:14 +000089std::string GetOperandSummary(const V1_3::Operand& operand);
Teresa Charlind3381d52021-06-02 18:35:16 +010090
91bool isQuantizedOperand(const V1_3::OperandType& operandType);
Kevin May42477c12020-03-26 13:34:14 +000092#endif
93
Matteo Martincighe48bdff2018-09-03 13:50:50 +010094template <typename HalModel>
95std::string GetModelSummary(const HalModel& model)
kevmay01bc5f7842018-08-30 12:34:39 +010096{
97 std::stringstream result;
98
Kevin May42477c12020-03-26 13:34:14 +000099 result << getMainModel(model).inputIndexes.size() << " input(s), "
100 << getMainModel(model).operations.size() << " operation(s), "
101 << getMainModel(model).outputIndexes.size() << " output(s), "
102 << getMainModel(model).operands.size() << " operand(s) "
103 << std::endl;
kevmay01bc5f7842018-08-30 12:34:39 +0100104
105 result << "Inputs: ";
Kevin May42477c12020-03-26 13:34:14 +0000106 for (uint32_t i = 0; i < getMainModel(model).inputIndexes.size(); i++)
kevmay01bc5f7842018-08-30 12:34:39 +0100107 {
Kevin May42477c12020-03-26 13:34:14 +0000108 result << GetOperandSummary(getMainModel(model).operands[getMainModel(model).inputIndexes[i]]) << ", ";
kevmay01bc5f7842018-08-30 12:34:39 +0100109 }
110 result << std::endl;
111
112 result << "Operations: ";
Kevin May42477c12020-03-26 13:34:14 +0000113 for (uint32_t i = 0; i < getMainModel(model).operations.size(); i++)
kevmay01bc5f7842018-08-30 12:34:39 +0100114 {
Kevin May42477c12020-03-26 13:34:14 +0000115 result << toString(getMainModel(model).operations[i].type).c_str() << ", ";
kevmay01bc5f7842018-08-30 12:34:39 +0100116 }
117 result << std::endl;
118
119 result << "Outputs: ";
Kevin May42477c12020-03-26 13:34:14 +0000120 for (uint32_t i = 0; i < getMainModel(model).outputIndexes.size(); i++)
kevmay01bc5f7842018-08-30 12:34:39 +0100121 {
Kevin May42477c12020-03-26 13:34:14 +0000122 result << GetOperandSummary(getMainModel(model).operands[getMainModel(model).outputIndexes[i]]) << ", ";
kevmay01bc5f7842018-08-30 12:34:39 +0100123 }
124 result << std::endl;
125
126 return result.str();
127}
telsoa015307bc12018-03-09 13:51:08 +0000128
Mike Kellybc8caca2021-11-09 15:43:37 +0000129template <typename TensorType>
telsoa015307bc12018-03-09 13:51:08 +0000130void DumpTensor(const std::string& dumpDir,
telsoa01ce3e84a2018-08-31 09:31:35 +0100131 const std::string& requestName,
132 const std::string& tensorName,
Mike Kellybc8caca2021-11-09 15:43:37 +0000133 const TensorType& tensor);
telsoa01ce3e84a2018-08-31 09:31:35 +0100134
135void DumpJsonProfilingIfRequired(bool gpuProfilingEnabled,
136 const std::string& dumpDir,
137 armnn::NetworkId networkId,
138 const armnn::IProfiler* profiler);
telsoa015307bc12018-03-09 13:51:08 +0000139
Jim Flynn829ad302019-12-13 14:43:24 +0000140std::string ExportNetworkGraphToDotFile(const armnn::IOptimizedNetwork& optimizedNetwork,
141 const std::string& dumpDir);
telsoa01ce3e84a2018-08-31 09:31:35 +0100142
Sadik Armagan0a2dfab2021-10-06 16:41:44 +0100143std::string SerializeNetwork(const armnn::INetwork& network,
144 const std::string& dumpDir,
145 std::vector<uint8_t>& dataCacheData,
146 bool dataCachingActive = true);
Sadik Armaganb3021432021-01-13 15:56:51 +0000147
148void RenameExportedFiles(const std::string& existingSerializedFileName,
149 const std::string& existingDotFileName,
150 const std::string& dumpDir,
151 const armnn::NetworkId networkId);
152
153void RenameFile(const std::string& existingName,
154 const std::string& extension,
155 const std::string& dumpDir,
156 const armnn::NetworkId networkId);
Matteo Martincighe48bdff2018-09-03 13:50:50 +0100157
Aron Virginas-Tar573a8fa2019-07-23 14:01:37 +0100158/// Checks if a tensor info represents a dynamic tensor
159bool IsDynamicTensor(const armnn::TensorInfo& outputInfo);
160
Finn Williamsa4983ce2020-07-23 12:55:12 +0100161/// Checks for ArmNN support of dynamic tensors.
162bool AreDynamicTensorsSupported(void);
163
Jim Flynn829ad302019-12-13 14:43:24 +0000164std::string GetFileTimestamp();
165
Kevin May42477c12020-03-26 13:34:14 +0000166#if defined(ARMNN_ANDROID_NN_V1_2) || defined(ARMNN_ANDROID_NN_V1_3)
167inline V1_2::OutputShape ComputeShape(const armnn::TensorInfo& info)
168{
169 V1_2::OutputShape shape;
170
Kevin May42477c12020-03-26 13:34:14 +0000171 armnn::TensorShape tensorShape = info.GetShape();
Finn Williamsfc884b42020-06-11 17:35:44 +0100172 // Android will expect scalars as a zero dimensional tensor
173 if(tensorShape.GetDimensionality() == armnn::Dimensionality::Scalar)
Kevin May42477c12020-03-26 13:34:14 +0000174 {
Finn Williamsfc884b42020-06-11 17:35:44 +0100175 shape.dimensions = android::hardware::hidl_vec<uint32_t>{};
176 }
177 else
178 {
179 android::hardware::hidl_vec<uint32_t> dimensions;
180 const unsigned int numDims = tensorShape.GetNumDimensions();
181 dimensions.resize(numDims);
182 for (unsigned int outputIdx = 0u; outputIdx < numDims; ++outputIdx)
183 {
184 dimensions[outputIdx] = tensorShape[outputIdx];
185 }
186 shape.dimensions = dimensions;
Kevin May42477c12020-03-26 13:34:14 +0000187 }
188
Kevin May42477c12020-03-26 13:34:14 +0000189 shape.isSufficient = true;
190
191 return shape;
192}
193#endif
194
195void CommitPools(std::vector<::android::nn::RunTimePoolInfo>& memPools);
196
Matthew Bentham912b3622019-05-03 15:49:14 +0100197} // namespace armnn_driver