blob: 98be0903baf4518f63623484cd188d2f0ebcf50a [file] [log] [blame]
surmeh0149b9e102018-05-17 14:11:25 +01001//
Mike Kellye2d611e2021-10-14 12:35:58 +01002// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
David Beck93e48982018-09-05 13:05:09 +01003// SPDX-License-Identifier: MIT
surmeh0149b9e102018-05-17 14:11:25 +01004//
5#pragma once
6
7#ifndef LOG_TAG
8#define LOG_TAG "ArmnnDriverTests"
9#endif // LOG_TAG
10
11#include "../ArmnnDriver.hpp"
12#include <iosfwd>
Kevin Mayec1e5b82020-02-26 17:00:39 +000013#include <android/hidl/allocator/1.0/IAllocator.h>
14
Mike Kellye2d611e2021-10-14 12:35:58 +010015// Some of the short name macros from 'third-party/doctest/doctest.h' clash with macros in
16// 'system/core/base/include/android-base/logging.h' so we use the full DOCTEST macro names
17#ifndef DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES
18#define DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES
19#endif // DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES
20
21#include <doctest/doctest.h>
Sadik Armagan9150bff2021-05-26 15:40:53 +010022
Sadik Armagan188675f2021-02-12 17:16:42 +000023using RequestArgument = V1_0::RequestArgument;
Kevin Mayec1e5b82020-02-26 17:00:39 +000024using ::android::hidl::allocator::V1_0::IAllocator;
25
Sadik Armagan188675f2021-02-12 17:16:42 +000026using ::android::hidl::memory::V1_0::IMemory;
27
surmeh0149b9e102018-05-17 14:11:25 +010028namespace android
29{
30namespace hardware
31{
32namespace neuralnetworks
33{
34namespace V1_0
35{
36
Kevin Mayec1e5b82020-02-26 17:00:39 +000037std::ostream& operator<<(std::ostream& os, V1_0::ErrorStatus stat);
surmeh0149b9e102018-05-17 14:11:25 +010038
39} // namespace android::hardware::neuralnetworks::V1_0
Sadik Armagan6a903a72020-05-26 10:41:54 +010040
41#ifdef ARMNN_ANDROID_NN_V1_3
42namespace V1_3
43{
44
45std::ostream& operator<<(std::ostream& os, V1_3::ErrorStatus stat);
46
47} // namespace android::hardware::neuralnetworks::V1_3
48#endif
49
surmeh0149b9e102018-05-17 14:11:25 +010050} // namespace android::hardware::neuralnetworks
51} // namespace android::hardware
52} // namespace android
53
54namespace driverTestHelpers
55{
56
Matteo Martincigh8b287c22018-09-07 09:25:10 +010057std::ostream& operator<<(std::ostream& os, V1_0::ErrorStatus stat);
surmeh0149b9e102018-05-17 14:11:25 +010058
Sadik Armagan6a903a72020-05-26 10:41:54 +010059#ifdef ARMNN_ANDROID_NN_V1_3
60std::ostream& operator<<(std::ostream& os, V1_3::ErrorStatus stat);
61#endif
62
Sadik Armagane6e54a82019-05-08 10:18:05 +010063struct ExecutionCallback : public V1_0::IExecutionCallback
surmeh0149b9e102018-05-17 14:11:25 +010064{
65 ExecutionCallback() : mNotified(false) {}
Kevin Mayec1e5b82020-02-26 17:00:39 +000066 Return<void> notify(V1_0::ErrorStatus status) override;
surmeh0149b9e102018-05-17 14:11:25 +010067 /// wait until the callback has notified us that it is done
68 Return<void> wait();
69
70private:
71 // use a mutex and a condition variable to wait for asynchronous callbacks
72 std::mutex mMutex;
73 std::condition_variable mCondition;
74 // and a flag, in case we are notified before the wait call
75 bool mNotified;
76};
77
Sadik Armagane6e54a82019-05-08 10:18:05 +010078class PreparedModelCallback : public V1_0::IPreparedModelCallback
surmeh0149b9e102018-05-17 14:11:25 +010079{
80public:
81 PreparedModelCallback()
Kevin Mayec1e5b82020-02-26 17:00:39 +000082 : m_ErrorStatus(V1_0::ErrorStatus::NONE)
surmeh0149b9e102018-05-17 14:11:25 +010083 , m_PreparedModel()
84 { }
85 ~PreparedModelCallback() override { }
86
Kevin Mayec1e5b82020-02-26 17:00:39 +000087 Return<void> notify(V1_0::ErrorStatus status,
Sadik Armagane6e54a82019-05-08 10:18:05 +010088 const android::sp<V1_0::IPreparedModel>& preparedModel) override;
Kevin Mayec1e5b82020-02-26 17:00:39 +000089 V1_0::ErrorStatus GetErrorStatus() { return m_ErrorStatus; }
Sadik Armagane6e54a82019-05-08 10:18:05 +010090 android::sp<V1_0::IPreparedModel> GetPreparedModel() { return m_PreparedModel; }
surmeh0149b9e102018-05-17 14:11:25 +010091
92private:
Kevin Mayec1e5b82020-02-26 17:00:39 +000093 V1_0::ErrorStatus m_ErrorStatus;
Sadik Armagane6e54a82019-05-08 10:18:05 +010094 android::sp<V1_0::IPreparedModel> m_PreparedModel;
surmeh0149b9e102018-05-17 14:11:25 +010095};
96
Sadik Armagan6a903a72020-05-26 10:41:54 +010097#if defined(ARMNN_ANDROID_NN_V1_2) || defined(ARMNN_ANDROID_NN_V1_3)
Ferran Balaguerb2397fd2019-07-25 12:12:39 +010098
99class PreparedModelCallback_1_2 : public V1_2::IPreparedModelCallback
100{
101public:
102 PreparedModelCallback_1_2()
Kevin Mayec1e5b82020-02-26 17:00:39 +0000103 : m_ErrorStatus(V1_0::ErrorStatus::NONE)
Ferran Balaguerb2397fd2019-07-25 12:12:39 +0100104 , m_PreparedModel()
105 , m_PreparedModel_1_2()
106 { }
107 ~PreparedModelCallback_1_2() override { }
108
Kevin Mayec1e5b82020-02-26 17:00:39 +0000109 Return<void> notify(V1_0::ErrorStatus status, const android::sp<V1_0::IPreparedModel>& preparedModel) override;
Ferran Balaguerb2397fd2019-07-25 12:12:39 +0100110
Kevin Mayec1e5b82020-02-26 17:00:39 +0000111 Return<void> notify_1_2(V1_0::ErrorStatus status, const android::sp<V1_2::IPreparedModel>& preparedModel) override;
Ferran Balaguerb2397fd2019-07-25 12:12:39 +0100112
Kevin Mayec1e5b82020-02-26 17:00:39 +0000113 V1_0::ErrorStatus GetErrorStatus() { return m_ErrorStatus; }
Ferran Balaguerb2397fd2019-07-25 12:12:39 +0100114
115 android::sp<V1_0::IPreparedModel> GetPreparedModel() { return m_PreparedModel; }
116
117 android::sp<V1_2::IPreparedModel> GetPreparedModel_1_2() { return m_PreparedModel_1_2; }
118
119private:
Kevin Mayec1e5b82020-02-26 17:00:39 +0000120 V1_0::ErrorStatus m_ErrorStatus;
Ferran Balaguerb2397fd2019-07-25 12:12:39 +0100121 android::sp<V1_0::IPreparedModel> m_PreparedModel;
122 android::sp<V1_2::IPreparedModel> m_PreparedModel_1_2;
123};
124
125#endif
126
Sadik Armagan6a903a72020-05-26 10:41:54 +0100127#ifdef ARMNN_ANDROID_NN_V1_3
128
129class PreparedModelCallback_1_3 : public V1_3::IPreparedModelCallback
130{
131public:
132 PreparedModelCallback_1_3()
133 : m_1_0_ErrorStatus(V1_0::ErrorStatus::NONE)
134 , m_1_3_ErrorStatus(V1_3::ErrorStatus::NONE)
135 , m_PreparedModel()
136 , m_PreparedModel_1_2()
137 , m_PreparedModel_1_3()
138 { }
139 ~PreparedModelCallback_1_3() override { }
140
141 Return<void> notify(V1_0::ErrorStatus status, const android::sp<V1_0::IPreparedModel>& preparedModel) override;
142
143 Return<void> notify_1_2(V1_0::ErrorStatus status, const android::sp<V1_2::IPreparedModel>& preparedModel) override;
144
145 Return<void> notify_1_3(V1_3::ErrorStatus status, const android::sp<V1_3::IPreparedModel>& preparedModel) override;
146
147 V1_0::ErrorStatus GetErrorStatus() { return m_1_0_ErrorStatus; }
148
149 V1_3::ErrorStatus Get_1_3_ErrorStatus() { return m_1_3_ErrorStatus; }
150
151 android::sp<V1_0::IPreparedModel> GetPreparedModel() { return m_PreparedModel; }
152
153 android::sp<V1_2::IPreparedModel> GetPreparedModel_1_2() { return m_PreparedModel_1_2; }
154
155 android::sp<V1_3::IPreparedModel> GetPreparedModel_1_3() { return m_PreparedModel_1_3; }
156
157private:
158 V1_0::ErrorStatus m_1_0_ErrorStatus;
159 V1_3::ErrorStatus m_1_3_ErrorStatus;
160 android::sp<V1_0::IPreparedModel> m_PreparedModel;
161 android::sp<V1_2::IPreparedModel> m_PreparedModel_1_2;
162 android::sp<V1_3::IPreparedModel> m_PreparedModel_1_3;
163};
164
165#endif
166
surmeh0149b9e102018-05-17 14:11:25 +0100167hidl_memory allocateSharedMemory(int64_t size);
168
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +0100169template<typename T>
Kevin Mayec1e5b82020-02-26 17:00:39 +0000170android::sp<IMemory> AddPoolAndGetData(uint32_t size, V1_0::Request& request)
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +0100171{
172 hidl_memory pool;
surmeh0149b9e102018-05-17 14:11:25 +0100173
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +0100174 android::sp<IAllocator> allocator = IAllocator::getService("ashmem");
175 allocator->allocate(sizeof(T) * size, [&](bool success, const hidl_memory& mem) {
Mike Kellye2d611e2021-10-14 12:35:58 +0100176 DOCTEST_CHECK(success);
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +0100177 pool = mem;
178 });
179
180 request.pools.resize(request.pools.size() + 1);
181 request.pools[request.pools.size() - 1] = pool;
182
183 android::sp<IMemory> mapped = mapMemory(pool);
184 mapped->update();
185 return mapped;
186}
187
188template<typename T>
Narumol Prangnawarat558a1d42022-02-07 13:12:24 +0000189android::sp<IMemory> AddPoolAndSetData(uint32_t size, V1_0::Request& request, const T* data)
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +0100190{
191 android::sp<IMemory> memory = AddPoolAndGetData<T>(size, request);
192
193 T* dst = static_cast<T*>(static_cast<void*>(memory->getPointer()));
194
195 memcpy(dst, data, size * sizeof(T));
Narumol Prangnawarat558a1d42022-02-07 13:12:24 +0000196
197 return memory;
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +0100198}
surmeh0149b9e102018-05-17 14:11:25 +0100199
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100200template<typename HalPolicy,
201 typename HalModel = typename HalPolicy::Model,
202 typename HalOperand = typename HalPolicy::Operand>
203void AddOperand(HalModel& model, const HalOperand& op)
Nikhil Raj77605822018-09-03 11:25:56 +0100204{
205 model.operands.resize(model.operands.size() + 1);
206 model.operands[model.operands.size() - 1] = op;
207}
surmeh0149b9e102018-05-17 14:11:25 +0100208
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100209template<typename HalPolicy, typename HalModel = typename HalPolicy::Model>
David Monahanc60d0fd2020-05-19 14:58:34 +0100210void AddBoolOperand(HalModel& model, bool value, uint32_t numberOfConsumers = 1)
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100211{
212 using HalOperand = typename HalPolicy::Operand;
213 using HalOperandType = typename HalPolicy::OperandType;
214 using HalOperandLifeTime = typename HalPolicy::OperandLifeTime;
215
Sadik Armagan188675f2021-02-12 17:16:42 +0000216 V1_0::DataLocation location = {};
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100217 location.offset = model.operandValues.size();
218 location.length = sizeof(uint8_t);
219
David Monahanc60d0fd2020-05-19 14:58:34 +0100220 HalOperand op = {};
221 op.type = HalOperandType::BOOL;
222 op.dimensions = hidl_vec<uint32_t>{};
223 op.lifetime = HalOperandLifeTime::CONSTANT_COPY;
224 op.location = location;
225 op.numberOfConsumers = numberOfConsumers;
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100226
227 model.operandValues.resize(model.operandValues.size() + location.length);
228 *reinterpret_cast<uint8_t*>(&model.operandValues[location.offset]) = static_cast<uint8_t>(value);
229
Nikhil Raj77605822018-09-03 11:25:56 +0100230 AddOperand<HalModel>(model, op);
231}
surmeh0149b9e102018-05-17 14:11:25 +0100232
233template<typename T>
234OperandType TypeToOperandType();
235
236template<>
237OperandType TypeToOperandType<float>();
238
239template<>
240OperandType TypeToOperandType<int32_t>();
241
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100242template<typename HalPolicy,
Sadik Armagan6a903a72020-05-26 10:41:54 +0100243 typename HalModel = typename HalPolicy::Model,
244 typename HalOperandType = typename HalPolicy::OperandType>
245void AddInputOperand(HalModel& model,
246 const hidl_vec<uint32_t>& dimensions,
247 HalOperandType operandType = HalOperandType::TENSOR_FLOAT32,
248 double scale = 0.f,
249 int offset = 0,
250 uint32_t numberOfConsumers = 1)
251{
252 using HalOperand = typename HalPolicy::Operand;
253 using HalOperandLifeTime = typename HalPolicy::OperandLifeTime;
254
255 HalOperand op = {};
256 op.type = operandType;
257 op.scale = scale;
258 op.zeroPoint = offset;
259 op.dimensions = dimensions;
260 op.lifetime = HalOperandLifeTime::MODEL_INPUT;
261 op.numberOfConsumers = numberOfConsumers;
262
263 AddOperand<HalPolicy>(model, op);
264
265 model.inputIndexes.resize(model.inputIndexes.size() + 1);
266 model.inputIndexes[model.inputIndexes.size() - 1] = model.operands.size() - 1;
267}
268
269template<typename HalPolicy,
270 typename HalModel = typename HalPolicy::Model,
271 typename HalOperandType = typename HalPolicy::OperandType>
272void AddOutputOperand(HalModel& model,
273 const hidl_vec<uint32_t>& dimensions,
274 HalOperandType operandType = HalOperandType::TENSOR_FLOAT32,
275 double scale = 0.f,
276 int offset = 0,
277 uint32_t numberOfConsumers = 0)
278{
279 using HalOperand = typename HalPolicy::Operand;
280 using HalOperandLifeTime = typename HalPolicy::OperandLifeTime;
281
282 HalOperand op = {};
283 op.type = operandType;
284 op.scale = scale;
285 op.zeroPoint = offset;
286 op.dimensions = dimensions;
287 op.lifetime = HalOperandLifeTime::MODEL_OUTPUT;
288 op.numberOfConsumers = numberOfConsumers;
289
290 AddOperand<HalPolicy>(model, op);
291
292 model.outputIndexes.resize(model.outputIndexes.size() + 1);
293 model.outputIndexes[model.outputIndexes.size() - 1] = model.operands.size() - 1;
294}
295
296android::sp<V1_0::IPreparedModel> PrepareModelWithStatus(const V1_0::Model& model,
297 armnn_driver::ArmnnDriver& driver,
298 V1_0::ErrorStatus& prepareStatus,
299 V1_0::ErrorStatus expectedStatus = V1_0::ErrorStatus::NONE);
300
301#if defined(ARMNN_ANDROID_NN_V1_1) || defined(ARMNN_ANDROID_NN_V1_2) || defined(ARMNN_ANDROID_NN_V1_3)
302
303android::sp<V1_0::IPreparedModel> PrepareModelWithStatus(const V1_1::Model& model,
304 armnn_driver::ArmnnDriver& driver,
305 V1_0::ErrorStatus& prepareStatus,
306 V1_0::ErrorStatus expectedStatus = V1_0::ErrorStatus::NONE);
307
308#endif
309
310template<typename HalModel>
311android::sp<V1_0::IPreparedModel> PrepareModel(const HalModel& model,
312 armnn_driver::ArmnnDriver& driver)
313{
314 V1_0::ErrorStatus prepareStatus = V1_0::ErrorStatus::NONE;
315 return PrepareModelWithStatus(model, driver, prepareStatus);
316}
317
318#if defined(ARMNN_ANDROID_NN_V1_2) || defined(ARMNN_ANDROID_NN_V1_3)
319
320android::sp<V1_2::IPreparedModel> PrepareModelWithStatus_1_2(const armnn_driver::hal_1_2::HalPolicy::Model& model,
321 armnn_driver::ArmnnDriver& driver,
322 V1_0::ErrorStatus& prepareStatus,
323 V1_0::ErrorStatus expectedStatus = V1_0::ErrorStatus::NONE);
324
325template<typename HalModel>
326android::sp<V1_2::IPreparedModel> PrepareModel_1_2(const HalModel& model,
327 armnn_driver::ArmnnDriver& driver)
328{
329 V1_0::ErrorStatus prepareStatus = V1_0::ErrorStatus::NONE;
330 return PrepareModelWithStatus_1_2(model, driver, prepareStatus);
331}
332
333#endif
334
335#ifdef ARMNN_ANDROID_NN_V1_3
336
337template<typename HalPolicy>
338void AddOperand(armnn_driver::hal_1_3::HalPolicy::Model& model,
339 const armnn_driver::hal_1_3::HalPolicy::Operand& op)
340{
341 model.main.operands.resize(model.main.operands.size() + 1);
342 model.main.operands[model.main.operands.size() - 1] = op;
343}
344
345template<typename HalPolicy>
346void AddInputOperand(armnn_driver::hal_1_3::HalPolicy::Model& model,
347 const hidl_vec<uint32_t>& dimensions,
348 armnn_driver::hal_1_3::HalPolicy::OperandType operandType =
349 armnn_driver::hal_1_3::HalPolicy::OperandType::TENSOR_FLOAT32,
350 double scale = 0.f,
351 int offset = 0,
352 uint32_t numberOfConsumers = 1)
353{
354 using HalOperand = typename armnn_driver::hal_1_3::HalPolicy::Operand;
355 using HalOperandLifeTime = typename armnn_driver::hal_1_3::HalPolicy::OperandLifeTime;
356
357 HalOperand op = {};
358 op.type = operandType;
359 op.scale = scale;
360 op.zeroPoint = offset;
361 op.dimensions = dimensions;
362 op.lifetime = HalOperandLifeTime::SUBGRAPH_INPUT;
363 op.numberOfConsumers = numberOfConsumers;
364
365 AddOperand<HalPolicy>(model, op);
366
367 model.main.inputIndexes.resize(model.main.inputIndexes.size() + 1);
368 model.main.inputIndexes[model.main.inputIndexes.size() - 1] = model.main.operands.size() - 1;
369}
370
371template<typename HalPolicy>
372void AddOutputOperand(armnn_driver::hal_1_3::HalPolicy::Model& model,
373 const hidl_vec<uint32_t>& dimensions,
374 armnn_driver::hal_1_3::HalPolicy::OperandType operandType =
375 armnn_driver::hal_1_3::HalPolicy::OperandType::TENSOR_FLOAT32,
376 double scale = 0.f,
377 int offset = 0,
378 uint32_t numberOfConsumers = 0)
379{
380 using HalOperand = typename armnn_driver::hal_1_3::HalPolicy::Operand;
381 using HalOperandLifeTime = typename armnn_driver::hal_1_3::HalPolicy::OperandLifeTime;
382
383 HalOperand op = {};
384 op.type = operandType;
385 op.scale = scale;
386 op.zeroPoint = offset;
387 op.dimensions = dimensions;
388 op.lifetime = HalOperandLifeTime::SUBGRAPH_OUTPUT;
389 op.numberOfConsumers = numberOfConsumers;
390
391 AddOperand<HalPolicy>(model, op);
392
393 model.main.outputIndexes.resize(model.main.outputIndexes.size() + 1);
394 model.main.outputIndexes[model.main.outputIndexes.size() - 1] = model.main.operands.size() - 1;
395}
396
397android::sp<V1_3::IPreparedModel> PrepareModelWithStatus_1_3(const armnn_driver::hal_1_3::HalPolicy::Model& model,
398 armnn_driver::ArmnnDriver& driver,
David Monahan82609562020-08-31 15:50:32 +0100399 V1_3::ErrorStatus& prepareStatus,
400 V1_3::Priority priority = V1_3::Priority::LOW);
Sadik Armagan6a903a72020-05-26 10:41:54 +0100401
402template<typename HalModel>
403android::sp<V1_3::IPreparedModel> PrepareModel_1_3(const HalModel& model,
404 armnn_driver::ArmnnDriver& driver)
405{
406 V1_3::ErrorStatus prepareStatus = V1_3::ErrorStatus::NONE;
407 return PrepareModelWithStatus_1_3(model, driver, prepareStatus);
408}
409
410#endif
411
412template<typename HalPolicy,
413 typename T,
414 typename HalModel = typename HalPolicy::Model,
415 typename HalOperandType = typename HalPolicy::OperandType,
416 typename HalOperandLifeTime = typename HalPolicy::OperandLifeTime>
Nikhil Raj77605822018-09-03 11:25:56 +0100417void AddTensorOperand(HalModel& model,
Matteo Martincighc7434122018-11-14 12:27:04 +0000418 const hidl_vec<uint32_t>& dimensions,
419 const T* values,
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100420 HalOperandType operandType = HalOperandType::TENSOR_FLOAT32,
Kevin Mayec1e5b82020-02-26 17:00:39 +0000421 HalOperandLifeTime operandLifeTime = V1_0::OperandLifeTime::CONSTANT_COPY,
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +0100422 double scale = 0.f,
David Monahanc60d0fd2020-05-19 14:58:34 +0100423 int offset = 0,
424 uint32_t numberOfConsumers = 1)
surmeh0149b9e102018-05-17 14:11:25 +0100425{
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100426 using HalOperand = typename HalPolicy::Operand;
427
surmeh0149b9e102018-05-17 14:11:25 +0100428 uint32_t totalElements = 1;
429 for (uint32_t dim : dimensions)
430 {
431 totalElements *= dim;
432 }
433
Sadik Armagan188675f2021-02-12 17:16:42 +0000434 V1_0::DataLocation location = {};
surmeh0149b9e102018-05-17 14:11:25 +0100435 location.length = totalElements * sizeof(T);
436
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100437 if(operandLifeTime == HalOperandLifeTime::CONSTANT_COPY)
Kevin Mayf29a2c52019-03-14 11:56:32 +0000438 {
439 location.offset = model.operandValues.size();
440 }
441
David Monahanc60d0fd2020-05-19 14:58:34 +0100442 HalOperand op = {};
443 op.type = operandType;
444 op.dimensions = dimensions;
445 op.scale = scale;
446 op.zeroPoint = offset;
447 op.lifetime = HalOperandLifeTime::CONSTANT_COPY;
448 op.location = location;
449 op.numberOfConsumers = numberOfConsumers;
surmeh0149b9e102018-05-17 14:11:25 +0100450
451 model.operandValues.resize(model.operandValues.size() + location.length);
452 for (uint32_t i = 0; i < totalElements; i++)
453 {
454 *(reinterpret_cast<T*>(&model.operandValues[location.offset]) + i) = values[i];
455 }
456
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100457 AddOperand<HalPolicy>(model, op);
surmeh0149b9e102018-05-17 14:11:25 +0100458}
459
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100460template<typename HalPolicy,
Sadik Armagan6a903a72020-05-26 10:41:54 +0100461 typename T,
462 typename HalModel = typename HalPolicy::Model,
463 typename HalOperandType = typename HalPolicy::OperandType,
464 typename HalOperandLifeTime = typename HalPolicy::OperandLifeTime>
Matteo Martincighc7434122018-11-14 12:27:04 +0000465void AddTensorOperand(HalModel& model,
466 const hidl_vec<uint32_t>& dimensions,
467 const std::vector<T>& values,
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100468 HalOperandType operandType = HalPolicy::OperandType::TENSOR_FLOAT32,
Kevin Mayec1e5b82020-02-26 17:00:39 +0000469 HalOperandLifeTime operandLifeTime = V1_0::OperandLifeTime::CONSTANT_COPY,
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +0100470 double scale = 0.f,
David Monahanc60d0fd2020-05-19 14:58:34 +0100471 int offset = 0,
472 uint32_t numberOfConsumers = 1)
Matteo Martincighc7434122018-11-14 12:27:04 +0000473{
David Monahanc60d0fd2020-05-19 14:58:34 +0100474 AddTensorOperand<HalPolicy, T>(model,
475 dimensions,
476 values.data(),
477 operandType,
478 operandLifeTime,
479 scale,
480 offset,
481 numberOfConsumers);
Matteo Martincighc7434122018-11-14 12:27:04 +0000482}
483
Sadik Armagan6a903a72020-05-26 10:41:54 +0100484template<typename HalPolicy, typename HalModel = typename HalPolicy::Model>
485void AddIntOperand(HalModel& model, int32_t value, uint32_t numberOfConsumers = 1)
486{
487 using HalOperand = typename HalPolicy::Operand;
488 using HalOperandType = typename HalPolicy::OperandType;
489 using HalOperandLifeTime = typename HalPolicy::OperandLifeTime;
490
Sadik Armagan188675f2021-02-12 17:16:42 +0000491 V1_0::DataLocation location = {};
Sadik Armagan6a903a72020-05-26 10:41:54 +0100492 location.offset = model.operandValues.size();
493 location.length = sizeof(int32_t);
494
495 HalOperand op = {};
496 op.type = HalOperandType::INT32;
497 op.dimensions = hidl_vec<uint32_t>{};
498 op.lifetime = HalOperandLifeTime::CONSTANT_COPY;
499 op.location = location;
500 op.numberOfConsumers = numberOfConsumers;
501
502 model.operandValues.resize(model.operandValues.size() + location.length);
503 *reinterpret_cast<int32_t*>(&model.operandValues[location.offset]) = value;
504
505 AddOperand<HalPolicy>(model, op);
506}
507
508template<typename HalPolicy, typename HalModel = typename HalPolicy::Model>
509void AddFloatOperand(HalModel& model,
510 float value,
David Monahanc60d0fd2020-05-19 14:58:34 +0100511 uint32_t numberOfConsumers = 1)
Nikhil Raj77605822018-09-03 11:25:56 +0100512{
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100513 using HalOperand = typename HalPolicy::Operand;
Sadik Armagan6a903a72020-05-26 10:41:54 +0100514 using HalOperandType = typename HalPolicy::OperandType;
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100515 using HalOperandLifeTime = typename HalPolicy::OperandLifeTime;
surmeh0149b9e102018-05-17 14:11:25 +0100516
Sadik Armagan188675f2021-02-12 17:16:42 +0000517 V1_0::DataLocation location = {};
Sadik Armagan6a903a72020-05-26 10:41:54 +0100518 location.offset = model.operandValues.size();
519 location.length = sizeof(float);
surmeh0149b9e102018-05-17 14:11:25 +0100520
David Monahanc60d0fd2020-05-19 14:58:34 +0100521 HalOperand op = {};
Sadik Armagan6a903a72020-05-26 10:41:54 +0100522 op.type = HalOperandType::FLOAT32;
523 op.dimensions = hidl_vec<uint32_t>{};
524 op.lifetime = HalOperandLifeTime::CONSTANT_COPY;
525 op.location = location;
David Monahanc60d0fd2020-05-19 14:58:34 +0100526 op.numberOfConsumers = numberOfConsumers;
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100527
Sadik Armagan6a903a72020-05-26 10:41:54 +0100528 model.operandValues.resize(model.operandValues.size() + location.length);
529 *reinterpret_cast<float*>(&model.operandValues[location.offset]) = value;
530
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100531 AddOperand<HalPolicy>(model, op);
Nikhil Raj77605822018-09-03 11:25:56 +0100532}
surmeh0149b9e102018-05-17 14:11:25 +0100533
Kevin Mayec1e5b82020-02-26 17:00:39 +0000534V1_0::ErrorStatus Execute(android::sp<V1_0::IPreparedModel> preparedModel,
535 const V1_0::Request& request,
536 V1_0::ErrorStatus expectedStatus = V1_0::ErrorStatus::NONE);
surmeh0149b9e102018-05-17 14:11:25 +0100537
Sadik Armagane6e54a82019-05-08 10:18:05 +0100538android::sp<ExecutionCallback> ExecuteNoWait(android::sp<V1_0::IPreparedModel> preparedModel,
Kevin Mayec1e5b82020-02-26 17:00:39 +0000539 const V1_0::Request& request);
surmeh0149b9e102018-05-17 14:11:25 +0100540
541} // namespace driverTestHelpers