blob: da101535ffa2eafe08874b35636fbb0520c923ec [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
129void DumpTensor(const std::string& dumpDir,
telsoa01ce3e84a2018-08-31 09:31:35 +0100130 const std::string& requestName,
131 const std::string& tensorName,
132 const armnn::ConstTensor& tensor);
133
134void DumpJsonProfilingIfRequired(bool gpuProfilingEnabled,
135 const std::string& dumpDir,
136 armnn::NetworkId networkId,
137 const armnn::IProfiler* profiler);
telsoa015307bc12018-03-09 13:51:08 +0000138
Jim Flynn829ad302019-12-13 14:43:24 +0000139std::string ExportNetworkGraphToDotFile(const armnn::IOptimizedNetwork& optimizedNetwork,
140 const std::string& dumpDir);
telsoa01ce3e84a2018-08-31 09:31:35 +0100141
Sadik Armaganb3021432021-01-13 15:56:51 +0000142std::string SerializeNetwork(const armnn::INetwork& network, const std::string& dumpDir);
143
144void RenameExportedFiles(const std::string& existingSerializedFileName,
145 const std::string& existingDotFileName,
146 const std::string& dumpDir,
147 const armnn::NetworkId networkId);
148
149void RenameFile(const std::string& existingName,
150 const std::string& extension,
151 const std::string& dumpDir,
152 const armnn::NetworkId networkId);
Matteo Martincighe48bdff2018-09-03 13:50:50 +0100153
Aron Virginas-Tar573a8fa2019-07-23 14:01:37 +0100154/// Checks if a tensor info represents a dynamic tensor
155bool IsDynamicTensor(const armnn::TensorInfo& outputInfo);
156
Finn Williamsa4983ce2020-07-23 12:55:12 +0100157/// Checks for ArmNN support of dynamic tensors.
158bool AreDynamicTensorsSupported(void);
159
Jim Flynn829ad302019-12-13 14:43:24 +0000160std::string GetFileTimestamp();
161
Kevin May42477c12020-03-26 13:34:14 +0000162#if defined(ARMNN_ANDROID_NN_V1_2) || defined(ARMNN_ANDROID_NN_V1_3)
163inline V1_2::OutputShape ComputeShape(const armnn::TensorInfo& info)
164{
165 V1_2::OutputShape shape;
166
Kevin May42477c12020-03-26 13:34:14 +0000167 armnn::TensorShape tensorShape = info.GetShape();
Finn Williamsfc884b42020-06-11 17:35:44 +0100168 // Android will expect scalars as a zero dimensional tensor
169 if(tensorShape.GetDimensionality() == armnn::Dimensionality::Scalar)
Kevin May42477c12020-03-26 13:34:14 +0000170 {
Finn Williamsfc884b42020-06-11 17:35:44 +0100171 shape.dimensions = android::hardware::hidl_vec<uint32_t>{};
172 }
173 else
174 {
175 android::hardware::hidl_vec<uint32_t> dimensions;
176 const unsigned int numDims = tensorShape.GetNumDimensions();
177 dimensions.resize(numDims);
178 for (unsigned int outputIdx = 0u; outputIdx < numDims; ++outputIdx)
179 {
180 dimensions[outputIdx] = tensorShape[outputIdx];
181 }
182 shape.dimensions = dimensions;
Kevin May42477c12020-03-26 13:34:14 +0000183 }
184
Kevin May42477c12020-03-26 13:34:14 +0000185 shape.isSufficient = true;
186
187 return shape;
188}
189#endif
190
191void CommitPools(std::vector<::android::nn::RunTimePoolInfo>& memPools);
192
Matthew Bentham912b3622019-05-03 15:49:14 +0100193} // namespace armnn_driver