1 //
2 // Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5
6 #include "DriverTestHelpers.hpp"
7 #include <log/log.h>
8
9 namespace android
10 {
11 namespace hardware
12 {
13 namespace neuralnetworks
14 {
15 namespace V1_0
16 {
17
operator <<(std::ostream & os,V1_0::ErrorStatus stat)18 std::ostream& operator<<(std::ostream& os, V1_0::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
28 namespace driverTestHelpers
29 {
30
31 using namespace android::hardware;
32 using namespace armnn_driver;
33
notify(V1_0::ErrorStatus status)34 Return<void> ExecutionCallback::notify(V1_0::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
wait()44 Return<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
notify(V1_0::ErrorStatus status,const android::sp<V1_0::IPreparedModel> & preparedModel)56 Return<void> PreparedModelCallback::notify(V1_0::ErrorStatus status,
57 const android::sp<V1_0::IPreparedModel>& preparedModel)
58 {
59 m_ErrorStatus = status;
60 m_PreparedModel = preparedModel;
61 return Void();
62 }
63
64 #if defined(ARMNN_ANDROID_NN_V1_2) || defined(ARMNN_ANDROID_NN_V1_3)
65
notify(V1_0::ErrorStatus status,const android::sp<V1_0::IPreparedModel> & preparedModel)66 Return<void> PreparedModelCallback_1_2::notify(V1_0::ErrorStatus status,
67 const android::sp<V1_0::IPreparedModel>& preparedModel)
68 {
69 m_ErrorStatus = status;
70 m_PreparedModel = preparedModel;
71 return Void();
72 }
73
notify_1_2(V1_0::ErrorStatus status,const android::sp<V1_2::IPreparedModel> & preparedModel)74 Return<void> PreparedModelCallback_1_2::notify_1_2(V1_0::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
84 #ifdef ARMNN_ANDROID_NN_V1_3
85
notify(V1_0::ErrorStatus status,const android::sp<V1_0::IPreparedModel> & preparedModel)86 Return<void> PreparedModelCallback_1_3::notify(V1_0::ErrorStatus status,
87 const android::sp<V1_0::IPreparedModel>& preparedModel)
88 {
89 m_1_0_ErrorStatus = status;
90 m_PreparedModel = preparedModel;
91 return Void();
92 }
93
notify_1_2(V1_0::ErrorStatus status,const android::sp<V1_2::IPreparedModel> & preparedModel)94 Return<void> PreparedModelCallback_1_3::notify_1_2(V1_0::ErrorStatus status,
95 const android::sp<V1_2::IPreparedModel>& preparedModel)
96 {
97 m_1_0_ErrorStatus = status;
98 m_PreparedModel_1_2 = preparedModel;
99 return Void();
100 }
101
notify_1_3(V1_3::ErrorStatus status,const android::sp<V1_3::IPreparedModel> & preparedModel)102 Return<void> PreparedModelCallback_1_3::notify_1_3(V1_3::ErrorStatus status,
103 const android::sp<V1_3::IPreparedModel>& preparedModel)
104 {
105 m_1_3_ErrorStatus = status;
106 m_PreparedModel_1_3 = preparedModel;
107 return Void();
108 }
109
110 #endif
111
112 // lifted from common/Utils.cpp
allocateSharedMemory(int64_t size)113 hidl_memory allocateSharedMemory(int64_t size)
114 {
115 hidl_memory memory;
116
117 const std::string& type = "ashmem";
118 android::sp<IAllocator> allocator = IAllocator::getService(type);
119 allocator->allocate(size, [&](bool success, const hidl_memory& mem) {
120 if (!success)
121 {
122 ALOGE("unable to allocate %li bytes of %s", size, type.c_str());
123 }
124 else
125 {
126 memory = mem;
127 }
128 });
129
130 return memory;
131 }
132
PrepareModelWithStatus(const V1_0::Model & model,armnn_driver::ArmnnDriver & driver,V1_0::ErrorStatus & prepareStatus,V1_0::ErrorStatus expectedStatus)133 android::sp<V1_0::IPreparedModel> PrepareModelWithStatus(const V1_0::Model& model,
134 armnn_driver::ArmnnDriver& driver,
135 V1_0::ErrorStatus& prepareStatus,
136 V1_0::ErrorStatus expectedStatus)
137 {
138 android::sp<PreparedModelCallback> cb(new PreparedModelCallback());
139 driver.prepareModel(model, cb);
140
141 prepareStatus = cb->GetErrorStatus();
142 DOCTEST_CHECK((int)prepareStatus == (int)expectedStatus);
143 if (expectedStatus == V1_0::ErrorStatus::NONE)
144 {
145 DOCTEST_CHECK((cb->GetPreparedModel() != nullptr));
146 }
147 return cb->GetPreparedModel();
148 }
149
150 #if defined(ARMNN_ANDROID_NN_V1_1) || defined(ARMNN_ANDROID_NN_V1_2) || defined(ARMNN_ANDROID_NN_V1_3)
151
PrepareModelWithStatus(const V1_1::Model & model,armnn_driver::ArmnnDriver & driver,V1_0::ErrorStatus & prepareStatus,V1_0::ErrorStatus expectedStatus)152 android::sp<V1_0::IPreparedModel> PrepareModelWithStatus(const V1_1::Model& model,
153 armnn_driver::ArmnnDriver& driver,
154 V1_0::ErrorStatus& prepareStatus,
155 V1_0::ErrorStatus expectedStatus)
156 {
157 android::sp<PreparedModelCallback> cb(new PreparedModelCallback());
158 driver.prepareModel_1_1(model, V1_1::ExecutionPreference::LOW_POWER, cb);
159
160 prepareStatus = cb->GetErrorStatus();
161 DOCTEST_CHECK((int)prepareStatus == (int)expectedStatus);
162 if (expectedStatus == V1_0::ErrorStatus::NONE)
163 {
164 DOCTEST_CHECK((cb->GetPreparedModel() != nullptr));
165 }
166 return cb->GetPreparedModel();
167 }
168
169 #endif
170
171 #if defined(ARMNN_ANDROID_NN_V1_2) || defined(ARMNN_ANDROID_NN_V1_3)
172
PrepareModelWithStatus_1_2(const armnn_driver::hal_1_2::HalPolicy::Model & model,armnn_driver::ArmnnDriver & driver,V1_0::ErrorStatus & prepareStatus,V1_0::ErrorStatus expectedStatus)173 android::sp<V1_2::IPreparedModel> PrepareModelWithStatus_1_2(const armnn_driver::hal_1_2::HalPolicy::Model& model,
174 armnn_driver::ArmnnDriver& driver,
175 V1_0::ErrorStatus& prepareStatus,
176 V1_0::ErrorStatus expectedStatus)
177 {
178 android::sp<PreparedModelCallback_1_2> cb(new PreparedModelCallback_1_2());
179
180 android::hardware::hidl_vec<android::hardware::hidl_handle> emptyHandle1;
181 android::hardware::hidl_vec<android::hardware::hidl_handle> emptyHandle2;
182 armnn_driver::ArmnnDriver::HidlToken emptyToken;
183
184 driver.prepareModel_1_2(model, V1_1::ExecutionPreference::LOW_POWER, emptyHandle1, emptyHandle2, emptyToken, cb);
185
186 prepareStatus = cb->GetErrorStatus();
187 DOCTEST_CHECK((int)prepareStatus == (int)expectedStatus);
188 if (expectedStatus == V1_0::ErrorStatus::NONE)
189 {
190 DOCTEST_CHECK((cb->GetPreparedModel_1_2() != nullptr));
191 }
192 return cb->GetPreparedModel_1_2();
193 }
194
195 #endif
196
197 #ifdef ARMNN_ANDROID_NN_V1_3
198
PrepareModelWithStatus_1_3(const armnn_driver::hal_1_3::HalPolicy::Model & model,armnn_driver::ArmnnDriver & driver,V1_3::ErrorStatus & prepareStatus,V1_3::Priority priority)199 android::sp<V1_3::IPreparedModel> PrepareModelWithStatus_1_3(const armnn_driver::hal_1_3::HalPolicy::Model& model,
200 armnn_driver::ArmnnDriver& driver,
201 V1_3::ErrorStatus& prepareStatus,
202 V1_3::Priority priority)
203 {
204 android::sp<PreparedModelCallback_1_3> cb(new PreparedModelCallback_1_3());
205
206 android::hardware::hidl_vec<android::hardware::hidl_handle> emptyHandle1;
207 android::hardware::hidl_vec<android::hardware::hidl_handle> emptyHandle2;
208 armnn_driver::ArmnnDriver::HidlToken emptyToken;
209
210 driver.prepareModel_1_3(model,
211 V1_1::ExecutionPreference::LOW_POWER,
212 priority,
213 {},
214 emptyHandle1,
215 emptyHandle2,
216 emptyToken,
217 cb);
218
219 prepareStatus = cb->Get_1_3_ErrorStatus();
220 if (prepareStatus == V1_3::ErrorStatus::NONE)
221 {
222 DOCTEST_CHECK((cb->GetPreparedModel_1_3() != nullptr));
223 }
224 return cb->GetPreparedModel_1_3();
225 }
226
227 #endif
228
Execute(android::sp<V1_0::IPreparedModel> preparedModel,const V1_0::Request & request,V1_0::ErrorStatus expectedStatus)229 V1_0::ErrorStatus Execute(android::sp<V1_0::IPreparedModel> preparedModel,
230 const V1_0::Request& request,
231 V1_0::ErrorStatus expectedStatus)
232 {
233 DOCTEST_CHECK(preparedModel.get() != nullptr);
234 android::sp<ExecutionCallback> cb(new ExecutionCallback());
235 V1_0::ErrorStatus execStatus = preparedModel->execute(request, cb);
236 DOCTEST_CHECK((int)execStatus == (int)expectedStatus);
237 ALOGI("Execute: waiting for callback to be invoked");
238 cb->wait();
239 return execStatus;
240 }
241
ExecuteNoWait(android::sp<V1_0::IPreparedModel> preparedModel,const V1_0::Request & request)242 android::sp<ExecutionCallback> ExecuteNoWait(android::sp<V1_0::IPreparedModel> preparedModel,
243 const V1_0::Request& request)
244 {
245 DOCTEST_CHECK(preparedModel.get() != nullptr);
246 android::sp<ExecutionCallback> cb(new ExecutionCallback());
247 V1_0::ErrorStatus execStatus = preparedModel->execute(request, cb);
248 DOCTEST_CHECK((int)execStatus == (int)V1_0::ErrorStatus::NONE);
249 ALOGI("ExecuteNoWait: returning callback object");
250 return cb;
251 }
252
253 template<>
TypeToOperandType()254 OperandType TypeToOperandType<float>()
255 {
256 return OperandType::TENSOR_FLOAT32;
257 }
258
259 template<>
TypeToOperandType()260 OperandType TypeToOperandType<int32_t>()
261 {
262 return OperandType::TENSOR_INT32;
263 }
264
265 } // namespace driverTestHelpers
266