Caffe2 - C++ API
A deep learning, cross platform ML framework
dlnnapi.c
1 
17 #include <dlfcn.h>
18 #include <stdint.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 
23 #include "dlnnapi.h"
24 
25 #define DLNNAPI_DEBUG_LOG 0
26 #if DLNNAPI_DEBUG_LOG
27 #include <android/log.h>
28 #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, "NNAPI", __VA_ARGS__)
29 #endif
30 
31 #define TAG_API_27 "\x01"
32 
33 /* clang-format off */
34 static const char function_names[] =
35  TAG_API_27 "ANeuralNetworksMemory_createFromFd\0"
36  TAG_API_27 "ANeuralNetworksMemory_free\0"
37  TAG_API_27 "ANeuralNetworksModel_create\0"
38  TAG_API_27 "ANeuralNetworksModel_finish\0"
39  TAG_API_27 "ANeuralNetworksModel_free\0"
40  TAG_API_27 "ANeuralNetworksCompilation_create\0"
41  TAG_API_27 "ANeuralNetworksCompilation_free\0"
42  TAG_API_27 "ANeuralNetworksCompilation_setPreference\0"
43  TAG_API_27 "ANeuralNetworksCompilation_finish\0"
44  TAG_API_27 "ANeuralNetworksModel_addOperand\0"
45  TAG_API_27 "ANeuralNetworksModel_setOperandValue\0"
46  TAG_API_27 "ANeuralNetworksModel_setOperandValueFromMemory\0"
47  TAG_API_27 "ANeuralNetworksModel_addOperation\0"
48  TAG_API_27 "ANeuralNetworksModel_identifyInputsAndOutputs\0"
49  TAG_API_27 "ANeuralNetworksExecution_create\0"
50  TAG_API_27 "ANeuralNetworksExecution_free\0"
51  TAG_API_27 "ANeuralNetworksExecution_setInput\0"
52  TAG_API_27 "ANeuralNetworksExecution_setInputFromMemory\0"
53  TAG_API_27 "ANeuralNetworksExecution_setOutput\0"
54  TAG_API_27 "ANeuralNetworksExecution_setOutputFromMemory\0"
55  TAG_API_27 "ANeuralNetworksExecution_startCompute\0"
56  TAG_API_27 "ANeuralNetworksEvent_wait\0"
57  TAG_API_27 "ANeuralNetworksEvent_free\0";
58 /* clang-format on */
59 
60 bool dlnnapi_load(struct dlnnapi* nnapi, uint32_t flags) {
61  if (nnapi == NULL) {
62  return false;
63  }
64 
65  memset(nnapi, 0, sizeof(struct dlnnapi));
66  if (!(flags & DLNNAPI_FLAG_VERSION_27)) {
67  /* No supported NNAPI version is requested */
68  return false;
69  }
70 
71  /* Clear libdl error state */
72  dlerror();
73 
74  nnapi->handle = dlopen("libneuralnetworks.so", RTLD_LAZY | RTLD_LOCAL);
75  if (nnapi->handle != NULL) {
76 #if DLNNAPI_DEBUG_LOG
77  LOGI("note: loaded libneuralnetworks.so\n");
78 #endif
79 
80  uint8_t version_flags = (uint8_t)(flags & DLNNAPI_FLAG_VERSION_MASK);
81  const char* function_name = function_names;
82  for (size_t i = 0; i < DLNNAPI_FUNCTION_COUNT; i++) {
83  const uint8_t tag = (uint8_t)*function_name++;
84  if ((tag & version_flags) != 0) {
85  void* function = dlsym(nnapi->handle, function_name);
86  if (function == NULL) {
87 #if DLNNAPI_DEBUG_LOG
88  LOGI(
89  "note: failed to locate %s in libneuralnetworks.so: %s\n",
90  function_name,
91  dlerror());
92 #endif
93  version_flags &= ~tag;
94  if (version_flags == 0) {
95  goto failed;
96  }
97  }
98  nnapi->functions[i] = function;
99  }
100 
101  function_name += strlen(function_name) + 1;
102  }
103  nnapi->flags = (uint32_t)version_flags;
104 
105  return true;
106  }
107 #if DLNNAPI_DEBUG_LOG
108  LOGI("note: failed to load libneuralnetworks.so: %s\n", dlerror());
109 #endif
110 
111 failed:
112  dlnnapi_free(nnapi);
113  return false;
114 }
115 
116 void dlnnapi_free(struct dlnnapi* nnapi) {
117  if (nnapi != NULL) {
118  if (nnapi->handle != NULL) {
119  /* Clear libdl error state */
120  dlerror();
121  if (dlclose(nnapi->handle) != 0) {
122 #if DLNNAPI_DEBUG_LOG
123  LOGI("note: failed to unload libneuralnetworks.so: %s\n", dlerror());
124 #endif
125  }
126  }
127  memset(nnapi, 0, sizeof(struct dlnnapi));
128  }
129 }