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