blob: 0a872b72e7405763658a68403484a402712e52f9 [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>
Michael Butlerefd0f262021-01-11 13:21:44 -080011#include <LegacyHalUtils.h>
arovir01b0717b52018-09-05 17:03:25 +010012#include <NeuralNetworks.h>
Kevin DuBois30c34ae2020-08-26 13:53:41 -070013#include "NamespaceAdaptor.hpp"
telsoa015307bc12018-03-09 13:51:08 +000014
15#include <vector>
16#include <string>
Matteo Martincighe48bdff2018-09-03 13:50:50 +010017#include <fstream>
18#include <iomanip>
telsoa015307bc12018-03-09 13:51:08 +000019
Matthew Bentham912b3622019-05-03 15:49:14 +010020namespace V1_0 = ::android::hardware::neuralnetworks::V1_0;
Kevin May42477c12020-03-26 13:34:14 +000021namespace V1_1 = ::android::hardware::neuralnetworks::V1_1;
Matthew Bentham912b3622019-05-03 15:49:14 +010022
Kevin May42477c12020-03-26 13:34:14 +000023#if defined(ARMNN_ANDROID_NN_V1_2) || defined(ARMNN_ANDROID_NN_V1_3)
Mike Kellyb5fdf382019-06-11 16:35:25 +010024namespace V1_2 = ::android::hardware::neuralnetworks::V1_2;
25#endif
26
Kevin May42477c12020-03-26 13:34:14 +000027#ifdef ARMNN_ANDROID_NN_V1_3
28namespace V1_3 = ::android::hardware::neuralnetworks::V1_3;
29#endif
30
telsoa015307bc12018-03-09 13:51:08 +000031namespace armnn_driver
32{
33
Kevin DuBoisc0945c72020-11-20 16:57:09 -080034#ifdef ARMNN_ANDROID_S
35using DataLocation = ::android::nn::DataLocation;
36#elif ARMNN_ANDROID_R
Kevin Mayec1e5b82020-02-26 17:00:39 +000037using DataLocation = ::android::nn::hal::DataLocation;
38#endif
39
Kevin May42477c12020-03-26 13:34:14 +000040inline const V1_0::Model& getMainModel(const V1_0::Model& model) { return model; }
41inline const V1_1::Model& getMainModel(const V1_1::Model& model) { return model; }
42
43#if defined (ARMNN_ANDROID_NN_V1_2) || defined (ARMNN_ANDROID_NN_V1_3)
44inline const V1_2::Model& getMainModel(const V1_2::Model& model) { return model; }
45#endif
46
47#ifdef ARMNN_ANDROID_NN_V1_3
48inline const V1_3::Subgraph& getMainModel(const V1_3::Model& model) { return model.main; }
49#endif
50
telsoa015307bc12018-03-09 13:51:08 +000051extern const armnn::PermutationVector g_DontPermute;
52
Mike Kellyb5fdf382019-06-11 16:35:25 +010053template <typename OperandType>
telsoa015307bc12018-03-09 13:51:08 +000054class UnsupportedOperand: public std::runtime_error
55{
56public:
Mike Kellyb5fdf382019-06-11 16:35:25 +010057 UnsupportedOperand(const OperandType type)
telsoa015307bc12018-03-09 13:51:08 +000058 : std::runtime_error("Operand type is unsupported")
59 , m_type(type)
60 {}
61
Mike Kellyb5fdf382019-06-11 16:35:25 +010062 OperandType m_type;
telsoa015307bc12018-03-09 13:51:08 +000063};
64
65/// Swizzles tensor data in @a input according to the dimension mappings.
66void SwizzleAndroidNn4dTensorToArmNn(const armnn::TensorInfo& tensor, const void* input, void* output,
67 const armnn::PermutationVector& mappings);
68
69/// Returns a pointer to a specific location in a pool
Kevin DuBois30c34ae2020-08-26 13:53:41 -070070void* GetMemoryFromPool(V1_0::DataLocation location,
telsoa015307bc12018-03-09 13:51:08 +000071 const std::vector<android::nn::RunTimePoolInfo>& memPools);
72
73/// Can throw UnsupportedOperand
Matthew Bentham912b3622019-05-03 15:49:14 +010074armnn::TensorInfo GetTensorInfoForOperand(const V1_0::Operand& operand);
telsoa015307bc12018-03-09 13:51:08 +000075
Kevin May42477c12020-03-26 13:34:14 +000076#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 +010077armnn::TensorInfo GetTensorInfoForOperand(const V1_2::Operand& operand);
78#endif
79
Kevin May42477c12020-03-26 13:34:14 +000080#ifdef ARMNN_ANDROID_NN_V1_3 // Using ::android::hardware::neuralnetworks::V1_3
81armnn::TensorInfo GetTensorInfoForOperand(const V1_3::Operand& operand);
82#endif
83
Matthew Bentham912b3622019-05-03 15:49:14 +010084std::string GetOperandSummary(const V1_0::Operand& operand);
kevmay01bc5f7842018-08-30 12:34:39 +010085
Kevin May42477c12020-03-26 13:34:14 +000086#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 +010087std::string GetOperandSummary(const V1_2::Operand& operand);
88#endif
89
Kevin May42477c12020-03-26 13:34:14 +000090#ifdef ARMNN_ANDROID_NN_V1_3 // Using ::android::hardware::neuralnetworks::V1_3
91std::string GetOperandSummary(const V1_3::Operand& operand);
92#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
Jim Flynn829ad302019-12-13 14:43:24 +0000142void RenameGraphDotFile(const std::string& oldName, const std::string& dumpDir, const armnn::NetworkId networkId);
Matteo Martincighe48bdff2018-09-03 13:50:50 +0100143
Aron Virginas-Tar573a8fa2019-07-23 14:01:37 +0100144/// Checks if a tensor info represents a dynamic tensor
145bool IsDynamicTensor(const armnn::TensorInfo& outputInfo);
146
Finn Williamsa4983ce2020-07-23 12:55:12 +0100147/// Checks for ArmNN support of dynamic tensors.
148bool AreDynamicTensorsSupported(void);
149
Jim Flynn829ad302019-12-13 14:43:24 +0000150std::string GetFileTimestamp();
151
Kevin May42477c12020-03-26 13:34:14 +0000152#if defined(ARMNN_ANDROID_NN_V1_2) || defined(ARMNN_ANDROID_NN_V1_3)
153inline V1_2::OutputShape ComputeShape(const armnn::TensorInfo& info)
154{
155 V1_2::OutputShape shape;
156
Kevin May42477c12020-03-26 13:34:14 +0000157 armnn::TensorShape tensorShape = info.GetShape();
Finn Williamsfc884b42020-06-11 17:35:44 +0100158 // Android will expect scalars as a zero dimensional tensor
159 if(tensorShape.GetDimensionality() == armnn::Dimensionality::Scalar)
Kevin May42477c12020-03-26 13:34:14 +0000160 {
Finn Williamsfc884b42020-06-11 17:35:44 +0100161 shape.dimensions = android::hardware::hidl_vec<uint32_t>{};
162 }
163 else
164 {
165 android::hardware::hidl_vec<uint32_t> dimensions;
166 const unsigned int numDims = tensorShape.GetNumDimensions();
167 dimensions.resize(numDims);
168 for (unsigned int outputIdx = 0u; outputIdx < numDims; ++outputIdx)
169 {
170 dimensions[outputIdx] = tensorShape[outputIdx];
171 }
172 shape.dimensions = dimensions;
Kevin May42477c12020-03-26 13:34:14 +0000173 }
174
Kevin May42477c12020-03-26 13:34:14 +0000175 shape.isSufficient = true;
176
177 return shape;
178}
179#endif
180
181void CommitPools(std::vector<::android::nn::RunTimePoolInfo>& memPools);
182
Matthew Bentham912b3622019-05-03 15:49:14 +0100183} // namespace armnn_driver