1*89c4ff92SAndroid Build Coastguard Worker //
2*89c4ff92SAndroid Build Coastguard Worker // Copyright © 2022 Arm Ltd and Contributors. All rights reserved.
3*89c4ff92SAndroid Build Coastguard Worker // SPDX-License-Identifier: MIT
4*89c4ff92SAndroid Build Coastguard Worker //
5*89c4ff92SAndroid Build Coastguard Worker
6*89c4ff92SAndroid Build Coastguard Worker #define LOG_TAG "arm-armnn-sl"
7*89c4ff92SAndroid Build Coastguard Worker
8*89c4ff92SAndroid Build Coastguard Worker #include "CanonicalUtils.hpp"
9*89c4ff92SAndroid Build Coastguard Worker
10*89c4ff92SAndroid Build Coastguard Worker #include <armnn/Utils.hpp>
11*89c4ff92SAndroid Build Coastguard Worker #include <armnn/utility/Assert.hpp>
12*89c4ff92SAndroid Build Coastguard Worker #include <armnnSerializer/ISerializer.hpp>
13*89c4ff92SAndroid Build Coastguard Worker #include <armnnUtils/Permute.hpp>
14*89c4ff92SAndroid Build Coastguard Worker
15*89c4ff92SAndroid Build Coastguard Worker #include <ghc/filesystem.hpp>
16*89c4ff92SAndroid Build Coastguard Worker namespace fs = ghc::filesystem;
17*89c4ff92SAndroid Build Coastguard Worker #include <half/half.hpp>
18*89c4ff92SAndroid Build Coastguard Worker #include <log/log.h>
19*89c4ff92SAndroid Build Coastguard Worker
20*89c4ff92SAndroid Build Coastguard Worker #include <cassert>
21*89c4ff92SAndroid Build Coastguard Worker #include <cerrno>
22*89c4ff92SAndroid Build Coastguard Worker #include <cinttypes>
23*89c4ff92SAndroid Build Coastguard Worker #include <cstdio>
24*89c4ff92SAndroid Build Coastguard Worker #include <sstream>
25*89c4ff92SAndroid Build Coastguard Worker #include <time.h>
26*89c4ff92SAndroid Build Coastguard Worker #include <variant>
27*89c4ff92SAndroid Build Coastguard Worker
28*89c4ff92SAndroid Build Coastguard Worker namespace armnn
29*89c4ff92SAndroid Build Coastguard Worker {
30*89c4ff92SAndroid Build Coastguard Worker using Half = half_float::half; //import half float implementation
31*89c4ff92SAndroid Build Coastguard Worker } //namespace armnn
32*89c4ff92SAndroid Build Coastguard Worker
33*89c4ff92SAndroid Build Coastguard Worker using namespace android;
34*89c4ff92SAndroid Build Coastguard Worker using namespace android::nn;
35*89c4ff92SAndroid Build Coastguard Worker
36*89c4ff92SAndroid Build Coastguard Worker namespace armnn_driver
37*89c4ff92SAndroid Build Coastguard Worker {
38*89c4ff92SAndroid Build Coastguard Worker const armnn::PermutationVector g_DontPermute{};
39*89c4ff92SAndroid Build Coastguard Worker
SwizzleAndroidNn4dTensorToArmNn(armnn::TensorInfo & tensorInfo,const void * input,void * output,const armnn::PermutationVector & mappings)40*89c4ff92SAndroid Build Coastguard Worker void SwizzleAndroidNn4dTensorToArmNn(armnn::TensorInfo& tensorInfo,
41*89c4ff92SAndroid Build Coastguard Worker const void* input,
42*89c4ff92SAndroid Build Coastguard Worker void* output,
43*89c4ff92SAndroid Build Coastguard Worker const armnn::PermutationVector& mappings)
44*89c4ff92SAndroid Build Coastguard Worker {
45*89c4ff92SAndroid Build Coastguard Worker assert(tensorInfo.GetNumDimensions() == 4U);
46*89c4ff92SAndroid Build Coastguard Worker
47*89c4ff92SAndroid Build Coastguard Worker armnn::DataType dataType = tensorInfo.GetDataType();
48*89c4ff92SAndroid Build Coastguard Worker switch (dataType)
49*89c4ff92SAndroid Build Coastguard Worker {
50*89c4ff92SAndroid Build Coastguard Worker case armnn::DataType::Float16:
51*89c4ff92SAndroid Build Coastguard Worker case armnn::DataType::Float32:
52*89c4ff92SAndroid Build Coastguard Worker case armnn::DataType::QAsymmU8:
53*89c4ff92SAndroid Build Coastguard Worker case armnn::DataType::QSymmS8:
54*89c4ff92SAndroid Build Coastguard Worker case armnn::DataType::QAsymmS8:
55*89c4ff92SAndroid Build Coastguard Worker // First swizzle tensor info
56*89c4ff92SAndroid Build Coastguard Worker tensorInfo = armnnUtils::Permuted(tensorInfo, mappings);
57*89c4ff92SAndroid Build Coastguard Worker // Then swizzle tensor data
58*89c4ff92SAndroid Build Coastguard Worker armnnUtils::Permute(tensorInfo.GetShape(), mappings, input, output, armnn::GetDataTypeSize(dataType));
59*89c4ff92SAndroid Build Coastguard Worker break;
60*89c4ff92SAndroid Build Coastguard Worker default:
61*89c4ff92SAndroid Build Coastguard Worker VLOG(DRIVER) << "Unknown armnn::DataType for swizzling";
62*89c4ff92SAndroid Build Coastguard Worker assert(0);
63*89c4ff92SAndroid Build Coastguard Worker }
64*89c4ff92SAndroid Build Coastguard Worker }
65*89c4ff92SAndroid Build Coastguard Worker
GetMemoryFromPool(DataLocation location,const std::vector<android::nn::RunTimePoolInfo> & memPools)66*89c4ff92SAndroid Build Coastguard Worker void* GetMemoryFromPool(DataLocation location, const std::vector<android::nn::RunTimePoolInfo>& memPools)
67*89c4ff92SAndroid Build Coastguard Worker {
68*89c4ff92SAndroid Build Coastguard Worker // find the location within the pool
69*89c4ff92SAndroid Build Coastguard Worker assert(location.poolIndex < memPools.size());
70*89c4ff92SAndroid Build Coastguard Worker
71*89c4ff92SAndroid Build Coastguard Worker const android::nn::RunTimePoolInfo& memPool = memPools[location.poolIndex];
72*89c4ff92SAndroid Build Coastguard Worker uint8_t* memPoolBuffer = memPool.getBuffer();
73*89c4ff92SAndroid Build Coastguard Worker uint8_t* memory = memPoolBuffer + location.offset;
74*89c4ff92SAndroid Build Coastguard Worker return memory;
75*89c4ff92SAndroid Build Coastguard Worker }
76*89c4ff92SAndroid Build Coastguard Worker
GetMemoryFromPointer(const Request::Argument & requestArg)77*89c4ff92SAndroid Build Coastguard Worker void* GetMemoryFromPointer(const Request::Argument& requestArg)
78*89c4ff92SAndroid Build Coastguard Worker {
79*89c4ff92SAndroid Build Coastguard Worker // get the pointer memory
80*89c4ff92SAndroid Build Coastguard Worker auto ptrMemory = std::visit([](std::variant<const void*, void*>&& memory)
81*89c4ff92SAndroid Build Coastguard Worker {
82*89c4ff92SAndroid Build Coastguard Worker if (std::holds_alternative<const void*>(memory))
83*89c4ff92SAndroid Build Coastguard Worker {
84*89c4ff92SAndroid Build Coastguard Worker auto ptr = std::get<const void*>(memory);
85*89c4ff92SAndroid Build Coastguard Worker auto ptrMemory = static_cast<const uint8_t*>(ptr);
86*89c4ff92SAndroid Build Coastguard Worker return const_cast<uint8_t*>(ptrMemory);
87*89c4ff92SAndroid Build Coastguard Worker }
88*89c4ff92SAndroid Build Coastguard Worker else
89*89c4ff92SAndroid Build Coastguard Worker {
90*89c4ff92SAndroid Build Coastguard Worker auto ptr = std::get<void*>(memory);
91*89c4ff92SAndroid Build Coastguard Worker return static_cast<uint8_t*>(ptr);
92*89c4ff92SAndroid Build Coastguard Worker }
93*89c4ff92SAndroid Build Coastguard Worker }, requestArg.location.pointer);
94*89c4ff92SAndroid Build Coastguard Worker return ptrMemory;
95*89c4ff92SAndroid Build Coastguard Worker }
96*89c4ff92SAndroid Build Coastguard Worker
GetTensorInfoForOperand(const Operand & operand)97*89c4ff92SAndroid Build Coastguard Worker armnn::TensorInfo GetTensorInfoForOperand(const Operand& operand)
98*89c4ff92SAndroid Build Coastguard Worker {
99*89c4ff92SAndroid Build Coastguard Worker using namespace armnn;
100*89c4ff92SAndroid Build Coastguard Worker bool perChannel = false;
101*89c4ff92SAndroid Build Coastguard Worker bool isScalar = false;
102*89c4ff92SAndroid Build Coastguard Worker
103*89c4ff92SAndroid Build Coastguard Worker DataType type;
104*89c4ff92SAndroid Build Coastguard Worker switch (operand.type)
105*89c4ff92SAndroid Build Coastguard Worker {
106*89c4ff92SAndroid Build Coastguard Worker case OperandType::TENSOR_BOOL8:
107*89c4ff92SAndroid Build Coastguard Worker type = armnn::DataType::Boolean;
108*89c4ff92SAndroid Build Coastguard Worker break;
109*89c4ff92SAndroid Build Coastguard Worker case OperandType::TENSOR_FLOAT32:
110*89c4ff92SAndroid Build Coastguard Worker type = armnn::DataType::Float32;
111*89c4ff92SAndroid Build Coastguard Worker break;
112*89c4ff92SAndroid Build Coastguard Worker case OperandType::TENSOR_FLOAT16:
113*89c4ff92SAndroid Build Coastguard Worker type = armnn::DataType::Float16;
114*89c4ff92SAndroid Build Coastguard Worker break;
115*89c4ff92SAndroid Build Coastguard Worker case OperandType::TENSOR_QUANT8_ASYMM:
116*89c4ff92SAndroid Build Coastguard Worker type = armnn::DataType::QAsymmU8;
117*89c4ff92SAndroid Build Coastguard Worker break;
118*89c4ff92SAndroid Build Coastguard Worker case OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL:
119*89c4ff92SAndroid Build Coastguard Worker perChannel=true;
120*89c4ff92SAndroid Build Coastguard Worker ARMNN_FALLTHROUGH;
121*89c4ff92SAndroid Build Coastguard Worker case OperandType::TENSOR_QUANT8_SYMM:
122*89c4ff92SAndroid Build Coastguard Worker type = armnn::DataType::QSymmS8;
123*89c4ff92SAndroid Build Coastguard Worker break;
124*89c4ff92SAndroid Build Coastguard Worker case OperandType::TENSOR_QUANT16_SYMM:
125*89c4ff92SAndroid Build Coastguard Worker type = armnn::DataType::QSymmS16;
126*89c4ff92SAndroid Build Coastguard Worker break;
127*89c4ff92SAndroid Build Coastguard Worker case OperandType::TENSOR_INT32:
128*89c4ff92SAndroid Build Coastguard Worker type = armnn::DataType::Signed32;
129*89c4ff92SAndroid Build Coastguard Worker break;
130*89c4ff92SAndroid Build Coastguard Worker case OperandType::INT32:
131*89c4ff92SAndroid Build Coastguard Worker type = armnn::DataType::Signed32;
132*89c4ff92SAndroid Build Coastguard Worker isScalar = true;
133*89c4ff92SAndroid Build Coastguard Worker break;
134*89c4ff92SAndroid Build Coastguard Worker case OperandType::TENSOR_QUANT8_ASYMM_SIGNED:
135*89c4ff92SAndroid Build Coastguard Worker type = armnn::DataType::QAsymmS8;
136*89c4ff92SAndroid Build Coastguard Worker break;
137*89c4ff92SAndroid Build Coastguard Worker default:
138*89c4ff92SAndroid Build Coastguard Worker throw UnsupportedOperand<OperandType>(operand.type);
139*89c4ff92SAndroid Build Coastguard Worker }
140*89c4ff92SAndroid Build Coastguard Worker
141*89c4ff92SAndroid Build Coastguard Worker TensorInfo ret;
142*89c4ff92SAndroid Build Coastguard Worker if (isScalar)
143*89c4ff92SAndroid Build Coastguard Worker {
144*89c4ff92SAndroid Build Coastguard Worker ret = TensorInfo(TensorShape(armnn::Dimensionality::Scalar), type);
145*89c4ff92SAndroid Build Coastguard Worker }
146*89c4ff92SAndroid Build Coastguard Worker else
147*89c4ff92SAndroid Build Coastguard Worker {
148*89c4ff92SAndroid Build Coastguard Worker if (operand.dimensions.size() == 0)
149*89c4ff92SAndroid Build Coastguard Worker {
150*89c4ff92SAndroid Build Coastguard Worker TensorShape tensorShape(Dimensionality::NotSpecified);
151*89c4ff92SAndroid Build Coastguard Worker ret = TensorInfo(tensorShape, type);
152*89c4ff92SAndroid Build Coastguard Worker }
153*89c4ff92SAndroid Build Coastguard Worker else
154*89c4ff92SAndroid Build Coastguard Worker {
155*89c4ff92SAndroid Build Coastguard Worker bool dimensionsSpecificity[5] = { true, true, true, true, true };
156*89c4ff92SAndroid Build Coastguard Worker int count = 0;
157*89c4ff92SAndroid Build Coastguard Worker std::for_each(operand.dimensions.data(),
158*89c4ff92SAndroid Build Coastguard Worker operand.dimensions.data() + operand.dimensions.size(),
159*89c4ff92SAndroid Build Coastguard Worker [&](const unsigned int val)
160*89c4ff92SAndroid Build Coastguard Worker {
161*89c4ff92SAndroid Build Coastguard Worker if (val == 0)
162*89c4ff92SAndroid Build Coastguard Worker {
163*89c4ff92SAndroid Build Coastguard Worker dimensionsSpecificity[count] = false;
164*89c4ff92SAndroid Build Coastguard Worker }
165*89c4ff92SAndroid Build Coastguard Worker count++;
166*89c4ff92SAndroid Build Coastguard Worker });
167*89c4ff92SAndroid Build Coastguard Worker
168*89c4ff92SAndroid Build Coastguard Worker TensorShape tensorShape(operand.dimensions.size(), operand.dimensions.data(), dimensionsSpecificity);
169*89c4ff92SAndroid Build Coastguard Worker ret = TensorInfo(tensorShape, type);
170*89c4ff92SAndroid Build Coastguard Worker }
171*89c4ff92SAndroid Build Coastguard Worker }
172*89c4ff92SAndroid Build Coastguard Worker
173*89c4ff92SAndroid Build Coastguard Worker if (perChannel)
174*89c4ff92SAndroid Build Coastguard Worker {
175*89c4ff92SAndroid Build Coastguard Worker // ExtraParams is expected to be of type channelQuant
176*89c4ff92SAndroid Build Coastguard Worker const auto& perAxisQuantParams = std::get<Operand::SymmPerChannelQuantParams>(operand.extraParams);
177*89c4ff92SAndroid Build Coastguard Worker
178*89c4ff92SAndroid Build Coastguard Worker ret.SetQuantizationScales(perAxisQuantParams.scales);
179*89c4ff92SAndroid Build Coastguard Worker ret.SetQuantizationDim(MakeOptional<unsigned int>(perAxisQuantParams.channelDim));
180*89c4ff92SAndroid Build Coastguard Worker }
181*89c4ff92SAndroid Build Coastguard Worker else
182*89c4ff92SAndroid Build Coastguard Worker {
183*89c4ff92SAndroid Build Coastguard Worker ret.SetQuantizationScale(operand.scale);
184*89c4ff92SAndroid Build Coastguard Worker ret.SetQuantizationOffset(operand.zeroPoint);
185*89c4ff92SAndroid Build Coastguard Worker }
186*89c4ff92SAndroid Build Coastguard Worker return ret;
187*89c4ff92SAndroid Build Coastguard Worker }
188*89c4ff92SAndroid Build Coastguard Worker
GetOperandSummary(const Operand & operand)189*89c4ff92SAndroid Build Coastguard Worker std::string GetOperandSummary(const Operand& operand)
190*89c4ff92SAndroid Build Coastguard Worker {
191*89c4ff92SAndroid Build Coastguard Worker std::stringstream ss;
192*89c4ff92SAndroid Build Coastguard Worker ss << "operand dimensions: [ ";
193*89c4ff92SAndroid Build Coastguard Worker for (unsigned int i = 0; i < operand.dimensions.size(); ++i)
194*89c4ff92SAndroid Build Coastguard Worker {
195*89c4ff92SAndroid Build Coastguard Worker ss << operand.dimensions[i] << " ";
196*89c4ff92SAndroid Build Coastguard Worker }
197*89c4ff92SAndroid Build Coastguard Worker ss << "] operand type: " << operand.type;
198*89c4ff92SAndroid Build Coastguard Worker return ss.str();
199*89c4ff92SAndroid Build Coastguard Worker }
200*89c4ff92SAndroid Build Coastguard Worker
201*89c4ff92SAndroid Build Coastguard Worker template <typename TensorType>
202*89c4ff92SAndroid Build Coastguard Worker using DumpElementFunction = void (*)(const TensorType& tensor,
203*89c4ff92SAndroid Build Coastguard Worker unsigned int elementIndex,
204*89c4ff92SAndroid Build Coastguard Worker std::ofstream& fileStream);
205*89c4ff92SAndroid Build Coastguard Worker
206*89c4ff92SAndroid Build Coastguard Worker namespace
207*89c4ff92SAndroid Build Coastguard Worker {
208*89c4ff92SAndroid Build Coastguard Worker template <typename TensorType, typename ElementType, typename PrintableType = ElementType>
DumpTensorElement(const TensorType & tensor,unsigned int elementIndex,std::ofstream & fileStream)209*89c4ff92SAndroid Build Coastguard Worker void DumpTensorElement(const TensorType& tensor, unsigned int elementIndex, std::ofstream& fileStream)
210*89c4ff92SAndroid Build Coastguard Worker {
211*89c4ff92SAndroid Build Coastguard Worker const ElementType* elements = reinterpret_cast<const ElementType*>(tensor.GetMemoryArea());
212*89c4ff92SAndroid Build Coastguard Worker fileStream << static_cast<PrintableType>(elements[elementIndex]) << " ";
213*89c4ff92SAndroid Build Coastguard Worker }
214*89c4ff92SAndroid Build Coastguard Worker
215*89c4ff92SAndroid Build Coastguard Worker } // namespace
216*89c4ff92SAndroid Build Coastguard Worker template <typename TensorType>
DumpTensor(const std::string & dumpDir,const std::string & requestName,const std::string & tensorName,const TensorType & tensor)217*89c4ff92SAndroid Build Coastguard Worker void DumpTensor(const std::string& dumpDir,
218*89c4ff92SAndroid Build Coastguard Worker const std::string& requestName,
219*89c4ff92SAndroid Build Coastguard Worker const std::string& tensorName,
220*89c4ff92SAndroid Build Coastguard Worker const TensorType& tensor)
221*89c4ff92SAndroid Build Coastguard Worker {
222*89c4ff92SAndroid Build Coastguard Worker // The dump directory must exist in advance.
223*89c4ff92SAndroid Build Coastguard Worker fs::path dumpPath = dumpDir;
224*89c4ff92SAndroid Build Coastguard Worker const fs::path fileName = dumpPath / (requestName + "_" + tensorName + ".dump");
225*89c4ff92SAndroid Build Coastguard Worker
226*89c4ff92SAndroid Build Coastguard Worker std::ofstream fileStream;
227*89c4ff92SAndroid Build Coastguard Worker fileStream.open(fileName.c_str(), std::ofstream::out | std::ofstream::trunc);
228*89c4ff92SAndroid Build Coastguard Worker
229*89c4ff92SAndroid Build Coastguard Worker if (!fileStream.good())
230*89c4ff92SAndroid Build Coastguard Worker {
231*89c4ff92SAndroid Build Coastguard Worker VLOG(DRIVER) << "Could not open file %s for writing" << fileName.c_str();
232*89c4ff92SAndroid Build Coastguard Worker return;
233*89c4ff92SAndroid Build Coastguard Worker }
234*89c4ff92SAndroid Build Coastguard Worker
235*89c4ff92SAndroid Build Coastguard Worker DumpElementFunction<TensorType> dumpElementFunction = nullptr;
236*89c4ff92SAndroid Build Coastguard Worker
237*89c4ff92SAndroid Build Coastguard Worker switch (tensor.GetDataType())
238*89c4ff92SAndroid Build Coastguard Worker {
239*89c4ff92SAndroid Build Coastguard Worker case armnn::DataType::Float32:
240*89c4ff92SAndroid Build Coastguard Worker {
241*89c4ff92SAndroid Build Coastguard Worker dumpElementFunction = &DumpTensorElement<TensorType, float>;
242*89c4ff92SAndroid Build Coastguard Worker break;
243*89c4ff92SAndroid Build Coastguard Worker }
244*89c4ff92SAndroid Build Coastguard Worker case armnn::DataType::QAsymmU8:
245*89c4ff92SAndroid Build Coastguard Worker {
246*89c4ff92SAndroid Build Coastguard Worker dumpElementFunction = &DumpTensorElement<TensorType, uint8_t, uint32_t>;
247*89c4ff92SAndroid Build Coastguard Worker break;
248*89c4ff92SAndroid Build Coastguard Worker }
249*89c4ff92SAndroid Build Coastguard Worker case armnn::DataType::Signed32:
250*89c4ff92SAndroid Build Coastguard Worker {
251*89c4ff92SAndroid Build Coastguard Worker dumpElementFunction = &DumpTensorElement<TensorType, int32_t>;
252*89c4ff92SAndroid Build Coastguard Worker break;
253*89c4ff92SAndroid Build Coastguard Worker }
254*89c4ff92SAndroid Build Coastguard Worker case armnn::DataType::Float16:
255*89c4ff92SAndroid Build Coastguard Worker {
256*89c4ff92SAndroid Build Coastguard Worker dumpElementFunction = &DumpTensorElement<TensorType, armnn::Half>;
257*89c4ff92SAndroid Build Coastguard Worker break;
258*89c4ff92SAndroid Build Coastguard Worker }
259*89c4ff92SAndroid Build Coastguard Worker case armnn::DataType::QAsymmS8:
260*89c4ff92SAndroid Build Coastguard Worker {
261*89c4ff92SAndroid Build Coastguard Worker dumpElementFunction = &DumpTensorElement<TensorType, int8_t, int32_t>;
262*89c4ff92SAndroid Build Coastguard Worker break;
263*89c4ff92SAndroid Build Coastguard Worker }
264*89c4ff92SAndroid Build Coastguard Worker case armnn::DataType::Boolean:
265*89c4ff92SAndroid Build Coastguard Worker {
266*89c4ff92SAndroid Build Coastguard Worker dumpElementFunction = &DumpTensorElement<TensorType, bool>;
267*89c4ff92SAndroid Build Coastguard Worker break;
268*89c4ff92SAndroid Build Coastguard Worker }
269*89c4ff92SAndroid Build Coastguard Worker default:
270*89c4ff92SAndroid Build Coastguard Worker {
271*89c4ff92SAndroid Build Coastguard Worker dumpElementFunction = nullptr;
272*89c4ff92SAndroid Build Coastguard Worker }
273*89c4ff92SAndroid Build Coastguard Worker }
274*89c4ff92SAndroid Build Coastguard Worker
275*89c4ff92SAndroid Build Coastguard Worker if (dumpElementFunction != nullptr)
276*89c4ff92SAndroid Build Coastguard Worker {
277*89c4ff92SAndroid Build Coastguard Worker const unsigned int numDimensions = tensor.GetNumDimensions();
278*89c4ff92SAndroid Build Coastguard Worker const armnn::TensorShape shape = tensor.GetShape();
279*89c4ff92SAndroid Build Coastguard Worker
280*89c4ff92SAndroid Build Coastguard Worker if (!shape.AreAllDimensionsSpecified())
281*89c4ff92SAndroid Build Coastguard Worker {
282*89c4ff92SAndroid Build Coastguard Worker fileStream << "Cannot dump tensor elements: not all dimensions are specified" << std::endl;
283*89c4ff92SAndroid Build Coastguard Worker return;
284*89c4ff92SAndroid Build Coastguard Worker }
285*89c4ff92SAndroid Build Coastguard Worker fileStream << "# Number of elements " << tensor.GetNumElements() << std::endl;
286*89c4ff92SAndroid Build Coastguard Worker
287*89c4ff92SAndroid Build Coastguard Worker if (numDimensions == 0)
288*89c4ff92SAndroid Build Coastguard Worker {
289*89c4ff92SAndroid Build Coastguard Worker fileStream << "# Shape []" << std::endl;
290*89c4ff92SAndroid Build Coastguard Worker return;
291*89c4ff92SAndroid Build Coastguard Worker }
292*89c4ff92SAndroid Build Coastguard Worker fileStream << "# Shape [" << shape[0];
293*89c4ff92SAndroid Build Coastguard Worker for (unsigned int d = 1; d < numDimensions; ++d)
294*89c4ff92SAndroid Build Coastguard Worker {
295*89c4ff92SAndroid Build Coastguard Worker fileStream << "," << shape[d];
296*89c4ff92SAndroid Build Coastguard Worker }
297*89c4ff92SAndroid Build Coastguard Worker fileStream << "]" << std::endl;
298*89c4ff92SAndroid Build Coastguard Worker fileStream << "Each line contains the data of each of the elements of dimension0. In NCHW and NHWC, each line"
299*89c4ff92SAndroid Build Coastguard Worker " will be a batch" << std::endl << std::endl;
300*89c4ff92SAndroid Build Coastguard Worker
301*89c4ff92SAndroid Build Coastguard Worker // Split will create a new line after all elements of the first dimension
302*89c4ff92SAndroid Build Coastguard Worker // (in a 4, 3, 2, 3 tensor, there will be 4 lines of 18 elements)
303*89c4ff92SAndroid Build Coastguard Worker unsigned int split = 1;
304*89c4ff92SAndroid Build Coastguard Worker if (numDimensions == 1)
305*89c4ff92SAndroid Build Coastguard Worker {
306*89c4ff92SAndroid Build Coastguard Worker split = shape[0];
307*89c4ff92SAndroid Build Coastguard Worker }
308*89c4ff92SAndroid Build Coastguard Worker else
309*89c4ff92SAndroid Build Coastguard Worker {
310*89c4ff92SAndroid Build Coastguard Worker for (unsigned int i = 1; i < numDimensions; ++i)
311*89c4ff92SAndroid Build Coastguard Worker {
312*89c4ff92SAndroid Build Coastguard Worker split *= shape[i];
313*89c4ff92SAndroid Build Coastguard Worker }
314*89c4ff92SAndroid Build Coastguard Worker }
315*89c4ff92SAndroid Build Coastguard Worker
316*89c4ff92SAndroid Build Coastguard Worker // Print all elements in the tensor
317*89c4ff92SAndroid Build Coastguard Worker for (unsigned int elementIndex = 0; elementIndex < tensor.GetNumElements(); ++elementIndex)
318*89c4ff92SAndroid Build Coastguard Worker {
319*89c4ff92SAndroid Build Coastguard Worker (*dumpElementFunction)(tensor, elementIndex, fileStream);
320*89c4ff92SAndroid Build Coastguard Worker
321*89c4ff92SAndroid Build Coastguard Worker if ( (elementIndex + 1) % split == 0 )
322*89c4ff92SAndroid Build Coastguard Worker {
323*89c4ff92SAndroid Build Coastguard Worker fileStream << std::endl;
324*89c4ff92SAndroid Build Coastguard Worker }
325*89c4ff92SAndroid Build Coastguard Worker }
326*89c4ff92SAndroid Build Coastguard Worker fileStream << std::endl;
327*89c4ff92SAndroid Build Coastguard Worker }
328*89c4ff92SAndroid Build Coastguard Worker else
329*89c4ff92SAndroid Build Coastguard Worker {
330*89c4ff92SAndroid Build Coastguard Worker fileStream << "Cannot dump tensor elements: Unsupported data type "
331*89c4ff92SAndroid Build Coastguard Worker << static_cast<unsigned int>(tensor.GetDataType()) << std::endl;
332*89c4ff92SAndroid Build Coastguard Worker }
333*89c4ff92SAndroid Build Coastguard Worker
334*89c4ff92SAndroid Build Coastguard Worker if (!fileStream.good())
335*89c4ff92SAndroid Build Coastguard Worker {
336*89c4ff92SAndroid Build Coastguard Worker VLOG(DRIVER) << "An error occurred when writing to file %s" << fileName.c_str();
337*89c4ff92SAndroid Build Coastguard Worker }
338*89c4ff92SAndroid Build Coastguard Worker }
339*89c4ff92SAndroid Build Coastguard Worker
340*89c4ff92SAndroid Build Coastguard Worker template void DumpTensor<armnn::ConstTensor>(const std::string& dumpDir,
341*89c4ff92SAndroid Build Coastguard Worker const std::string& requestName,
342*89c4ff92SAndroid Build Coastguard Worker const std::string& tensorName,
343*89c4ff92SAndroid Build Coastguard Worker const armnn::ConstTensor& tensor);
344*89c4ff92SAndroid Build Coastguard Worker
345*89c4ff92SAndroid Build Coastguard Worker template void DumpTensor<armnn::Tensor>(const std::string& dumpDir,
346*89c4ff92SAndroid Build Coastguard Worker const std::string& requestName,
347*89c4ff92SAndroid Build Coastguard Worker const std::string& tensorName,
348*89c4ff92SAndroid Build Coastguard Worker const armnn::Tensor& tensor);
349*89c4ff92SAndroid Build Coastguard Worker
DumpJsonProfilingIfRequired(bool gpuProfilingEnabled,const std::string & dumpDir,armnn::NetworkId networkId,const armnn::IProfiler * profiler)350*89c4ff92SAndroid Build Coastguard Worker void DumpJsonProfilingIfRequired(bool gpuProfilingEnabled,
351*89c4ff92SAndroid Build Coastguard Worker const std::string& dumpDir,
352*89c4ff92SAndroid Build Coastguard Worker armnn::NetworkId networkId,
353*89c4ff92SAndroid Build Coastguard Worker const armnn::IProfiler* profiler)
354*89c4ff92SAndroid Build Coastguard Worker {
355*89c4ff92SAndroid Build Coastguard Worker // Check if profiling is required.
356*89c4ff92SAndroid Build Coastguard Worker if (!gpuProfilingEnabled)
357*89c4ff92SAndroid Build Coastguard Worker {
358*89c4ff92SAndroid Build Coastguard Worker return;
359*89c4ff92SAndroid Build Coastguard Worker }
360*89c4ff92SAndroid Build Coastguard Worker
361*89c4ff92SAndroid Build Coastguard Worker // The dump directory must exist in advance.
362*89c4ff92SAndroid Build Coastguard Worker if (dumpDir.empty())
363*89c4ff92SAndroid Build Coastguard Worker {
364*89c4ff92SAndroid Build Coastguard Worker return;
365*89c4ff92SAndroid Build Coastguard Worker }
366*89c4ff92SAndroid Build Coastguard Worker
367*89c4ff92SAndroid Build Coastguard Worker ARMNN_ASSERT(profiler);
368*89c4ff92SAndroid Build Coastguard Worker
369*89c4ff92SAndroid Build Coastguard Worker // Set the name of the output profiling file.
370*89c4ff92SAndroid Build Coastguard Worker fs::path dumpPath = dumpDir;
371*89c4ff92SAndroid Build Coastguard Worker const fs::path fileName = dumpPath / (std::to_string(networkId) + "_profiling.json");
372*89c4ff92SAndroid Build Coastguard Worker
373*89c4ff92SAndroid Build Coastguard Worker // Open the ouput file for writing.
374*89c4ff92SAndroid Build Coastguard Worker std::ofstream fileStream;
375*89c4ff92SAndroid Build Coastguard Worker fileStream.open(fileName.c_str(), std::ofstream::out | std::ofstream::trunc);
376*89c4ff92SAndroid Build Coastguard Worker
377*89c4ff92SAndroid Build Coastguard Worker if (!fileStream.good())
378*89c4ff92SAndroid Build Coastguard Worker {
379*89c4ff92SAndroid Build Coastguard Worker VLOG(DRIVER) << "Could not open file %s for writing" << fileName.c_str();
380*89c4ff92SAndroid Build Coastguard Worker return;
381*89c4ff92SAndroid Build Coastguard Worker }
382*89c4ff92SAndroid Build Coastguard Worker
383*89c4ff92SAndroid Build Coastguard Worker // Write the profiling info to a JSON file.
384*89c4ff92SAndroid Build Coastguard Worker profiler->Print(fileStream);
385*89c4ff92SAndroid Build Coastguard Worker }
386*89c4ff92SAndroid Build Coastguard Worker
ExportNetworkGraphToDotFile(const armnn::IOptimizedNetwork & optimizedNetwork,const std::string & dumpDir)387*89c4ff92SAndroid Build Coastguard Worker std::string ExportNetworkGraphToDotFile(const armnn::IOptimizedNetwork& optimizedNetwork,
388*89c4ff92SAndroid Build Coastguard Worker const std::string& dumpDir)
389*89c4ff92SAndroid Build Coastguard Worker {
390*89c4ff92SAndroid Build Coastguard Worker std::string fileName;
391*89c4ff92SAndroid Build Coastguard Worker // The dump directory must exist in advance.
392*89c4ff92SAndroid Build Coastguard Worker if (dumpDir.empty())
393*89c4ff92SAndroid Build Coastguard Worker {
394*89c4ff92SAndroid Build Coastguard Worker return fileName;
395*89c4ff92SAndroid Build Coastguard Worker }
396*89c4ff92SAndroid Build Coastguard Worker
397*89c4ff92SAndroid Build Coastguard Worker std::string timestamp = GetFileTimestamp();
398*89c4ff92SAndroid Build Coastguard Worker if (timestamp.empty())
399*89c4ff92SAndroid Build Coastguard Worker {
400*89c4ff92SAndroid Build Coastguard Worker return fileName;
401*89c4ff92SAndroid Build Coastguard Worker }
402*89c4ff92SAndroid Build Coastguard Worker
403*89c4ff92SAndroid Build Coastguard Worker // Set the name of the output .dot file.
404*89c4ff92SAndroid Build Coastguard Worker fs::path dumpPath = dumpDir;
405*89c4ff92SAndroid Build Coastguard Worker fs::path tempFilePath = dumpPath / (timestamp + "_networkgraph.dot");
406*89c4ff92SAndroid Build Coastguard Worker fileName = tempFilePath.string();
407*89c4ff92SAndroid Build Coastguard Worker
408*89c4ff92SAndroid Build Coastguard Worker VLOG(DRIVER) << "Exporting the optimized network graph to file: %s" << fileName.c_str();
409*89c4ff92SAndroid Build Coastguard Worker
410*89c4ff92SAndroid Build Coastguard Worker // Write the network graph to a dot file.
411*89c4ff92SAndroid Build Coastguard Worker std::ofstream fileStream;
412*89c4ff92SAndroid Build Coastguard Worker fileStream.open(fileName, std::ofstream::out | std::ofstream::trunc);
413*89c4ff92SAndroid Build Coastguard Worker
414*89c4ff92SAndroid Build Coastguard Worker if (!fileStream.good())
415*89c4ff92SAndroid Build Coastguard Worker {
416*89c4ff92SAndroid Build Coastguard Worker VLOG(DRIVER) << "Could not open file %s for writing" << fileName.c_str();
417*89c4ff92SAndroid Build Coastguard Worker return fileName;
418*89c4ff92SAndroid Build Coastguard Worker }
419*89c4ff92SAndroid Build Coastguard Worker
420*89c4ff92SAndroid Build Coastguard Worker if (optimizedNetwork.SerializeToDot(fileStream) != armnn::Status::Success)
421*89c4ff92SAndroid Build Coastguard Worker {
422*89c4ff92SAndroid Build Coastguard Worker VLOG(DRIVER) << "An error occurred when writing to file %s" << fileName.c_str();
423*89c4ff92SAndroid Build Coastguard Worker }
424*89c4ff92SAndroid Build Coastguard Worker return fileName;
425*89c4ff92SAndroid Build Coastguard Worker }
426*89c4ff92SAndroid Build Coastguard Worker
SerializeNetwork(const armnn::INetwork & network,const std::string & dumpDir,std::vector<uint8_t> & dataCacheData,bool dataCachingActive)427*89c4ff92SAndroid Build Coastguard Worker std::string SerializeNetwork(const armnn::INetwork& network,
428*89c4ff92SAndroid Build Coastguard Worker const std::string& dumpDir,
429*89c4ff92SAndroid Build Coastguard Worker std::vector<uint8_t>& dataCacheData,
430*89c4ff92SAndroid Build Coastguard Worker bool dataCachingActive)
431*89c4ff92SAndroid Build Coastguard Worker {
432*89c4ff92SAndroid Build Coastguard Worker std::string fileName;
433*89c4ff92SAndroid Build Coastguard Worker bool bSerializeToFile = true;
434*89c4ff92SAndroid Build Coastguard Worker if (dumpDir.empty())
435*89c4ff92SAndroid Build Coastguard Worker {
436*89c4ff92SAndroid Build Coastguard Worker bSerializeToFile = false;
437*89c4ff92SAndroid Build Coastguard Worker }
438*89c4ff92SAndroid Build Coastguard Worker else
439*89c4ff92SAndroid Build Coastguard Worker {
440*89c4ff92SAndroid Build Coastguard Worker std::string timestamp = GetFileTimestamp();
441*89c4ff92SAndroid Build Coastguard Worker if (timestamp.empty())
442*89c4ff92SAndroid Build Coastguard Worker {
443*89c4ff92SAndroid Build Coastguard Worker bSerializeToFile = false;
444*89c4ff92SAndroid Build Coastguard Worker }
445*89c4ff92SAndroid Build Coastguard Worker }
446*89c4ff92SAndroid Build Coastguard Worker if (!bSerializeToFile && !dataCachingActive)
447*89c4ff92SAndroid Build Coastguard Worker {
448*89c4ff92SAndroid Build Coastguard Worker return fileName;
449*89c4ff92SAndroid Build Coastguard Worker }
450*89c4ff92SAndroid Build Coastguard Worker
451*89c4ff92SAndroid Build Coastguard Worker auto serializer(armnnSerializer::ISerializer::Create());
452*89c4ff92SAndroid Build Coastguard Worker // Serialize the Network
453*89c4ff92SAndroid Build Coastguard Worker serializer->Serialize(network);
454*89c4ff92SAndroid Build Coastguard Worker if (dataCachingActive)
455*89c4ff92SAndroid Build Coastguard Worker {
456*89c4ff92SAndroid Build Coastguard Worker std::stringstream stream;
457*89c4ff92SAndroid Build Coastguard Worker auto serialized = serializer->SaveSerializedToStream(stream);
458*89c4ff92SAndroid Build Coastguard Worker if (serialized)
459*89c4ff92SAndroid Build Coastguard Worker {
460*89c4ff92SAndroid Build Coastguard Worker std::string const serializedString{stream.str()};
461*89c4ff92SAndroid Build Coastguard Worker std::copy(serializedString.begin(),
462*89c4ff92SAndroid Build Coastguard Worker serializedString.end(),
463*89c4ff92SAndroid Build Coastguard Worker std::back_inserter(dataCacheData));
464*89c4ff92SAndroid Build Coastguard Worker }
465*89c4ff92SAndroid Build Coastguard Worker }
466*89c4ff92SAndroid Build Coastguard Worker
467*89c4ff92SAndroid Build Coastguard Worker if (bSerializeToFile)
468*89c4ff92SAndroid Build Coastguard Worker {
469*89c4ff92SAndroid Build Coastguard Worker // Set the name of the output .armnn file.
470*89c4ff92SAndroid Build Coastguard Worker fs::path dumpPath = dumpDir;
471*89c4ff92SAndroid Build Coastguard Worker std::string timestamp = GetFileTimestamp();
472*89c4ff92SAndroid Build Coastguard Worker fs::path tempFilePath = dumpPath / (timestamp + "_network.armnn");
473*89c4ff92SAndroid Build Coastguard Worker fileName = tempFilePath.string();
474*89c4ff92SAndroid Build Coastguard Worker
475*89c4ff92SAndroid Build Coastguard Worker // Save serialized network to a file
476*89c4ff92SAndroid Build Coastguard Worker std::ofstream serializedFile(fileName, std::ios::out | std::ios::binary);
477*89c4ff92SAndroid Build Coastguard Worker auto serialized = serializer->SaveSerializedToStream(serializedFile);
478*89c4ff92SAndroid Build Coastguard Worker if (!serialized)
479*89c4ff92SAndroid Build Coastguard Worker {
480*89c4ff92SAndroid Build Coastguard Worker VLOG(DRIVER) << "An error occurred when serializing to file %s" << fileName.c_str();
481*89c4ff92SAndroid Build Coastguard Worker }
482*89c4ff92SAndroid Build Coastguard Worker }
483*89c4ff92SAndroid Build Coastguard Worker return fileName;
484*89c4ff92SAndroid Build Coastguard Worker }
485*89c4ff92SAndroid Build Coastguard Worker
IsDynamicTensor(const armnn::TensorInfo & tensorInfo)486*89c4ff92SAndroid Build Coastguard Worker bool IsDynamicTensor(const armnn::TensorInfo& tensorInfo)
487*89c4ff92SAndroid Build Coastguard Worker {
488*89c4ff92SAndroid Build Coastguard Worker if (tensorInfo.GetShape().GetDimensionality() == armnn::Dimensionality::NotSpecified)
489*89c4ff92SAndroid Build Coastguard Worker {
490*89c4ff92SAndroid Build Coastguard Worker return true;
491*89c4ff92SAndroid Build Coastguard Worker }
492*89c4ff92SAndroid Build Coastguard Worker // Account for the usage of the TensorShape empty constructor
493*89c4ff92SAndroid Build Coastguard Worker if (tensorInfo.GetNumDimensions() == 0)
494*89c4ff92SAndroid Build Coastguard Worker {
495*89c4ff92SAndroid Build Coastguard Worker return true;
496*89c4ff92SAndroid Build Coastguard Worker }
497*89c4ff92SAndroid Build Coastguard Worker return !tensorInfo.GetShape().AreAllDimensionsSpecified();
498*89c4ff92SAndroid Build Coastguard Worker }
499*89c4ff92SAndroid Build Coastguard Worker
AreDynamicTensorsSupported()500*89c4ff92SAndroid Build Coastguard Worker bool AreDynamicTensorsSupported() //TODO
501*89c4ff92SAndroid Build Coastguard Worker {
502*89c4ff92SAndroid Build Coastguard Worker return true;
503*89c4ff92SAndroid Build Coastguard Worker }
504*89c4ff92SAndroid Build Coastguard Worker
isQuantizedOperand(const OperandType & operandType)505*89c4ff92SAndroid Build Coastguard Worker bool isQuantizedOperand(const OperandType& operandType)
506*89c4ff92SAndroid Build Coastguard Worker {
507*89c4ff92SAndroid Build Coastguard Worker if (operandType == OperandType::TENSOR_QUANT8_ASYMM ||
508*89c4ff92SAndroid Build Coastguard Worker operandType == OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL ||
509*89c4ff92SAndroid Build Coastguard Worker operandType == OperandType::TENSOR_QUANT8_SYMM ||
510*89c4ff92SAndroid Build Coastguard Worker operandType == OperandType::TENSOR_QUANT16_SYMM ||
511*89c4ff92SAndroid Build Coastguard Worker operandType == OperandType::TENSOR_QUANT8_ASYMM_SIGNED)
512*89c4ff92SAndroid Build Coastguard Worker {
513*89c4ff92SAndroid Build Coastguard Worker return true;
514*89c4ff92SAndroid Build Coastguard Worker }
515*89c4ff92SAndroid Build Coastguard Worker else
516*89c4ff92SAndroid Build Coastguard Worker {
517*89c4ff92SAndroid Build Coastguard Worker return false;
518*89c4ff92SAndroid Build Coastguard Worker }
519*89c4ff92SAndroid Build Coastguard Worker }
520*89c4ff92SAndroid Build Coastguard Worker
GetModelSummary(const Model & model)521*89c4ff92SAndroid Build Coastguard Worker std::string GetModelSummary(const Model& model)
522*89c4ff92SAndroid Build Coastguard Worker {
523*89c4ff92SAndroid Build Coastguard Worker std::stringstream result;
524*89c4ff92SAndroid Build Coastguard Worker
525*89c4ff92SAndroid Build Coastguard Worker result << model.main.inputIndexes.size() << " input(s), "
526*89c4ff92SAndroid Build Coastguard Worker << model.main.operations.size() << " operation(s), "
527*89c4ff92SAndroid Build Coastguard Worker << model.main.outputIndexes.size() << " output(s), "
528*89c4ff92SAndroid Build Coastguard Worker << model.main.operands.size() << " operand(s) "
529*89c4ff92SAndroid Build Coastguard Worker << std::endl;
530*89c4ff92SAndroid Build Coastguard Worker
531*89c4ff92SAndroid Build Coastguard Worker result << "Inputs: ";
532*89c4ff92SAndroid Build Coastguard Worker for (uint32_t i = 0; i < model.main.inputIndexes.size(); i++)
533*89c4ff92SAndroid Build Coastguard Worker {
534*89c4ff92SAndroid Build Coastguard Worker result << GetOperandSummary(model.main.operands[model.main.inputIndexes[i]]) << ", ";
535*89c4ff92SAndroid Build Coastguard Worker }
536*89c4ff92SAndroid Build Coastguard Worker result << std::endl;
537*89c4ff92SAndroid Build Coastguard Worker
538*89c4ff92SAndroid Build Coastguard Worker result << "Operations: ";
539*89c4ff92SAndroid Build Coastguard Worker for (uint32_t i = 0; i < model.main.operations.size(); i++)
540*89c4ff92SAndroid Build Coastguard Worker {
541*89c4ff92SAndroid Build Coastguard Worker result << model.main.operations[i].type << ", ";
542*89c4ff92SAndroid Build Coastguard Worker }
543*89c4ff92SAndroid Build Coastguard Worker result << std::endl;
544*89c4ff92SAndroid Build Coastguard Worker
545*89c4ff92SAndroid Build Coastguard Worker result << "Outputs: ";
546*89c4ff92SAndroid Build Coastguard Worker for (uint32_t i = 0; i < model.main.outputIndexes.size(); i++)
547*89c4ff92SAndroid Build Coastguard Worker {
548*89c4ff92SAndroid Build Coastguard Worker result << GetOperandSummary(model.main.operands[model.main.outputIndexes[i]]) << ", ";
549*89c4ff92SAndroid Build Coastguard Worker }
550*89c4ff92SAndroid Build Coastguard Worker result << std::endl;
551*89c4ff92SAndroid Build Coastguard Worker
552*89c4ff92SAndroid Build Coastguard Worker return result.str();
553*89c4ff92SAndroid Build Coastguard Worker }
554*89c4ff92SAndroid Build Coastguard Worker
GetFileTimestamp()555*89c4ff92SAndroid Build Coastguard Worker std::string GetFileTimestamp()
556*89c4ff92SAndroid Build Coastguard Worker {
557*89c4ff92SAndroid Build Coastguard Worker // used to get a timestamp to name diagnostic files (the ArmNN serialized graph
558*89c4ff92SAndroid Build Coastguard Worker // and getSupportedOperations.txt files)
559*89c4ff92SAndroid Build Coastguard Worker timespec ts;
560*89c4ff92SAndroid Build Coastguard Worker int iRet = clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
561*89c4ff92SAndroid Build Coastguard Worker std::stringstream ss;
562*89c4ff92SAndroid Build Coastguard Worker if (iRet == 0)
563*89c4ff92SAndroid Build Coastguard Worker {
564*89c4ff92SAndroid Build Coastguard Worker ss << std::to_string(ts.tv_sec) << "_" << std::to_string(ts.tv_nsec);
565*89c4ff92SAndroid Build Coastguard Worker }
566*89c4ff92SAndroid Build Coastguard Worker else
567*89c4ff92SAndroid Build Coastguard Worker {
568*89c4ff92SAndroid Build Coastguard Worker VLOG(DRIVER) << "clock_gettime failed with errno " <<
569*89c4ff92SAndroid Build Coastguard Worker std::to_string(errno).c_str() << " : " <<
570*89c4ff92SAndroid Build Coastguard Worker std::strerror(errno);
571*89c4ff92SAndroid Build Coastguard Worker }
572*89c4ff92SAndroid Build Coastguard Worker return ss.str();
573*89c4ff92SAndroid Build Coastguard Worker }
574*89c4ff92SAndroid Build Coastguard Worker
RenameExportedFiles(const std::string & existingSerializedFileName,const std::string & existingDotFileName,const std::string & dumpDir,const armnn::NetworkId networkId)575*89c4ff92SAndroid Build Coastguard Worker void RenameExportedFiles(const std::string& existingSerializedFileName,
576*89c4ff92SAndroid Build Coastguard Worker const std::string& existingDotFileName,
577*89c4ff92SAndroid Build Coastguard Worker const std::string& dumpDir,
578*89c4ff92SAndroid Build Coastguard Worker const armnn::NetworkId networkId)
579*89c4ff92SAndroid Build Coastguard Worker {
580*89c4ff92SAndroid Build Coastguard Worker if (dumpDir.empty())
581*89c4ff92SAndroid Build Coastguard Worker {
582*89c4ff92SAndroid Build Coastguard Worker return;
583*89c4ff92SAndroid Build Coastguard Worker }
584*89c4ff92SAndroid Build Coastguard Worker RenameFile(existingSerializedFileName, std::string("_network.armnn"), dumpDir, networkId);
585*89c4ff92SAndroid Build Coastguard Worker RenameFile(existingDotFileName, std::string("_networkgraph.dot"), dumpDir, networkId);
586*89c4ff92SAndroid Build Coastguard Worker }
587*89c4ff92SAndroid Build Coastguard Worker
RenameFile(const std::string & existingName,const std::string & extension,const std::string & dumpDir,const armnn::NetworkId networkId)588*89c4ff92SAndroid Build Coastguard Worker void RenameFile(const std::string& existingName,
589*89c4ff92SAndroid Build Coastguard Worker const std::string& extension,
590*89c4ff92SAndroid Build Coastguard Worker const std::string& dumpDir,
591*89c4ff92SAndroid Build Coastguard Worker const armnn::NetworkId networkId)
592*89c4ff92SAndroid Build Coastguard Worker {
593*89c4ff92SAndroid Build Coastguard Worker if (existingName.empty() || dumpDir.empty())
594*89c4ff92SAndroid Build Coastguard Worker {
595*89c4ff92SAndroid Build Coastguard Worker return;
596*89c4ff92SAndroid Build Coastguard Worker }
597*89c4ff92SAndroid Build Coastguard Worker
598*89c4ff92SAndroid Build Coastguard Worker fs::path dumpPath = dumpDir;
599*89c4ff92SAndroid Build Coastguard Worker const fs::path newFileName = dumpPath / (std::to_string(networkId) + extension);
600*89c4ff92SAndroid Build Coastguard Worker int iRet = rename(existingName.c_str(), newFileName.c_str());
601*89c4ff92SAndroid Build Coastguard Worker if (iRet != 0)
602*89c4ff92SAndroid Build Coastguard Worker {
603*89c4ff92SAndroid Build Coastguard Worker std::stringstream ss;
604*89c4ff92SAndroid Build Coastguard Worker ss << "rename of [" << existingName << "] to [" << newFileName << "] failed with errno "
605*89c4ff92SAndroid Build Coastguard Worker << std::to_string(errno) << " : " << std::strerror(errno);
606*89c4ff92SAndroid Build Coastguard Worker VLOG(DRIVER) << ss.str().c_str();
607*89c4ff92SAndroid Build Coastguard Worker }
608*89c4ff92SAndroid Build Coastguard Worker }
609*89c4ff92SAndroid Build Coastguard Worker
CommitPools(std::vector<::android::nn::RunTimePoolInfo> & memPools)610*89c4ff92SAndroid Build Coastguard Worker void CommitPools(std::vector<::android::nn::RunTimePoolInfo>& memPools)
611*89c4ff92SAndroid Build Coastguard Worker {
612*89c4ff92SAndroid Build Coastguard Worker // Commit output buffers.
613*89c4ff92SAndroid Build Coastguard Worker // Note that we update *all* pools, even if they aren't actually used as outputs -
614*89c4ff92SAndroid Build Coastguard Worker // this is simpler and is what the CpuExecutor does.
615*89c4ff92SAndroid Build Coastguard Worker for (auto& pool : memPools)
616*89c4ff92SAndroid Build Coastguard Worker {
617*89c4ff92SAndroid Build Coastguard Worker // Type android::nn::RunTimePoolInfo has changed between Android P & Q and Android R, where
618*89c4ff92SAndroid Build Coastguard Worker // update() has been removed and flush() added.
619*89c4ff92SAndroid Build Coastguard Worker pool.flush();
620*89c4ff92SAndroid Build Coastguard Worker }
621*89c4ff92SAndroid Build Coastguard Worker }
622*89c4ff92SAndroid Build Coastguard Worker } // namespace armnn_driver
623