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