xref: /aosp_15_r20/external/tensorflow/tensorflow/lite/delegates/gpu/common/selectors/simple_selectors.cc (revision b6fb3261f9314811a0f4371741dbb8839866f948)
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 
16 #include "tensorflow/lite/delegates/gpu/common/selectors/simple_selectors.h"
17 
18 #include <memory>
19 #include <set>
20 #include <utility>
21 
22 #include "absl/memory/memory.h"
23 #include "tensorflow/lite/delegates/gpu/common/status.h"
24 #include "tensorflow/lite/delegates/gpu/common/tasks/add.h"
25 #include "tensorflow/lite/delegates/gpu/common/tasks/cast.h"
26 #include "tensorflow/lite/delegates/gpu/common/tasks/concat_xy.h"
27 #include "tensorflow/lite/delegates/gpu/common/tasks/concat_z.h"
28 #include "tensorflow/lite/delegates/gpu/common/tasks/cumsum.h"
29 #include "tensorflow/lite/delegates/gpu/common/tasks/depthwise_conv.h"
30 #include "tensorflow/lite/delegates/gpu/common/tasks/gather.h"
31 #include "tensorflow/lite/delegates/gpu/common/tasks/lstm.h"
32 #include "tensorflow/lite/delegates/gpu/common/tasks/max_unpooling.h"
33 #include "tensorflow/lite/delegates/gpu/common/tasks/one_hot.h"
34 #include "tensorflow/lite/delegates/gpu/common/tasks/padding.h"
35 #include "tensorflow/lite/delegates/gpu/common/tasks/pooling.h"
36 #include "tensorflow/lite/delegates/gpu/common/tasks/prelu.h"
37 #include "tensorflow/lite/delegates/gpu/common/tasks/quantize_and_dequantize.h"
38 #include "tensorflow/lite/delegates/gpu/common/tasks/reduce.h"
39 #include "tensorflow/lite/delegates/gpu/common/tasks/relu.h"
40 #include "tensorflow/lite/delegates/gpu/common/tasks/resampler.h"
41 #include "tensorflow/lite/delegates/gpu/common/tasks/reshape.h"
42 #include "tensorflow/lite/delegates/gpu/common/tasks/reshapex4.h"
43 #include "tensorflow/lite/delegates/gpu/common/tasks/resize.h"
44 #include "tensorflow/lite/delegates/gpu/common/tasks/select_v2.h"
45 #include "tensorflow/lite/delegates/gpu/common/tasks/softmax.h"
46 #include "tensorflow/lite/delegates/gpu/common/tasks/softmax1x1.h"
47 #include "tensorflow/lite/delegates/gpu/common/tasks/space_to_depth.h"
48 #include "tensorflow/lite/delegates/gpu/common/tasks/split.h"
49 #include "tensorflow/lite/delegates/gpu/common/tasks/strided_slice.h"
50 #include "tensorflow/lite/delegates/gpu/common/tasks/tile.h"
51 #include "tensorflow/lite/delegates/gpu/common/tasks/transpose.h"
52 #include "tensorflow/lite/delegates/gpu/common/tasks/winograd.h"
53 
54 namespace tflite {
55 namespace gpu {
56 
SelectLSTM(const OperationDef & op_def,const GpuInfo & gpu_info)57 std::unique_ptr<GPUOperation> SelectLSTM(const OperationDef& op_def,
58                                          const GpuInfo& gpu_info) {
59   return std::make_unique<GPUOperation>(CreateLSTM(op_def, gpu_info));
60 }
61 
SelectReLU(const ReLUAttributes & attr,const OperationDef & op_def)62 std::unique_ptr<GPUOperation> SelectReLU(const ReLUAttributes& attr,
63                                          const OperationDef& op_def) {
64   return std::make_unique<GPUOperation>(CreateReLU(op_def, attr));
65 }
66 
SelectPReLU(const PReLUAttributes & attr,const GpuInfo & gpu_info,const OperationDef & op_def)67 std::unique_ptr<GPUOperation> SelectPReLU(const PReLUAttributes& attr,
68                                           const GpuInfo& gpu_info,
69                                           const OperationDef& op_def) {
70   return std::make_unique<GPUOperation>(CreatePReLU(gpu_info, op_def, attr));
71 }
72 
SelectPooling(const Pooling2DAttributes & attr,const GpuInfo & gpu_info,const OperationDef & op_def)73 std::unique_ptr<GPUOperation> SelectPooling(const Pooling2DAttributes& attr,
74                                             const GpuInfo& gpu_info,
75                                             const OperationDef& op_def) {
76   return std::make_unique<GPUOperation>(CreatePooling(op_def, gpu_info, attr));
77 }
78 
SelectMaxUnpooling(const MaxUnpooling2DAttributes & attr,const GpuInfo & gpu_info,const OperationDef & op_def)79 std::unique_ptr<GPUOperation> SelectMaxUnpooling(
80     const MaxUnpooling2DAttributes& attr, const GpuInfo& gpu_info,
81     const OperationDef& op_def) {
82   return std::make_unique<GPUOperation>(
83       CreateMaxUnpooling(gpu_info, op_def, attr));
84 }
85 
SelectAdd(const OperationDef & op_def,const std::vector<int> & channels,int dst_channels,std::unique_ptr<GPUOperation> * ptr)86 void SelectAdd(const OperationDef& op_def, const std::vector<int>& channels,
87                int dst_channels, std::unique_ptr<GPUOperation>* ptr) {
88   GPUOperation operation = CreateAdd(op_def, channels, dst_channels);
89   *ptr = std::make_unique<GPUOperation>(std::move(operation));
90 }
91 
SelectGather(const GatherAttributes & attr,const OperationDef & op_def,std::unique_ptr<GPUOperation> * ptr)92 absl::Status SelectGather(const GatherAttributes& attr,
93                           const OperationDef& op_def,
94                           std::unique_ptr<GPUOperation>* ptr) {
95   if (attr.axis != Axis::WIDTH) {
96     return absl::UnimplementedError(
97         "No gather for this axis. Only Width axis supported.");
98   }
99   GPUOperation operation = CreateGather(op_def, attr);
100   *ptr = std::make_unique<GPUOperation>(std::move(operation));
101   return absl::OkStatus();
102 }
103 
SelectResampler(const OperationDef & op_def,const GpuInfo & gpu_info)104 std::unique_ptr<GPUOperation> SelectResampler(const OperationDef& op_def,
105                                               const GpuInfo& gpu_info) {
106   GPUOperation operation = CreateResampler(gpu_info, op_def);
107   return std::make_unique<GPUOperation>(std::move(operation));
108 }
109 
SelectResize(const Resize2DAttributes & attr,const OperationDef & op_def,std::unique_ptr<GPUOperation> * ptr)110 absl::Status SelectResize(const Resize2DAttributes& attr,
111                           const OperationDef& op_def,
112                           std::unique_ptr<GPUOperation>* ptr) {
113   Resize operation = CreateResize(op_def, attr);
114   *ptr = std::make_unique<Resize>(std::move(operation));
115   return absl::OkStatus();
116 }
117 
SelectConcat(const ConcatAttributes & attr,const std::vector<int> & channels,const OperationDef & op_def,const GpuInfo & gpu_info,std::unique_ptr<GPUOperation> * ptr)118 absl::Status SelectConcat(const ConcatAttributes& attr,
119                           const std::vector<int>& channels,
120                           const OperationDef& op_def, const GpuInfo& gpu_info,
121                           std::unique_ptr<GPUOperation>* ptr) {
122   switch (attr.axis) {
123     case Axis::CHANNELS: {
124       GPUOperation operation = CreateConcatZ(op_def, channels, gpu_info);
125       *ptr = std::make_unique<GPUOperation>(std::move(operation));
126       return absl::OkStatus();
127     }
128     case Axis::BATCH:
129     case Axis::DEPTH:
130     case Axis::HEIGHT:
131     case Axis::WIDTH: {
132       GPUOperation operation = CreateConcatXY(op_def, attr);
133       *ptr = std::make_unique<GPUOperation>(std::move(operation));
134       return absl::OkStatus();
135     }
136     default:
137       return absl::UnimplementedError("No concat for this axis.");
138   }
139 }
140 
SelectDWConvolutionDynamicWeights(const DepthwiseConvolution2DAttributes & attr,const GpuInfo & gpu_info,const OperationDef & op_def)141 std::unique_ptr<GPUOperation> SelectDWConvolutionDynamicWeights(
142     const DepthwiseConvolution2DAttributes& attr, const GpuInfo& gpu_info,
143     const OperationDef& op_def) {
144   return std::make_unique<DepthwiseConv>(
145       CreateDepthwiseConvolution2DDynamicWeights(gpu_info, op_def, attr));
146 }
147 
SelectReshape(int src_channels,int dst_channels,const OperationDef & op_def,std::unique_ptr<GPUOperation> * ptr)148 void SelectReshape(int src_channels, int dst_channels,
149                    const OperationDef& op_def,
150                    std::unique_ptr<GPUOperation>* ptr) {
151   if (src_channels % 4 == 0 && dst_channels % 4 == 0) {
152     GPUOperation operation = CreateReshapex4(op_def);
153     *ptr = std::make_unique<GPUOperation>(std::move(operation));
154   } else {
155     GPUOperation operation = CreateReshape(op_def);
156     *ptr = std::make_unique<GPUOperation>(std::move(operation));
157   }
158 }
159 
SelectSpaceToDepth(const SpaceToDepthAttributes & attr,const OperationDef & op_def,std::unique_ptr<GPUOperation> * ptr)160 void SelectSpaceToDepth(const SpaceToDepthAttributes& attr,
161                         const OperationDef& op_def,
162                         std::unique_ptr<GPUOperation>* ptr) {
163   GPUOperation operation = CreateSpaceToDepth(op_def, attr);
164   *ptr = std::make_unique<GPUOperation>(std::move(operation));
165 }
166 
SelectDepthToSpace(const SpaceToDepthAttributes & attr,const OperationDef & op_def,std::unique_ptr<GPUOperation> * ptr)167 void SelectDepthToSpace(const SpaceToDepthAttributes& attr,
168                         const OperationDef& op_def,
169                         std::unique_ptr<GPUOperation>* ptr) {
170   GPUOperation operation = CreateDepthToSpace(op_def, attr);
171   *ptr = std::make_unique<GPUOperation>(std::move(operation));
172 }
173 
SelectSplit(const SplitAttributes & attr,const GpuInfo & gpu_info,const std::vector<int> & channels,const OperationDef & op_def,std::unique_ptr<GPUOperation> * ptr)174 void SelectSplit(const SplitAttributes& attr, const GpuInfo& gpu_info,
175                  const std::vector<int>& channels, const OperationDef& op_def,
176                  std::unique_ptr<GPUOperation>* ptr) {
177   Split operation = CreateSplit(gpu_info, op_def, attr, channels);
178   *ptr = std::make_unique<Split>(std::move(operation));
179 }
180 
SelectPadding(const PadAttributes & attr,const OperationDef & op_def,std::unique_ptr<GPUOperation> * ptr)181 void SelectPadding(const PadAttributes& attr, const OperationDef& op_def,
182                    std::unique_ptr<GPUOperation>* ptr) {
183   GPUOperation operation = CreatePadding(op_def, attr);
184   *ptr = std::make_unique<GPUOperation>(std::move(operation));
185 }
186 
SelectStridedSlice(const SliceAttributes & attr,const OperationDef & op_def,std::unique_ptr<GPUOperation> * ptr)187 void SelectStridedSlice(const SliceAttributes& attr, const OperationDef& op_def,
188                         std::unique_ptr<GPUOperation>* ptr) {
189   StridedSlice operation = CreateStridedSlice(op_def, attr);
190   *ptr = std::make_unique<StridedSlice>(std::move(operation));
191 }
192 
SelectReduce(const std::set<Axis> & axis_to_reduce,const BHWC & src_shape,OperationType op_type,const OperationDef & op_def,const GpuInfo & gpu_info)193 std::unique_ptr<GPUOperation> SelectReduce(const std::set<Axis>& axis_to_reduce,
194                                            const BHWC& src_shape,
195                                            OperationType op_type,
196                                            const OperationDef& op_def,
197                                            const GpuInfo& gpu_info) {
198   return std::make_unique<Reduce>(
199       CreateReduce(axis_to_reduce, src_shape, op_type, op_def, gpu_info));
200 }
201 
SelectSoftmax(const BHWC & shape,const OperationDef & op_def,std::unique_ptr<GPUOperation> * ptr)202 void SelectSoftmax(const BHWC& shape, const OperationDef& op_def,
203                    std::unique_ptr<GPUOperation>* ptr) {
204   if (shape.w == 1 && shape.h == 1) {
205     Softmax1x1 operation = CreateSoftmax1x1(op_def);
206     *ptr = std::make_unique<Softmax1x1>(std::move(operation));
207   } else {
208     GPUOperation operation = CreateSoftmax(op_def);
209     *ptr = std::make_unique<GPUOperation>(std::move(operation));
210   }
211 }
212 
SelectTile(const OperationDef & op_def,const BHWC & src_shape)213 std::unique_ptr<GPUOperation> SelectTile(const OperationDef& op_def,
214                                          const BHWC& src_shape) {
215   return std::make_unique<GPUOperation>(CreateTile(op_def, src_shape.c));
216 }
217 
SelectTranspose(const TransposeAttributes & attr,const OperationDef & op_def,std::unique_ptr<GPUOperation> * ptr)218 void SelectTranspose(const TransposeAttributes& attr,
219                      const OperationDef& op_def,
220                      std::unique_ptr<GPUOperation>* ptr) {
221   GPUOperation operation = CreateTranspose(op_def, attr);
222   *ptr = std::make_unique<GPUOperation>(std::move(operation));
223 }
224 
SelectWinograd4x4To36(const GpuInfo & gpu_info,const Padding2D & padding,const OperationDef & op_def)225 std::unique_ptr<GPUOperation> SelectWinograd4x4To36(
226     const GpuInfo& gpu_info, const Padding2D& padding,
227     const OperationDef& op_def) {
228   if (gpu_info.IsApple() || gpu_info.IsAMD()) {
229     Winograd4x4To36 operation =
230         CreateWinograd4x4To36(op_def, padding, gpu_info);
231     return std::make_unique<Winograd4x4To36>(std::move(operation));
232   }
233   return std::make_unique<Winograd4x4To36TileX6>(
234       CreateWinograd4x4To36TileX6(gpu_info, op_def, padding));
235 }
236 
SelectWinograd36To4x4(const GpuInfo & gpu_info,const OperationDef & op_def,const tflite::gpu::Tensor<Linear,DataType::FLOAT32> & biases)237 std::unique_ptr<GPUOperation> SelectWinograd36To4x4(
238     const GpuInfo& gpu_info, const OperationDef& op_def,
239     const tflite::gpu::Tensor<Linear, DataType::FLOAT32>& biases) {
240   if (gpu_info.IsApple() || gpu_info.IsAMD()) {
241     Winograd36To4x4 operation = CreateWinograd36To4x4(op_def, biases);
242     return std::make_unique<Winograd36To4x4>(std::move(operation));
243   }
244   return std::make_unique<Winograd36To4x4Tile4x1>(
245       CreateWinograd36To4x4Tile4x1(gpu_info, op_def, biases));
246 }
247 
SelectQuantizeAndDequantize(const QuantizeAndDequantizeAttributes & attr,const OperationDef & op_def)248 std::unique_ptr<GPUOperation> SelectQuantizeAndDequantize(
249     const QuantizeAndDequantizeAttributes& attr, const OperationDef& op_def) {
250   return std::make_unique<GPUOperation>(
251       CreateQuantizeAndDequantize(op_def, attr));
252 }
253 
SelectCast(const OperationDef & op_def,const GpuInfo & gpu_info,std::unique_ptr<GPUOperation> * ptr)254 void SelectCast(const OperationDef& op_def, const GpuInfo& gpu_info,
255                 std::unique_ptr<GPUOperation>* ptr) {
256   GPUOperation operation = CreateCast(op_def, gpu_info);
257   *ptr = std::make_unique<GPUOperation>(std::move(operation));
258 }
259 
SelectCumsum(const OperationDef & op_def,const CumsumAttributes & attr,std::unique_ptr<GPUOperation> * ptr)260 void SelectCumsum(const OperationDef& op_def, const CumsumAttributes& attr,
261                   std::unique_ptr<GPUOperation>* ptr) {
262   Cumsum operation = CreateCumsum(op_def, attr);
263   *ptr = std::make_unique<Cumsum>(std::move(operation));
264 }
265 
SelectOneHot(const OperationDef & op_def,const OneHotAttributes & attr,std::unique_ptr<GPUOperation> * ptr)266 void SelectOneHot(const OperationDef& op_def, const OneHotAttributes& attr,
267                   std::unique_ptr<GPUOperation>* ptr) {
268   GPUOperation operation = CreateOneHot(op_def, attr);
269   *ptr = std::make_unique<GPUOperation>(std::move(operation));
270 }
271 
SelectSelectV2(const OperationDef & op_def,const SelectV2Attributes & attr,std::unique_ptr<GPUOperation> * ptr)272 void SelectSelectV2(const OperationDef& op_def, const SelectV2Attributes& attr,
273                     std::unique_ptr<GPUOperation>* ptr) {
274   GPUOperation operation = CreateSelectV2(op_def, attr);
275   *ptr = std::make_unique<GPUOperation>(std::move(operation));
276 }
277 
278 }  // namespace gpu
279 }  // namespace tflite
280