blob: d37fbf2616a7bff195cabdbd0e70d89d4f7b2988 [file] [log] [blame]
surmeh0149b9e102018-05-17 14:11:25 +01001//
2// Copyright © 2017 Arm Ltd. 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>
Nikhil Raj77605822018-09-03 11:25:56 +010013#include <boost/test/unit_test.hpp>
surmeh0149b9e102018-05-17 14:11:25 +010014
Kevin Mayec1e5b82020-02-26 17:00:39 +000015#include <android/hidl/allocator/1.0/IAllocator.h>
16
Sadik Armagan188675f2021-02-12 17:16:42 +000017using RequestArgument = V1_0::RequestArgument;
Kevin Mayec1e5b82020-02-26 17:00:39 +000018using ::android::hidl::allocator::V1_0::IAllocator;
19
Sadik Armagan188675f2021-02-12 17:16:42 +000020using ::android::hidl::memory::V1_0::IMemory;
21
surmeh0149b9e102018-05-17 14:11:25 +010022namespace android
23{
24namespace hardware
25{
26namespace neuralnetworks
27{
28namespace V1_0
29{
30
Kevin Mayec1e5b82020-02-26 17:00:39 +000031std::ostream& operator<<(std::ostream& os, V1_0::ErrorStatus stat);
surmeh0149b9e102018-05-17 14:11:25 +010032
33} // namespace android::hardware::neuralnetworks::V1_0
Sadik Armagan6a903a72020-05-26 10:41:54 +010034
35#ifdef ARMNN_ANDROID_NN_V1_3
36namespace V1_3
37{
38
39std::ostream& operator<<(std::ostream& os, V1_3::ErrorStatus stat);
40
41} // namespace android::hardware::neuralnetworks::V1_3
42#endif
43
surmeh0149b9e102018-05-17 14:11:25 +010044} // namespace android::hardware::neuralnetworks
45} // namespace android::hardware
46} // namespace android
47
48namespace driverTestHelpers
49{
50
Matteo Martincigh8b287c22018-09-07 09:25:10 +010051std::ostream& operator<<(std::ostream& os, V1_0::ErrorStatus stat);
surmeh0149b9e102018-05-17 14:11:25 +010052
Sadik Armagan6a903a72020-05-26 10:41:54 +010053#ifdef ARMNN_ANDROID_NN_V1_3
54std::ostream& operator<<(std::ostream& os, V1_3::ErrorStatus stat);
55#endif
56
Sadik Armagane6e54a82019-05-08 10:18:05 +010057struct ExecutionCallback : public V1_0::IExecutionCallback
surmeh0149b9e102018-05-17 14:11:25 +010058{
59 ExecutionCallback() : mNotified(false) {}
Kevin Mayec1e5b82020-02-26 17:00:39 +000060 Return<void> notify(V1_0::ErrorStatus status) override;
surmeh0149b9e102018-05-17 14:11:25 +010061 /// wait until the callback has notified us that it is done
62 Return<void> wait();
63
64private:
65 // use a mutex and a condition variable to wait for asynchronous callbacks
66 std::mutex mMutex;
67 std::condition_variable mCondition;
68 // and a flag, in case we are notified before the wait call
69 bool mNotified;
70};
71
Sadik Armagane6e54a82019-05-08 10:18:05 +010072class PreparedModelCallback : public V1_0::IPreparedModelCallback
surmeh0149b9e102018-05-17 14:11:25 +010073{
74public:
75 PreparedModelCallback()
Kevin Mayec1e5b82020-02-26 17:00:39 +000076 : m_ErrorStatus(V1_0::ErrorStatus::NONE)
surmeh0149b9e102018-05-17 14:11:25 +010077 , m_PreparedModel()
78 { }
79 ~PreparedModelCallback() override { }
80
Kevin Mayec1e5b82020-02-26 17:00:39 +000081 Return<void> notify(V1_0::ErrorStatus status,
Sadik Armagane6e54a82019-05-08 10:18:05 +010082 const android::sp<V1_0::IPreparedModel>& preparedModel) override;
Kevin Mayec1e5b82020-02-26 17:00:39 +000083 V1_0::ErrorStatus GetErrorStatus() { return m_ErrorStatus; }
Sadik Armagane6e54a82019-05-08 10:18:05 +010084 android::sp<V1_0::IPreparedModel> GetPreparedModel() { return m_PreparedModel; }
surmeh0149b9e102018-05-17 14:11:25 +010085
86private:
Kevin Mayec1e5b82020-02-26 17:00:39 +000087 V1_0::ErrorStatus m_ErrorStatus;
Sadik Armagane6e54a82019-05-08 10:18:05 +010088 android::sp<V1_0::IPreparedModel> m_PreparedModel;
surmeh0149b9e102018-05-17 14:11:25 +010089};
90
Sadik Armagan6a903a72020-05-26 10:41:54 +010091#if defined(ARMNN_ANDROID_NN_V1_2) || defined(ARMNN_ANDROID_NN_V1_3)
Ferran Balaguerb2397fd2019-07-25 12:12:39 +010092
93class PreparedModelCallback_1_2 : public V1_2::IPreparedModelCallback
94{
95public:
96 PreparedModelCallback_1_2()
Kevin Mayec1e5b82020-02-26 17:00:39 +000097 : m_ErrorStatus(V1_0::ErrorStatus::NONE)
Ferran Balaguerb2397fd2019-07-25 12:12:39 +010098 , m_PreparedModel()
99 , m_PreparedModel_1_2()
100 { }
101 ~PreparedModelCallback_1_2() override { }
102
Kevin Mayec1e5b82020-02-26 17:00:39 +0000103 Return<void> notify(V1_0::ErrorStatus status, const android::sp<V1_0::IPreparedModel>& preparedModel) override;
Ferran Balaguerb2397fd2019-07-25 12:12:39 +0100104
Kevin Mayec1e5b82020-02-26 17:00:39 +0000105 Return<void> notify_1_2(V1_0::ErrorStatus status, const android::sp<V1_2::IPreparedModel>& preparedModel) override;
Ferran Balaguerb2397fd2019-07-25 12:12:39 +0100106
Kevin Mayec1e5b82020-02-26 17:00:39 +0000107 V1_0::ErrorStatus GetErrorStatus() { return m_ErrorStatus; }
Ferran Balaguerb2397fd2019-07-25 12:12:39 +0100108
109 android::sp<V1_0::IPreparedModel> GetPreparedModel() { return m_PreparedModel; }
110
111 android::sp<V1_2::IPreparedModel> GetPreparedModel_1_2() { return m_PreparedModel_1_2; }
112
113private:
Kevin Mayec1e5b82020-02-26 17:00:39 +0000114 V1_0::ErrorStatus m_ErrorStatus;
Ferran Balaguerb2397fd2019-07-25 12:12:39 +0100115 android::sp<V1_0::IPreparedModel> m_PreparedModel;
116 android::sp<V1_2::IPreparedModel> m_PreparedModel_1_2;
117};
118
119#endif
120
Sadik Armagan6a903a72020-05-26 10:41:54 +0100121#ifdef ARMNN_ANDROID_NN_V1_3
122
123class PreparedModelCallback_1_3 : public V1_3::IPreparedModelCallback
124{
125public:
126 PreparedModelCallback_1_3()
127 : m_1_0_ErrorStatus(V1_0::ErrorStatus::NONE)
128 , m_1_3_ErrorStatus(V1_3::ErrorStatus::NONE)
129 , m_PreparedModel()
130 , m_PreparedModel_1_2()
131 , m_PreparedModel_1_3()
132 { }
133 ~PreparedModelCallback_1_3() override { }
134
135 Return<void> notify(V1_0::ErrorStatus status, const android::sp<V1_0::IPreparedModel>& preparedModel) override;
136
137 Return<void> notify_1_2(V1_0::ErrorStatus status, const android::sp<V1_2::IPreparedModel>& preparedModel) override;
138
139 Return<void> notify_1_3(V1_3::ErrorStatus status, const android::sp<V1_3::IPreparedModel>& preparedModel) override;
140
141 V1_0::ErrorStatus GetErrorStatus() { return m_1_0_ErrorStatus; }
142
143 V1_3::ErrorStatus Get_1_3_ErrorStatus() { return m_1_3_ErrorStatus; }
144
145 android::sp<V1_0::IPreparedModel> GetPreparedModel() { return m_PreparedModel; }
146
147 android::sp<V1_2::IPreparedModel> GetPreparedModel_1_2() { return m_PreparedModel_1_2; }
148
149 android::sp<V1_3::IPreparedModel> GetPreparedModel_1_3() { return m_PreparedModel_1_3; }
150
151private:
152 V1_0::ErrorStatus m_1_0_ErrorStatus;
153 V1_3::ErrorStatus m_1_3_ErrorStatus;
154 android::sp<V1_0::IPreparedModel> m_PreparedModel;
155 android::sp<V1_2::IPreparedModel> m_PreparedModel_1_2;
156 android::sp<V1_3::IPreparedModel> m_PreparedModel_1_3;
157};
158
159#endif
160
surmeh0149b9e102018-05-17 14:11:25 +0100161hidl_memory allocateSharedMemory(int64_t size);
162
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +0100163template<typename T>
Kevin Mayec1e5b82020-02-26 17:00:39 +0000164android::sp<IMemory> AddPoolAndGetData(uint32_t size, V1_0::Request& request)
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +0100165{
166 hidl_memory pool;
surmeh0149b9e102018-05-17 14:11:25 +0100167
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +0100168 android::sp<IAllocator> allocator = IAllocator::getService("ashmem");
169 allocator->allocate(sizeof(T) * size, [&](bool success, const hidl_memory& mem) {
170 BOOST_TEST(success);
171 pool = mem;
172 });
173
174 request.pools.resize(request.pools.size() + 1);
175 request.pools[request.pools.size() - 1] = pool;
176
177 android::sp<IMemory> mapped = mapMemory(pool);
178 mapped->update();
179 return mapped;
180}
181
182template<typename T>
Kevin Mayec1e5b82020-02-26 17:00:39 +0000183void AddPoolAndSetData(uint32_t size, V1_0::Request& request, const T* data)
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +0100184{
185 android::sp<IMemory> memory = AddPoolAndGetData<T>(size, request);
186
187 T* dst = static_cast<T*>(static_cast<void*>(memory->getPointer()));
188
189 memcpy(dst, data, size * sizeof(T));
190}
surmeh0149b9e102018-05-17 14:11:25 +0100191
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100192template<typename HalPolicy,
193 typename HalModel = typename HalPolicy::Model,
194 typename HalOperand = typename HalPolicy::Operand>
195void AddOperand(HalModel& model, const HalOperand& op)
Nikhil Raj77605822018-09-03 11:25:56 +0100196{
197 model.operands.resize(model.operands.size() + 1);
198 model.operands[model.operands.size() - 1] = op;
199}
surmeh0149b9e102018-05-17 14:11:25 +0100200
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100201template<typename HalPolicy, typename HalModel = typename HalPolicy::Model>
David Monahanc60d0fd2020-05-19 14:58:34 +0100202void AddBoolOperand(HalModel& model, bool value, uint32_t numberOfConsumers = 1)
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100203{
204 using HalOperand = typename HalPolicy::Operand;
205 using HalOperandType = typename HalPolicy::OperandType;
206 using HalOperandLifeTime = typename HalPolicy::OperandLifeTime;
207
Sadik Armagan188675f2021-02-12 17:16:42 +0000208 V1_0::DataLocation location = {};
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100209 location.offset = model.operandValues.size();
210 location.length = sizeof(uint8_t);
211
David Monahanc60d0fd2020-05-19 14:58:34 +0100212 HalOperand op = {};
213 op.type = HalOperandType::BOOL;
214 op.dimensions = hidl_vec<uint32_t>{};
215 op.lifetime = HalOperandLifeTime::CONSTANT_COPY;
216 op.location = location;
217 op.numberOfConsumers = numberOfConsumers;
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100218
219 model.operandValues.resize(model.operandValues.size() + location.length);
220 *reinterpret_cast<uint8_t*>(&model.operandValues[location.offset]) = static_cast<uint8_t>(value);
221
Nikhil Raj77605822018-09-03 11:25:56 +0100222 AddOperand<HalModel>(model, op);
223}
surmeh0149b9e102018-05-17 14:11:25 +0100224
225template<typename T>
226OperandType TypeToOperandType();
227
228template<>
229OperandType TypeToOperandType<float>();
230
231template<>
232OperandType TypeToOperandType<int32_t>();
233
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100234template<typename HalPolicy,
Sadik Armagan6a903a72020-05-26 10:41:54 +0100235 typename HalModel = typename HalPolicy::Model,
236 typename HalOperandType = typename HalPolicy::OperandType>
237void AddInputOperand(HalModel& model,
238 const hidl_vec<uint32_t>& dimensions,
239 HalOperandType operandType = HalOperandType::TENSOR_FLOAT32,
240 double scale = 0.f,
241 int offset = 0,
242 uint32_t numberOfConsumers = 1)
243{
244 using HalOperand = typename HalPolicy::Operand;
245 using HalOperandLifeTime = typename HalPolicy::OperandLifeTime;
246
247 HalOperand op = {};
248 op.type = operandType;
249 op.scale = scale;
250 op.zeroPoint = offset;
251 op.dimensions = dimensions;
252 op.lifetime = HalOperandLifeTime::MODEL_INPUT;
253 op.numberOfConsumers = numberOfConsumers;
254
255 AddOperand<HalPolicy>(model, op);
256
257 model.inputIndexes.resize(model.inputIndexes.size() + 1);
258 model.inputIndexes[model.inputIndexes.size() - 1] = model.operands.size() - 1;
259}
260
261template<typename HalPolicy,
262 typename HalModel = typename HalPolicy::Model,
263 typename HalOperandType = typename HalPolicy::OperandType>
264void AddOutputOperand(HalModel& model,
265 const hidl_vec<uint32_t>& dimensions,
266 HalOperandType operandType = HalOperandType::TENSOR_FLOAT32,
267 double scale = 0.f,
268 int offset = 0,
269 uint32_t numberOfConsumers = 0)
270{
271 using HalOperand = typename HalPolicy::Operand;
272 using HalOperandLifeTime = typename HalPolicy::OperandLifeTime;
273
274 HalOperand op = {};
275 op.type = operandType;
276 op.scale = scale;
277 op.zeroPoint = offset;
278 op.dimensions = dimensions;
279 op.lifetime = HalOperandLifeTime::MODEL_OUTPUT;
280 op.numberOfConsumers = numberOfConsumers;
281
282 AddOperand<HalPolicy>(model, op);
283
284 model.outputIndexes.resize(model.outputIndexes.size() + 1);
285 model.outputIndexes[model.outputIndexes.size() - 1] = model.operands.size() - 1;
286}
287
288android::sp<V1_0::IPreparedModel> PrepareModelWithStatus(const V1_0::Model& model,
289 armnn_driver::ArmnnDriver& driver,
290 V1_0::ErrorStatus& prepareStatus,
291 V1_0::ErrorStatus expectedStatus = V1_0::ErrorStatus::NONE);
292
293#if defined(ARMNN_ANDROID_NN_V1_1) || defined(ARMNN_ANDROID_NN_V1_2) || defined(ARMNN_ANDROID_NN_V1_3)
294
295android::sp<V1_0::IPreparedModel> PrepareModelWithStatus(const V1_1::Model& model,
296 armnn_driver::ArmnnDriver& driver,
297 V1_0::ErrorStatus& prepareStatus,
298 V1_0::ErrorStatus expectedStatus = V1_0::ErrorStatus::NONE);
299
300#endif
301
302template<typename HalModel>
303android::sp<V1_0::IPreparedModel> PrepareModel(const HalModel& model,
304 armnn_driver::ArmnnDriver& driver)
305{
306 V1_0::ErrorStatus prepareStatus = V1_0::ErrorStatus::NONE;
307 return PrepareModelWithStatus(model, driver, prepareStatus);
308}
309
310#if defined(ARMNN_ANDROID_NN_V1_2) || defined(ARMNN_ANDROID_NN_V1_3)
311
312android::sp<V1_2::IPreparedModel> PrepareModelWithStatus_1_2(const armnn_driver::hal_1_2::HalPolicy::Model& model,
313 armnn_driver::ArmnnDriver& driver,
314 V1_0::ErrorStatus& prepareStatus,
315 V1_0::ErrorStatus expectedStatus = V1_0::ErrorStatus::NONE);
316
317template<typename HalModel>
318android::sp<V1_2::IPreparedModel> PrepareModel_1_2(const HalModel& model,
319 armnn_driver::ArmnnDriver& driver)
320{
321 V1_0::ErrorStatus prepareStatus = V1_0::ErrorStatus::NONE;
322 return PrepareModelWithStatus_1_2(model, driver, prepareStatus);
323}
324
325#endif
326
327#ifdef ARMNN_ANDROID_NN_V1_3
328
329template<typename HalPolicy>
330void AddOperand(armnn_driver::hal_1_3::HalPolicy::Model& model,
331 const armnn_driver::hal_1_3::HalPolicy::Operand& op)
332{
333 model.main.operands.resize(model.main.operands.size() + 1);
334 model.main.operands[model.main.operands.size() - 1] = op;
335}
336
337template<typename HalPolicy>
338void AddInputOperand(armnn_driver::hal_1_3::HalPolicy::Model& model,
339 const hidl_vec<uint32_t>& dimensions,
340 armnn_driver::hal_1_3::HalPolicy::OperandType operandType =
341 armnn_driver::hal_1_3::HalPolicy::OperandType::TENSOR_FLOAT32,
342 double scale = 0.f,
343 int offset = 0,
344 uint32_t numberOfConsumers = 1)
345{
346 using HalOperand = typename armnn_driver::hal_1_3::HalPolicy::Operand;
347 using HalOperandLifeTime = typename armnn_driver::hal_1_3::HalPolicy::OperandLifeTime;
348
349 HalOperand op = {};
350 op.type = operandType;
351 op.scale = scale;
352 op.zeroPoint = offset;
353 op.dimensions = dimensions;
354 op.lifetime = HalOperandLifeTime::SUBGRAPH_INPUT;
355 op.numberOfConsumers = numberOfConsumers;
356
357 AddOperand<HalPolicy>(model, op);
358
359 model.main.inputIndexes.resize(model.main.inputIndexes.size() + 1);
360 model.main.inputIndexes[model.main.inputIndexes.size() - 1] = model.main.operands.size() - 1;
361}
362
363template<typename HalPolicy>
364void AddOutputOperand(armnn_driver::hal_1_3::HalPolicy::Model& model,
365 const hidl_vec<uint32_t>& dimensions,
366 armnn_driver::hal_1_3::HalPolicy::OperandType operandType =
367 armnn_driver::hal_1_3::HalPolicy::OperandType::TENSOR_FLOAT32,
368 double scale = 0.f,
369 int offset = 0,
370 uint32_t numberOfConsumers = 0)
371{
372 using HalOperand = typename armnn_driver::hal_1_3::HalPolicy::Operand;
373 using HalOperandLifeTime = typename armnn_driver::hal_1_3::HalPolicy::OperandLifeTime;
374
375 HalOperand op = {};
376 op.type = operandType;
377 op.scale = scale;
378 op.zeroPoint = offset;
379 op.dimensions = dimensions;
380 op.lifetime = HalOperandLifeTime::SUBGRAPH_OUTPUT;
381 op.numberOfConsumers = numberOfConsumers;
382
383 AddOperand<HalPolicy>(model, op);
384
385 model.main.outputIndexes.resize(model.main.outputIndexes.size() + 1);
386 model.main.outputIndexes[model.main.outputIndexes.size() - 1] = model.main.operands.size() - 1;
387}
388
389android::sp<V1_3::IPreparedModel> PrepareModelWithStatus_1_3(const armnn_driver::hal_1_3::HalPolicy::Model& model,
390 armnn_driver::ArmnnDriver& driver,
David Monahan82609562020-08-31 15:50:32 +0100391 V1_3::ErrorStatus& prepareStatus,
392 V1_3::Priority priority = V1_3::Priority::LOW);
Sadik Armagan6a903a72020-05-26 10:41:54 +0100393
394template<typename HalModel>
395android::sp<V1_3::IPreparedModel> PrepareModel_1_3(const HalModel& model,
396 armnn_driver::ArmnnDriver& driver)
397{
398 V1_3::ErrorStatus prepareStatus = V1_3::ErrorStatus::NONE;
399 return PrepareModelWithStatus_1_3(model, driver, prepareStatus);
400}
401
402#endif
403
404template<typename HalPolicy,
405 typename T,
406 typename HalModel = typename HalPolicy::Model,
407 typename HalOperandType = typename HalPolicy::OperandType,
408 typename HalOperandLifeTime = typename HalPolicy::OperandLifeTime>
Nikhil Raj77605822018-09-03 11:25:56 +0100409void AddTensorOperand(HalModel& model,
Matteo Martincighc7434122018-11-14 12:27:04 +0000410 const hidl_vec<uint32_t>& dimensions,
411 const T* values,
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100412 HalOperandType operandType = HalOperandType::TENSOR_FLOAT32,
Kevin Mayec1e5b82020-02-26 17:00:39 +0000413 HalOperandLifeTime operandLifeTime = V1_0::OperandLifeTime::CONSTANT_COPY,
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +0100414 double scale = 0.f,
David Monahanc60d0fd2020-05-19 14:58:34 +0100415 int offset = 0,
416 uint32_t numberOfConsumers = 1)
surmeh0149b9e102018-05-17 14:11:25 +0100417{
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100418 using HalOperand = typename HalPolicy::Operand;
419
surmeh0149b9e102018-05-17 14:11:25 +0100420 uint32_t totalElements = 1;
421 for (uint32_t dim : dimensions)
422 {
423 totalElements *= dim;
424 }
425
Sadik Armagan188675f2021-02-12 17:16:42 +0000426 V1_0::DataLocation location = {};
surmeh0149b9e102018-05-17 14:11:25 +0100427 location.length = totalElements * sizeof(T);
428
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100429 if(operandLifeTime == HalOperandLifeTime::CONSTANT_COPY)
Kevin Mayf29a2c52019-03-14 11:56:32 +0000430 {
431 location.offset = model.operandValues.size();
432 }
433
David Monahanc60d0fd2020-05-19 14:58:34 +0100434 HalOperand op = {};
435 op.type = operandType;
436 op.dimensions = dimensions;
437 op.scale = scale;
438 op.zeroPoint = offset;
439 op.lifetime = HalOperandLifeTime::CONSTANT_COPY;
440 op.location = location;
441 op.numberOfConsumers = numberOfConsumers;
surmeh0149b9e102018-05-17 14:11:25 +0100442
443 model.operandValues.resize(model.operandValues.size() + location.length);
444 for (uint32_t i = 0; i < totalElements; i++)
445 {
446 *(reinterpret_cast<T*>(&model.operandValues[location.offset]) + i) = values[i];
447 }
448
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100449 AddOperand<HalPolicy>(model, op);
surmeh0149b9e102018-05-17 14:11:25 +0100450}
451
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100452template<typename HalPolicy,
Sadik Armagan6a903a72020-05-26 10:41:54 +0100453 typename T,
454 typename HalModel = typename HalPolicy::Model,
455 typename HalOperandType = typename HalPolicy::OperandType,
456 typename HalOperandLifeTime = typename HalPolicy::OperandLifeTime>
Matteo Martincighc7434122018-11-14 12:27:04 +0000457void AddTensorOperand(HalModel& model,
458 const hidl_vec<uint32_t>& dimensions,
459 const std::vector<T>& values,
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100460 HalOperandType operandType = HalPolicy::OperandType::TENSOR_FLOAT32,
Kevin Mayec1e5b82020-02-26 17:00:39 +0000461 HalOperandLifeTime operandLifeTime = V1_0::OperandLifeTime::CONSTANT_COPY,
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +0100462 double scale = 0.f,
David Monahanc60d0fd2020-05-19 14:58:34 +0100463 int offset = 0,
464 uint32_t numberOfConsumers = 1)
Matteo Martincighc7434122018-11-14 12:27:04 +0000465{
David Monahanc60d0fd2020-05-19 14:58:34 +0100466 AddTensorOperand<HalPolicy, T>(model,
467 dimensions,
468 values.data(),
469 operandType,
470 operandLifeTime,
471 scale,
472 offset,
473 numberOfConsumers);
Matteo Martincighc7434122018-11-14 12:27:04 +0000474}
475
Sadik Armagan6a903a72020-05-26 10:41:54 +0100476template<typename HalPolicy, typename HalModel = typename HalPolicy::Model>
477void AddIntOperand(HalModel& model, int32_t value, uint32_t numberOfConsumers = 1)
478{
479 using HalOperand = typename HalPolicy::Operand;
480 using HalOperandType = typename HalPolicy::OperandType;
481 using HalOperandLifeTime = typename HalPolicy::OperandLifeTime;
482
Sadik Armagan188675f2021-02-12 17:16:42 +0000483 V1_0::DataLocation location = {};
Sadik Armagan6a903a72020-05-26 10:41:54 +0100484 location.offset = model.operandValues.size();
485 location.length = sizeof(int32_t);
486
487 HalOperand op = {};
488 op.type = HalOperandType::INT32;
489 op.dimensions = hidl_vec<uint32_t>{};
490 op.lifetime = HalOperandLifeTime::CONSTANT_COPY;
491 op.location = location;
492 op.numberOfConsumers = numberOfConsumers;
493
494 model.operandValues.resize(model.operandValues.size() + location.length);
495 *reinterpret_cast<int32_t*>(&model.operandValues[location.offset]) = value;
496
497 AddOperand<HalPolicy>(model, op);
498}
499
500template<typename HalPolicy, typename HalModel = typename HalPolicy::Model>
501void AddFloatOperand(HalModel& model,
502 float value,
David Monahanc60d0fd2020-05-19 14:58:34 +0100503 uint32_t numberOfConsumers = 1)
Nikhil Raj77605822018-09-03 11:25:56 +0100504{
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100505 using HalOperand = typename HalPolicy::Operand;
Sadik Armagan6a903a72020-05-26 10:41:54 +0100506 using HalOperandType = typename HalPolicy::OperandType;
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100507 using HalOperandLifeTime = typename HalPolicy::OperandLifeTime;
surmeh0149b9e102018-05-17 14:11:25 +0100508
Sadik Armagan188675f2021-02-12 17:16:42 +0000509 V1_0::DataLocation location = {};
Sadik Armagan6a903a72020-05-26 10:41:54 +0100510 location.offset = model.operandValues.size();
511 location.length = sizeof(float);
surmeh0149b9e102018-05-17 14:11:25 +0100512
David Monahanc60d0fd2020-05-19 14:58:34 +0100513 HalOperand op = {};
Sadik Armagan6a903a72020-05-26 10:41:54 +0100514 op.type = HalOperandType::FLOAT32;
515 op.dimensions = hidl_vec<uint32_t>{};
516 op.lifetime = HalOperandLifeTime::CONSTANT_COPY;
517 op.location = location;
David Monahanc60d0fd2020-05-19 14:58:34 +0100518 op.numberOfConsumers = numberOfConsumers;
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100519
Sadik Armagan6a903a72020-05-26 10:41:54 +0100520 model.operandValues.resize(model.operandValues.size() + location.length);
521 *reinterpret_cast<float*>(&model.operandValues[location.offset]) = value;
522
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100523 AddOperand<HalPolicy>(model, op);
Nikhil Raj77605822018-09-03 11:25:56 +0100524}
surmeh0149b9e102018-05-17 14:11:25 +0100525
Kevin Mayec1e5b82020-02-26 17:00:39 +0000526V1_0::ErrorStatus Execute(android::sp<V1_0::IPreparedModel> preparedModel,
527 const V1_0::Request& request,
528 V1_0::ErrorStatus expectedStatus = V1_0::ErrorStatus::NONE);
surmeh0149b9e102018-05-17 14:11:25 +0100529
Sadik Armagane6e54a82019-05-08 10:18:05 +0100530android::sp<ExecutionCallback> ExecuteNoWait(android::sp<V1_0::IPreparedModel> preparedModel,
Kevin Mayec1e5b82020-02-26 17:00:39 +0000531 const V1_0::Request& request);
surmeh0149b9e102018-05-17 14:11:25 +0100532
533} // namespace driverTestHelpers