blob: 05b78925928b3434d63317656b6ca103aa360751 [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
17using ::android::hidl::allocator::V1_0::IAllocator;
18
surmeh0149b9e102018-05-17 14:11:25 +010019namespace android
20{
21namespace hardware
22{
23namespace neuralnetworks
24{
25namespace V1_0
26{
27
Kevin Mayec1e5b82020-02-26 17:00:39 +000028std::ostream& operator<<(std::ostream& os, V1_0::ErrorStatus stat);
surmeh0149b9e102018-05-17 14:11:25 +010029
30} // namespace android::hardware::neuralnetworks::V1_0
Sadik Armagan6a903a72020-05-26 10:41:54 +010031
32#ifdef ARMNN_ANDROID_NN_V1_3
33namespace V1_3
34{
35
36std::ostream& operator<<(std::ostream& os, V1_3::ErrorStatus stat);
37
38} // namespace android::hardware::neuralnetworks::V1_3
39#endif
40
surmeh0149b9e102018-05-17 14:11:25 +010041} // namespace android::hardware::neuralnetworks
42} // namespace android::hardware
43} // namespace android
44
45namespace driverTestHelpers
46{
47
Matteo Martincigh8b287c22018-09-07 09:25:10 +010048std::ostream& operator<<(std::ostream& os, V1_0::ErrorStatus stat);
surmeh0149b9e102018-05-17 14:11:25 +010049
Sadik Armagan6a903a72020-05-26 10:41:54 +010050#ifdef ARMNN_ANDROID_NN_V1_3
51std::ostream& operator<<(std::ostream& os, V1_3::ErrorStatus stat);
52#endif
53
Sadik Armagane6e54a82019-05-08 10:18:05 +010054struct ExecutionCallback : public V1_0::IExecutionCallback
surmeh0149b9e102018-05-17 14:11:25 +010055{
56 ExecutionCallback() : mNotified(false) {}
Kevin Mayec1e5b82020-02-26 17:00:39 +000057 Return<void> notify(V1_0::ErrorStatus status) override;
surmeh0149b9e102018-05-17 14:11:25 +010058 /// wait until the callback has notified us that it is done
59 Return<void> wait();
60
61private:
62 // use a mutex and a condition variable to wait for asynchronous callbacks
63 std::mutex mMutex;
64 std::condition_variable mCondition;
65 // and a flag, in case we are notified before the wait call
66 bool mNotified;
67};
68
Sadik Armagane6e54a82019-05-08 10:18:05 +010069class PreparedModelCallback : public V1_0::IPreparedModelCallback
surmeh0149b9e102018-05-17 14:11:25 +010070{
71public:
72 PreparedModelCallback()
Kevin Mayec1e5b82020-02-26 17:00:39 +000073 : m_ErrorStatus(V1_0::ErrorStatus::NONE)
surmeh0149b9e102018-05-17 14:11:25 +010074 , m_PreparedModel()
75 { }
76 ~PreparedModelCallback() override { }
77
Kevin Mayec1e5b82020-02-26 17:00:39 +000078 Return<void> notify(V1_0::ErrorStatus status,
Sadik Armagane6e54a82019-05-08 10:18:05 +010079 const android::sp<V1_0::IPreparedModel>& preparedModel) override;
Kevin Mayec1e5b82020-02-26 17:00:39 +000080 V1_0::ErrorStatus GetErrorStatus() { return m_ErrorStatus; }
Sadik Armagane6e54a82019-05-08 10:18:05 +010081 android::sp<V1_0::IPreparedModel> GetPreparedModel() { return m_PreparedModel; }
surmeh0149b9e102018-05-17 14:11:25 +010082
83private:
Kevin Mayec1e5b82020-02-26 17:00:39 +000084 V1_0::ErrorStatus m_ErrorStatus;
Sadik Armagane6e54a82019-05-08 10:18:05 +010085 android::sp<V1_0::IPreparedModel> m_PreparedModel;
surmeh0149b9e102018-05-17 14:11:25 +010086};
87
Sadik Armagan6a903a72020-05-26 10:41:54 +010088#if defined(ARMNN_ANDROID_NN_V1_2) || defined(ARMNN_ANDROID_NN_V1_3)
Ferran Balaguerb2397fd2019-07-25 12:12:39 +010089
90class PreparedModelCallback_1_2 : public V1_2::IPreparedModelCallback
91{
92public:
93 PreparedModelCallback_1_2()
Kevin Mayec1e5b82020-02-26 17:00:39 +000094 : m_ErrorStatus(V1_0::ErrorStatus::NONE)
Ferran Balaguerb2397fd2019-07-25 12:12:39 +010095 , m_PreparedModel()
96 , m_PreparedModel_1_2()
97 { }
98 ~PreparedModelCallback_1_2() override { }
99
Kevin Mayec1e5b82020-02-26 17:00:39 +0000100 Return<void> notify(V1_0::ErrorStatus status, const android::sp<V1_0::IPreparedModel>& preparedModel) override;
Ferran Balaguerb2397fd2019-07-25 12:12:39 +0100101
Kevin Mayec1e5b82020-02-26 17:00:39 +0000102 Return<void> notify_1_2(V1_0::ErrorStatus status, const android::sp<V1_2::IPreparedModel>& preparedModel) override;
Ferran Balaguerb2397fd2019-07-25 12:12:39 +0100103
Kevin Mayec1e5b82020-02-26 17:00:39 +0000104 V1_0::ErrorStatus GetErrorStatus() { return m_ErrorStatus; }
Ferran Balaguerb2397fd2019-07-25 12:12:39 +0100105
106 android::sp<V1_0::IPreparedModel> GetPreparedModel() { return m_PreparedModel; }
107
108 android::sp<V1_2::IPreparedModel> GetPreparedModel_1_2() { return m_PreparedModel_1_2; }
109
110private:
Kevin Mayec1e5b82020-02-26 17:00:39 +0000111 V1_0::ErrorStatus m_ErrorStatus;
Ferran Balaguerb2397fd2019-07-25 12:12:39 +0100112 android::sp<V1_0::IPreparedModel> m_PreparedModel;
113 android::sp<V1_2::IPreparedModel> m_PreparedModel_1_2;
114};
115
116#endif
117
Sadik Armagan6a903a72020-05-26 10:41:54 +0100118#ifdef ARMNN_ANDROID_NN_V1_3
119
120class PreparedModelCallback_1_3 : public V1_3::IPreparedModelCallback
121{
122public:
123 PreparedModelCallback_1_3()
124 : m_1_0_ErrorStatus(V1_0::ErrorStatus::NONE)
125 , m_1_3_ErrorStatus(V1_3::ErrorStatus::NONE)
126 , m_PreparedModel()
127 , m_PreparedModel_1_2()
128 , m_PreparedModel_1_3()
129 { }
130 ~PreparedModelCallback_1_3() override { }
131
132 Return<void> notify(V1_0::ErrorStatus status, const android::sp<V1_0::IPreparedModel>& preparedModel) override;
133
134 Return<void> notify_1_2(V1_0::ErrorStatus status, const android::sp<V1_2::IPreparedModel>& preparedModel) override;
135
136 Return<void> notify_1_3(V1_3::ErrorStatus status, const android::sp<V1_3::IPreparedModel>& preparedModel) override;
137
138 V1_0::ErrorStatus GetErrorStatus() { return m_1_0_ErrorStatus; }
139
140 V1_3::ErrorStatus Get_1_3_ErrorStatus() { return m_1_3_ErrorStatus; }
141
142 android::sp<V1_0::IPreparedModel> GetPreparedModel() { return m_PreparedModel; }
143
144 android::sp<V1_2::IPreparedModel> GetPreparedModel_1_2() { return m_PreparedModel_1_2; }
145
146 android::sp<V1_3::IPreparedModel> GetPreparedModel_1_3() { return m_PreparedModel_1_3; }
147
148private:
149 V1_0::ErrorStatus m_1_0_ErrorStatus;
150 V1_3::ErrorStatus m_1_3_ErrorStatus;
151 android::sp<V1_0::IPreparedModel> m_PreparedModel;
152 android::sp<V1_2::IPreparedModel> m_PreparedModel_1_2;
153 android::sp<V1_3::IPreparedModel> m_PreparedModel_1_3;
154};
155
156#endif
157
surmeh0149b9e102018-05-17 14:11:25 +0100158hidl_memory allocateSharedMemory(int64_t size);
159
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +0100160template<typename T>
Kevin Mayec1e5b82020-02-26 17:00:39 +0000161android::sp<IMemory> AddPoolAndGetData(uint32_t size, V1_0::Request& request)
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +0100162{
163 hidl_memory pool;
surmeh0149b9e102018-05-17 14:11:25 +0100164
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +0100165 android::sp<IAllocator> allocator = IAllocator::getService("ashmem");
166 allocator->allocate(sizeof(T) * size, [&](bool success, const hidl_memory& mem) {
167 BOOST_TEST(success);
168 pool = mem;
169 });
170
171 request.pools.resize(request.pools.size() + 1);
172 request.pools[request.pools.size() - 1] = pool;
173
174 android::sp<IMemory> mapped = mapMemory(pool);
175 mapped->update();
176 return mapped;
177}
178
179template<typename T>
Kevin Mayec1e5b82020-02-26 17:00:39 +0000180void AddPoolAndSetData(uint32_t size, V1_0::Request& request, const T* data)
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +0100181{
182 android::sp<IMemory> memory = AddPoolAndGetData<T>(size, request);
183
184 T* dst = static_cast<T*>(static_cast<void*>(memory->getPointer()));
185
186 memcpy(dst, data, size * sizeof(T));
187}
surmeh0149b9e102018-05-17 14:11:25 +0100188
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100189template<typename HalPolicy,
190 typename HalModel = typename HalPolicy::Model,
191 typename HalOperand = typename HalPolicy::Operand>
192void AddOperand(HalModel& model, const HalOperand& op)
Nikhil Raj77605822018-09-03 11:25:56 +0100193{
194 model.operands.resize(model.operands.size() + 1);
195 model.operands[model.operands.size() - 1] = op;
196}
surmeh0149b9e102018-05-17 14:11:25 +0100197
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100198template<typename HalPolicy, typename HalModel = typename HalPolicy::Model>
David Monahanc60d0fd2020-05-19 14:58:34 +0100199void AddBoolOperand(HalModel& model, bool value, uint32_t numberOfConsumers = 1)
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100200{
201 using HalOperand = typename HalPolicy::Operand;
202 using HalOperandType = typename HalPolicy::OperandType;
203 using HalOperandLifeTime = typename HalPolicy::OperandLifeTime;
204
205 DataLocation location = {};
206 location.offset = model.operandValues.size();
207 location.length = sizeof(uint8_t);
208
David Monahanc60d0fd2020-05-19 14:58:34 +0100209 HalOperand op = {};
210 op.type = HalOperandType::BOOL;
211 op.dimensions = hidl_vec<uint32_t>{};
212 op.lifetime = HalOperandLifeTime::CONSTANT_COPY;
213 op.location = location;
214 op.numberOfConsumers = numberOfConsumers;
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100215
216 model.operandValues.resize(model.operandValues.size() + location.length);
217 *reinterpret_cast<uint8_t*>(&model.operandValues[location.offset]) = static_cast<uint8_t>(value);
218
Nikhil Raj77605822018-09-03 11:25:56 +0100219 AddOperand<HalModel>(model, op);
220}
surmeh0149b9e102018-05-17 14:11:25 +0100221
222template<typename T>
223OperandType TypeToOperandType();
224
225template<>
226OperandType TypeToOperandType<float>();
227
228template<>
229OperandType TypeToOperandType<int32_t>();
230
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100231template<typename HalPolicy,
Sadik Armagan6a903a72020-05-26 10:41:54 +0100232 typename HalModel = typename HalPolicy::Model,
233 typename HalOperandType = typename HalPolicy::OperandType>
234void AddInputOperand(HalModel& model,
235 const hidl_vec<uint32_t>& dimensions,
236 HalOperandType operandType = HalOperandType::TENSOR_FLOAT32,
237 double scale = 0.f,
238 int offset = 0,
239 uint32_t numberOfConsumers = 1)
240{
241 using HalOperand = typename HalPolicy::Operand;
242 using HalOperandLifeTime = typename HalPolicy::OperandLifeTime;
243
244 HalOperand op = {};
245 op.type = operandType;
246 op.scale = scale;
247 op.zeroPoint = offset;
248 op.dimensions = dimensions;
249 op.lifetime = HalOperandLifeTime::MODEL_INPUT;
250 op.numberOfConsumers = numberOfConsumers;
251
252 AddOperand<HalPolicy>(model, op);
253
254 model.inputIndexes.resize(model.inputIndexes.size() + 1);
255 model.inputIndexes[model.inputIndexes.size() - 1] = model.operands.size() - 1;
256}
257
258template<typename HalPolicy,
259 typename HalModel = typename HalPolicy::Model,
260 typename HalOperandType = typename HalPolicy::OperandType>
261void AddOutputOperand(HalModel& model,
262 const hidl_vec<uint32_t>& dimensions,
263 HalOperandType operandType = HalOperandType::TENSOR_FLOAT32,
264 double scale = 0.f,
265 int offset = 0,
266 uint32_t numberOfConsumers = 0)
267{
268 using HalOperand = typename HalPolicy::Operand;
269 using HalOperandLifeTime = typename HalPolicy::OperandLifeTime;
270
271 HalOperand op = {};
272 op.type = operandType;
273 op.scale = scale;
274 op.zeroPoint = offset;
275 op.dimensions = dimensions;
276 op.lifetime = HalOperandLifeTime::MODEL_OUTPUT;
277 op.numberOfConsumers = numberOfConsumers;
278
279 AddOperand<HalPolicy>(model, op);
280
281 model.outputIndexes.resize(model.outputIndexes.size() + 1);
282 model.outputIndexes[model.outputIndexes.size() - 1] = model.operands.size() - 1;
283}
284
285android::sp<V1_0::IPreparedModel> PrepareModelWithStatus(const V1_0::Model& model,
286 armnn_driver::ArmnnDriver& driver,
287 V1_0::ErrorStatus& prepareStatus,
288 V1_0::ErrorStatus expectedStatus = V1_0::ErrorStatus::NONE);
289
290#if defined(ARMNN_ANDROID_NN_V1_1) || defined(ARMNN_ANDROID_NN_V1_2) || defined(ARMNN_ANDROID_NN_V1_3)
291
292android::sp<V1_0::IPreparedModel> PrepareModelWithStatus(const V1_1::Model& model,
293 armnn_driver::ArmnnDriver& driver,
294 V1_0::ErrorStatus& prepareStatus,
295 V1_0::ErrorStatus expectedStatus = V1_0::ErrorStatus::NONE);
296
297#endif
298
299template<typename HalModel>
300android::sp<V1_0::IPreparedModel> PrepareModel(const HalModel& model,
301 armnn_driver::ArmnnDriver& driver)
302{
303 V1_0::ErrorStatus prepareStatus = V1_0::ErrorStatus::NONE;
304 return PrepareModelWithStatus(model, driver, prepareStatus);
305}
306
307#if defined(ARMNN_ANDROID_NN_V1_2) || defined(ARMNN_ANDROID_NN_V1_3)
308
309android::sp<V1_2::IPreparedModel> PrepareModelWithStatus_1_2(const armnn_driver::hal_1_2::HalPolicy::Model& model,
310 armnn_driver::ArmnnDriver& driver,
311 V1_0::ErrorStatus& prepareStatus,
312 V1_0::ErrorStatus expectedStatus = V1_0::ErrorStatus::NONE);
313
314template<typename HalModel>
315android::sp<V1_2::IPreparedModel> PrepareModel_1_2(const HalModel& model,
316 armnn_driver::ArmnnDriver& driver)
317{
318 V1_0::ErrorStatus prepareStatus = V1_0::ErrorStatus::NONE;
319 return PrepareModelWithStatus_1_2(model, driver, prepareStatus);
320}
321
322#endif
323
324#ifdef ARMNN_ANDROID_NN_V1_3
325
326template<typename HalPolicy>
327void AddOperand(armnn_driver::hal_1_3::HalPolicy::Model& model,
328 const armnn_driver::hal_1_3::HalPolicy::Operand& op)
329{
330 model.main.operands.resize(model.main.operands.size() + 1);
331 model.main.operands[model.main.operands.size() - 1] = op;
332}
333
334template<typename HalPolicy>
335void AddInputOperand(armnn_driver::hal_1_3::HalPolicy::Model& model,
336 const hidl_vec<uint32_t>& dimensions,
337 armnn_driver::hal_1_3::HalPolicy::OperandType operandType =
338 armnn_driver::hal_1_3::HalPolicy::OperandType::TENSOR_FLOAT32,
339 double scale = 0.f,
340 int offset = 0,
341 uint32_t numberOfConsumers = 1)
342{
343 using HalOperand = typename armnn_driver::hal_1_3::HalPolicy::Operand;
344 using HalOperandLifeTime = typename armnn_driver::hal_1_3::HalPolicy::OperandLifeTime;
345
346 HalOperand op = {};
347 op.type = operandType;
348 op.scale = scale;
349 op.zeroPoint = offset;
350 op.dimensions = dimensions;
351 op.lifetime = HalOperandLifeTime::SUBGRAPH_INPUT;
352 op.numberOfConsumers = numberOfConsumers;
353
354 AddOperand<HalPolicy>(model, op);
355
356 model.main.inputIndexes.resize(model.main.inputIndexes.size() + 1);
357 model.main.inputIndexes[model.main.inputIndexes.size() - 1] = model.main.operands.size() - 1;
358}
359
360template<typename HalPolicy>
361void AddOutputOperand(armnn_driver::hal_1_3::HalPolicy::Model& model,
362 const hidl_vec<uint32_t>& dimensions,
363 armnn_driver::hal_1_3::HalPolicy::OperandType operandType =
364 armnn_driver::hal_1_3::HalPolicy::OperandType::TENSOR_FLOAT32,
365 double scale = 0.f,
366 int offset = 0,
367 uint32_t numberOfConsumers = 0)
368{
369 using HalOperand = typename armnn_driver::hal_1_3::HalPolicy::Operand;
370 using HalOperandLifeTime = typename armnn_driver::hal_1_3::HalPolicy::OperandLifeTime;
371
372 HalOperand op = {};
373 op.type = operandType;
374 op.scale = scale;
375 op.zeroPoint = offset;
376 op.dimensions = dimensions;
377 op.lifetime = HalOperandLifeTime::SUBGRAPH_OUTPUT;
378 op.numberOfConsumers = numberOfConsumers;
379
380 AddOperand<HalPolicy>(model, op);
381
382 model.main.outputIndexes.resize(model.main.outputIndexes.size() + 1);
383 model.main.outputIndexes[model.main.outputIndexes.size() - 1] = model.main.operands.size() - 1;
384}
385
386android::sp<V1_3::IPreparedModel> PrepareModelWithStatus_1_3(const armnn_driver::hal_1_3::HalPolicy::Model& model,
387 armnn_driver::ArmnnDriver& driver,
David Monahan82609562020-08-31 15:50:32 +0100388 V1_3::ErrorStatus& prepareStatus,
389 V1_3::Priority priority = V1_3::Priority::LOW);
Sadik Armagan6a903a72020-05-26 10:41:54 +0100390
391template<typename HalModel>
392android::sp<V1_3::IPreparedModel> PrepareModel_1_3(const HalModel& model,
393 armnn_driver::ArmnnDriver& driver)
394{
395 V1_3::ErrorStatus prepareStatus = V1_3::ErrorStatus::NONE;
396 return PrepareModelWithStatus_1_3(model, driver, prepareStatus);
397}
398
399#endif
400
401template<typename HalPolicy,
402 typename T,
403 typename HalModel = typename HalPolicy::Model,
404 typename HalOperandType = typename HalPolicy::OperandType,
405 typename HalOperandLifeTime = typename HalPolicy::OperandLifeTime>
Nikhil Raj77605822018-09-03 11:25:56 +0100406void AddTensorOperand(HalModel& model,
Matteo Martincighc7434122018-11-14 12:27:04 +0000407 const hidl_vec<uint32_t>& dimensions,
408 const T* values,
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100409 HalOperandType operandType = HalOperandType::TENSOR_FLOAT32,
Kevin Mayec1e5b82020-02-26 17:00:39 +0000410 HalOperandLifeTime operandLifeTime = V1_0::OperandLifeTime::CONSTANT_COPY,
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +0100411 double scale = 0.f,
David Monahanc60d0fd2020-05-19 14:58:34 +0100412 int offset = 0,
413 uint32_t numberOfConsumers = 1)
surmeh0149b9e102018-05-17 14:11:25 +0100414{
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100415 using HalOperand = typename HalPolicy::Operand;
416
surmeh0149b9e102018-05-17 14:11:25 +0100417 uint32_t totalElements = 1;
418 for (uint32_t dim : dimensions)
419 {
420 totalElements *= dim;
421 }
422
423 DataLocation location = {};
surmeh0149b9e102018-05-17 14:11:25 +0100424 location.length = totalElements * sizeof(T);
425
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100426 if(operandLifeTime == HalOperandLifeTime::CONSTANT_COPY)
Kevin Mayf29a2c52019-03-14 11:56:32 +0000427 {
428 location.offset = model.operandValues.size();
429 }
430
David Monahanc60d0fd2020-05-19 14:58:34 +0100431 HalOperand op = {};
432 op.type = operandType;
433 op.dimensions = dimensions;
434 op.scale = scale;
435 op.zeroPoint = offset;
436 op.lifetime = HalOperandLifeTime::CONSTANT_COPY;
437 op.location = location;
438 op.numberOfConsumers = numberOfConsumers;
surmeh0149b9e102018-05-17 14:11:25 +0100439
440 model.operandValues.resize(model.operandValues.size() + location.length);
441 for (uint32_t i = 0; i < totalElements; i++)
442 {
443 *(reinterpret_cast<T*>(&model.operandValues[location.offset]) + i) = values[i];
444 }
445
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100446 AddOperand<HalPolicy>(model, op);
surmeh0149b9e102018-05-17 14:11:25 +0100447}
448
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100449template<typename HalPolicy,
Sadik Armagan6a903a72020-05-26 10:41:54 +0100450 typename T,
451 typename HalModel = typename HalPolicy::Model,
452 typename HalOperandType = typename HalPolicy::OperandType,
453 typename HalOperandLifeTime = typename HalPolicy::OperandLifeTime>
Matteo Martincighc7434122018-11-14 12:27:04 +0000454void AddTensorOperand(HalModel& model,
455 const hidl_vec<uint32_t>& dimensions,
456 const std::vector<T>& values,
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100457 HalOperandType operandType = HalPolicy::OperandType::TENSOR_FLOAT32,
Kevin Mayec1e5b82020-02-26 17:00:39 +0000458 HalOperandLifeTime operandLifeTime = V1_0::OperandLifeTime::CONSTANT_COPY,
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +0100459 double scale = 0.f,
David Monahanc60d0fd2020-05-19 14:58:34 +0100460 int offset = 0,
461 uint32_t numberOfConsumers = 1)
Matteo Martincighc7434122018-11-14 12:27:04 +0000462{
David Monahanc60d0fd2020-05-19 14:58:34 +0100463 AddTensorOperand<HalPolicy, T>(model,
464 dimensions,
465 values.data(),
466 operandType,
467 operandLifeTime,
468 scale,
469 offset,
470 numberOfConsumers);
Matteo Martincighc7434122018-11-14 12:27:04 +0000471}
472
Sadik Armagan6a903a72020-05-26 10:41:54 +0100473template<typename HalPolicy, typename HalModel = typename HalPolicy::Model>
474void AddIntOperand(HalModel& model, int32_t value, uint32_t numberOfConsumers = 1)
475{
476 using HalOperand = typename HalPolicy::Operand;
477 using HalOperandType = typename HalPolicy::OperandType;
478 using HalOperandLifeTime = typename HalPolicy::OperandLifeTime;
479
480 DataLocation location = {};
481 location.offset = model.operandValues.size();
482 location.length = sizeof(int32_t);
483
484 HalOperand op = {};
485 op.type = HalOperandType::INT32;
486 op.dimensions = hidl_vec<uint32_t>{};
487 op.lifetime = HalOperandLifeTime::CONSTANT_COPY;
488 op.location = location;
489 op.numberOfConsumers = numberOfConsumers;
490
491 model.operandValues.resize(model.operandValues.size() + location.length);
492 *reinterpret_cast<int32_t*>(&model.operandValues[location.offset]) = value;
493
494 AddOperand<HalPolicy>(model, op);
495}
496
497template<typename HalPolicy, typename HalModel = typename HalPolicy::Model>
498void AddFloatOperand(HalModel& model,
499 float value,
David Monahanc60d0fd2020-05-19 14:58:34 +0100500 uint32_t numberOfConsumers = 1)
Nikhil Raj77605822018-09-03 11:25:56 +0100501{
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100502 using HalOperand = typename HalPolicy::Operand;
Sadik Armagan6a903a72020-05-26 10:41:54 +0100503 using HalOperandType = typename HalPolicy::OperandType;
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100504 using HalOperandLifeTime = typename HalPolicy::OperandLifeTime;
surmeh0149b9e102018-05-17 14:11:25 +0100505
Sadik Armagan6a903a72020-05-26 10:41:54 +0100506 DataLocation location = {};
507 location.offset = model.operandValues.size();
508 location.length = sizeof(float);
surmeh0149b9e102018-05-17 14:11:25 +0100509
David Monahanc60d0fd2020-05-19 14:58:34 +0100510 HalOperand op = {};
Sadik Armagan6a903a72020-05-26 10:41:54 +0100511 op.type = HalOperandType::FLOAT32;
512 op.dimensions = hidl_vec<uint32_t>{};
513 op.lifetime = HalOperandLifeTime::CONSTANT_COPY;
514 op.location = location;
David Monahanc60d0fd2020-05-19 14:58:34 +0100515 op.numberOfConsumers = numberOfConsumers;
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100516
Sadik Armagan6a903a72020-05-26 10:41:54 +0100517 model.operandValues.resize(model.operandValues.size() + location.length);
518 *reinterpret_cast<float*>(&model.operandValues[location.offset]) = value;
519
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100520 AddOperand<HalPolicy>(model, op);
Nikhil Raj77605822018-09-03 11:25:56 +0100521}
surmeh0149b9e102018-05-17 14:11:25 +0100522
Kevin Mayec1e5b82020-02-26 17:00:39 +0000523V1_0::ErrorStatus Execute(android::sp<V1_0::IPreparedModel> preparedModel,
524 const V1_0::Request& request,
525 V1_0::ErrorStatus expectedStatus = V1_0::ErrorStatus::NONE);
surmeh0149b9e102018-05-17 14:11:25 +0100526
Sadik Armagane6e54a82019-05-08 10:18:05 +0100527android::sp<ExecutionCallback> ExecuteNoWait(android::sp<V1_0::IPreparedModel> preparedModel,
Kevin Mayec1e5b82020-02-26 17:00:39 +0000528 const V1_0::Request& request);
surmeh0149b9e102018-05-17 14:11:25 +0100529
530} // namespace driverTestHelpers