blob: f14560a183714ed27f64c6dbc3e3139d29eda33a [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#define LOG_TAG "ArmnnDriver"
7
8#include "ArmnnPreparedModel.hpp"
9#include "Utils.hpp"
10
telsoa015307bc12018-03-09 13:51:08 +000011#include <log/log.h>
12#include <OperationsUtils.h>
surmeh01deb3bdb2018-07-05 12:06:04 +010013#include <ValidateHal.h>
Kevin Mayec1e5b82020-02-26 17:00:39 +000014
telsoa015307bc12018-03-09 13:51:08 +000015#include <cassert>
16#include <cinttypes>
17
Sadik Armagan188675f2021-02-12 17:16:42 +000018#ifdef ARMNN_ANDROID_S
19#include <LegacyUtils.h>
20#endif
21
telsoa015307bc12018-03-09 13:51:08 +000022using namespace android;
23
24namespace
25{
26using namespace armnn_driver;
27
Kevin Mayec1e5b82020-02-26 17:00:39 +000028void NotifyCallbackAndCheck(const ::android::sp<V1_0::IExecutionCallback>& callback, V1_0::ErrorStatus errorStatus,
telsoa015307bc12018-03-09 13:51:08 +000029 std::string callingFunction)
30{
31 Return<void> returned = callback->notify(errorStatus);
32 // This check is required, if the callback fails and it isn't checked it will bring down the service
33 if (!returned.isOk())
34 {
35 ALOGE("ArmnnDriver::%s: hidl callback failed to return properly: %s",
36 callingFunction.c_str(), returned.description().c_str());
37 }
38}
39
Sadik Armagan188675f2021-02-12 17:16:42 +000040bool ValidateRequestArgument(const V1_0::RequestArgument& requestArg, const armnn::TensorInfo& tensorInfo)
telsoa015307bc12018-03-09 13:51:08 +000041{
42 if (requestArg.dimensions.size() != 0)
43 {
44 if (requestArg.dimensions.size() != tensorInfo.GetNumDimensions())
45 {
46 ALOGE("Mismatched dimensions (request argument: %zu, expected: %u)",
47 requestArg.dimensions.size(), tensorInfo.GetNumDimensions());
48 return false;
49 }
50
51 for (unsigned int d = 0; d < tensorInfo.GetNumDimensions(); ++d)
52 {
Finn Williamsa4983ce2020-07-23 12:55:12 +010053 if (requestArg.dimensions[d] != 0 && requestArg.dimensions[d] != tensorInfo.GetShape()[d])
telsoa015307bc12018-03-09 13:51:08 +000054 {
55 ALOGE("Mismatched size for dimension %d (request argument: %u, expected %u)",
56 d, requestArg.dimensions[d], tensorInfo.GetShape()[d]);
57 return false;
58 }
59 }
60 }
61
62 return true;
63}
64
Sadik Armagan188675f2021-02-12 17:16:42 +000065armnn::Tensor GetTensorForRequestArgument(const V1_0::RequestArgument& requestArg,
telsoa015307bc12018-03-09 13:51:08 +000066 const armnn::TensorInfo& tensorInfo,
67 const std::vector<::android::nn::RunTimePoolInfo>& requestPools)
68{
69 if (!ValidateRequestArgument(requestArg, tensorInfo))
70 {
71 return armnn::Tensor();
72 }
73
74 return armnn::Tensor(tensorInfo, GetMemoryFromPool(requestArg.location, requestPools));
75}
76
77inline std::string BuildTensorName(const char* tensorNamePrefix, std::size_t index)
78{
79 return tensorNamePrefix + std::to_string(index);
80}
81
Matteo Martincighe48bdff2018-09-03 13:50:50 +010082} // anonymous namespace
telsoa015307bc12018-03-09 13:51:08 +000083
telsoa01ce3e84a2018-08-31 09:31:35 +010084using namespace android::hardware;
85
telsoa015307bc12018-03-09 13:51:08 +000086namespace armnn_driver
87{
Matteo Martincighe48bdff2018-09-03 13:50:50 +010088template<typename HalVersion>
Derek Lamberti4de83c52020-03-17 13:40:18 +000089RequestThread<ArmnnPreparedModel, HalVersion, CallbackContext_1_0>
90 ArmnnPreparedModel<HalVersion>::m_RequestThread;
telsoa015307bc12018-03-09 13:51:08 +000091
Matteo Martincighe48bdff2018-09-03 13:50:50 +010092template<typename HalVersion>
Finn Williamsfdf2eae2021-07-08 13:07:19 +010093std::unique_ptr<armnn::Threadpool> ArmnnPreparedModel<HalVersion>::m_Threadpool(nullptr);
94
95template<typename HalVersion>
telsoa015307bc12018-03-09 13:51:08 +000096template <typename TensorBindingCollection>
Matteo Martincighe48bdff2018-09-03 13:50:50 +010097void ArmnnPreparedModel<HalVersion>::DumpTensorsIfRequired(char const* tensorNamePrefix,
98 const TensorBindingCollection& tensorBindings)
telsoa015307bc12018-03-09 13:51:08 +000099{
100 if (!m_RequestInputsAndOutputsDumpDir.empty())
101 {
Colm Donelan08d9a1c2020-09-09 17:56:55 +0100102 const std::string requestName = std::to_string(m_NetworkId) + "_" + std::to_string(m_RequestCount) + ".dump";
telsoa015307bc12018-03-09 13:51:08 +0000103 for (std::size_t i = 0u; i < tensorBindings.size(); ++i)
104 {
105 DumpTensor(m_RequestInputsAndOutputsDumpDir,
106 requestName,
107 BuildTensorName(tensorNamePrefix, i),
108 tensorBindings[i].second);
109 }
110 }
111}
112
Matteo Martincighe48bdff2018-09-03 13:50:50 +0100113template<typename HalVersion>
114ArmnnPreparedModel<HalVersion>::ArmnnPreparedModel(armnn::NetworkId networkId,
115 armnn::IRuntime* runtime,
116 const HalModel& model,
117 const std::string& requestInputsAndOutputsDumpDir,
Finn Williamsd8fb5402021-05-19 20:52:00 +0100118 const bool gpuProfilingEnabled,
Finn Williamsca3a3e02021-06-11 15:04:02 +0100119 const bool asyncModelExecutionEnabled,
120 const unsigned int numberOfThreads)
telsoa01ce3e84a2018-08-31 09:31:35 +0100121 : m_NetworkId(networkId)
122 , m_Runtime(runtime)
123 , m_Model(model)
124 , m_RequestCount(0)
125 , m_RequestInputsAndOutputsDumpDir(requestInputsAndOutputsDumpDir)
126 , m_GpuProfilingEnabled(gpuProfilingEnabled)
Finn Williamsd8fb5402021-05-19 20:52:00 +0100127 , m_AsyncModelExecutionEnabled(asyncModelExecutionEnabled)
telsoa015307bc12018-03-09 13:51:08 +0000128{
telsoa01ce3e84a2018-08-31 09:31:35 +0100129 // Enable profiling if required.
130 m_Runtime->GetProfiler(m_NetworkId)->EnableProfiling(m_GpuProfilingEnabled);
Finn Williamsd8fb5402021-05-19 20:52:00 +0100131
Finn Williamsfdf2eae2021-07-08 13:07:19 +0100132 if (m_AsyncModelExecutionEnabled)
Finn Williamsd8fb5402021-05-19 20:52:00 +0100133 {
Finn Williamsca3a3e02021-06-11 15:04:02 +0100134 std::vector<std::shared_ptr<armnn::IWorkingMemHandle>> memHandles;
Finn Williamsd27c13b2021-06-25 10:06:09 +0100135 for (unsigned int i=0; i < numberOfThreads; ++i)
Finn Williamsca3a3e02021-06-11 15:04:02 +0100136 {
137 memHandles.emplace_back(m_Runtime->CreateWorkingMemHandle(networkId));
138 }
139
Finn Williamsfdf2eae2021-07-08 13:07:19 +0100140 if (!m_Threadpool)
141 {
142 m_Threadpool = std::make_unique<armnn::Threadpool>(numberOfThreads, runtime, memHandles);
143 }
144 else
145 {
146 m_Threadpool->LoadMemHandles(memHandles);
147 }
148
Finn Williamsca3a3e02021-06-11 15:04:02 +0100149 m_WorkingMemHandle = memHandles.back();
Finn Williamsd8fb5402021-05-19 20:52:00 +0100150 }
telsoa015307bc12018-03-09 13:51:08 +0000151}
152
Matteo Martincighe48bdff2018-09-03 13:50:50 +0100153template<typename HalVersion>
154ArmnnPreparedModel<HalVersion>::~ArmnnPreparedModel()
telsoa015307bc12018-03-09 13:51:08 +0000155{
telsoa01ce3e84a2018-08-31 09:31:35 +0100156 // Get a hold of the profiler used by this model.
157 std::shared_ptr<armnn::IProfiler> profiler = m_Runtime->GetProfiler(m_NetworkId);
158
159 // Unload the network associated with this model.
telsoa015307bc12018-03-09 13:51:08 +0000160 m_Runtime->UnloadNetwork(m_NetworkId);
telsoa01ce3e84a2018-08-31 09:31:35 +0100161
Finn Williamsfdf2eae2021-07-08 13:07:19 +0100162 // Unload the network memhandles from the threadpool
163 if (m_AsyncModelExecutionEnabled)
164 {
165 m_Threadpool->UnloadMemHandles(m_NetworkId);
166 }
167
telsoa01ce3e84a2018-08-31 09:31:35 +0100168 // Dump the profiling info to a file if required.
169 DumpJsonProfilingIfRequired(m_GpuProfilingEnabled, m_RequestInputsAndOutputsDumpDir, m_NetworkId, profiler.get());
telsoa015307bc12018-03-09 13:51:08 +0000170}
171
Matteo Martincighe48bdff2018-09-03 13:50:50 +0100172template<typename HalVersion>
Kevin Mayec1e5b82020-02-26 17:00:39 +0000173Return<V1_0::ErrorStatus> ArmnnPreparedModel<HalVersion>::execute(
174 const V1_0::Request& request,
175 const ::android::sp<V1_0::IExecutionCallback>& callback)
telsoa015307bc12018-03-09 13:51:08 +0000176{
177 ALOGV("ArmnnPreparedModel::execute(): %s", GetModelSummary(m_Model).c_str());
178 m_RequestCount++;
179
180 if (callback.get() == nullptr) {
181 ALOGE("ArmnnPreparedModel::execute invalid callback passed");
Kevin Mayec1e5b82020-02-26 17:00:39 +0000182 return V1_0::ErrorStatus::INVALID_ARGUMENT;
telsoa015307bc12018-03-09 13:51:08 +0000183 }
184
185 if (!android::nn::validateRequest(request, m_Model))
186 {
Kevin Mayec1e5b82020-02-26 17:00:39 +0000187 NotifyCallbackAndCheck(callback, V1_0::ErrorStatus::INVALID_ARGUMENT, "ArmnnPreparedModel::execute");
188 return V1_0::ErrorStatus::INVALID_ARGUMENT;
telsoa015307bc12018-03-09 13:51:08 +0000189 }
190
191 if (!m_RequestInputsAndOutputsDumpDir.empty())
192 {
193 ALOGD("Dumping inputs and outputs for request %" PRIuPTR, reinterpret_cast<std::uintptr_t>(callback.get()));
194 }
195
196 // allocate the tensors on the heap, as they are passed to the request thread
197 auto pInputTensors = std::make_shared<armnn::InputTensors>();
198 auto pOutputTensors = std::make_shared<armnn::OutputTensors>();
199
200 // map the memory pool into shared pointers
201 // use a shared memory pools vector on the heap, as it is passed to the request thread
202 auto pMemPools = std::make_shared<std::vector<android::nn::RunTimePoolInfo>>();
Sadik Armagan188675f2021-02-12 17:16:42 +0000203#if !defined(ARMNN_ANDROID_S)
telsoa015307bc12018-03-09 13:51:08 +0000204 if (!setRunTimePoolInfosFromHidlMemories(pMemPools.get(), request.pools))
Sadik Armagan188675f2021-02-12 17:16:42 +0000205#else
206 if (!setRunTimePoolInfosFromCanonicalMemories(pMemPools.get(), uncheckedConvert(request.pools)))
207#endif
telsoa015307bc12018-03-09 13:51:08 +0000208 {
Kevin Mayec1e5b82020-02-26 17:00:39 +0000209 NotifyCallbackAndCheck(callback, V1_0::ErrorStatus::GENERAL_FAILURE, "ArmnnPreparedModel::execute");
210 return V1_0::ErrorStatus::GENERAL_FAILURE;
telsoa015307bc12018-03-09 13:51:08 +0000211 }
telsoa015307bc12018-03-09 13:51:08 +0000212 // add the inputs and outputs with their data
213 try
214 {
215 pInputTensors->reserve(request.inputs.size());
216 for (unsigned int i = 0; i < request.inputs.size(); i++)
217 {
218 const auto& inputArg = request.inputs[i];
219
220 const armnn::TensorInfo inputTensorInfo = m_Runtime->GetInputTensorInfo(m_NetworkId, i);
221 const armnn::Tensor inputTensor = GetTensorForRequestArgument(inputArg, inputTensorInfo, *pMemPools);
222 if (inputTensor.GetMemoryArea() == nullptr)
223 {
224 ALOGE("Cannot execute request. Error converting request input %u to tensor", i);
Kevin Mayec1e5b82020-02-26 17:00:39 +0000225 return V1_0::ErrorStatus::GENERAL_FAILURE;
telsoa015307bc12018-03-09 13:51:08 +0000226 }
227
228 pInputTensors->emplace_back(i, inputTensor);
229 }
230
231 pOutputTensors->reserve(request.outputs.size());
232 for (unsigned int i = 0; i < request.outputs.size(); i++)
233 {
234 const auto& outputArg = request.outputs[i];
235
236 const armnn::TensorInfo outputTensorInfo = m_Runtime->GetOutputTensorInfo(m_NetworkId, i);
237 const armnn::Tensor outputTensor = GetTensorForRequestArgument(outputArg, outputTensorInfo, *pMemPools);
238 if (outputTensor.GetMemoryArea() == nullptr)
239 {
240 ALOGE("Cannot execute request. Error converting request output %u to tensor", i);
Kevin Mayec1e5b82020-02-26 17:00:39 +0000241 return V1_0::ErrorStatus::GENERAL_FAILURE;
telsoa015307bc12018-03-09 13:51:08 +0000242 }
243
244 pOutputTensors->emplace_back(i, outputTensor);
245 }
246 }
Kevin May7bdaac52020-02-10 12:10:07 +0000247 catch (armnn::Exception& e)
248 {
249 ALOGW("armnn::Exception caught while preparing for EnqueueWorkload: %s", e.what());
Kevin Mayec1e5b82020-02-26 17:00:39 +0000250 NotifyCallbackAndCheck(callback, V1_0::ErrorStatus::GENERAL_FAILURE, "ArmnnPreparedModel::execute");
251 return V1_0::ErrorStatus::GENERAL_FAILURE;
Kevin May7bdaac52020-02-10 12:10:07 +0000252 }
Derek Lambertib9cb8442019-11-28 13:34:48 +0000253 catch (std::exception& e)
telsoa015307bc12018-03-09 13:51:08 +0000254 {
Kevin May7bdaac52020-02-10 12:10:07 +0000255 ALOGE("std::exception caught while preparing for EnqueueWorkload: %s", e.what());
Kevin Mayec1e5b82020-02-26 17:00:39 +0000256 NotifyCallbackAndCheck(callback, V1_0::ErrorStatus::GENERAL_FAILURE, "ArmnnPreparedModel::execute");
257 return V1_0::ErrorStatus::GENERAL_FAILURE;
telsoa015307bc12018-03-09 13:51:08 +0000258 }
259
Kevin Mayec1e5b82020-02-26 17:00:39 +0000260 auto cb = [callback](V1_0::ErrorStatus errorStatus, std::string callingFunction)
Mike Kelly65c42dc2019-07-22 14:06:00 +0100261 {
262 NotifyCallbackAndCheck(callback, errorStatus, callingFunction);
263 };
264
Derek Lamberti4de83c52020-03-17 13:40:18 +0000265 CallbackContext_1_0 armnnCb;
Mike Kelly65c42dc2019-07-22 14:06:00 +0100266 armnnCb.callback = cb;
Finn Williamsd8fb5402021-05-19 20:52:00 +0100267
268 if (m_AsyncModelExecutionEnabled)
269 {
270 ALOGV("ArmnnPreparedModel::execute(...) before ScheduleGraphForExecution");
271 ScheduleGraphForExecution(pMemPools, pInputTensors, pOutputTensors, armnnCb);
272 ALOGV("ArmnnPreparedModel::execute(...) after ScheduleGraphForExecution");
273 return V1_0::ErrorStatus::NONE;
274 }
275
Mike Kelly65c42dc2019-07-22 14:06:00 +0100276 // post the request for asynchronous execution
Finn Williamsd8fb5402021-05-19 20:52:00 +0100277 ALOGV("ArmnnPreparedModel::execute(...) before PostMsg");
Mike Kelly65c42dc2019-07-22 14:06:00 +0100278 m_RequestThread.PostMsg(this, pMemPools, pInputTensors, pOutputTensors, armnnCb);
279 ALOGV("ArmnnPreparedModel::execute(...) after PostMsg");
Kevin Mayec1e5b82020-02-26 17:00:39 +0000280 return V1_0::ErrorStatus::NONE; // successfully queued
telsoa015307bc12018-03-09 13:51:08 +0000281}
282
Matteo Martincighe48bdff2018-09-03 13:50:50 +0100283template<typename HalVersion>
284void ArmnnPreparedModel<HalVersion>::ExecuteGraph(
285 std::shared_ptr<std::vector<::android::nn::RunTimePoolInfo>>& pMemPools,
Derek Lamberti4de83c52020-03-17 13:40:18 +0000286 armnn::InputTensors& inputTensors,
287 armnn::OutputTensors& outputTensors,
288 CallbackContext_1_0 cb)
telsoa015307bc12018-03-09 13:51:08 +0000289{
290 ALOGV("ArmnnPreparedModel::ExecuteGraph(...)");
291
Derek Lamberti4de83c52020-03-17 13:40:18 +0000292 DumpTensorsIfRequired("Input", inputTensors);
telsoa015307bc12018-03-09 13:51:08 +0000293
294 // run it
295 try
296 {
Finn Williamsd8fb5402021-05-19 20:52:00 +0100297 armnn::Status status;
298 if (m_AsyncModelExecutionEnabled)
299 {
300 ALOGW("ArmnnPreparedModel::ExecuteGraph m_AsyncModelExecutionEnabled true");
301 status = m_Runtime->Execute(*m_WorkingMemHandle, inputTensors, outputTensors);
302 }
303 else
304 {
305 ALOGW("ArmnnPreparedModel::ExecuteGraph m_AsyncModelExecutionEnabled false");
306 status = m_Runtime->EnqueueWorkload(m_NetworkId, inputTensors, outputTensors);
307 }
308
Matthew Bentham16196e22019-04-01 17:17:58 +0100309 if (status != armnn::Status::Success)
310 {
311 ALOGW("EnqueueWorkload failed");
Kevin Mayec1e5b82020-02-26 17:00:39 +0000312 cb.callback(V1_0::ErrorStatus::GENERAL_FAILURE, "ArmnnPreparedModel::ExecuteGraph");
Matthew Bentham16196e22019-04-01 17:17:58 +0100313 return;
314 }
telsoa015307bc12018-03-09 13:51:08 +0000315 }
Kevin May7bdaac52020-02-10 12:10:07 +0000316 catch (armnn::Exception& e)
317 {
318 ALOGW("armnn::Exception caught from EnqueueWorkload: %s", e.what());
Kevin Mayec1e5b82020-02-26 17:00:39 +0000319 cb.callback(V1_0::ErrorStatus::GENERAL_FAILURE, "ArmnnPreparedModel::ExecuteGraph");
Kevin May7bdaac52020-02-10 12:10:07 +0000320 return;
321 }
Derek Lambertib9cb8442019-11-28 13:34:48 +0000322 catch (std::exception& e)
telsoa015307bc12018-03-09 13:51:08 +0000323 {
Kevin May7bdaac52020-02-10 12:10:07 +0000324 ALOGE("std::exception caught from EnqueueWorkload: %s", e.what());
Kevin Mayec1e5b82020-02-26 17:00:39 +0000325 cb.callback(V1_0::ErrorStatus::GENERAL_FAILURE, "ArmnnPreparedModel::ExecuteGraph");
telsoa015307bc12018-03-09 13:51:08 +0000326 return;
327 }
328
Derek Lamberti4de83c52020-03-17 13:40:18 +0000329 DumpTensorsIfRequired("Output", outputTensors);
telsoa015307bc12018-03-09 13:51:08 +0000330
331 // Commit output buffers.
332 // Note that we update *all* pools, even if they aren't actually used as outputs -
333 // this is simpler and is what the CpuExecutor does.
334 for (android::nn::RunTimePoolInfo& pool : *pMemPools)
335 {
Kevin Mayec1e5b82020-02-26 17:00:39 +0000336 // Type android::nn::RunTimePoolInfo has changed between Android P & Q and Android R, where
337 // update() has been removed and flush() added.
Sadik Armagan188675f2021-02-12 17:16:42 +0000338 #if defined(ARMNN_ANDROID_R) || defined(ARMNN_ANDROID_S) // Use the new Android implementation.
Kevin Mayec1e5b82020-02-26 17:00:39 +0000339 pool.flush();
340 #else
341 pool.update();
342 #endif
telsoa015307bc12018-03-09 13:51:08 +0000343 }
344
Kevin Mayec1e5b82020-02-26 17:00:39 +0000345 cb.callback(V1_0::ErrorStatus::NONE, "ExecuteGraph");
telsoa015307bc12018-03-09 13:51:08 +0000346}
347
Matteo Martincighe48bdff2018-09-03 13:50:50 +0100348template<typename HalVersion>
Matthew Bentham16196e22019-04-01 17:17:58 +0100349bool ArmnnPreparedModel<HalVersion>::ExecuteWithDummyInputs()
telsoa015307bc12018-03-09 13:51:08 +0000350{
351 std::vector<std::vector<char>> storage;
352 armnn::InputTensors inputTensors;
Kevin May42477c12020-03-26 13:34:14 +0000353 for (unsigned int i = 0; i < getMainModel(m_Model).inputIndexes.size(); i++)
telsoa015307bc12018-03-09 13:51:08 +0000354 {
355 const armnn::TensorInfo inputTensorInfo = m_Runtime->GetInputTensorInfo(m_NetworkId, i);
356 storage.emplace_back(inputTensorInfo.GetNumBytes());
357 const armnn::ConstTensor inputTensor(inputTensorInfo, storage.back().data());
358
359 inputTensors.emplace_back(i, inputTensor);
360 }
361
362 armnn::OutputTensors outputTensors;
Kevin May42477c12020-03-26 13:34:14 +0000363 for (unsigned int i = 0; i < getMainModel(m_Model).outputIndexes.size(); i++)
telsoa015307bc12018-03-09 13:51:08 +0000364 {
365 const armnn::TensorInfo outputTensorInfo = m_Runtime->GetOutputTensorInfo(m_NetworkId, i);
366 storage.emplace_back(outputTensorInfo.GetNumBytes());
367 const armnn::Tensor outputTensor(outputTensorInfo, storage.back().data());
368
369 outputTensors.emplace_back(i, outputTensor);
370 }
371
372 try
373 {
Finn Williams8fde84b2021-05-31 14:57:15 +0100374 armnn::Status status;
375 if (m_AsyncModelExecutionEnabled)
376 {
377 ALOGW("ArmnnPreparedModel::ExecuteGraph m_AsyncModelExecutionEnabled true");
378 status = m_Runtime->Execute(*m_WorkingMemHandle, inputTensors, outputTensors);
379 }
380 else
381 {
382 ALOGW("ArmnnPreparedModel::ExecuteGraph m_AsyncModelExecutionEnabled false");
383 status = m_Runtime->EnqueueWorkload(m_NetworkId, inputTensors, outputTensors);
384 }
Matthew Bentham16196e22019-04-01 17:17:58 +0100385 if (status != armnn::Status::Success)
386 {
387 ALOGW("ExecuteWithDummyInputs: EnqueueWorkload failed");
388 return false;
389 }
telsoa015307bc12018-03-09 13:51:08 +0000390 }
Kevin May7bdaac52020-02-10 12:10:07 +0000391 catch (armnn::Exception& e)
392 {
393 ALOGW("ExecuteWithDummyInputs: armnn::Exception caught from EnqueueWorkload: %s", e.what());
394 return false;
395 }
Derek Lambertib9cb8442019-11-28 13:34:48 +0000396 catch (std::exception& e)
telsoa015307bc12018-03-09 13:51:08 +0000397 {
Kevin May7bdaac52020-02-10 12:10:07 +0000398 ALOGE("ExecuteWithDummyInputs: std::exception caught from EnqueueWorkload: %s", e.what());
Matthew Bentham16196e22019-04-01 17:17:58 +0100399 return false;
telsoa015307bc12018-03-09 13:51:08 +0000400 }
Matthew Bentham16196e22019-04-01 17:17:58 +0100401 return true;
telsoa015307bc12018-03-09 13:51:08 +0000402}
403
Finn Williamsd8fb5402021-05-19 20:52:00 +0100404/// Schedule the graph prepared from the request for execution
405template<typename HalVersion>
406template<typename CallbackContext>
407void ArmnnPreparedModel<HalVersion>::ScheduleGraphForExecution(
408 std::shared_ptr<std::vector<::android::nn::RunTimePoolInfo>>& pMemPools,
409 std::shared_ptr<armnn::InputTensors>& inputTensors,
410 std::shared_ptr<armnn::OutputTensors>& outputTensors,
411 CallbackContext callbackContext)
412{
413 ALOGV("ArmnnPreparedModel::ScheduleGraphForExecution(...)");
414
415 DumpTensorsIfRequired("Input", *inputTensors);
416
417
418 auto tpCb = std::make_shared<
419 ArmnnThreadPoolCallback<CallbackContext_1_0>>(this,
420 pMemPools,
421 inputTensors,
422 outputTensors,
423 callbackContext);
424
Finn Williamsca3a3e02021-06-11 15:04:02 +0100425 m_Threadpool->Schedule(m_NetworkId,
426 *tpCb->m_InputTensors,
427 *tpCb->m_OutputTensors,
428 armnn::QosExecPriority::Medium,
429 tpCb);
Finn Williamsd8fb5402021-05-19 20:52:00 +0100430 ALOGV("ArmnnPreparedModel::ScheduleGraphForExecution end");
431}
432
433template<typename HalVersion>
434template <typename CallbackContext>
435void ArmnnPreparedModel<HalVersion>::ArmnnThreadPoolCallback<CallbackContext>::Notify(
436 armnn::Status status, armnn::InferenceTimingPair timeTaken)
437{
438 armnn::IgnoreUnused(status, timeTaken);
439 ALOGV("ArmnnPreparedModel::ArmnnThreadPoolCallback_1_2 Notify");
440
441 m_Model->DumpTensorsIfRequired("Output", *m_OutputTensors);
442
443 // Commit output buffers.
444 // Note that we update *all* pools, even if they aren't actually used as outputs -
445 // this is simpler and is what the CpuExecutor does.
446 for (android::nn::RunTimePoolInfo& pool : *m_MemPools)
447 {
448 // Type android::nn::RunTimePoolInfo has changed between Android P & Q and Android R, where
449 // update() has been removed and flush() added.
450 #if defined(ARMNN_ANDROID_R) || defined(ARMNN_ANDROID_S) // Use the new Android implementation.
451 pool.flush();
452 #else
453 pool.update();
454 #endif
455 }
456
457 m_CallbackContext.callback(V1_0::ErrorStatus::NONE, "ArmnnPreparedModel::ArmnnThreadPoolCallback_1_2 Notify");
458 return;
459}
460
arovir01b0717b52018-09-05 17:03:25 +0100461///
462/// Class template specializations
463///
Matteo Martincighe48bdff2018-09-03 13:50:50 +0100464
arovir01b0717b52018-09-05 17:03:25 +0100465template class ArmnnPreparedModel<hal_1_0::HalPolicy>;
Finn Williamsd8fb5402021-05-19 20:52:00 +0100466template void ArmnnPreparedModel<hal_1_0::HalPolicy>::ScheduleGraphForExecution<CallbackContext_1_0>(
467 std::shared_ptr<std::vector<::android::nn::RunTimePoolInfo>>& pMemPools,
468 std::shared_ptr<armnn::InputTensors>& inputTensors,
469 std::shared_ptr<armnn::OutputTensors>& outputTensors,
470 CallbackContext_1_0 callbackContext);
arovir01b0717b52018-09-05 17:03:25 +0100471
Matteo Martincigh8b287c22018-09-07 09:25:10 +0100472#ifdef ARMNN_ANDROID_NN_V1_1
arovir01b0717b52018-09-05 17:03:25 +0100473template class ArmnnPreparedModel<hal_1_1::HalPolicy>;
Matteo Martincighe48bdff2018-09-03 13:50:50 +0100474#endif
475
Mike Kellyb5fdf382019-06-11 16:35:25 +0100476#ifdef ARMNN_ANDROID_NN_V1_2
477template class ArmnnPreparedModel<hal_1_1::HalPolicy>;
478template class ArmnnPreparedModel<hal_1_2::HalPolicy>;
479#endif
Kevin May42477c12020-03-26 13:34:14 +0000480
481#ifdef ARMNN_ANDROID_NN_V1_3
482template class ArmnnPreparedModel<hal_1_1::HalPolicy>;
483template class ArmnnPreparedModel<hal_1_2::HalPolicy>;
484template class ArmnnPreparedModel<hal_1_3::HalPolicy>;
485#endif
Nikhil Raj77605822018-09-03 11:25:56 +0100486} // namespace armnn_driver