• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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