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/canonicalize_value.h"
25 #include "tensorflow/lite/experimental/acceleration/compatibility/database_generated.h"
26 #include "tensorflow/lite/experimental/acceleration/compatibility/devicedb.h"
27 #include "tensorflow/lite/experimental/acceleration/compatibility/gpu_compatibility_binary.h"
28 #include "tensorflow/lite/experimental/acceleration/compatibility/variables.h"
29
30 namespace tflite {
31 namespace acceleration {
32 namespace {
33
CanonicalizeValues(std::map<std::string,std::string> * variable_values)34 void CanonicalizeValues(std::map<std::string, std::string>* variable_values) {
35 for (auto& i : *variable_values) {
36 i.second = CanonicalizeValue(i.second);
37 }
38 }
39
40 } // namespace
41
GPUCompatibilityList(const unsigned char * compatibility_list_flatbuffer)42 GPUCompatibilityList::GPUCompatibilityList(
43 const unsigned char* compatibility_list_flatbuffer) {
44 if (!compatibility_list_flatbuffer) return;
45 database_ =
46 flatbuffers::GetRoot<DeviceDatabase>(compatibility_list_flatbuffer);
47 }
48
Create()49 std::unique_ptr<GPUCompatibilityList> GPUCompatibilityList::Create() {
50 return Create(g_tflite_acceleration_gpu_compatibility_binary,
51 g_tflite_acceleration_gpu_compatibility_binary_len);
52 }
53
Create(const unsigned char * compatibility_list_flatbuffer,int length)54 std::unique_ptr<GPUCompatibilityList> GPUCompatibilityList::Create(
55 const unsigned char* compatibility_list_flatbuffer, int length) {
56 if (!compatibility_list_flatbuffer ||
57 !IsValidFlatbuffer(compatibility_list_flatbuffer, length)) {
58 return nullptr;
59 }
60 return std::unique_ptr<GPUCompatibilityList>(
61 new GPUCompatibilityList(compatibility_list_flatbuffer));
62 }
63
CalculateVariables(const AndroidInfo & android_info,const::tflite::gpu::GpuInfo & gpu_info) const64 std::map<std::string, std::string> GPUCompatibilityList::CalculateVariables(
65 const AndroidInfo& android_info,
66 const ::tflite::gpu::GpuInfo& gpu_info) const {
67 std::map<std::string, std::string> variables;
68
69 variables[kAndroidSdkVersion] = android_info.android_sdk_version;
70 variables[kDeviceModel] = android_info.model;
71 variables[kDeviceName] = android_info.device;
72 variables[kManufacturer] = android_info.manufacturer;
73 const auto& gl_info = gpu_info.opengl_info;
74 variables[kGPUModel] = gl_info.renderer_name;
75 char buffer[128];
76 int len = snprintf(buffer, 128 - 1, "%d.%d", gl_info.major_version,
77 gl_info.minor_version);
78 buffer[len] = '\0';
79 variables[kOpenGLESVersion] = std::string(buffer);
80 CanonicalizeValues(&variables);
81 if (!database_) return variables;
82 UpdateVariablesFromDatabase(&variables, *database_);
83 return variables;
84 }
85
Includes(const AndroidInfo & android_info,const::tflite::gpu::GpuInfo & gpu_info) const86 bool GPUCompatibilityList::Includes(
87 const AndroidInfo& android_info,
88 const ::tflite::gpu::GpuInfo& gpu_info) const {
89 auto variables = CalculateVariables(android_info, gpu_info);
90 return variables[gpu::kStatus] == std::string(gpu::kStatusSupported);
91 }
92
GetBestOptionsFor(const AndroidInfo &,const::tflite::gpu::GpuInfo &) const93 TfLiteGpuDelegateOptionsV2 GPUCompatibilityList::GetBestOptionsFor(
94 const AndroidInfo& /* android_info */,
95 const ::tflite::gpu::GpuInfo& /* gpu_info */) const {
96 // This method is for forwards-compatibility: the list may later include
97 // information about which backend to choose (OpenGL/OpenCL/Vulkan) or other
98 // options.
99 return TfLiteGpuDelegateOptionsV2Default();
100 }
101
102 // static
IsValidFlatbuffer(const unsigned char * data,int len)103 bool GPUCompatibilityList::IsValidFlatbuffer(const unsigned char* data,
104 int len) {
105 // Verify opensource db.
106 flatbuffers::Verifier verifier(reinterpret_cast<const uint8_t*>(data), len);
107 return tflite::acceleration::VerifyDeviceDatabaseBuffer(verifier);
108 }
109
110 } // namespace acceleration
111 } // namespace tflite
112