1 /* Copyright 2021 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/delegates/gpu/metal/metal_device.h"
17
18 #include <string>
19
20 namespace tflite {
21 namespace gpu {
22 namespace metal {
23 namespace {
CreateGpuInfoFromMetalDevice(id<MTLDevice> device)24 GpuInfo CreateGpuInfoFromMetalDevice(id<MTLDevice> device) {
25 std::string device_name = std::string([[device name] UTF8String]);
26 GpuInfo gpu_info;
27 GetGpuInfoFromDeviceDescription(device_name, GpuApi::kMetal, &gpu_info);
28
29 if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) {
30 MTLSize threadsPerGroup = [device maxThreadsPerThreadgroup];
31 gpu_info.metal_info.max_work_group_size_x = threadsPerGroup.width;
32 gpu_info.metal_info.max_work_group_size_y = threadsPerGroup.height;
33 gpu_info.metal_info.max_work_group_size_z = threadsPerGroup.depth;
34 } else {
35 gpu_info.metal_info.max_work_group_size_x = 256;
36 gpu_info.metal_info.max_work_group_size_y = 256;
37 gpu_info.metal_info.max_work_group_size_z = 64;
38 }
39
40 if (@available(macOS 10.14, iOS 12.0, tvOS 12.0, *)) {
41 gpu_info.metal_info.buffer_max_size = [device maxBufferLength];
42 } else {
43 // 256 MB
44 gpu_info.metal_info.buffer_max_size = 256 * 1024 * 1024;
45 }
46
47 if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
48 gpu_info.metal_info.language_version = MetalLanguageVersion::kMetal2_3;
49 } else if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) {
50 gpu_info.metal_info.language_version = MetalLanguageVersion::kMetal2_2;
51 } else if (@available(macOS 10.14, iOS 12.0, tvOS 12.0, *)) {
52 gpu_info.metal_info.language_version = MetalLanguageVersion::kMetal2_1;
53 } else if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
54 gpu_info.metal_info.language_version = MetalLanguageVersion::kMetal2_0;
55 } else if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, *)) {
56 gpu_info.metal_info.language_version = MetalLanguageVersion::kMetal1_2;
57 } else if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) {
58 gpu_info.metal_info.language_version = MetalLanguageVersion::kMetal1_1;
59 } else {
60 gpu_info.metal_info.language_version = MetalLanguageVersion::kMetal1_0;
61 }
62
63 return gpu_info;
64 }
65 } // namespace
66
MetalDevice()67 MetalDevice::MetalDevice() : device_(MTLCreateSystemDefaultDevice()) {
68 info_ = CreateGpuInfoFromMetalDevice(device_);
69 }
MetalDevice(id<MTLDevice> device)70 MetalDevice::MetalDevice(id<MTLDevice> device) : device_(device) {
71 info_ = CreateGpuInfoFromMetalDevice(device_);
72 }
73
IsLanguageVersion2orHigher() const74 bool MetalDevice::IsLanguageVersion2orHigher() const {
75 auto version = info_.metal_info.language_version;
76 return version != MetalLanguageVersion::kMetal1_0 &&
77 version != MetalLanguageVersion::kMetal1_1 &&
78 version != MetalLanguageVersion::kMetal1_2;
79 }
80
81 } // namespace metal
82 } // namespace gpu
83 } // namespace tflite
84