xref: /aosp_15_r20/external/tensorflow/tensorflow/lite/nnapi/nnapi_implementation.cc (revision b6fb3261f9314811a0f4371741dbb8839866f948)
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