• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2019 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 #include "tensorflow/lite/delegates/hexagon/hexagon_delegate.h"
16 
17 #include <memory>
18 #include <string>
19 #include <vector>
20 
21 #include "tensorflow/lite/c/common.h"
22 #include "tensorflow/lite/context_util.h"
23 #include "tensorflow/lite/delegates/hexagon/hexagon_delegate_kernel.h"
24 #include "tensorflow/lite/delegates/hexagon/hexagon_implementation.h"
25 #include "tensorflow/lite/delegates/hexagon/utils.h"
26 #include "tensorflow/lite/delegates/utils/simple_delegate.h"
27 #include "tensorflow/lite/minimal_logging.h"
28 
29 namespace tflite {
30 namespace {
31 // Should be > 0. > 16 causes problems.
32 constexpr int kMaxHexagonGraphs = 4;
33 constexpr int kMaxMaxHexagonGraphs = 16;
34 constexpr int kMinNodesPerHexagonGraph = 2;
35 
36 class HexagonDelegate : public SimpleDelegateInterface {
37  public:
HexagonDelegate(const TfLiteHexagonDelegateOptions * params)38   explicit HexagonDelegate(const TfLiteHexagonDelegateOptions* params)
39       : params_(params != nullptr ? *params
40                                   : TfLiteHexagonDelegateOptions({0})) {
41     if (params_.max_delegated_partitions <= 0) {
42       params_.max_delegated_partitions = kMaxHexagonGraphs;
43     } else if (params_.max_delegated_partitions > kMaxMaxHexagonGraphs) {
44       TFLITE_LOG_PROD(tflite::TFLITE_LOG_WARNING,
45                       "Hexagon delegate: cannot have this many %d partitions, "
46                       "and will cap to at most %d partitions.\n",
47                       params_.max_delegated_partitions, kMaxMaxHexagonGraphs);
48       params_.max_delegated_partitions = kMaxMaxHexagonGraphs;
49     }
50     if (params_.min_nodes_per_partition <= 0) {
51       params_.min_nodes_per_partition = kMinNodesPerHexagonGraph;
52     }
53   }
54 
IsNodeSupportedByDelegate(const TfLiteRegistration * registration,const TfLiteNode * node,TfLiteContext * context) const55   bool IsNodeSupportedByDelegate(const TfLiteRegistration* registration,
56                                  const TfLiteNode* node,
57                                  TfLiteContext* context) const override {
58     return IsNodeSupportedByHexagon(registration, node, context);
59   }
60 
Initialize(TfLiteContext * context)61   TfLiteStatus Initialize(TfLiteContext* context) override { return kTfLiteOk; }
62 
Name() const63   const char* Name() const override { return "TfLiteHexagonDelegate"; }
64 
CreateDelegateKernelInterface()65   std::unique_ptr<SimpleDelegateKernelInterface> CreateDelegateKernelInterface()
66       override {
67     return std::make_unique<HexagonDelegateKernel>(params_);
68   }
69 
DelegateOptions() const70   SimpleDelegateInterface::Options DelegateOptions() const override {
71     auto options = SimpleDelegateInterface::Options();
72     options.max_delegated_partitions = params_.max_delegated_partitions;
73     options.min_nodes_per_partition = params_.min_nodes_per_partition;
74     return options;
75   }
76 
VerifyDelegate()77   bool VerifyDelegate() {
78     auto* hexagon_nn = HexagonNNImplementation();
79     if (hexagon_nn == nullptr) {
80       return false;
81     }
82     if (hexagon_nn->hexagon_nn_version != nullptr &&
83         hexagon_nn->hexagon_nn_hexagon_interface_version) {
84       int hexagon_nn_version = -1;
85       int hexagon_interface_version =
86           hexagon_nn->hexagon_nn_hexagon_interface_version();
87       if (hexagon_nn->hexagon_nn_version(&hexagon_nn_version) != 0) {
88         TFLITE_LOG_PROD(tflite::TFLITE_LOG_WARNING,
89                         "Failed to fetch Hexagon NN version. This might be "
90                         "because you're using incompatible versions of "
91                         "libhexagon_interface and libhexagon_nn_skel. "
92                         "You must use compatible versions. "
93                         "Refer to Tensorflow Lite Hexagon Delegate Guide.");
94         return false;
95       }
96       if (hexagon_nn_version != hexagon_interface_version) {
97         TFLITE_LOG_PROD(
98             tflite::TFLITE_LOG_WARNING,
99             "Incompatible versions between interface library and "
100             "libhexagon_skel %d vs %d. You must use compatible versions. "
101             "Refer to Tensorflow Lite Hexagon Delegate Guide.",
102             hexagon_interface_version, hexagon_nn_version);
103         return false;
104       }
105     }
106     return hexagon_nn->hexagon_nn_is_device_supported &&
107            hexagon_nn->hexagon_nn_is_device_supported();
108   }
109 
110  private:
111   TfLiteHexagonDelegateOptions params_;
112 };
113 
114 }  // namespace
115 }  // namespace tflite
116 
TfLiteHexagonDelegateCreate(const TfLiteHexagonDelegateOptions * options)117 TfLiteDelegate* TfLiteHexagonDelegateCreate(
118     const TfLiteHexagonDelegateOptions* options) {
119   auto hexagon_delegate_interface =
120       std::make_unique<tflite::HexagonDelegate>(options);
121   if (!hexagon_delegate_interface->VerifyDelegate()) {
122     TFLITE_LOG_PROD_ONCE(tflite::TFLITE_LOG_INFO,
123                          "Hexagon Delegate is not supported.\n");
124     return nullptr;
125   }
126   auto* initialized_delegate =
127       tflite::TfLiteDelegateFactory::CreateSimpleDelegate(
128           std::move(hexagon_delegate_interface));
129   if (options->enable_dynamic_batch_size) {
130     initialized_delegate->flags |= kTfLiteDelegateFlagsAllowDynamicTensors;
131   }
132   return initialized_delegate;
133 }
134 
TfLiteHexagonDelegateOptionsDefault()135 TfLiteHexagonDelegateOptions TfLiteHexagonDelegateOptionsDefault() {
136   TfLiteHexagonDelegateOptions result{0};
137   return result;
138 }
139 
TfLiteHexagonDelegateDelete(TfLiteDelegate * delegate)140 void TfLiteHexagonDelegateDelete(TfLiteDelegate* delegate) {
141   tflite::TfLiteDelegateFactory::DeleteSimpleDelegate(delegate);
142 }
143 
TfLiteHexagonInit()144 void TfLiteHexagonInit() { tflite::HexagonDelegateKernel::InitState(); }
145 
TfLiteHexagonInitWithPath(const char * lib_directory_path)146 void TfLiteHexagonInitWithPath(const char* lib_directory_path) {
147   if (lib_directory_path != nullptr) {
148     std::string env_var_value = lib_directory_path;
149     env_var_value += ";/system/lib/rfsa/adsp;/system/vendor/lib/rfsa/adsp;/dsp";
150     setenv("ADSP_LIBRARY_PATH", env_var_value.c_str(), 1 /* overwrite */);
151   }
152   tflite::HexagonDelegateKernel::InitState();
153 }
TfLiteHexagonTearDown()154 void TfLiteHexagonTearDown() { tflite::HexagonDelegateKernel::Teardown(); }
155