1 /*
2 * Copyright (C) 2017 The Android Open Source Project
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 #define LOG_TAG "android.hardware.neuralnetworks@1.0-impl-hvx"
18
19 #include "HexagonController.h"
20
21 #define LOAD_HEXAGON_FUNCTION(name) \
22 mFn_##name = loadFunction<hexagon_nn_controller_##name##_fn>("hexagon_nn_controller_" #name);
23
24 #define CLOSE_HEXAGON_FUNCTION(name) mFn_##name = nullptr;
25
26 #define FOR_EACH_FUNCTION(MACRO) \
27 MACRO(init) \
28 MACRO(getlog) \
29 MACRO(snpprint) \
30 MACRO(set_debug_level) \
31 MACRO(prepare) \
32 MACRO(append_node) \
33 MACRO(append_const_node) \
34 MACRO(execute_new) \
35 MACRO(execute) \
36 MACRO(teardown) \
37 MACRO(get_perfinfo) \
38 MACRO(reset_perfinfo) \
39 MACRO(version) \
40 MACRO(last_execution_cycles) \
41 MACRO(GetHexagonBinaryVersion) \
42 MACRO(PrintLog) \
43 MACRO(op_name_to_id) \
44 MACRO(op_id_to_name) \
45 MACRO(disable_dcvs) \
46 MACRO(set_powersave_level) \
47 MACRO(config) \
48 MACRO(get_dsp_offset) \
49 MACRO(boost) \
50 MACRO(slow)
51
52 #define CONTROLLER_CHECK(function, ...) \
53 if (mFn_##function == nullptr) { \
54 return -1; \
55 } \
56 int err = mFn_##function(__VA_ARGS__); \
57 if (err != 0) { \
58 return err; \
59 } \
60 return 0;
61
62 namespace android {
63 namespace hardware {
64 namespace neuralnetworks {
65 namespace V1_0 {
66 namespace implementation {
67 namespace hexagon {
68
69 const char Controller::kFilename[] = "libhexagon_nn_controller.so";
70
Controller()71 Controller::Controller() {
72 openNnlib();
73 }
74
~Controller()75 Controller::~Controller() {
76 closeNnlib();
77 }
78
openNnlib()79 bool Controller::openNnlib() {
80 mHandle = dlopen(kFilename, RTLD_LAZY | RTLD_LOCAL);
81 HEXAGON_SOFT_ASSERT_NE(mHandle, 0,
82 "FAILED TO LOAD LIBRARY " /* << kFilename << ": " << dlerror()*/);
83 FOR_EACH_FUNCTION(LOAD_HEXAGON_FUNCTION)
84 return true;
85 }
86
closeNnlib()87 bool Controller::closeNnlib() {
88 FOR_EACH_FUNCTION(CLOSE_HEXAGON_FUNCTION)
89 if (mHandle != nullptr) {
90 int err = dlclose(mHandle);
91 mHandle = nullptr;
92 HEXAGON_SOFT_ASSERT_EQ(err, 0, "FAILED TO CLOSE LIBRARY " << kFilename);
93 }
94 return true;
95 }
96
resetNnlib()97 bool Controller::resetNnlib() {
98 return closeNnlib() && openNnlib();
99 }
100
getInstance()101 Controller& Controller::getInstance() {
102 static Controller instance{};
103 return instance;
104 }
105
init(hexagon_nn_nn_id * g)106 int Controller::init(hexagon_nn_nn_id* g) {
107 CONTROLLER_CHECK(init, g);
108 }
109
getlog(hexagon_nn_nn_id id,unsigned char * buf,uint32_t length)110 int Controller::getlog(hexagon_nn_nn_id id, unsigned char* buf, uint32_t length) {
111 CONTROLLER_CHECK(getlog, id, buf, length);
112 }
113
snpprint(hexagon_nn_nn_id id,unsigned char * buf,uint32_t length)114 int Controller::snpprint(hexagon_nn_nn_id id, unsigned char* buf, uint32_t length) {
115 CONTROLLER_CHECK(snpprint, id, buf, length);
116 }
117
set_debug_level(hexagon_nn_nn_id id,int level)118 int Controller::set_debug_level(hexagon_nn_nn_id id, int level) {
119 CONTROLLER_CHECK(set_debug_level, id, level);
120 }
121
prepare(hexagon_nn_nn_id id)122 int Controller::prepare(hexagon_nn_nn_id id) {
123 CONTROLLER_CHECK(prepare, id);
124 }
125
append_node(hexagon_nn_nn_id id,uint32_t node_id,op_type operation,hexagon_nn_padding_type padding,const hexagon_nn_input * inputs,uint32_t num_inputs,const hexagon_nn_output * outputs,uint32_t num_outputs)126 int Controller::append_node(hexagon_nn_nn_id id, uint32_t node_id, op_type operation,
127 hexagon_nn_padding_type padding, const hexagon_nn_input* inputs,
128 uint32_t num_inputs, const hexagon_nn_output* outputs,
129 uint32_t num_outputs) {
130 CONTROLLER_CHECK(append_node, id, node_id, operation, padding, inputs, num_inputs, outputs,
131 num_outputs);
132 }
133
append_const_node(hexagon_nn_nn_id id,uint32_t node_id,uint32_t batches,uint32_t height,uint32_t width,uint32_t depth,const uint8_t * data,uint32_t data_len)134 int Controller::append_const_node(hexagon_nn_nn_id id, uint32_t node_id, uint32_t batches,
135 uint32_t height, uint32_t width, uint32_t depth,
136 const uint8_t* data, uint32_t data_len) {
137 CONTROLLER_CHECK(append_const_node, id, node_id, batches, height, width, depth, data, data_len);
138 }
139
execute_new(hexagon_nn_nn_id id,const hexagon_nn_tensordef * inputs,uint32_t n_inputs,hexagon_nn_tensordef * outputs,uint32_t n_outputs)140 int Controller::execute_new(hexagon_nn_nn_id id, const hexagon_nn_tensordef* inputs,
141 uint32_t n_inputs, hexagon_nn_tensordef* outputs, uint32_t n_outputs) {
142 CONTROLLER_CHECK(execute_new, id, inputs, n_inputs, outputs, n_outputs);
143 }
144
execute(hexagon_nn_nn_id id,uint32_t batches_in,uint32_t height_in,uint32_t width_in,uint32_t depth_in,const uint8_t * data_in,uint32_t data_len_in,uint32_t * batches_out,uint32_t * height_out,uint32_t * width_out,uint32_t * depth_out,uint8_t * data_out,uint32_t data_out_max,uint32_t * data_out_size)145 int Controller::execute(hexagon_nn_nn_id id, uint32_t batches_in, uint32_t height_in,
146 uint32_t width_in, uint32_t depth_in, const uint8_t* data_in,
147 uint32_t data_len_in, uint32_t* batches_out, uint32_t* height_out,
148 uint32_t* width_out, uint32_t* depth_out, uint8_t* data_out,
149 uint32_t data_out_max, uint32_t* data_out_size) {
150 CONTROLLER_CHECK(execute, id, batches_in, height_in, width_in, depth_in, data_in, data_len_in,
151 batches_out, height_out, width_out, depth_out, data_out, data_out_max,
152 data_out_size);
153 }
154
teardown(hexagon_nn_nn_id id)155 int Controller::teardown(hexagon_nn_nn_id id) {
156 CONTROLLER_CHECK(teardown, id);
157 }
158
get_perfinfo(hexagon_nn_nn_id id,hexagon_nn_perfinfo * info_out,unsigned int info_out_len,unsigned int * n_items_out)159 int Controller::get_perfinfo(hexagon_nn_nn_id id, hexagon_nn_perfinfo* info_out,
160 unsigned int info_out_len, unsigned int* n_items_out) {
161 CONTROLLER_CHECK(get_perfinfo, id, info_out, info_out_len, n_items_out);
162 }
163
reset_perfinfo(hexagon_nn_nn_id id,uint32_t event)164 int Controller::reset_perfinfo(hexagon_nn_nn_id id, uint32_t event) {
165 CONTROLLER_CHECK(reset_perfinfo, id, event);
166 }
167
version(int * ver)168 int Controller::version(int* ver) {
169 CONTROLLER_CHECK(version, ver);
170 }
171
last_execution_cycles(hexagon_nn_nn_id id,unsigned int * cycles_lo,unsigned int * cycles_hi)172 int Controller::last_execution_cycles(hexagon_nn_nn_id id, unsigned int* cycles_lo,
173 unsigned int* cycles_hi) {
174 CONTROLLER_CHECK(last_execution_cycles, id, cycles_lo, cycles_hi);
175 }
176
GetHexagonBinaryVersion(int * ver)177 int Controller::GetHexagonBinaryVersion(int* ver) {
178 CONTROLLER_CHECK(GetHexagonBinaryVersion, ver);
179 }
180
PrintLog(const uint8_t * data_in,unsigned int data_in_len)181 int Controller::PrintLog(const uint8_t* data_in, unsigned int data_in_len) {
182 CONTROLLER_CHECK(PrintLog, data_in, data_in_len);
183 }
184
op_name_to_id(const char * name,unsigned int * id)185 int Controller::op_name_to_id(const char* name, unsigned int* id) {
186 CONTROLLER_CHECK(op_name_to_id, name, id);
187 }
188
op_id_to_name(const unsigned int id,char * name,int name_len)189 int Controller::op_id_to_name(const unsigned int id, char* name, int name_len) {
190 CONTROLLER_CHECK(op_id_to_name, id, name, name_len);
191 }
192
disable_dcvs()193 int Controller::disable_dcvs() {
194 CONTROLLER_CHECK(disable_dcvs);
195 }
196
set_powersave_level(unsigned int level)197 int Controller::set_powersave_level(unsigned int level) {
198 CONTROLLER_CHECK(set_powersave_level, level);
199 }
200
config()201 int Controller::config() {
202 CONTROLLER_CHECK(config);
203 }
204
get_dsp_offset()205 unsigned int Controller::get_dsp_offset() {
206 CONTROLLER_CHECK(get_dsp_offset);
207 }
208
boost(int bus_usage)209 int Controller::boost(int bus_usage) {
210 CONTROLLER_CHECK(boost, bus_usage);
211 }
212
slow()213 int Controller::slow() {
214 CONTROLLER_CHECK(slow);
215 }
216
217 } // namespace hexagon
218 } // namespace implementation
219 } // namespace V1_0
220 } // namespace neuralnetworks
221 } // namespace hardware
222 } // namespace android
223