• 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 
16 #include "tensorflow/lite/tools/evaluation/utils.h"
17 
18 #if !defined(_WIN32)
19 #include <dirent.h>
20 #endif
21 #include <sys/stat.h>
22 
23 #include <algorithm>
24 #include <fstream>
25 #include <memory>
26 #include <string>
27 
28 namespace tflite {
29 namespace evaluation {
30 
31 namespace {
32 
CreateNullDelegate()33 TfLiteDelegatePtr CreateNullDelegate() {
34   return TfLiteDelegatePtr(nullptr, [](TfLiteDelegate*) {});
35 }
36 
37 }  // namespace
38 
StripTrailingSlashes(const std::string & path)39 std::string StripTrailingSlashes(const std::string& path) {
40   int end = path.size();
41   while (end > 0 && path[end - 1] == '/') {
42     end--;
43   }
44   return path.substr(0, end);
45 }
46 
ReadFileLines(const std::string & file_path,std::vector<std::string> * lines_output)47 bool ReadFileLines(const std::string& file_path,
48                    std::vector<std::string>* lines_output) {
49   if (!lines_output) {
50     return false;
51   }
52   std::ifstream stream(file_path.c_str());
53   if (!stream) {
54     return false;
55   }
56   std::string line;
57   while (std::getline(stream, line)) {
58     lines_output->push_back(line);
59   }
60   return true;
61 }
62 
63 #if !defined(_WIN32)
GetSortedFileNames(const std::string & directory,std::vector<std::string> * result,const std::unordered_set<std::string> & extensions)64 TfLiteStatus GetSortedFileNames(
65     const std::string& directory, std::vector<std::string>* result,
66     const std::unordered_set<std::string>& extensions) {
67   DIR* dir;
68   struct dirent* ent;
69   if (result == nullptr) {
70     return kTfLiteError;
71   }
72   result->clear();
73   std::string dir_path = StripTrailingSlashes(directory);
74   if ((dir = opendir(dir_path.c_str())) != nullptr) {
75     while ((ent = readdir(dir)) != nullptr) {
76       if (ent->d_type == DT_DIR) continue;
77       std::string filename(std::string(ent->d_name));
78       size_t lastdot = filename.find_last_of('.');
79       std::string ext = lastdot != std::string::npos ? filename.substr(lastdot)
80                                                      : std::string();
81       std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
82       if (!extensions.empty() && extensions.find(ext) == extensions.end()) {
83         continue;
84       }
85       result->emplace_back(dir_path + "/" + filename);
86     }
87     closedir(dir);
88   } else {
89     return kTfLiteError;
90   }
91   std::sort(result->begin(), result->end());
92   return kTfLiteOk;
93 }
94 #endif
95 
96 // TODO(b/138448769): Migrate delegate helper APIs to lite/testing.
CreateNNAPIDelegate()97 TfLiteDelegatePtr CreateNNAPIDelegate() {
98 #if defined(__ANDROID__)
99   return TfLiteDelegatePtr(
100       NnApiDelegate(),
101       // NnApiDelegate() returns a singleton, so provide a no-op deleter.
102       [](TfLiteDelegate*) {});
103 #else
104   return CreateNullDelegate();
105 #endif  // defined(__ANDROID__)
106 }
107 
CreateNNAPIDelegate(StatefulNnApiDelegate::Options options)108 TfLiteDelegatePtr CreateNNAPIDelegate(StatefulNnApiDelegate::Options options) {
109 #if defined(__ANDROID__)
110   return TfLiteDelegatePtr(
111       new StatefulNnApiDelegate(options), [](TfLiteDelegate* delegate) {
112         delete reinterpret_cast<StatefulNnApiDelegate*>(delegate);
113       });
114 #else
115   return CreateNullDelegate();
116 #endif  // defined(__ANDROID__)
117 }
118 
119 #if TFLITE_SUPPORTS_GPU_DELEGATE
CreateGPUDelegate(TfLiteGpuDelegateOptionsV2 * options)120 TfLiteDelegatePtr CreateGPUDelegate(TfLiteGpuDelegateOptionsV2* options) {
121   return TfLiteDelegatePtr(TfLiteGpuDelegateV2Create(options),
122                            &TfLiteGpuDelegateV2Delete);
123 }
124 #endif  // TFLITE_SUPPORTS_GPU_DELEGATE
125 
CreateGPUDelegate()126 TfLiteDelegatePtr CreateGPUDelegate() {
127 #if TFLITE_SUPPORTS_GPU_DELEGATE
128   TfLiteGpuDelegateOptionsV2 options = TfLiteGpuDelegateOptionsV2Default();
129   options.inference_priority1 = TFLITE_GPU_INFERENCE_PRIORITY_MIN_LATENCY;
130   options.inference_preference =
131       TFLITE_GPU_INFERENCE_PREFERENCE_SUSTAINED_SPEED;
132 
133   return CreateGPUDelegate(&options);
134 #else
135   return CreateNullDelegate();
136 #endif  // TFLITE_SUPPORTS_GPU_DELEGATE
137 }
138 
CreateHexagonDelegate(const std::string & library_directory_path,bool profiling)139 TfLiteDelegatePtr CreateHexagonDelegate(
140     const std::string& library_directory_path, bool profiling) {
141 #if defined(__ANDROID__) && (defined(__arm__) || defined(__aarch64__))
142   TfLiteHexagonDelegateOptions options = {0};
143   options.print_graph_profile = profiling;
144   return CreateHexagonDelegate(&options, library_directory_path);
145 #else
146   return CreateNullDelegate();
147 #endif  // defined(__ANDROID__)
148 }
149 
150 #if defined(__ANDROID__) && (defined(__arm__) || defined(__aarch64__))
CreateHexagonDelegate(const TfLiteHexagonDelegateOptions * options,const std::string & library_directory_path)151 TfLiteDelegatePtr CreateHexagonDelegate(
152     const TfLiteHexagonDelegateOptions* options,
153     const std::string& library_directory_path) {
154   if (library_directory_path.empty()) {
155     TfLiteHexagonInit();
156   } else {
157     TfLiteHexagonInitWithPath(library_directory_path.c_str());
158   }
159 
160   TfLiteDelegate* delegate = TfLiteHexagonDelegateCreate(options);
161   if (!delegate) {
162     TfLiteHexagonTearDown();
163     return CreateNullDelegate();
164   }
165   return TfLiteDelegatePtr(delegate, [](TfLiteDelegate* delegate) {
166     TfLiteHexagonDelegateDelete(delegate);
167     TfLiteHexagonTearDown();
168   });
169 }
170 #endif
171 
172 // TODO(b/149248802): include XNNPACK delegate when the issue is resolved.
173 #if defined(__Fuchsia__) || defined(TFLITE_WITHOUT_XNNPACK)
CreateXNNPACKDelegate(int num_threads)174 TfLiteDelegatePtr CreateXNNPACKDelegate(int num_threads) {
175   return CreateNullDelegate();
176 }
177 #else
CreateXNNPACKDelegate()178 TfLiteDelegatePtr CreateXNNPACKDelegate() {
179   TfLiteXNNPackDelegateOptions xnnpack_options =
180       TfLiteXNNPackDelegateOptionsDefault();
181   return CreateXNNPACKDelegate(&xnnpack_options);
182 }
183 
CreateXNNPACKDelegate(const TfLiteXNNPackDelegateOptions * xnnpack_options)184 TfLiteDelegatePtr CreateXNNPACKDelegate(
185     const TfLiteXNNPackDelegateOptions* xnnpack_options) {
186   auto xnnpack_delegate = TfLiteXNNPackDelegateCreate(xnnpack_options);
187   return TfLiteDelegatePtr(xnnpack_delegate, [](TfLiteDelegate* delegate) {
188     TfLiteXNNPackDelegateDelete(delegate);
189   });
190 }
191 
CreateXNNPACKDelegate(int num_threads)192 TfLiteDelegatePtr CreateXNNPACKDelegate(int num_threads) {
193   auto opts = TfLiteXNNPackDelegateOptionsDefault();
194   // Note that we don't want to use the thread pool for num_threads == 1.
195   opts.num_threads = num_threads > 1 ? num_threads : 0;
196   return CreateXNNPACKDelegate(&opts);
197 }
198 #endif
199 }  // namespace evaluation
200 }  // namespace tflite
201