Home | History | Annotate | Download | only in src_soc_interface
      1 /* Copyright 2016 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 
     16 #include "soc_interface.h"
     17 
     18 #include <inttypes.h>
     19 
     20 #include "hexagon_controller.h"
     21 #include "hexagon_nn.h"
     22 #include "node_data_float.h"
     23 #include "tfm_log.h"
     24 
     25 // to demonstrate the performance difference between ION and HLOS memory
     26 // for sharing with ADSP.
     27 #define USE_ION_MEMORY
     28 
     29 const int64_t FLAG_ENABLE_INCEPTION_DUMMY_BINARY_INPUT = 0x01;
     30 const int64_t FLAG_ENABLE_EXPERIMENTAL_DEBUG = 0x02;
     31 
     32 static const int INCEPTION_VERSION = 3;
     33 
     34 static hexagon_nn_input* s_node_inputs_array;
     35 static int s_node_inputs_array_index;
     36 static int s_node_inputs_array_max_count;
     37 
     38 static hexagon_nn_output* s_node_outputs_array;
     39 static int s_node_outputs_array_index;
     40 static int s_node_outputs_array_max_count;
     41 
     42 int soc_interface_GetWrapperVersion() {
     43   TFMLOGD("GetWrapperVersion");
     44   return hexagon_controller_GetWrapperVersion();
     45 }
     46 
     47 int soc_interface_GetSocControllerVersion() {
     48   TFMLOGD("GetSocControllerVersion");
     49   return hexagon_controller_GetHexagonBinaryVersion();
     50 }
     51 
     52 bool soc_interface_Init() {
     53   TFMLOGD("Init");
     54   hexagon_controller_InitHexagonWithMaxAttributes(
     55       0, 100, INCEPTION_VERSION /* version */);
     56   hexagon_controller_GrowMemorySize();
     57   return true;
     58 }
     59 
     60 bool soc_interface_Finalize() {
     61   TFMLOGD("Finalize");
     62   hexagon_controller_DeInitHexagon();
     63   return true;
     64 }
     65 
     66 bool soc_interface_ExecuteGraph() {
     67   TFMLOGD("ExecuteGraph");
     68   if (hexagon_controller_IsDbgUseInceptionDummyDataEnabled()) {
     69     hexagon_controller_InitInputNodeDataToInceptionDummyData(
     70         INCEPTION_VERSION /* version */);
     71   }
     72   const uint32_t graph_id = hexagon_controller_GetTargetGraphId();
     73   if (graph_id == 0) {
     74     TFMLOGE("Graph id has not been set yet.");
     75     return false;
     76   }
     77   hexagon_controller_ExecuteGraphWithBuffer(graph_id, true);
     78   return true;
     79 }
     80 
     81 bool soc_interface_TeardownGraph() {
     82   TFMLOGD("TeardownGraph");
     83   const uint32_t graph_id = hexagon_controller_GetTargetGraphId();
     84   if (graph_id == 0) {
     85     TFMLOGE("Graph id has not been set yet.");
     86     return false;
     87   }
     88   hexagon_controller_Teardown(graph_id);
     89   return true;
     90 }
     91 
     92 bool soc_interface_AllocateInOutNodeBuffers(int input_count, int* input_sizes,
     93                                             int output_count,
     94                                             int* output_sizes) {
     95   TFMLOGD("AllocateInOutNodeBuffers");
     96   return hexagon_controller_AllocateMultipleNodeDataBuffers(
     97       input_count, input_sizes, output_count, output_sizes);
     98 }
     99 
    100 bool soc_interface_FillInputNodeWithPort(int port, int x, int y, int z, int d,
    101                                          const uint8_t* const buf,
    102                                          uint64_t buf_byte_size) {
    103   TFMLOGD("FillInputNodeWithPort %d", port);
    104   struct NodeDataFloat* node_data =
    105       hexagon_controller_GetInputNodeDataBuffer(port);
    106   if (buf_byte_size > node_data->max_buf_byte_size) {
    107     TFMLOGE("buf size exceeds max buf size");
    108     return false;
    109   }
    110   memcpy(node_data->byte_array_data, buf, buf_byte_size);
    111   node_data->x = x;
    112   node_data->y = y;
    113   node_data->z = z;
    114   node_data->d = d;
    115   node_data->array_byte_size = buf_byte_size;
    116   return true;
    117 }
    118 
    119 bool soc_interface_FillInputNodeFloat(int x, int y, int z, int d,
    120                                       const uint8_t* const buf,
    121                                       uint64_t buf_byte_size) {
    122   return soc_interface_FillInputNodeWithPort(
    123       /*port=*/0, x, y, z, d, buf, buf_byte_size);
    124 }
    125 
    126 // TODO(satok): Remove and use runtime version
    127 bool soc_interface_ReadOutputNodeWithPort(int port, uint8_t** buf,
    128                                           uint64_t* buf_byte_size) {
    129   TFMLOGD("ReadOutputNodeWithPort");
    130   int array_byte_size = -1;
    131   uint8_t* output_node_data_buffer =
    132       hexagon_controller_GetOutputNodeDataBuffer(port, &array_byte_size);
    133   if (array_byte_size < 0) {
    134     TFMLOGE("Failed to read data.");
    135     return false;
    136   }
    137   *buf = output_node_data_buffer;
    138   *buf_byte_size = array_byte_size;
    139   return true;
    140 }
    141 
    142 bool soc_interface_ReadOutputNodeFloat(const char* const node_name,
    143                                        uint8_t** buf, uint64_t* buf_byte_size) {
    144   return soc_interface_ReadOutputNodeWithPort(/*port=*/0, buf, buf_byte_size);
    145 }
    146 
    147 bool soc_interface_setupDummyGraph(int version) {
    148   TFMLOGD("SetupGraphDummy");
    149   const uint32_t graph_id = hexagon_controller_SetupGraph(version);
    150   if (graph_id == 0) {
    151     TFMLOGE("Failed to setup graph");
    152     return false;
    153   }
    154   hexagon_controller_SetTargetGraphId(graph_id);
    155   return true;
    156 }
    157 
    158 bool soc_interface_AllocateNodeInputAndNodeOutputArray(int total_input_count,
    159                                                        int total_output_count) {
    160   TFMLOGD("Allocate node inputs and node outputs array %d, %d",
    161           total_input_count, total_output_count);
    162   posix_memalign((void**)&s_node_inputs_array, 128,
    163                  total_input_count * sizeof(hexagon_nn_input));
    164   posix_memalign((void**)&s_node_outputs_array, 128,
    165                  total_output_count * sizeof(hexagon_nn_output));
    166   s_node_inputs_array_index = 0;
    167   s_node_outputs_array_index = 0;
    168   s_node_inputs_array_max_count = total_input_count;
    169   s_node_outputs_array_max_count = total_output_count;
    170   return true;
    171 }
    172 
    173 bool soc_interface_ReleaseNodeInputAndNodeOutputArray() {
    174   TFMLOGD("Release node inputs and node outputs array");
    175   free(s_node_inputs_array);
    176   free(s_node_outputs_array);
    177   return true;
    178 }
    179 
    180 void* soc_interface_SetOneNodeInputs(
    181     int input_count, const int* const node_id, const int* const port) {
    182   if (s_node_inputs_array_index + input_count > s_node_inputs_array_max_count) {
    183     TFMLOGE("input count exceeds limit");
    184     return 0;
    185   }
    186   for (int i = 0; i < input_count; ++i) {
    187     const int index = s_node_inputs_array_index + i;
    188     s_node_inputs_array[index].src_id = node_id[i];
    189     s_node_inputs_array[index].output_idx = port[i];
    190   }
    191   void* retval = (void*)(&s_node_inputs_array[s_node_inputs_array_index]);
    192   s_node_inputs_array_index += input_count;
    193   return retval;
    194 }
    195 
    196 void* soc_interface_SetOneNodeOutputs(int output_count, int* max_size) {
    197   if (s_node_outputs_array_index + output_count >
    198       s_node_outputs_array_max_count) {
    199     TFMLOGE("output count exceeds limit");
    200     return 0;
    201   }
    202   for (int i = 0; i < output_count; ++i) {
    203     const int index = s_node_outputs_array_index + i;
    204     s_node_outputs_array[index].max_size = max_size[i];
    205   }
    206   void* retval = (void*)(&s_node_outputs_array[s_node_outputs_array_index]);
    207   s_node_outputs_array_index += output_count;
    208   return retval;
    209 }
    210 
    211 // Append const node to the graph
    212 bool soc_interface_AppendConstNode(const char* const name, int node_id,
    213                                    int batch, int height, int width, int depth,
    214                                    const uint8_t* const data, int data_length) {
    215   const uint32_t graph_id = hexagon_controller_GetTargetGraphId();
    216   const int retval = hexagon_controller_AppendConstNode(
    217       name, graph_id, node_id, batch, height, width, depth, data, data_length);
    218   if (retval != 0) {
    219     TFMLOGE("Failed to append const node %d", node_id);
    220     return false;
    221   }
    222   return true;
    223 }
    224 
    225 // Append node to the graph
    226 bool soc_interface_AppendNode(const char* const name, int node_id, int ops_id,
    227                               int padding_id, const void* const inputs,
    228                               int inputs_count, const void* const outputs,
    229                               int outputs_count) {
    230   const uint32_t graph_id = hexagon_controller_GetTargetGraphId();
    231   const int retval = hexagon_controller_AppendNode(
    232       name, graph_id, node_id, ops_id, padding_id, (hexagon_nn_input*)inputs,
    233       inputs_count, (hexagon_nn_output*)outputs, outputs_count);
    234   if (retval != 0) {
    235     TFMLOGE("Failed to append const node %d", node_id);
    236     return false;
    237   }
    238   return true;
    239 }
    240 
    241 // Instantiate graph
    242 bool soc_interface_InstantiateGraph() {
    243   const uint32_t nn_id = hexagon_controller_InstantiateGraph();
    244   hexagon_controller_SetTargetGraphId(nn_id);
    245   return true;
    246 }
    247 
    248 // Construct graph
    249 bool soc_interface_ConstructGraph() {
    250   const uint32_t graph_id = hexagon_controller_GetTargetGraphId();
    251   return hexagon_controller_ConstructGraph(graph_id);
    252 }
    253 
    254 void soc_interface_SetLogLevel(int log_level) {
    255   SetLogLevel(log_level);
    256 }
    257 
    258 void soc_interface_SetDebugFlag(uint64_t flag) {
    259   TFMLOGI("Set debug flag 0x%" PRIx64, flag);
    260   if ((flag & FLAG_ENABLE_INCEPTION_DUMMY_BINARY_INPUT) != 0) {
    261     TFMLOGI("Enable always use panda data");
    262     hexagon_controller_EnableDbgUseInceptionDummyData(true);
    263   } else if ((flag & FLAG_ENABLE_EXPERIMENTAL_DEBUG) != 0) {
    264     SetExperimentalDebug();
    265   }
    266 }
    267