blob: 4c26174bb4c727f03a839b5675c3a66bd25ef54f [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#include "DriverTestHelpers.hpp"
6#include <log/log.h>
7#include <boost/test/unit_test.hpp>
8
9namespace android
10{
11namespace hardware
12{
13namespace neuralnetworks
14{
15namespace V1_0
16{
17
18std::ostream& operator<<(std::ostream& os, ErrorStatus stat)
19{
20 return os << static_cast<int>(stat);
21}
22
23} // namespace android::hardware::neuralnetworks::V1_0
24} // namespace android::hardware::neuralnetworks
25} // namespace android::hardware
26} // namespace android
27
surmeh0149b9e102018-05-17 14:11:25 +010028namespace driverTestHelpers
29{
30
telsoa01ce3e84a2018-08-31 09:31:35 +010031using namespace android::hardware;
32using namespace armnn_driver;
33
surmeh0149b9e102018-05-17 14:11:25 +010034Return<void> ExecutionCallback::notify(ErrorStatus status)
35{
36 (void)status;
37 ALOGI("ExecutionCallback::notify invoked");
38 std::lock_guard<std::mutex> executionLock(mMutex);
39 mNotified = true;
40 mCondition.notify_one();
41 return Void();
42}
43
44Return<void> ExecutionCallback::wait()
45{
46 ALOGI("ExecutionCallback::wait invoked");
47 std::unique_lock<std::mutex> executionLock(mMutex);
48 while (!mNotified)
49 {
50 mCondition.wait(executionLock);
51 }
52 mNotified = false;
53 return Void();
54}
55
56Return<void> PreparedModelCallback::notify(ErrorStatus status,
Sadik Armagane6e54a82019-05-08 10:18:05 +010057 const android::sp<V1_0::IPreparedModel>& preparedModel)
surmeh0149b9e102018-05-17 14:11:25 +010058{
59 m_ErrorStatus = status;
60 m_PreparedModel = preparedModel;
61 return Void();
62}
63
Ferran Balaguerb2397fd2019-07-25 12:12:39 +010064#ifdef ARMNN_ANDROID_NN_V1_2
65
66Return<void> PreparedModelCallback_1_2::notify(ErrorStatus status,
67 const android::sp<V1_0::IPreparedModel>& preparedModel)
68{
69 m_ErrorStatus = status;
70 m_PreparedModel = preparedModel;
71 return Void();
72}
73
74Return<void> PreparedModelCallback_1_2::notify_1_2(ErrorStatus status,
75 const android::sp<V1_2::IPreparedModel>& preparedModel)
76{
77 m_ErrorStatus = status;
78 m_PreparedModel_1_2 = preparedModel;
79 return Void();
80}
81
82#endif
83
surmeh0149b9e102018-05-17 14:11:25 +010084// lifted from common/Utils.cpp
85hidl_memory allocateSharedMemory(int64_t size)
86{
87 hidl_memory memory;
88
89 const std::string& type = "ashmem";
90 android::sp<IAllocator> allocator = IAllocator::getService(type);
91 allocator->allocate(size, [&](bool success, const hidl_memory& mem) {
92 if (!success)
93 {
94 ALOGE("unable to allocate %li bytes of %s", size, type.c_str());
95 }
96 else
97 {
98 memory = mem;
99 }
100 });
101
102 return memory;
103}
104
105android::sp<IMemory> AddPoolAndGetData(uint32_t size, Request& request)
106{
107 hidl_memory pool;
108
109 android::sp<IAllocator> allocator = IAllocator::getService("ashmem");
110 allocator->allocate(sizeof(float) * size, [&](bool success, const hidl_memory& mem) {
111 BOOST_TEST(success);
112 pool = mem;
113 });
114
115 request.pools.resize(request.pools.size() + 1);
116 request.pools[request.pools.size() - 1] = pool;
117
118 android::sp<IMemory> mapped = mapMemory(pool);
119 mapped->update();
120 return mapped;
121}
122
123void AddPoolAndSetData(uint32_t size, Request& request, const float* data)
124{
125 android::sp<IMemory> memory = AddPoolAndGetData(size, request);
126
127 float* dst = static_cast<float*>(static_cast<void*>(memory->getPointer()));
128
129 memcpy(dst, data, size * sizeof(float));
130}
131
Sadik Armagane6e54a82019-05-08 10:18:05 +0100132android::sp<V1_0::IPreparedModel> PrepareModelWithStatus(const V1_0::Model& model,
133 armnn_driver::ArmnnDriver& driver,
134 ErrorStatus& prepareStatus,
135 ErrorStatus expectedStatus)
surmeh0149b9e102018-05-17 14:11:25 +0100136{
surmeh0149b9e102018-05-17 14:11:25 +0100137 android::sp<PreparedModelCallback> cb(new PreparedModelCallback());
138 driver.prepareModel(model, cb);
139
140 prepareStatus = cb->GetErrorStatus();
141 BOOST_TEST(prepareStatus == expectedStatus);
142 if (expectedStatus == ErrorStatus::NONE)
143 {
144 BOOST_TEST((cb->GetPreparedModel() != nullptr));
145 }
146 return cb->GetPreparedModel();
147}
148
Matteo Martincigha5f9e762019-06-17 13:26:34 +0100149#if defined(ARMNN_ANDROID_NN_V1_1) || defined(ARMNN_ANDROID_NN_V1_2)
Nikhil Raj77605822018-09-03 11:25:56 +0100150
Sadik Armagane6e54a82019-05-08 10:18:05 +0100151android::sp<V1_0::IPreparedModel> PrepareModelWithStatus(const V1_1::Model& model,
152 armnn_driver::ArmnnDriver& driver,
153 ErrorStatus& prepareStatus,
154 ErrorStatus expectedStatus)
surmeh0149b9e102018-05-17 14:11:25 +0100155{
Nikhil Raj77605822018-09-03 11:25:56 +0100156 android::sp<PreparedModelCallback> cb(new PreparedModelCallback());
Matteo Martincigh8b287c22018-09-07 09:25:10 +0100157 driver.prepareModel_1_1(model, V1_1::ExecutionPreference::LOW_POWER, cb);
Nikhil Raj77605822018-09-03 11:25:56 +0100158
159 prepareStatus = cb->GetErrorStatus();
160 BOOST_TEST(prepareStatus == expectedStatus);
161 if (expectedStatus == ErrorStatus::NONE)
162 {
163 BOOST_TEST((cb->GetPreparedModel() != nullptr));
164 }
165 return cb->GetPreparedModel();
surmeh0149b9e102018-05-17 14:11:25 +0100166}
167
Nikhil Raj77605822018-09-03 11:25:56 +0100168#endif
169
Ferran Balaguerb2397fd2019-07-25 12:12:39 +0100170#ifdef ARMNN_ANDROID_NN_V1_2
171
172android::sp<V1_2::IPreparedModel> PrepareModelWithStatus_1_2(const armnn_driver::hal_1_2::HalPolicy::Model& model,
173 armnn_driver::ArmnnDriver& driver,
174 ErrorStatus& prepareStatus,
175 ErrorStatus expectedStatus)
176{
177 android::sp<PreparedModelCallback_1_2> cb(new PreparedModelCallback_1_2());
178
179 android::hardware::hidl_vec<android::hardware::hidl_handle> emptyHandle1;
180 android::hardware::hidl_vec<android::hardware::hidl_handle> emptyHandle2;
181 armnn_driver::ArmnnDriver::HidlToken emptyToken;
182
183 driver.prepareModel_1_2(model, V1_1::ExecutionPreference::LOW_POWER, emptyHandle1, emptyHandle2, emptyToken, cb);
184
185 prepareStatus = cb->GetErrorStatus();
186 BOOST_TEST(prepareStatus == expectedStatus);
187 if (expectedStatus == ErrorStatus::NONE)
188 {
189 BOOST_TEST((cb->GetPreparedModel_1_2() != nullptr));
190 }
191 return cb->GetPreparedModel_1_2();
192}
193
194#endif
195
Sadik Armagane6e54a82019-05-08 10:18:05 +0100196ErrorStatus Execute(android::sp<V1_0::IPreparedModel> preparedModel,
surmeh0149b9e102018-05-17 14:11:25 +0100197 const Request& request,
198 ErrorStatus expectedStatus)
199{
telsoa01ce3e84a2018-08-31 09:31:35 +0100200 BOOST_TEST(preparedModel.get() != nullptr);
surmeh0149b9e102018-05-17 14:11:25 +0100201 android::sp<ExecutionCallback> cb(new ExecutionCallback());
202 ErrorStatus execStatus = preparedModel->execute(request, cb);
203 BOOST_TEST(execStatus == expectedStatus);
204 ALOGI("Execute: waiting for callback to be invoked");
205 cb->wait();
206 return execStatus;
207}
208
Sadik Armagane6e54a82019-05-08 10:18:05 +0100209android::sp<ExecutionCallback> ExecuteNoWait(android::sp<V1_0::IPreparedModel> preparedModel, const Request& request)
surmeh0149b9e102018-05-17 14:11:25 +0100210{
211 android::sp<ExecutionCallback> cb(new ExecutionCallback());
212 BOOST_TEST(preparedModel->execute(request, cb) == ErrorStatus::NONE);
213 ALOGI("ExecuteNoWait: returning callback object");
214 return cb;
215}
216
217template<>
218OperandType TypeToOperandType<float>()
219{
220 return OperandType::TENSOR_FLOAT32;
Matteo Martincigh8b287c22018-09-07 09:25:10 +0100221}
surmeh0149b9e102018-05-17 14:11:25 +0100222
223template<>
224OperandType TypeToOperandType<int32_t>()
225{
226 return OperandType::TENSOR_INT32;
Matteo Martincigh8b287c22018-09-07 09:25:10 +0100227}
surmeh0149b9e102018-05-17 14:11:25 +0100228
229} // namespace driverTestHelpers