xref: /aosp_15_r20/external/pytorch/aten/src/ATen/nnapi/nnapi_wrapper.cpp (revision da0073e96a02ea20f0ac840b70461e3646d07c45)
1 /**
2  * Copyright (c) Facebook, Inc. and its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 // This file is generated by nnapi/codegen.py
18 #ifndef _WIN32
19 #include <dlfcn.h>
20 #endif
21 #include <ATen/nnapi/nnapi_wrapper.h>
22 #include <c10/util/Logging.h>
23 static int loaded = 0;
24 static struct nnapi_wrapper nnapi_;
25 static struct nnapi_wrapper check_nnapi_;
check__getDeviceCount(uint32_t * numDevices)26 static int check__getDeviceCount(uint32_t* numDevices) {
27   CAFFE_ENFORCE(nnapi_._getDeviceCount);
28   int ret = nnapi_._getDeviceCount(numDevices);
29   // TODO: Maybe add better logging here.
30   CAFFE_ENFORCE(
31     ret == ANEURALNETWORKS_NO_ERROR,
32     "_getDeviceCount", "failed with error ", ret
33   );
34   return ret;
35 }
check__getDevice(uint32_t devIndex,ANeuralNetworksDevice ** device)36 static int check__getDevice(uint32_t devIndex, ANeuralNetworksDevice** device) {
37   CAFFE_ENFORCE(nnapi_._getDevice);
38   int ret = nnapi_._getDevice(devIndex,device);
39   // TODO: Maybe add better logging here.
40   CAFFE_ENFORCE(
41     ret == ANEURALNETWORKS_NO_ERROR,
42     "_getDevice", "failed with error ", ret
43   );
44   return ret;
45 }
check_Device_getName(const ANeuralNetworksDevice * device,const char ** name)46 static int check_Device_getName(const ANeuralNetworksDevice* device, const char** name) {
47   CAFFE_ENFORCE(nnapi_.Device_getName);
48   int ret = nnapi_.Device_getName(device,name);
49   // TODO: Maybe add better logging here.
50   CAFFE_ENFORCE(
51     ret == ANEURALNETWORKS_NO_ERROR,
52     "Device_getName", "failed with error ", ret
53   );
54   return ret;
55 }
check_Device_getVersion(const ANeuralNetworksDevice * device,const char ** version)56 static int check_Device_getVersion(const ANeuralNetworksDevice* device, const char** version) {
57   CAFFE_ENFORCE(nnapi_.Device_getVersion);
58   int ret = nnapi_.Device_getVersion(device,version);
59   // TODO: Maybe add better logging here.
60   CAFFE_ENFORCE(
61     ret == ANEURALNETWORKS_NO_ERROR,
62     "Device_getVersion", "failed with error ", ret
63   );
64   return ret;
65 }
check_Device_getFeatureLevel(const ANeuralNetworksDevice * device,int64_t * featureLevel)66 static int check_Device_getFeatureLevel(const ANeuralNetworksDevice* device, int64_t* featureLevel) {
67   CAFFE_ENFORCE(nnapi_.Device_getFeatureLevel);
68   int ret = nnapi_.Device_getFeatureLevel(device,featureLevel);
69   // TODO: Maybe add better logging here.
70   CAFFE_ENFORCE(
71     ret == ANEURALNETWORKS_NO_ERROR,
72     "Device_getFeatureLevel", "failed with error ", ret
73   );
74   return ret;
75 }
check_Model_getSupportedOperationsForDevices(const ANeuralNetworksModel * model,const ANeuralNetworksDevice * const * devices,uint32_t numDevices,bool * supportedOps)76 static int check_Model_getSupportedOperationsForDevices( const ANeuralNetworksModel* model, const ANeuralNetworksDevice* const* devices, uint32_t numDevices, bool* supportedOps) {
77   CAFFE_ENFORCE(nnapi_.Model_getSupportedOperationsForDevices);
78   int ret = nnapi_.Model_getSupportedOperationsForDevices(model,devices,numDevices,supportedOps);
79   // TODO: Maybe add better logging here.
80   CAFFE_ENFORCE(
81     ret == ANEURALNETWORKS_NO_ERROR,
82     "Model_getSupportedOperationsForDevices", "failed with error ", ret
83   );
84   return ret;
85 }
check_Compilation_createForDevices(ANeuralNetworksModel * model,const ANeuralNetworksDevice * const * devices,uint32_t numDevices,ANeuralNetworksCompilation ** compilation)86 static int check_Compilation_createForDevices(ANeuralNetworksModel* model, const ANeuralNetworksDevice* const* devices, uint32_t numDevices, ANeuralNetworksCompilation** compilation) {
87   CAFFE_ENFORCE(nnapi_.Compilation_createForDevices);
88   int ret = nnapi_.Compilation_createForDevices(model,devices,numDevices,compilation);
89   // TODO: Maybe add better logging here.
90   CAFFE_ENFORCE(
91     ret == ANEURALNETWORKS_NO_ERROR,
92     "Compilation_createForDevices", "failed with error ", ret
93   );
94   return ret;
95 }
check_Execution_compute(ANeuralNetworksExecution * execution)96 static int check_Execution_compute(ANeuralNetworksExecution* execution) {
97   CAFFE_ENFORCE(nnapi_.Execution_compute);
98   int ret = nnapi_.Execution_compute(execution);
99   // TODO: Maybe add better logging here.
100   CAFFE_ENFORCE(
101     ret == ANEURALNETWORKS_NO_ERROR,
102     "Execution_compute", "failed with error ", ret
103   );
104   return ret;
105 }
check_Memory_createFromFd(size_t size,int protect,int fd,size_t offset,ANeuralNetworksMemory ** memory)106 static int check_Memory_createFromFd(size_t size, int protect, int fd, size_t offset, ANeuralNetworksMemory** memory) {
107   CAFFE_ENFORCE(nnapi_.Memory_createFromFd);
108   int ret = nnapi_.Memory_createFromFd(size,protect,fd,offset,memory);
109   // TODO: Maybe add better logging here.
110   CAFFE_ENFORCE(
111     ret == ANEURALNETWORKS_NO_ERROR,
112     "Memory_createFromFd", "failed with error ", ret
113   );
114   return ret;
115 }
check_Memory_free(ANeuralNetworksMemory * memory)116 static void check_Memory_free(ANeuralNetworksMemory* memory) {
117   CAFFE_ENFORCE(nnapi_.Memory_free);
118   nnapi_.Memory_free(memory);
119 }
check_Model_create(ANeuralNetworksModel ** model)120 static int check_Model_create(ANeuralNetworksModel** model) {
121   CAFFE_ENFORCE(nnapi_.Model_create);
122   int ret = nnapi_.Model_create(model);
123   // TODO: Maybe add better logging here.
124   CAFFE_ENFORCE(
125     ret == ANEURALNETWORKS_NO_ERROR,
126     "Model_create", "failed with error ", ret
127   );
128   return ret;
129 }
check_Model_free(ANeuralNetworksModel * model)130 static void check_Model_free(ANeuralNetworksModel* model) {
131   CAFFE_ENFORCE(nnapi_.Model_free);
132   nnapi_.Model_free(model);
133 }
check_Model_finish(ANeuralNetworksModel * model)134 static int check_Model_finish(ANeuralNetworksModel* model) {
135   CAFFE_ENFORCE(nnapi_.Model_finish);
136   int ret = nnapi_.Model_finish(model);
137   // TODO: Maybe add better logging here.
138   CAFFE_ENFORCE(
139     ret == ANEURALNETWORKS_NO_ERROR,
140     "Model_finish", "failed with error ", ret
141   );
142   return ret;
143 }
check_Model_addOperand(ANeuralNetworksModel * model,const ANeuralNetworksOperandType * type)144 static int check_Model_addOperand(ANeuralNetworksModel* model, const ANeuralNetworksOperandType* type) {
145   CAFFE_ENFORCE(nnapi_.Model_addOperand);
146   int ret = nnapi_.Model_addOperand(model,type);
147   // TODO: Maybe add better logging here.
148   CAFFE_ENFORCE(
149     ret == ANEURALNETWORKS_NO_ERROR,
150     "Model_addOperand", "failed with error ", ret
151   );
152   return ret;
153 }
check_Model_setOperandValue(ANeuralNetworksModel * model,int32_t index,const void * buffer,size_t length)154 static int check_Model_setOperandValue(ANeuralNetworksModel* model, int32_t index, const void* buffer, size_t length) {
155   CAFFE_ENFORCE(nnapi_.Model_setOperandValue);
156   int ret = nnapi_.Model_setOperandValue(model,index,buffer,length);
157   // TODO: Maybe add better logging here.
158   CAFFE_ENFORCE(
159     ret == ANEURALNETWORKS_NO_ERROR,
160     "Model_setOperandValue", "failed with error ", ret
161   );
162   return ret;
163 }
check_Model_setOperandValueFromMemory(ANeuralNetworksModel * model,int32_t index,const ANeuralNetworksMemory * memory,size_t offset,size_t length)164 static int check_Model_setOperandValueFromMemory(ANeuralNetworksModel* model, int32_t index, const ANeuralNetworksMemory* memory, size_t offset, size_t length) {
165   CAFFE_ENFORCE(nnapi_.Model_setOperandValueFromMemory);
166   int ret = nnapi_.Model_setOperandValueFromMemory(model,index,memory,offset,length);
167   // TODO: Maybe add better logging here.
168   CAFFE_ENFORCE(
169     ret == ANEURALNETWORKS_NO_ERROR,
170     "Model_setOperandValueFromMemory", "failed with error ", ret
171   );
172   return ret;
173 }
check_Model_addOperation(ANeuralNetworksModel * model,ANeuralNetworksOperationType type,uint32_t inputCount,const uint32_t * inputs,uint32_t outputCount,const uint32_t * outputs)174 static int check_Model_addOperation(ANeuralNetworksModel* model, ANeuralNetworksOperationType type, uint32_t inputCount, const uint32_t* inputs, uint32_t outputCount, const uint32_t* outputs) {
175   CAFFE_ENFORCE(nnapi_.Model_addOperation);
176   int ret = nnapi_.Model_addOperation(model,type,inputCount,inputs,outputCount,outputs);
177   // TODO: Maybe add better logging here.
178   CAFFE_ENFORCE(
179     ret == ANEURALNETWORKS_NO_ERROR,
180     "Model_addOperation", "failed with error ", ret
181   );
182   return ret;
183 }
check_Model_identifyInputsAndOutputs(ANeuralNetworksModel * model,uint32_t inputCount,const uint32_t * inputs,uint32_t outputCount,const uint32_t * outputs)184 static int check_Model_identifyInputsAndOutputs(ANeuralNetworksModel* model, uint32_t inputCount, const uint32_t* inputs, uint32_t outputCount, const uint32_t* outputs) {
185   CAFFE_ENFORCE(nnapi_.Model_identifyInputsAndOutputs);
186   int ret = nnapi_.Model_identifyInputsAndOutputs(model,inputCount,inputs,outputCount,outputs);
187   // TODO: Maybe add better logging here.
188   CAFFE_ENFORCE(
189     ret == ANEURALNETWORKS_NO_ERROR,
190     "Model_identifyInputsAndOutputs", "failed with error ", ret
191   );
192   return ret;
193 }
check_Model_relaxComputationFloat32toFloat16(ANeuralNetworksModel * model,bool allow)194 static int check_Model_relaxComputationFloat32toFloat16(ANeuralNetworksModel* model, bool allow) {
195   CAFFE_ENFORCE(nnapi_.Model_relaxComputationFloat32toFloat16);
196   int ret = nnapi_.Model_relaxComputationFloat32toFloat16(model,allow);
197   // TODO: Maybe add better logging here.
198   CAFFE_ENFORCE(
199     ret == ANEURALNETWORKS_NO_ERROR,
200     "Model_relaxComputationFloat32toFloat16", "failed with error ", ret
201   );
202   return ret;
203 }
check_Compilation_create(ANeuralNetworksModel * model,ANeuralNetworksCompilation ** compilation)204 static int check_Compilation_create(ANeuralNetworksModel* model, ANeuralNetworksCompilation** compilation) {
205   CAFFE_ENFORCE(nnapi_.Compilation_create);
206   int ret = nnapi_.Compilation_create(model,compilation);
207   // TODO: Maybe add better logging here.
208   CAFFE_ENFORCE(
209     ret == ANEURALNETWORKS_NO_ERROR,
210     "Compilation_create", "failed with error ", ret
211   );
212   return ret;
213 }
check_Compilation_free(ANeuralNetworksCompilation * compilation)214 static void check_Compilation_free(ANeuralNetworksCompilation* compilation) {
215   CAFFE_ENFORCE(nnapi_.Compilation_free);
216   nnapi_.Compilation_free(compilation);
217 }
check_Compilation_setPreference(ANeuralNetworksCompilation * compilation,int32_t preference)218 static int check_Compilation_setPreference(ANeuralNetworksCompilation* compilation, int32_t preference) {
219   CAFFE_ENFORCE(nnapi_.Compilation_setPreference);
220   int ret = nnapi_.Compilation_setPreference(compilation,preference);
221   // TODO: Maybe add better logging here.
222   CAFFE_ENFORCE(
223     ret == ANEURALNETWORKS_NO_ERROR,
224     "Compilation_setPreference", "failed with error ", ret
225   );
226   return ret;
227 }
check_Compilation_finish(ANeuralNetworksCompilation * compilation)228 static int check_Compilation_finish(ANeuralNetworksCompilation* compilation) {
229   CAFFE_ENFORCE(nnapi_.Compilation_finish);
230   int ret = nnapi_.Compilation_finish(compilation);
231   // TODO: Maybe add better logging here.
232   CAFFE_ENFORCE(
233     ret == ANEURALNETWORKS_NO_ERROR,
234     "Compilation_finish", "failed with error ", ret
235   );
236   return ret;
237 }
check_Execution_create(ANeuralNetworksCompilation * compilation,ANeuralNetworksExecution ** execution)238 static int check_Execution_create(ANeuralNetworksCompilation* compilation, ANeuralNetworksExecution** execution) {
239   CAFFE_ENFORCE(nnapi_.Execution_create);
240   int ret = nnapi_.Execution_create(compilation,execution);
241   // TODO: Maybe add better logging here.
242   CAFFE_ENFORCE(
243     ret == ANEURALNETWORKS_NO_ERROR,
244     "Execution_create", "failed with error ", ret
245   );
246   return ret;
247 }
check_Execution_free(ANeuralNetworksExecution * execution)248 static void check_Execution_free(ANeuralNetworksExecution* execution) {
249   CAFFE_ENFORCE(nnapi_.Execution_free);
250   nnapi_.Execution_free(execution);
251 }
check_Execution_setInput(ANeuralNetworksExecution * execution,int32_t index,const ANeuralNetworksOperandType * type,const void * buffer,size_t length)252 static int check_Execution_setInput(ANeuralNetworksExecution* execution, int32_t index, const ANeuralNetworksOperandType* type, const void* buffer, size_t length) {
253   CAFFE_ENFORCE(nnapi_.Execution_setInput);
254   int ret = nnapi_.Execution_setInput(execution,index,type,buffer,length);
255   // TODO: Maybe add better logging here.
256   CAFFE_ENFORCE(
257     ret == ANEURALNETWORKS_NO_ERROR,
258     "Execution_setInput", "failed with error ", ret
259   );
260   return ret;
261 }
check_Execution_setInputFromMemory(ANeuralNetworksExecution * execution,int32_t index,const ANeuralNetworksOperandType * type,const ANeuralNetworksMemory * memory,size_t offset,size_t length)262 static int check_Execution_setInputFromMemory(ANeuralNetworksExecution* execution, int32_t index, const ANeuralNetworksOperandType* type, const ANeuralNetworksMemory* memory, size_t offset, size_t length) {
263   CAFFE_ENFORCE(nnapi_.Execution_setInputFromMemory);
264   int ret = nnapi_.Execution_setInputFromMemory(execution,index,type,memory,offset,length);
265   // TODO: Maybe add better logging here.
266   CAFFE_ENFORCE(
267     ret == ANEURALNETWORKS_NO_ERROR,
268     "Execution_setInputFromMemory", "failed with error ", ret
269   );
270   return ret;
271 }
check_Execution_setOutput(ANeuralNetworksExecution * execution,int32_t index,const ANeuralNetworksOperandType * type,void * buffer,size_t length)272 static int check_Execution_setOutput(ANeuralNetworksExecution* execution, int32_t index, const ANeuralNetworksOperandType* type, void* buffer, size_t length) {
273   CAFFE_ENFORCE(nnapi_.Execution_setOutput);
274   int ret = nnapi_.Execution_setOutput(execution,index,type,buffer,length);
275   // TODO: Maybe add better logging here.
276   CAFFE_ENFORCE(
277     ret == ANEURALNETWORKS_NO_ERROR,
278     "Execution_setOutput", "failed with error ", ret
279   );
280   return ret;
281 }
check_Execution_setOutputFromMemory(ANeuralNetworksExecution * execution,int32_t index,const ANeuralNetworksOperandType * type,const ANeuralNetworksMemory * memory,size_t offset,size_t length)282 static int check_Execution_setOutputFromMemory(ANeuralNetworksExecution* execution, int32_t index, const ANeuralNetworksOperandType* type, const ANeuralNetworksMemory* memory, size_t offset, size_t length) {
283   CAFFE_ENFORCE(nnapi_.Execution_setOutputFromMemory);
284   int ret = nnapi_.Execution_setOutputFromMemory(execution,index,type,memory,offset,length);
285   // TODO: Maybe add better logging here.
286   CAFFE_ENFORCE(
287     ret == ANEURALNETWORKS_NO_ERROR,
288     "Execution_setOutputFromMemory", "failed with error ", ret
289   );
290   return ret;
291 }
check_Execution_startCompute(ANeuralNetworksExecution * execution,ANeuralNetworksEvent ** event)292 static int check_Execution_startCompute(ANeuralNetworksExecution* execution, ANeuralNetworksEvent** event) {
293   CAFFE_ENFORCE(nnapi_.Execution_startCompute);
294   int ret = nnapi_.Execution_startCompute(execution,event);
295   // TODO: Maybe add better logging here.
296   CAFFE_ENFORCE(
297     ret == ANEURALNETWORKS_NO_ERROR,
298     "Execution_startCompute", "failed with error ", ret
299   );
300   return ret;
301 }
check_Event_wait(ANeuralNetworksEvent * event)302 static int check_Event_wait(ANeuralNetworksEvent* event) {
303   CAFFE_ENFORCE(nnapi_.Event_wait);
304   int ret = nnapi_.Event_wait(event);
305   // TODO: Maybe add better logging here.
306   CAFFE_ENFORCE(
307     ret == ANEURALNETWORKS_NO_ERROR,
308     "Event_wait", "failed with error ", ret
309   );
310   return ret;
311 }
check_Event_free(ANeuralNetworksEvent * event)312 static void check_Event_free(ANeuralNetworksEvent* event) {
313   CAFFE_ENFORCE(nnapi_.Event_free);
314   nnapi_.Event_free(event);
315 }
check_Execution_getOutputOperandRank(ANeuralNetworksExecution * execution,int32_t index,uint32_t * rank)316 static int check_Execution_getOutputOperandRank(ANeuralNetworksExecution* execution, int32_t index, uint32_t* rank) {
317   CAFFE_ENFORCE(nnapi_.Execution_getOutputOperandRank);
318   int ret = nnapi_.Execution_getOutputOperandRank(execution,index,rank);
319   // TODO: Maybe add better logging here.
320   CAFFE_ENFORCE(
321     ret == ANEURALNETWORKS_NO_ERROR,
322     "Execution_getOutputOperandRank", "failed with error ", ret
323   );
324   return ret;
325 }
check_Execution_getOutputOperandDimensions(ANeuralNetworksExecution * execution,int32_t index,uint32_t * dimensions)326 static int check_Execution_getOutputOperandDimensions(ANeuralNetworksExecution* execution, int32_t index, uint32_t* dimensions) {
327   CAFFE_ENFORCE(nnapi_.Execution_getOutputOperandDimensions);
328   int ret = nnapi_.Execution_getOutputOperandDimensions(execution,index,dimensions);
329   // TODO: Maybe add better logging here.
330   CAFFE_ENFORCE(
331     ret == ANEURALNETWORKS_NO_ERROR,
332     "Execution_getOutputOperandDimensions", "failed with error ", ret
333   );
334   return ret;
335 }
nnapi_wrapper_load(struct nnapi_wrapper ** nnapi,struct nnapi_wrapper ** check_nnapi)336 void nnapi_wrapper_load(struct nnapi_wrapper** nnapi, struct nnapi_wrapper** check_nnapi) {
337 #ifdef _WIN32
338   TORCH_CHECK(false, "Running NNAPI models is not supported on Windows.");
339 #else
340   if (!loaded) {
341     // Clear error flag.
342     dlerror();
343     void* handle = dlopen("libneuralnetworks.so", RTLD_LAZY | RTLD_LOCAL);
344     CAFFE_ENFORCE(handle, "Failed to load libneuralnetworks.so ", dlerror());
345     *(void**)&nnapi_._getDeviceCount = dlsym(handle, "ANeuralNetworks_getDeviceCount");
346     check_nnapi_._getDeviceCount = check__getDeviceCount;
347     *(void**)&nnapi_._getDevice = dlsym(handle, "ANeuralNetworks_getDevice");
348     check_nnapi_._getDevice = check__getDevice;
349     *(void**)&nnapi_.Device_getName = dlsym(handle, "ANeuralNetworksDevice_getName");
350     check_nnapi_.Device_getName = check_Device_getName;
351     *(void**)&nnapi_.Device_getVersion = dlsym(handle, "ANeuralNetworksDevice_getVersion");
352     check_nnapi_.Device_getVersion = check_Device_getVersion;
353     *(void**)&nnapi_.Device_getFeatureLevel = dlsym(handle, "ANeuralNetworksDevice_getFeatureLevel");
354     check_nnapi_.Device_getFeatureLevel = check_Device_getFeatureLevel;
355     *(void**)&nnapi_.Model_getSupportedOperationsForDevices = dlsym(handle, "ANeuralNetworksModel_getSupportedOperationsForDevices");
356     check_nnapi_.Model_getSupportedOperationsForDevices = check_Model_getSupportedOperationsForDevices;
357     *(void**)&nnapi_.Compilation_createForDevices = dlsym(handle, "ANeuralNetworksCompilation_createForDevices");
358     check_nnapi_.Compilation_createForDevices = check_Compilation_createForDevices;
359     *(void**)&nnapi_.Execution_compute = dlsym(handle, "ANeuralNetworksExecution_compute");
360     check_nnapi_.Execution_compute = check_Execution_compute;
361     *(void**)&nnapi_.Memory_createFromFd = dlsym(handle, "ANeuralNetworksMemory_createFromFd");
362     check_nnapi_.Memory_createFromFd = check_Memory_createFromFd;
363     *(void**)&nnapi_.Memory_free = dlsym(handle, "ANeuralNetworksMemory_free");
364     check_nnapi_.Memory_free = check_Memory_free;
365     *(void**)&nnapi_.Model_create = dlsym(handle, "ANeuralNetworksModel_create");
366     check_nnapi_.Model_create = check_Model_create;
367     *(void**)&nnapi_.Model_free = dlsym(handle, "ANeuralNetworksModel_free");
368     check_nnapi_.Model_free = check_Model_free;
369     *(void**)&nnapi_.Model_finish = dlsym(handle, "ANeuralNetworksModel_finish");
370     check_nnapi_.Model_finish = check_Model_finish;
371     *(void**)&nnapi_.Model_addOperand = dlsym(handle, "ANeuralNetworksModel_addOperand");
372     check_nnapi_.Model_addOperand = check_Model_addOperand;
373     *(void**)&nnapi_.Model_setOperandValue = dlsym(handle, "ANeuralNetworksModel_setOperandValue");
374     check_nnapi_.Model_setOperandValue = check_Model_setOperandValue;
375     *(void**)&nnapi_.Model_setOperandValueFromMemory = dlsym(handle, "ANeuralNetworksModel_setOperandValueFromMemory");
376     check_nnapi_.Model_setOperandValueFromMemory = check_Model_setOperandValueFromMemory;
377     *(void**)&nnapi_.Model_addOperation = dlsym(handle, "ANeuralNetworksModel_addOperation");
378     check_nnapi_.Model_addOperation = check_Model_addOperation;
379     *(void**)&nnapi_.Model_identifyInputsAndOutputs = dlsym(handle, "ANeuralNetworksModel_identifyInputsAndOutputs");
380     check_nnapi_.Model_identifyInputsAndOutputs = check_Model_identifyInputsAndOutputs;
381     *(void**)&nnapi_.Model_relaxComputationFloat32toFloat16 = dlsym(handle, "ANeuralNetworksModel_relaxComputationFloat32toFloat16");
382     check_nnapi_.Model_relaxComputationFloat32toFloat16 = check_Model_relaxComputationFloat32toFloat16;
383     *(void**)&nnapi_.Compilation_create = dlsym(handle, "ANeuralNetworksCompilation_create");
384     check_nnapi_.Compilation_create = check_Compilation_create;
385     *(void**)&nnapi_.Compilation_free = dlsym(handle, "ANeuralNetworksCompilation_free");
386     check_nnapi_.Compilation_free = check_Compilation_free;
387     *(void**)&nnapi_.Compilation_setPreference = dlsym(handle, "ANeuralNetworksCompilation_setPreference");
388     check_nnapi_.Compilation_setPreference = check_Compilation_setPreference;
389     *(void**)&nnapi_.Compilation_finish = dlsym(handle, "ANeuralNetworksCompilation_finish");
390     check_nnapi_.Compilation_finish = check_Compilation_finish;
391     *(void**)&nnapi_.Execution_create = dlsym(handle, "ANeuralNetworksExecution_create");
392     check_nnapi_.Execution_create = check_Execution_create;
393     *(void**)&nnapi_.Execution_free = dlsym(handle, "ANeuralNetworksExecution_free");
394     check_nnapi_.Execution_free = check_Execution_free;
395     *(void**)&nnapi_.Execution_setInput = dlsym(handle, "ANeuralNetworksExecution_setInput");
396     check_nnapi_.Execution_setInput = check_Execution_setInput;
397     *(void**)&nnapi_.Execution_setInputFromMemory = dlsym(handle, "ANeuralNetworksExecution_setInputFromMemory");
398     check_nnapi_.Execution_setInputFromMemory = check_Execution_setInputFromMemory;
399     *(void**)&nnapi_.Execution_setOutput = dlsym(handle, "ANeuralNetworksExecution_setOutput");
400     check_nnapi_.Execution_setOutput = check_Execution_setOutput;
401     *(void**)&nnapi_.Execution_setOutputFromMemory = dlsym(handle, "ANeuralNetworksExecution_setOutputFromMemory");
402     check_nnapi_.Execution_setOutputFromMemory = check_Execution_setOutputFromMemory;
403     *(void**)&nnapi_.Execution_startCompute = dlsym(handle, "ANeuralNetworksExecution_startCompute");
404     check_nnapi_.Execution_startCompute = check_Execution_startCompute;
405     *(void**)&nnapi_.Event_wait = dlsym(handle, "ANeuralNetworksEvent_wait");
406     check_nnapi_.Event_wait = check_Event_wait;
407     *(void**)&nnapi_.Event_free = dlsym(handle, "ANeuralNetworksEvent_free");
408     check_nnapi_.Event_free = check_Event_free;
409     *(void**)&nnapi_.Execution_getOutputOperandRank = dlsym(handle, "ANeuralNetworksExecution_getOutputOperandRank");
410     check_nnapi_.Execution_getOutputOperandRank = check_Execution_getOutputOperandRank;
411     *(void**)&nnapi_.Execution_getOutputOperandDimensions = dlsym(handle, "ANeuralNetworksExecution_getOutputOperandDimensions");
412     check_nnapi_.Execution_getOutputOperandDimensions = check_Execution_getOutputOperandDimensions;
413     loaded = 1;
414   }
415   *nnapi = &nnapi_;
416   *check_nnapi = &check_nnapi_;
417 #endif
418 }
419