• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2020 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/experimental/acceleration/compatibility/gpu_compatibility.h"
16 
17 #include <cctype>
18 #include <map>
19 #include <memory>
20 #include <string>
21 
22 #include "absl/strings/string_view.h"
23 #include "flatbuffers/flatbuffers.h"  // from @flatbuffers
24 #include "tensorflow/lite/experimental/acceleration/compatibility/database_generated.h"
25 #include "tensorflow/lite/experimental/acceleration/compatibility/devicedb.h"
26 #include "tensorflow/lite/experimental/acceleration/compatibility/gpu_compatibility_binary.h"
27 #include "tensorflow/lite/experimental/acceleration/compatibility/variables.h"
28 
29 namespace tflite {
30 namespace acceleration {
31 namespace {
32 
CanonicalizeValue(absl::string_view input)33 std::string CanonicalizeValue(absl::string_view input) {
34   // This assumes ASCII, which holds for all values we have in the list.
35   std::string output(input);
36   for (int i = 0; i < output.size(); i++) {
37     char c = output[i];
38     if (c == ' ' || c == '-') {
39       output[i] = '_';
40     } else if (isalpha(c)) {
41       output[i] = tolower(c);
42     }
43   }
44   return output;
45 }
46 
CanonicalizeValues(std::map<std::string,std::string> * variable_values)47 void CanonicalizeValues(std::map<std::string, std::string>* variable_values) {
48   for (auto& i : *variable_values) {
49     i.second = CanonicalizeValue(i.second);
50   }
51 }
52 
53 }  // namespace
54 
GPUCompatibilityList(const unsigned char * compatibility_list_flatbuffer)55 GPUCompatibilityList::GPUCompatibilityList(
56     const unsigned char* compatibility_list_flatbuffer) {
57   if (!compatibility_list_flatbuffer) return;
58   database_ =
59       flatbuffers::GetRoot<DeviceDatabase>(compatibility_list_flatbuffer);
60 }
61 
Create()62 std::unique_ptr<GPUCompatibilityList> GPUCompatibilityList::Create() {
63   return Create(g_tflite_acceleration_gpu_compatibility_binary,
64                 g_tflite_acceleration_gpu_compatibility_binary_len);
65 }
66 
Create(const unsigned char * compatibility_list_flatbuffer,int length)67 std::unique_ptr<GPUCompatibilityList> GPUCompatibilityList::Create(
68     const unsigned char* compatibility_list_flatbuffer, int length) {
69   if (!compatibility_list_flatbuffer ||
70       !IsValidFlatbuffer(compatibility_list_flatbuffer, length)) {
71     return nullptr;
72   }
73   return std::unique_ptr<GPUCompatibilityList>(
74       new GPUCompatibilityList(compatibility_list_flatbuffer));
75 }
76 
CalculateVariables(const AndroidInfo & android_info,const::tflite::gpu::GpuInfo & gpu_info) const77 std::map<std::string, std::string> GPUCompatibilityList::CalculateVariables(
78     const AndroidInfo& android_info,
79     const ::tflite::gpu::GpuInfo& gpu_info) const {
80   std::map<std::string, std::string> variables;
81 
82   variables[kAndroidSdkVersion] = android_info.android_sdk_version;
83   variables[kDeviceModel] = android_info.model;
84   variables[kDeviceName] = android_info.device;
85   variables[kManufacturer] = android_info.manufacturer;
86   const auto& gl_info = gpu_info.opengl_info;
87   variables[kGPUModel] = gl_info.renderer_name;
88   char buffer[128];
89   int len = snprintf(buffer, 128 - 1, "%d.%d", gl_info.major_version,
90                      gl_info.minor_version);
91   buffer[len] = '\0';
92   variables[kOpenGLESVersion] = std::string(buffer);
93   CanonicalizeValues(&variables);
94   if (!database_) return variables;
95   UpdateVariablesFromDatabase(&variables, *database_);
96   return variables;
97 }
98 
Includes(const AndroidInfo & android_info,const::tflite::gpu::GpuInfo & gpu_info) const99 bool GPUCompatibilityList::Includes(
100     const AndroidInfo& android_info,
101     const ::tflite::gpu::GpuInfo& gpu_info) const {
102   auto variables = CalculateVariables(android_info, gpu_info);
103   return variables[gpu::kStatus] == std::string(gpu::kStatusSupported);
104 }
105 
GetBestOptionsFor(const AndroidInfo &,const::tflite::gpu::GpuInfo &) const106 TfLiteGpuDelegateOptionsV2 GPUCompatibilityList::GetBestOptionsFor(
107     const AndroidInfo& /* android_info */,
108     const ::tflite::gpu::GpuInfo& /* gpu_info */) const {
109   // This method is for forwards-compatibility: the list may later include
110   // information about which backend to choose (OpenGL/OpenCL/Vulkan) or other
111   // options.
112   return TfLiteGpuDelegateOptionsV2Default();
113 }
114 
115 // static
IsValidFlatbuffer(const unsigned char * data,int len)116 bool GPUCompatibilityList::IsValidFlatbuffer(const unsigned char* data,
117                                              int len) {
118   // Verify opensource db.
119   flatbuffers::Verifier verifier(reinterpret_cast<const uint8_t*>(data), len);
120   return tflite::acceleration::VerifyDeviceDatabaseBuffer(verifier);
121 }
122 
123 }  // namespace acceleration
124 }  // namespace tflite
125