blob: 86eb6db48d03c40c8e0c86b5c2cd6128dfec781d [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>
telsoa015307bc12018-03-09 13:51:08 +000012
Matteo Martincighe48bdff2018-09-03 13:50:50 +010013#include <boost/format.hpp>
14#include <log/log.h>
15
telsoa015307bc12018-03-09 13:51:08 +000016#include <vector>
17#include <string>
Matteo Martincighe48bdff2018-09-03 13:50:50 +010018#include <fstream>
19#include <iomanip>
telsoa015307bc12018-03-09 13:51:08 +000020
Matthew Bentham912b3622019-05-03 15:49:14 +010021namespace V1_0 = ::android::hardware::neuralnetworks::V1_0;
Kevin May42477c12020-03-26 13:34:14 +000022namespace V1_1 = ::android::hardware::neuralnetworks::V1_1;
Matthew Bentham912b3622019-05-03 15:49:14 +010023
Kevin May42477c12020-03-26 13:34:14 +000024#if defined(ARMNN_ANDROID_NN_V1_2) || defined(ARMNN_ANDROID_NN_V1_3)
Mike Kellyb5fdf382019-06-11 16:35:25 +010025namespace V1_2 = ::android::hardware::neuralnetworks::V1_2;
26#endif
27
Kevin May42477c12020-03-26 13:34:14 +000028#ifdef ARMNN_ANDROID_NN_V1_3
29namespace V1_3 = ::android::hardware::neuralnetworks::V1_3;
30#endif
31
telsoa015307bc12018-03-09 13:51:08 +000032namespace armnn_driver
33{
34
Kevin Mayec1e5b82020-02-26 17:00:39 +000035#ifdef ARMNN_ANDROID_R
36using DataLocation = ::android::nn::hal::DataLocation;
37#endif
38
Kevin May42477c12020-03-26 13:34:14 +000039inline const V1_0::Model& getMainModel(const V1_0::Model& model) { return model; }
40inline const V1_1::Model& getMainModel(const V1_1::Model& model) { return model; }
41
42#if defined (ARMNN_ANDROID_NN_V1_2) || defined (ARMNN_ANDROID_NN_V1_3)
43inline const V1_2::Model& getMainModel(const V1_2::Model& model) { return model; }
44#endif
45
46#ifdef ARMNN_ANDROID_NN_V1_3
47inline const V1_3::Subgraph& getMainModel(const V1_3::Model& model) { return model.main; }
48#endif
49
telsoa015307bc12018-03-09 13:51:08 +000050extern const armnn::PermutationVector g_DontPermute;
51
Mike Kellyb5fdf382019-06-11 16:35:25 +010052template <typename OperandType>
telsoa015307bc12018-03-09 13:51:08 +000053class UnsupportedOperand: public std::runtime_error
54{
55public:
Mike Kellyb5fdf382019-06-11 16:35:25 +010056 UnsupportedOperand(const OperandType type)
telsoa015307bc12018-03-09 13:51:08 +000057 : std::runtime_error("Operand type is unsupported")
58 , m_type(type)
59 {}
60
Mike Kellyb5fdf382019-06-11 16:35:25 +010061 OperandType m_type;
telsoa015307bc12018-03-09 13:51:08 +000062};
63
64/// Swizzles tensor data in @a input according to the dimension mappings.
65void SwizzleAndroidNn4dTensorToArmNn(const armnn::TensorInfo& tensor, const void* input, void* output,
66 const armnn::PermutationVector& mappings);
67
68/// Returns a pointer to a specific location in a pool
69void* GetMemoryFromPool(DataLocation location,
70 const std::vector<android::nn::RunTimePoolInfo>& memPools);
71
72/// Can throw UnsupportedOperand
Matthew Bentham912b3622019-05-03 15:49:14 +010073armnn::TensorInfo GetTensorInfoForOperand(const V1_0::Operand& operand);
telsoa015307bc12018-03-09 13:51:08 +000074
Kevin May42477c12020-03-26 13:34:14 +000075#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 +010076armnn::TensorInfo GetTensorInfoForOperand(const V1_2::Operand& operand);
77#endif
78
Kevin May42477c12020-03-26 13:34:14 +000079#ifdef ARMNN_ANDROID_NN_V1_3 // Using ::android::hardware::neuralnetworks::V1_3
80armnn::TensorInfo GetTensorInfoForOperand(const V1_3::Operand& operand);
81#endif
82
Matthew Bentham912b3622019-05-03 15:49:14 +010083std::string GetOperandSummary(const V1_0::Operand& operand);
kevmay01bc5f7842018-08-30 12:34:39 +010084
Kevin May42477c12020-03-26 13:34:14 +000085#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 +010086std::string GetOperandSummary(const V1_2::Operand& operand);
87#endif
88
Kevin May42477c12020-03-26 13:34:14 +000089#ifdef ARMNN_ANDROID_NN_V1_3 // Using ::android::hardware::neuralnetworks::V1_3
90std::string GetOperandSummary(const V1_3::Operand& operand);
91#endif
92
Matteo Martincighe48bdff2018-09-03 13:50:50 +010093template <typename HalModel>
94std::string GetModelSummary(const HalModel& model)
kevmay01bc5f7842018-08-30 12:34:39 +010095{
96 std::stringstream result;
97
Kevin May42477c12020-03-26 13:34:14 +000098 result << getMainModel(model).inputIndexes.size() << " input(s), "
99 << getMainModel(model).operations.size() << " operation(s), "
100 << getMainModel(model).outputIndexes.size() << " output(s), "
101 << getMainModel(model).operands.size() << " operand(s) "
102 << std::endl;
kevmay01bc5f7842018-08-30 12:34:39 +0100103
104 result << "Inputs: ";
Kevin May42477c12020-03-26 13:34:14 +0000105 for (uint32_t i = 0; i < getMainModel(model).inputIndexes.size(); i++)
kevmay01bc5f7842018-08-30 12:34:39 +0100106 {
Kevin May42477c12020-03-26 13:34:14 +0000107 result << GetOperandSummary(getMainModel(model).operands[getMainModel(model).inputIndexes[i]]) << ", ";
kevmay01bc5f7842018-08-30 12:34:39 +0100108 }
109 result << std::endl;
110
111 result << "Operations: ";
Kevin May42477c12020-03-26 13:34:14 +0000112 for (uint32_t i = 0; i < getMainModel(model).operations.size(); i++)
kevmay01bc5f7842018-08-30 12:34:39 +0100113 {
Kevin May42477c12020-03-26 13:34:14 +0000114 result << toString(getMainModel(model).operations[i].type).c_str() << ", ";
kevmay01bc5f7842018-08-30 12:34:39 +0100115 }
116 result << std::endl;
117
118 result << "Outputs: ";
Kevin May42477c12020-03-26 13:34:14 +0000119 for (uint32_t i = 0; i < getMainModel(model).outputIndexes.size(); i++)
kevmay01bc5f7842018-08-30 12:34:39 +0100120 {
Kevin May42477c12020-03-26 13:34:14 +0000121 result << GetOperandSummary(getMainModel(model).operands[getMainModel(model).outputIndexes[i]]) << ", ";
kevmay01bc5f7842018-08-30 12:34:39 +0100122 }
123 result << std::endl;
124
125 return result.str();
126}
telsoa015307bc12018-03-09 13:51:08 +0000127
128void DumpTensor(const std::string& dumpDir,
telsoa01ce3e84a2018-08-31 09:31:35 +0100129 const std::string& requestName,
130 const std::string& tensorName,
131 const armnn::ConstTensor& tensor);
132
133void DumpJsonProfilingIfRequired(bool gpuProfilingEnabled,
134 const std::string& dumpDir,
135 armnn::NetworkId networkId,
136 const armnn::IProfiler* profiler);
telsoa015307bc12018-03-09 13:51:08 +0000137
Jim Flynn829ad302019-12-13 14:43:24 +0000138std::string ExportNetworkGraphToDotFile(const armnn::IOptimizedNetwork& optimizedNetwork,
139 const std::string& dumpDir);
telsoa01ce3e84a2018-08-31 09:31:35 +0100140
Jim Flynn829ad302019-12-13 14:43:24 +0000141void RenameGraphDotFile(const std::string& oldName, const std::string& dumpDir, const armnn::NetworkId networkId);
Matteo Martincighe48bdff2018-09-03 13:50:50 +0100142
Aron Virginas-Tar573a8fa2019-07-23 14:01:37 +0100143/// Checks if a tensor info represents a dynamic tensor
144bool IsDynamicTensor(const armnn::TensorInfo& outputInfo);
145
Finn Williamsa4983ce2020-07-23 12:55:12 +0100146/// Checks for ArmNN support of dynamic tensors.
147bool AreDynamicTensorsSupported(void);
148
Jim Flynn829ad302019-12-13 14:43:24 +0000149std::string GetFileTimestamp();
150
Kevin May42477c12020-03-26 13:34:14 +0000151#if defined(ARMNN_ANDROID_NN_V1_2) || defined(ARMNN_ANDROID_NN_V1_3)
152inline V1_2::OutputShape ComputeShape(const armnn::TensorInfo& info)
153{
154 V1_2::OutputShape shape;
155
Kevin May42477c12020-03-26 13:34:14 +0000156 armnn::TensorShape tensorShape = info.GetShape();
Finn Williamsfc884b42020-06-11 17:35:44 +0100157 // Android will expect scalars as a zero dimensional tensor
158 if(tensorShape.GetDimensionality() == armnn::Dimensionality::Scalar)
Kevin May42477c12020-03-26 13:34:14 +0000159 {
Finn Williamsfc884b42020-06-11 17:35:44 +0100160 shape.dimensions = android::hardware::hidl_vec<uint32_t>{};
161 }
162 else
163 {
164 android::hardware::hidl_vec<uint32_t> dimensions;
165 const unsigned int numDims = tensorShape.GetNumDimensions();
166 dimensions.resize(numDims);
167 for (unsigned int outputIdx = 0u; outputIdx < numDims; ++outputIdx)
168 {
169 dimensions[outputIdx] = tensorShape[outputIdx];
170 }
171 shape.dimensions = dimensions;
Kevin May42477c12020-03-26 13:34:14 +0000172 }
173
Kevin May42477c12020-03-26 13:34:14 +0000174 shape.isSufficient = true;
175
176 return shape;
177}
178#endif
179
180void CommitPools(std::vector<::android::nn::RunTimePoolInfo>& memPools);
181
Matthew Bentham912b3622019-05-03 15:49:14 +0100182} // namespace armnn_driver