1 /* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
2
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 #include "tensorflow/lite/nnapi/nnapi_implementation.h"
16
17 #include <dlfcn.h>
18 #include <fcntl.h>
19 #include <sys/mman.h>
20 #include <sys/stat.h>
21 #include <unistd.h>
22
23 #include <algorithm>
24 #include <cstdlib>
25
26 #include "tensorflow/lite/nnapi/sl/public/NeuralNetworksSupportLibraryImpl.h"
27
28 #ifdef __ANDROID__
29 #include <sys/system_properties.h>
30 #endif // __ANDROID__
31
32 #define NNAPI_LOG(format, ...) fprintf(stderr, format "\n", __VA_ARGS__);
33
34 namespace {
35
36 #ifdef __ANDROID__
GetAndroidSdkVersion()37 int32_t GetAndroidSdkVersion() {
38 const char* sdkProp = "ro.build.version.sdk";
39 char sdkVersion[PROP_VALUE_MAX];
40 int length = __system_property_get(sdkProp, sdkVersion);
41 if (length != 0) {
42 int32_t result = 0;
43 for (int i = 0; i < length; ++i) {
44 int digit = sdkVersion[i] - '0';
45 if (digit < 0 || digit > 9) {
46 // Non-numeric SDK version, assume it's higher than expected;
47 return 0xffff;
48 }
49 result = result * 10 + digit;
50 }
51 return result;
52 }
53 return 0;
54 }
55 #endif // __ANDROID__
56
LoadFunction(void * handle,const char * name,bool optional)57 void* LoadFunction(void* handle, const char* name, bool optional) {
58 if (handle == nullptr) {
59 return nullptr;
60 }
61 void* fn = dlsym(handle, name);
62 if (fn == nullptr && !optional) {
63 NNAPI_LOG("nnapi error: unable to open function %s", name);
64 }
65 return fn;
66 }
67
68 #ifndef __ANDROID__
69 // Add /dev/shm implementation of shared memory for non-Android platforms
ASharedMemory_create(const char * name,size_t size)70 int ASharedMemory_create(const char* name, size_t size) {
71 // Each call to ASharedMemory_create produces a unique memory space, hence
72 // name should be unique, otherwise two calls to create memory regions using
73 // the same 'name', will collide.
74 // Caller is responsible to provide a unique name.
75
76 // Make sure new shared memory region is created: shm_open return an error if
77 // shm object with given name already exists (O_CREAT | O_EXCL)
78 int fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0644);
79 if (fd < 0) {
80 return fd;
81 }
82 int result = ftruncate(fd, size);
83 if (result < 0) {
84 close(fd);
85 return -1;
86 }
87 return fd;
88 }
89
90 // Determine the NnApi version from loaded entry points
CalculateAndroidSdkVersion(NnApi const & nnapi)91 uint32_t CalculateAndroidSdkVersion(NnApi const& nnapi) {
92 // Test for specific NNAPI 1.0, 1.1, 1.2 and 1.3 functions
93 bool has_10 = nnapi.ANeuralNetworksMemory_createFromFd != nullptr;
94 bool has_11 =
95 nnapi.ANeuralNetworksModel_relaxComputationFloat32toFloat16 != nullptr;
96 bool has_12 = nnapi.ANeuralNetworks_getDeviceCount != nullptr;
97 bool has_13 = nnapi.ANeuralNetworksCompilation_setTimeout != nullptr;
98 bool has_14 = nnapi.ANeuralNetworks_getRuntimeFeatureLevel != nullptr;
99
100 uint32_t sdk_version = 0;
101 if (has_10) {
102 sdk_version = 27;
103 }
104 if (sdk_version == 27 && has_11) {
105 sdk_version = 28;
106 }
107 if (sdk_version == 28 && has_12) {
108 sdk_version = 29;
109 }
110 if (sdk_version == 29 && has_13) {
111 sdk_version = 30;
112 }
113 if (sdk_version == 30 && has_14) {
114 sdk_version = 31;
115 }
116 return sdk_version;
117 }
118 #else
119
getASharedMemory_create()120 ASharedMemory_create_fn getASharedMemory_create() {
121 // ASharedMemory_create has different implementations in Android depending on
122 // the partition. Generally it can be loaded from libandroid.so but in vendor
123 // partition (e.g. if a HAL wants to use NNAPI) it is only accessible through
124 // libcutils.
125 void* libandroid = nullptr;
126 libandroid = dlopen("libandroid.so", RTLD_LAZY | RTLD_LOCAL);
127 if (libandroid != nullptr) {
128 return reinterpret_cast<ASharedMemory_create_fn>(
129 LoadFunction(libandroid, "ASharedMemory_create", false));
130 }
131
132 std::string libandroid_error = dlerror();
133 void* cutils_handle = dlopen("libcutils.so", RTLD_LAZY | RTLD_LOCAL);
134 if (cutils_handle != nullptr) {
135 return reinterpret_cast<ASharedMemory_create_fn>(
136 LoadFunction(cutils_handle, "ashmem_create_region", false));
137 }
138
139 NNAPI_LOG(
140 "nnapi error: unable to open both library %s (%s) and library %s "
141 "(%s)",
142 "libandroid.so", libandroid_error.c_str(), "libcutils.so", dlerror());
143 return nullptr;
144 }
145
146 #endif // __ANDROID__
147
148 #define LOAD_FUNCTION(handle, name) \
149 nnapi.name = reinterpret_cast<name##_fn>( \
150 LoadFunction(handle, #name, /*optional*/ false));
151
152 #define LOAD_FUNCTION_OPTIONAL(handle, name) \
153 nnapi.name = reinterpret_cast<name##_fn>( \
154 LoadFunction(handle, #name, /*optional*/ true));
155
156 #define LOAD_FUNCTION_RENAME(handle, name, symbol) \
157 nnapi.name = reinterpret_cast<name##_fn>( \
158 LoadFunction(handle, symbol, /*optional*/ false));
159
LoadNnApi()160 const NnApi LoadNnApi() {
161 NnApi nnapi = {};
162 nnapi.android_sdk_version = 0;
163
164 #ifdef __ANDROID__
165 nnapi.android_sdk_version = GetAndroidSdkVersion();
166 if (nnapi.android_sdk_version < 27) {
167 NNAPI_LOG("nnapi error: requires android sdk version to be at least %d",
168 27);
169 nnapi.nnapi_exists = false;
170 return nnapi;
171 }
172 #endif // __ANDROID__
173
174 void* libneuralnetworks = nullptr;
175 // TODO(b/123243014): change RTLD_LOCAL? Assumes there can be multiple
176 // instances of nn api RT
177 static const char nnapi_library_name[] = "libneuralnetworks.so";
178 libneuralnetworks = dlopen(nnapi_library_name, RTLD_LAZY | RTLD_LOCAL);
179 #ifdef __ANDROID__
180 // Note: If there is an problem trying to open the NNAPI library on a
181 // non-Android system, the error message is suppressed. This is to avoid
182 // showing confusing errors when running in environments that do not support
183 // NNAPI. As more platforms support NNAPI, the #ifdef logic above can be
184 // expanded.
185 if (libneuralnetworks == nullptr) {
186 const char* error = dlerror();
187 if (error) {
188 NNAPI_LOG("%s\n", error);
189 }
190 NNAPI_LOG("nnapi error: unable to open library %s", nnapi_library_name);
191 }
192 #endif // __ANDROID__
193
194 nnapi.nnapi_exists = libneuralnetworks != nullptr;
195
196 // API 27 (NN 1.0) methods.
197 LOAD_FUNCTION(libneuralnetworks, ANeuralNetworksMemory_createFromFd);
198 LOAD_FUNCTION(libneuralnetworks, ANeuralNetworksMemory_free);
199 LOAD_FUNCTION(libneuralnetworks, ANeuralNetworksModel_create);
200 LOAD_FUNCTION(libneuralnetworks, ANeuralNetworksModel_free);
201 LOAD_FUNCTION(libneuralnetworks, ANeuralNetworksModel_finish);
202 LOAD_FUNCTION(libneuralnetworks, ANeuralNetworksModel_addOperand);
203 LOAD_FUNCTION(libneuralnetworks, ANeuralNetworksModel_setOperandValue);
204 LOAD_FUNCTION_OPTIONAL(
205 libneuralnetworks,
206 ANeuralNetworksModel_setOperandSymmPerChannelQuantParams);
207 LOAD_FUNCTION(libneuralnetworks,
208 ANeuralNetworksModel_setOperandValueFromMemory);
209 LOAD_FUNCTION(libneuralnetworks, ANeuralNetworksModel_addOperation);
210 LOAD_FUNCTION(libneuralnetworks,
211 ANeuralNetworksModel_identifyInputsAndOutputs);
212 LOAD_FUNCTION(libneuralnetworks, ANeuralNetworksCompilation_create);
213 LOAD_FUNCTION(libneuralnetworks, ANeuralNetworksCompilation_free);
214 LOAD_FUNCTION(libneuralnetworks, ANeuralNetworksCompilation_setPreference);
215 LOAD_FUNCTION(libneuralnetworks, ANeuralNetworksCompilation_finish);
216 LOAD_FUNCTION(libneuralnetworks, ANeuralNetworksExecution_create);
217 LOAD_FUNCTION(libneuralnetworks, ANeuralNetworksExecution_free);
218 LOAD_FUNCTION(libneuralnetworks, ANeuralNetworksExecution_setInput);
219 LOAD_FUNCTION(libneuralnetworks, ANeuralNetworksExecution_setInputFromMemory);
220 LOAD_FUNCTION(libneuralnetworks, ANeuralNetworksExecution_setOutput);
221 LOAD_FUNCTION(libneuralnetworks,
222 ANeuralNetworksExecution_setOutputFromMemory);
223 LOAD_FUNCTION(libneuralnetworks, ANeuralNetworksExecution_startCompute);
224 LOAD_FUNCTION(libneuralnetworks, ANeuralNetworksEvent_wait);
225 LOAD_FUNCTION(libneuralnetworks, ANeuralNetworksEvent_free);
226
227 #ifdef __ANDROID__
228 nnapi.ASharedMemory_create = getASharedMemory_create();
229 #else
230 // Mock ASharedMemory_create only if libneuralnetworks.so was successfully
231 // loaded. This ensures identical behaviour on platforms which use this
232 // implementation, but don't have libneuralnetworks.so library, and
233 // platforms which use nnapi_implementation_disabled.cc stub.
234 if (libneuralnetworks != nullptr) {
235 nnapi.ASharedMemory_create = ASharedMemory_create;
236 }
237 #endif // __ANDROID__
238
239 // API 28 (NN 1.1) methods.
240 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
241 ANeuralNetworksModel_relaxComputationFloat32toFloat16);
242
243 // API 29 (NN 1.2) methods.
244 LOAD_FUNCTION_OPTIONAL(libneuralnetworks, ANeuralNetworks_getDeviceCount);
245 LOAD_FUNCTION_OPTIONAL(libneuralnetworks, ANeuralNetworks_getDevice);
246 LOAD_FUNCTION_OPTIONAL(libneuralnetworks, ANeuralNetworksDevice_getName);
247 LOAD_FUNCTION_OPTIONAL(libneuralnetworks, ANeuralNetworksDevice_getVersion);
248 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
249 ANeuralNetworksDevice_getFeatureLevel);
250 LOAD_FUNCTION_OPTIONAL(libneuralnetworks, ANeuralNetworksDevice_getType);
251 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
252 ANeuralNetworksModel_getSupportedOperationsForDevices);
253 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
254 ANeuralNetworksCompilation_createForDevices);
255 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
256 ANeuralNetworksCompilation_setCaching);
257 LOAD_FUNCTION_OPTIONAL(libneuralnetworks, ANeuralNetworksExecution_compute);
258 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
259 ANeuralNetworksExecution_getOutputOperandRank);
260 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
261 ANeuralNetworksExecution_getOutputOperandDimensions);
262 LOAD_FUNCTION_OPTIONAL(libneuralnetworks, ANeuralNetworksBurst_create);
263 LOAD_FUNCTION_OPTIONAL(libneuralnetworks, ANeuralNetworksBurst_free);
264 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
265 ANeuralNetworksExecution_burstCompute);
266 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
267 ANeuralNetworksMemory_createFromAHardwareBuffer);
268 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
269 ANeuralNetworksExecution_setMeasureTiming);
270 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
271 ANeuralNetworksExecution_getDuration);
272 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
273 ANeuralNetworksDevice_getExtensionSupport);
274 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
275 ANeuralNetworksModel_getExtensionOperandType);
276 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
277 ANeuralNetworksModel_getExtensionOperationType);
278 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
279 ANeuralNetworksModel_setOperandExtensionData);
280
281 // API 30 (NNAPI 1.3) methods.
282 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
283 ANeuralNetworksCompilation_setTimeout);
284 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
285 ANeuralNetworksCompilation_setPriority);
286 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
287 ANeuralNetworksExecution_setTimeout);
288 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
289 ANeuralNetworksExecution_setLoopTimeout);
290 LOAD_FUNCTION_OPTIONAL(libneuralnetworks, ANeuralNetworksMemoryDesc_create);
291 LOAD_FUNCTION_OPTIONAL(libneuralnetworks, ANeuralNetworksMemoryDesc_free);
292 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
293 ANeuralNetworksMemoryDesc_addInputRole);
294 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
295 ANeuralNetworksMemoryDesc_addOutputRole);
296 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
297 ANeuralNetworksMemoryDesc_setDimensions);
298 LOAD_FUNCTION_OPTIONAL(libneuralnetworks, ANeuralNetworksMemoryDesc_finish);
299 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
300 ANeuralNetworksMemory_createFromDesc);
301 LOAD_FUNCTION_OPTIONAL(libneuralnetworks, ANeuralNetworksMemory_copy);
302 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
303 ANeuralNetworksEvent_createFromSyncFenceFd);
304 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
305 ANeuralNetworksEvent_getSyncFenceFd);
306 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
307 ANeuralNetworksExecution_startComputeWithDependencies);
308
309 // API 31 methods
310 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
311 ANeuralNetworks_getRuntimeFeatureLevel);
312 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
313 ANeuralNetworksExecution_enableInputAndOutputPadding);
314 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
315 ANeuralNetworksExecution_setReusable);
316
317 LOAD_FUNCTION_OPTIONAL(
318 libneuralnetworks,
319 SL_ANeuralNetworksDiagnosticCompilationInfo_getSessionId);
320 LOAD_FUNCTION_OPTIONAL(
321 libneuralnetworks,
322 SL_ANeuralNetworksDiagnosticCompilationInfo_getNnApiVersion);
323 LOAD_FUNCTION_OPTIONAL(
324 libneuralnetworks,
325 SL_ANeuralNetworksDiagnosticCompilationInfo_getModelArchHash);
326 LOAD_FUNCTION_OPTIONAL(
327 libneuralnetworks,
328 SL_ANeuralNetworksDiagnosticCompilationInfo_getDeviceIds);
329 LOAD_FUNCTION_OPTIONAL(
330 libneuralnetworks,
331 SL_ANeuralNetworksDiagnosticCompilationInfo_getErrorCode);
332 LOAD_FUNCTION_OPTIONAL(
333 libneuralnetworks,
334 SL_ANeuralNetworksDiagnosticCompilationInfo_getInputDataClass);
335 LOAD_FUNCTION_OPTIONAL(
336 libneuralnetworks,
337 SL_ANeuralNetworksDiagnosticCompilationInfo_getOutputDataClass);
338 LOAD_FUNCTION_OPTIONAL(
339 libneuralnetworks,
340 SL_ANeuralNetworksDiagnosticCompilationInfo_getCompilationTimeNanos);
341 LOAD_FUNCTION_OPTIONAL(
342 libneuralnetworks,
343 SL_ANeuralNetworksDiagnosticCompilationInfo_isCachingEnabled);
344 LOAD_FUNCTION_OPTIONAL(
345 libneuralnetworks,
346 SL_ANeuralNetworksDiagnosticCompilationInfo_isControlFlowUsed);
347 LOAD_FUNCTION_OPTIONAL(
348 libneuralnetworks,
349 SL_ANeuralNetworksDiagnosticCompilationInfo_areDynamicTensorsUsed);
350 LOAD_FUNCTION_OPTIONAL(
351 libneuralnetworks,
352 SL_ANeuralNetworksDiagnosticExecutionInfo_getSessionId);
353 LOAD_FUNCTION_OPTIONAL(
354 libneuralnetworks,
355 SL_ANeuralNetworksDiagnosticExecutionInfo_getNnApiVersion);
356 LOAD_FUNCTION_OPTIONAL(
357 libneuralnetworks,
358 SL_ANeuralNetworksDiagnosticExecutionInfo_getModelArchHash);
359 LOAD_FUNCTION_OPTIONAL(
360 libneuralnetworks,
361 SL_ANeuralNetworksDiagnosticExecutionInfo_getDeviceIds);
362 LOAD_FUNCTION_OPTIONAL(
363 libneuralnetworks,
364 SL_ANeuralNetworksDiagnosticExecutionInfo_getExecutionMode);
365 LOAD_FUNCTION_OPTIONAL(
366 libneuralnetworks,
367 SL_ANeuralNetworksDiagnosticExecutionInfo_getInputDataClass);
368 LOAD_FUNCTION_OPTIONAL(
369 libneuralnetworks,
370 SL_ANeuralNetworksDiagnosticExecutionInfo_getOutputDataClass);
371 LOAD_FUNCTION_OPTIONAL(
372 libneuralnetworks,
373 SL_ANeuralNetworksDiagnosticExecutionInfo_getErrorCode);
374 LOAD_FUNCTION_OPTIONAL(
375 libneuralnetworks,
376 SL_ANeuralNetworksDiagnosticExecutionInfo_getRuntimeExecutionTimeNanos);
377 LOAD_FUNCTION_OPTIONAL(
378 libneuralnetworks,
379 SL_ANeuralNetworksDiagnosticExecutionInfo_getDriverExecutionTimeNanos);
380 LOAD_FUNCTION_OPTIONAL(
381 libneuralnetworks,
382 SL_ANeuralNetworksDiagnosticExecutionInfo_getHardwareExecutionTimeNanos);
383 LOAD_FUNCTION_OPTIONAL(
384 libneuralnetworks,
385 SL_ANeuralNetworksDiagnosticExecutionInfo_isCachingEnabled);
386 LOAD_FUNCTION_OPTIONAL(
387 libneuralnetworks,
388 SL_ANeuralNetworksDiagnosticExecutionInfo_isControlFlowUsed);
389 LOAD_FUNCTION_OPTIONAL(
390 libneuralnetworks,
391 SL_ANeuralNetworksDiagnosticExecutionInfo_areDynamicTensorsUsed);
392 LOAD_FUNCTION_OPTIONAL(libneuralnetworks,
393 SL_ANeuralNetworksDiagnostic_registerCallbacks);
394
395 #ifndef __ANDROID__
396 // If libneuralnetworks.so is loaded, but android_sdk_version is not set,
397 // then determine android_sdk_version by testing which functions are
398 // available.
399 if (nnapi.nnapi_exists && nnapi.android_sdk_version == 0) {
400 nnapi.android_sdk_version = CalculateAndroidSdkVersion(nnapi);
401 }
402 #endif // __ANDROID__
403 // Determin NNAPI Runtime feature level.
404 if (nnapi.ANeuralNetworks_getRuntimeFeatureLevel) {
405 nnapi.nnapi_runtime_feature_level =
406 nnapi.ANeuralNetworks_getRuntimeFeatureLevel();
407 } else {
408 nnapi.nnapi_runtime_feature_level = nnapi.android_sdk_version;
409 }
410
411 return nnapi;
412 }
413
414 } // namespace
415
CreateNnApiFromSupportLibrary(const NnApiSLDriverImplFL5 * nnapi_support_library_driver)416 std::unique_ptr<const NnApi> CreateNnApiFromSupportLibrary(
417 const NnApiSLDriverImplFL5* nnapi_support_library_driver) {
418 auto nnapi = std::make_unique<NnApi>();
419 nnapi->nnapi_exists = true;
420 nnapi->android_sdk_version = ANEURALNETWORKS_FEATURE_LEVEL_5;
421 nnapi->nnapi_runtime_feature_level =
422 nnapi_support_library_driver->base.implFeatureLevel;
423
424 #define ASSIGN_SL_FUNCTION_TO_NNAPI(name) \
425 nnapi->name = nnapi_support_library_driver->name;
426
427 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksMemory_createFromFd);
428 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksMemory_free);
429 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksModel_create);
430 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksModel_free);
431 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksModel_finish);
432 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksModel_addOperand);
433 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksModel_setOperandValue);
434 ASSIGN_SL_FUNCTION_TO_NNAPI(
435 ANeuralNetworksModel_setOperandSymmPerChannelQuantParams);
436 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksModel_setOperandValueFromMemory);
437 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksModel_addOperation);
438 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksModel_identifyInputsAndOutputs);
439 ASSIGN_SL_FUNCTION_TO_NNAPI(
440 ANeuralNetworksModel_relaxComputationFloat32toFloat16);
441 // ANeuralNetworksCompilation_create is not available in the support library
442 // because its clients are expected to know which accelerator they want to
443 // use. ANeuralNetworksCompilation_createForDevices is available to create
444 // compilation for specified devices.
445 nnapi->ANeuralNetworksCompilation_create = nullptr;
446 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksCompilation_free);
447 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksCompilation_setPreference);
448 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksCompilation_finish);
449 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksExecution_create);
450 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksExecution_free);
451 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksExecution_setInput);
452 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksExecution_setInputFromMemory);
453 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksExecution_setOutput);
454 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksExecution_setOutputFromMemory);
455 // Support library doesn't support regular asynchronous execution.
456 nnapi->ANeuralNetworksExecution_startCompute = nullptr;
457 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksEvent_wait);
458 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksEvent_free);
459
460 #ifdef __ANDROID__
461 nnapi->ASharedMemory_create = getASharedMemory_create();
462 #else
463 nnapi->ASharedMemory_create = ASharedMemory_create;
464 #endif // __ANDROID__
465
466 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworks_getDeviceCount);
467 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworks_getDevice);
468 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksDevice_getName);
469 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksDevice_getVersion);
470 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksDevice_getFeatureLevel);
471 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksDevice_getType);
472 ASSIGN_SL_FUNCTION_TO_NNAPI(
473 ANeuralNetworksModel_getSupportedOperationsForDevices);
474 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksCompilation_createForDevices);
475 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksCompilation_setCaching);
476 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksCompilation_setTimeout);
477 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksCompilation_setPriority);
478 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksExecution_compute);
479 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksExecution_setTimeout);
480 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksExecution_setLoopTimeout);
481 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksExecution_getOutputOperandRank);
482 ASSIGN_SL_FUNCTION_TO_NNAPI(
483 ANeuralNetworksExecution_getOutputOperandDimensions);
484 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksBurst_create);
485 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksBurst_free);
486 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksExecution_burstCompute);
487 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksMemory_createFromAHardwareBuffer);
488 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksExecution_setMeasureTiming);
489 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksExecution_getDuration);
490 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksDevice_getExtensionSupport);
491 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksModel_getExtensionOperandType);
492 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksModel_getExtensionOperationType);
493 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksModel_setOperandExtensionData);
494
495 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksMemoryDesc_create);
496 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksMemoryDesc_free);
497 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksMemoryDesc_addInputRole);
498 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksMemoryDesc_addOutputRole);
499 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksMemoryDesc_setDimensions);
500 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksMemoryDesc_finish);
501
502 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksMemory_createFromDesc);
503 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksMemory_copy);
504
505 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksEvent_createFromSyncFenceFd);
506 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksEvent_getSyncFenceFd);
507
508 ASSIGN_SL_FUNCTION_TO_NNAPI(
509 ANeuralNetworksExecution_startComputeWithDependencies);
510 ASSIGN_SL_FUNCTION_TO_NNAPI(
511 ANeuralNetworksExecution_enableInputAndOutputPadding);
512 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworksExecution_setReusable);
513
514 ASSIGN_SL_FUNCTION_TO_NNAPI(ANeuralNetworks_getRuntimeFeatureLevel);
515
516 ASSIGN_SL_FUNCTION_TO_NNAPI(
517 SL_ANeuralNetworksDiagnosticCompilationInfo_getSessionId);
518 ASSIGN_SL_FUNCTION_TO_NNAPI(
519 SL_ANeuralNetworksDiagnosticCompilationInfo_getNnApiVersion);
520 ASSIGN_SL_FUNCTION_TO_NNAPI(
521 SL_ANeuralNetworksDiagnosticCompilationInfo_getModelArchHash);
522 ASSIGN_SL_FUNCTION_TO_NNAPI(
523 SL_ANeuralNetworksDiagnosticCompilationInfo_getDeviceIds);
524 ASSIGN_SL_FUNCTION_TO_NNAPI(
525 SL_ANeuralNetworksDiagnosticCompilationInfo_getErrorCode);
526 ASSIGN_SL_FUNCTION_TO_NNAPI(
527 SL_ANeuralNetworksDiagnosticCompilationInfo_getInputDataClass);
528 ASSIGN_SL_FUNCTION_TO_NNAPI(
529 SL_ANeuralNetworksDiagnosticCompilationInfo_getOutputDataClass);
530 ASSIGN_SL_FUNCTION_TO_NNAPI(
531 SL_ANeuralNetworksDiagnosticCompilationInfo_getCompilationTimeNanos);
532 ASSIGN_SL_FUNCTION_TO_NNAPI(
533 SL_ANeuralNetworksDiagnosticCompilationInfo_isCachingEnabled);
534 ASSIGN_SL_FUNCTION_TO_NNAPI(
535 SL_ANeuralNetworksDiagnosticCompilationInfo_isControlFlowUsed);
536 ASSIGN_SL_FUNCTION_TO_NNAPI(
537 SL_ANeuralNetworksDiagnosticCompilationInfo_areDynamicTensorsUsed);
538 ASSIGN_SL_FUNCTION_TO_NNAPI(
539 SL_ANeuralNetworksDiagnosticExecutionInfo_getSessionId);
540 ASSIGN_SL_FUNCTION_TO_NNAPI(
541 SL_ANeuralNetworksDiagnosticExecutionInfo_getNnApiVersion);
542 ASSIGN_SL_FUNCTION_TO_NNAPI(
543 SL_ANeuralNetworksDiagnosticExecutionInfo_getModelArchHash);
544 ASSIGN_SL_FUNCTION_TO_NNAPI(
545 SL_ANeuralNetworksDiagnosticExecutionInfo_getDeviceIds);
546 ASSIGN_SL_FUNCTION_TO_NNAPI(
547 SL_ANeuralNetworksDiagnosticExecutionInfo_getExecutionMode);
548 ASSIGN_SL_FUNCTION_TO_NNAPI(
549 SL_ANeuralNetworksDiagnosticExecutionInfo_getInputDataClass);
550 ASSIGN_SL_FUNCTION_TO_NNAPI(
551 SL_ANeuralNetworksDiagnosticExecutionInfo_getOutputDataClass);
552 ASSIGN_SL_FUNCTION_TO_NNAPI(
553 SL_ANeuralNetworksDiagnosticExecutionInfo_getErrorCode);
554 ASSIGN_SL_FUNCTION_TO_NNAPI(
555 SL_ANeuralNetworksDiagnosticExecutionInfo_getRuntimeExecutionTimeNanos);
556 ASSIGN_SL_FUNCTION_TO_NNAPI(
557 SL_ANeuralNetworksDiagnosticExecutionInfo_getDriverExecutionTimeNanos);
558 ASSIGN_SL_FUNCTION_TO_NNAPI(
559 SL_ANeuralNetworksDiagnosticExecutionInfo_getHardwareExecutionTimeNanos);
560 ASSIGN_SL_FUNCTION_TO_NNAPI(
561 SL_ANeuralNetworksDiagnosticExecutionInfo_isCachingEnabled);
562 ASSIGN_SL_FUNCTION_TO_NNAPI(
563 SL_ANeuralNetworksDiagnosticExecutionInfo_isControlFlowUsed);
564 ASSIGN_SL_FUNCTION_TO_NNAPI(
565 SL_ANeuralNetworksDiagnosticExecutionInfo_areDynamicTensorsUsed);
566 ASSIGN_SL_FUNCTION_TO_NNAPI(SL_ANeuralNetworksDiagnostic_registerCallbacks);
567
568 // There are several functions that are defined in the SL but are not yet used
569 // in the delegate:
570 // * ANeuralNetworksDevice_wait
571 // * ANeuralNetworksModel_setOperandValueFromModel
572 // * ANeuralNetworks_getDefaultLoopTimeout
573 // * ANeuralNetworks_getMaximumLoopTimeout
574
575 return nnapi;
576 }
577
NnApiImplementation()578 const NnApi* NnApiImplementation() {
579 static const NnApi nnapi = LoadNnApi();
580 return &nnapi;
581 }
582