• 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 "absl/memory/memory.h"
17 #include "tensorflow/lite/delegates/gpu/common/model_hints.h"
18 #include "tensorflow/lite/delegates/gpu/common/operations.h"
19 #include "tensorflow/lite/delegates/gpu/common/shape.h"
20 #include "tensorflow/lite/delegates/gpu/common/status.h"
21 #include "tensorflow/lite/delegates/gpu/common/task/gpu_operation.h"
22 #include "tensorflow/lite/delegates/gpu/common/task/tensor_desc.h"
23 #include "tensorflow/lite/delegates/gpu/common/task/weights_layout.h"
24 #include "tensorflow/lite/delegates/gpu/common/task/work_group_picking.h"
25 #include "tensorflow/lite/delegates/gpu/common/tasks/conv_buffer_1x1.h"
26 #include "tensorflow/lite/delegates/gpu/common/tasks/conv_constants.h"
27 #include "tensorflow/lite/delegates/gpu/common/tasks/conv_metal.h"
28 #include "tensorflow/lite/delegates/gpu/common/tasks/conv_powervr.h"
29 #include "tensorflow/lite/delegates/gpu/common/tasks/conv_weights_converter.h"
30 #include "tensorflow/lite/delegates/gpu/common/util.h"
31 
32 namespace tflite {
33 namespace gpu {
34 namespace {
35 
SelectConvolutionAdreno(const Convolution2DAttributes & attr,const BHWC & dst_shape,const GpuInfo & gpu_info,const OperationDef & op_def,ModelHints hints)36 std::unique_ptr<GPUOperation> SelectConvolutionAdreno(
37     const Convolution2DAttributes& attr, const BHWC& dst_shape,
38     const GpuInfo& gpu_info, const OperationDef& op_def,
39     ModelHints hints) {
40   if (IsConvConstantsSupported(gpu_info, op_def, attr)) {
41     GPUOperation conv = CreateConvConstants(gpu_info, op_def, attr);
42     return absl::make_unique<GPUOperation>(std::move(conv));
43   } else {
44     ConvPowerVR conv = CreateConvPowerVR(gpu_info, op_def, attr, &dst_shape);
45     return absl::make_unique<ConvPowerVR>(std::move(conv));
46   }
47 }
48 
SelectConvolutionWinogradAdreno(const Convolution2DAttributes & attr,const BHWC & dst_shape,const GpuInfo & gpu_info,const OperationDef & op_def,ModelHints hints)49 std::unique_ptr<GPUOperation> SelectConvolutionWinogradAdreno(
50     const Convolution2DAttributes& attr, const BHWC& dst_shape,
51     const GpuInfo& gpu_info, const OperationDef& op_def,
52     ModelHints hints) {
53   ConvPowerVR conv =
54       CreateConvPowerVRWino4x4To6x6(gpu_info, op_def, attr, &dst_shape);
55   return absl::make_unique<ConvPowerVR>(std::move(conv));
56 }
57 
SelectConvolutionDynamicWeightsAdreno(const Convolution2DAttributes & attr,const BHWC & weights_shape,const BHWC & dst_shape,const GpuInfo & gpu_info,const OperationDef & op_def,ModelHints hints,WeightsDescription * weights_desc)58 std::unique_ptr<GPUOperation> SelectConvolutionDynamicWeightsAdreno(
59     const Convolution2DAttributes& attr, const BHWC& weights_shape,
60     const BHWC& dst_shape, const GpuInfo& gpu_info,
61     const OperationDef& op_def, ModelHints hints,
62     WeightsDescription* weights_desc) {
63   ConvPowerVR conv = CreateConvPowerVRDynamicWeights(
64       gpu_info, op_def, attr, weights_shape, &dst_shape);
65   *weights_desc = conv.GetWeightsDescription();
66   return absl::make_unique<ConvPowerVR>(std::move(conv));
67 }
68 
SelectConvolutionNVidia(const Convolution2DAttributes & attr,const BHWC & dst_shape,const GpuInfo & gpu_info,const OperationDef & op_def)69 std::unique_ptr<GPUOperation> SelectConvolutionNVidia(
70     const Convolution2DAttributes& attr, const BHWC& dst_shape,
71     const GpuInfo& gpu_info, const OperationDef& op_def) {
72   if (IsConvConstantsSupported(gpu_info, op_def, attr)) {
73     GPUOperation conv = CreateConvConstants(gpu_info, op_def, attr);
74     return absl::make_unique<GPUOperation>(std::move(conv));
75   } else {
76     ConvPowerVR conv = CreateConvPowerVR(gpu_info, op_def, attr, &dst_shape);
77     return absl::make_unique<ConvPowerVR>(std::move(conv));
78   }
79 }
80 
SelectConvolutionPowerVR(const Convolution2DAttributes & attr,const GpuInfo & gpu_info,const OperationDef & op_def)81 std::unique_ptr<GPUOperation> SelectConvolutionPowerVR(
82     const Convolution2DAttributes& attr, const GpuInfo& gpu_info,
83     const OperationDef& op_def) {
84   ConvPowerVR conv = CreateConvPowerVR(gpu_info, op_def, attr);
85   return absl::make_unique<ConvPowerVR>(std::move(conv));
86 }
87 
SelectConvolutionMali(const Convolution2DAttributes & attr,const BHWC & dst_shape,const GpuInfo & gpu_info,const OperationDef & op_def)88 std::unique_ptr<GPUOperation> SelectConvolutionMali(
89     const Convolution2DAttributes& attr, const BHWC& dst_shape,
90     const GpuInfo& gpu_info, const OperationDef& op_def) {
91   if (op_def.src_tensors[0].storage_type == TensorStorageType::BUFFER &&
92       IsConvBuffer1x1Supported(op_def, attr)) {
93     ConvBuffer1x1 conv =
94         CreateConvBuffer1x1(gpu_info, op_def, attr, &dst_shape);
95     return absl::make_unique<ConvBuffer1x1>(std::move(conv));
96   } else {
97     ConvPowerVR conv = CreateConvPowerVR(gpu_info, op_def, attr, &dst_shape);
98     return absl::make_unique<ConvPowerVR>(std::move(conv));
99   }
100 }
101 
SelectConvolutionWinogradMali(const Convolution2DAttributes & attr,const BHWC & dst_shape,const GpuInfo & gpu_info,const OperationDef & op_def)102 std::unique_ptr<GPUOperation> SelectConvolutionWinogradMali(
103     const Convolution2DAttributes& attr, const BHWC& dst_shape,
104     const GpuInfo& gpu_info, const OperationDef& op_def) {
105   if (op_def.src_tensors[0].storage_type == TensorStorageType::BUFFER) {
106     ConvBuffer1x1 conv =
107         CreateConvBuffer1x1Wino4x4To6x6(gpu_info, op_def, attr, &dst_shape);
108     return absl::make_unique<ConvBuffer1x1>(std::move(conv));
109   } else {
110     ConvPowerVR conv =
111         CreateConvPowerVRWino4x4To6x6(gpu_info, op_def, attr, &dst_shape);
112     return absl::make_unique<ConvPowerVR>(std::move(conv));
113   }
114 }
115 
SelectConvolutionDynamicWeightsMali(const Convolution2DAttributes & attr,const BHWC & weights_shape,const BHWC & dst_shape,const GpuInfo & gpu_info,const OperationDef & op_def,ModelHints hints,WeightsDescription * weights_desc)116 std::unique_ptr<GPUOperation> SelectConvolutionDynamicWeightsMali(
117     const Convolution2DAttributes& attr, const BHWC& weights_shape,
118     const BHWC& dst_shape, const GpuInfo& gpu_info,
119     const OperationDef& op_def, ModelHints hints,
120     WeightsDescription* weights_desc) {
121   if (op_def.src_tensors[0].storage_type == TensorStorageType::BUFFER &&
122       IsConvBuffer1x1Supported(op_def, weights_shape, attr)) {
123     ConvBuffer1x1 conv = CreateConvBuffer1x1DynamicWeights(
124         gpu_info, op_def, attr, weights_shape, &dst_shape);
125     *weights_desc = conv.GetWeightsDescription();
126     return absl::make_unique<ConvBuffer1x1>(std::move(conv));
127   } else {
128     ConvPowerVR conv = CreateConvPowerVRDynamicWeights(
129         gpu_info, op_def, attr, weights_shape, &dst_shape);
130     *weights_desc = conv.GetWeightsDescription();
131     return absl::make_unique<ConvPowerVR>(std::move(conv));
132   }
133 }
134 
135 }  // namespace
136 
SelectConvolution(const Convolution2DAttributes & attr,const BHWC & dst_shape,const GpuInfo & gpu_info,const OperationDef & op_def,ModelHints hints)137 std::unique_ptr<GPUOperation> SelectConvolution(
138     const Convolution2DAttributes& attr, const BHWC& dst_shape,
139     const GpuInfo& gpu_info, const OperationDef& op_def,
140     ModelHints hints) {
141   if (gpu_info.IsApiMetal() && IsConvolutionMetalSupported(op_def)) {
142     ConvolutionMetal conv =
143         CreateConvolutionMetal(op_def, dst_shape, attr, gpu_info);
144     return absl::make_unique<ConvolutionMetal>(std::move(conv));
145   } else if (gpu_info.IsAdreno()) {
146     return SelectConvolutionAdreno(attr, dst_shape, gpu_info, op_def, hints);
147   } else if (gpu_info.IsPowerVR() || gpu_info.IsAMD() || gpu_info.IsIntel() ||
148              gpu_info.IsApple()) {
149     return SelectConvolutionPowerVR(attr, gpu_info, op_def);
150   } else if (gpu_info.IsNvidia()) {
151     return SelectConvolutionNVidia(attr, dst_shape, gpu_info, op_def);
152   } else if (gpu_info.IsMali()) {
153     return SelectConvolutionMali(attr, dst_shape, gpu_info, op_def);
154   } else {
155     return SelectConvolutionAdreno(attr, dst_shape, gpu_info, op_def, hints);
156   }
157 }
158 
SelectConvolutionForWinograd(const Convolution2DAttributes & attr,const BHWC & dst_shape,const GpuInfo & gpu_info,const OperationDef & op_def,ModelHints hints)159 std::unique_ptr<GPUOperation> SelectConvolutionForWinograd(
160     const Convolution2DAttributes& attr, const BHWC& dst_shape,
161     const GpuInfo& gpu_info, const OperationDef& op_def,
162     ModelHints hints) {
163   if (gpu_info.IsApiMetal() && IsConvolutionMetalSupported(op_def)) {
164     ConvolutionMetal conv =
165         CreateConvolutionMetalWino4x4To6x6(op_def, dst_shape, attr, gpu_info);
166     return absl::make_unique<ConvolutionMetal>(std::move(conv));
167   } else if (gpu_info.IsAdreno()) {
168     return SelectConvolutionWinogradAdreno(attr, dst_shape, gpu_info, op_def,
169                                            hints);
170   } else if (gpu_info.IsPowerVR() || gpu_info.IsAMD() || gpu_info.IsNvidia() ||
171              gpu_info.IsIntel() || gpu_info.IsApple()) {
172     ConvPowerVR conv =
173         CreateConvPowerVRWino4x4To6x6(gpu_info, op_def, attr, &dst_shape);
174     return absl::make_unique<ConvPowerVR>(std::move(conv));
175   } else if (gpu_info.IsMali()) {
176     return SelectConvolutionWinogradMali(attr, dst_shape, gpu_info, op_def);
177   } else {
178     return SelectConvolutionWinogradAdreno(attr, dst_shape, gpu_info, op_def,
179                                            hints);
180   }
181 }
182 
SelectConvolutionWithDynamicWeights(const Convolution2DAttributes & attr,const BHWC & weights_shape,const BHWC & dst_shape,const GpuInfo & gpu_info,const OperationDef & op_def,ModelHints hints,WeightsDescription * weights_desc)183 std::unique_ptr<GPUOperation> SelectConvolutionWithDynamicWeights(
184     const Convolution2DAttributes& attr, const BHWC& weights_shape,
185     const BHWC& dst_shape, const GpuInfo& gpu_info,
186     const OperationDef& op_def, ModelHints hints,
187     WeightsDescription* weights_desc) {
188   if (gpu_info.IsApiMetal() && IsConvolutionMetalSupported(op_def)) {
189     Convolution2DAttributes attr_copy = attr;
190     attr_copy.weights.shape = OHWI(weights_shape.b, weights_shape.h,
191                                    weights_shape.w, weights_shape.c);
192     ConvolutionMetal conv =
193         CreateConvolutionMetal(op_def, dst_shape, attr_copy, gpu_info);
194     return absl::make_unique<ConvolutionMetal>(std::move(conv));
195   } else if (gpu_info.IsAdreno()) {
196     return SelectConvolutionDynamicWeightsAdreno(attr, weights_shape, dst_shape,
197                                                  gpu_info, op_def, hints,
198                                                  weights_desc);
199   } else if (gpu_info.IsMali()) {
200     return SelectConvolutionDynamicWeightsMali(attr, weights_shape, dst_shape,
201                                                gpu_info, op_def, hints,
202                                                weights_desc);
203   } else {
204     ConvPowerVR conv = CreateConvPowerVRDynamicWeights(
205         gpu_info, op_def, attr, weights_shape, &dst_shape);
206     *weights_desc = conv.GetWeightsDescription();
207     return absl::make_unique<ConvPowerVR>(std::move(conv));
208   }
209 }
210 
SelectConverterToConvWeights(const WeightsDescription & weights_desc,const OperationDef & op_def,ModelHints hints)211 std::unique_ptr<GPUOperation> SelectConverterToConvWeights(
212     const WeightsDescription& weights_desc, const OperationDef& op_def,
213     ModelHints hints) {
214   ConverterToConvWeights converter =
215       ConverterToConvWeights(op_def, weights_desc);
216   return absl::make_unique<ConverterToConvWeights>(std::move(converter));
217 }
218 
219 }  // namespace gpu
220 }  // namespace tflite
221