blob: fe5612200979baf103338b82eb65948c23867f06 [file] [log] [blame]
Georgios Pinitas407c3e62017-10-25 18:26:46 +01001/*
Giorgio Arena11674872018-02-07 15:38:12 +00002 * Copyright (c) 2017-2018 ARM Limited.
Georgios Pinitas407c3e62017-10-25 18:26:46 +01003 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24#include "arm_compute/core/CL/ICLTensor.h"
25#include "arm_compute/core/Error.h"
26#include "arm_compute/graph/IOperation.h"
27#include "arm_compute/graph/NodeContext.h"
28#include "arm_compute/graph/OperationRegistrar.h"
29#include "arm_compute/graph/Types.h"
30#include "arm_compute/runtime/CL/CLFunctions.h"
31#include "support/ToolchainSupport.h"
32#include "utils/GraphTypePrinter.h"
33#include "utils/TypePrinter.h"
34
35#include <memory>
36
37using namespace arm_compute::graph;
38
39/* Activation Layer */
40REGISTER_SIMPLE_OPERATION(CLActivationLayerOperation, OPENCL, OperationType::ActivationLayer)
41{
42 ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1);
43 ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1);
44 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0)) == nullptr);
45 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0)) == nullptr);
46
47 // Extract IO and info
48 auto *in = dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0));
49 auto *out = dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0));
50 const auto act_info = ctx.parameter<ActivationLayerInfo>("ActivationLayerInfo");
51
52 // Create and configure function
53 auto activation = arm_compute::support::cpp14::make_unique<arm_compute::CLActivationLayer>();
54 activation->configure(in, out, act_info);
55
56 // Log info
57 ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLActivationLayer"
58 << " Data Type: " << in->info()->data_type()
59 << " Input shape: " << in->info()->tensor_shape()
60 << " Output shape: " << out->info()->tensor_shape()
61 << " Activation function: " << act_info.activation()
62 << " a: " << act_info.a()
63 << " b: " << act_info.b()
64 << std::endl);
65
66 return std::move(activation);
67}
68
Alex Gilday8913d8d2018-02-15 11:07:18 +000069/* Arithmetic addition */
70REGISTER_SIMPLE_OPERATION(CLArithmeticAdditionOperation, OPENCL, OperationType::ArithmeticAddition)
71{
72 ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 2);
73 ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1);
74 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0)) == nullptr);
75 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.input(1)) == nullptr);
76 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0)) == nullptr);
77
78 // Extract IO and info
79 auto *in1 = dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0));
80 auto *in2 = dynamic_cast<arm_compute::ICLTensor *>(ctx.input(1));
81 auto *out = dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0));
82
83 auto addition = arm_compute::support::cpp14::make_unique<arm_compute::CLArithmeticAddition>();
84 addition->configure(in1, in2, out, ConvertPolicy::SATURATE);
85
86 // Log info
87 ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLArithmeticAddition"
88 << " Data Type: " << in1->info()->data_type()
89 << " Input 1 shape: " << in1->info()->tensor_shape()
90 << " Input 2 shape: " << in2->info()->tensor_shape()
91 << " Output shape: " << out->info()->tensor_shape()
92 << std::endl);
93
94 return std::move(addition);
95}
96
Georgios Pinitas407c3e62017-10-25 18:26:46 +010097/* Batch Normalization Layer */
98REGISTER_SIMPLE_OPERATION(CLBatchNormalizationLayerOperation, OPENCL, OperationType::BatchNormalizationLayer)
99{
100 ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 5);
101 ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1);
102 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0)) == nullptr);
103 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.input(1)) == nullptr);
104 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.input(2)) == nullptr);
105 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.input(3)) == nullptr);
106 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.input(4)) == nullptr);
107 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0)) == nullptr);
108
109 // Extract IO and info
Giorgio Arena11674872018-02-07 15:38:12 +0000110 auto *in = dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0));
111 auto *mean = dynamic_cast<arm_compute::ICLTensor *>(ctx.input(1));
112 auto *var = dynamic_cast<arm_compute::ICLTensor *>(ctx.input(2));
113 auto *beta = dynamic_cast<arm_compute::ICLTensor *>(ctx.input(3));
114 auto *gamma = dynamic_cast<arm_compute::ICLTensor *>(ctx.input(4));
115 auto *out = dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0));
116 const auto epsilon = ctx.parameter<float>("epsilon");
117 const auto act_info = ctx.parameter<ActivationLayerInfo>("act_info");
Georgios Pinitas407c3e62017-10-25 18:26:46 +0100118
119 // Create and configure function
120 auto batch_norm = arm_compute::support::cpp14::make_unique<arm_compute::CLBatchNormalizationLayer>();
Giorgio Arena11674872018-02-07 15:38:12 +0000121 batch_norm->configure(in, out, mean, var, beta, gamma, epsilon, act_info);
Georgios Pinitas407c3e62017-10-25 18:26:46 +0100122
123 // Log info
124 ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLBatchNormalizationLayer"
125 << " Data Type: " << in->info()->data_type()
126 << " Input shape: " << in->info()->tensor_shape()
127 << " Output shape: " << out->info()->tensor_shape()
128 << " Mean shape: " << mean->info()->tensor_shape()
129 << " Var shape: " << var->info()->tensor_shape()
130 << " Beta shape: " << beta->info()->tensor_shape()
131 << " Gamma shape: " << gamma->info()->tensor_shape()
132 << " Epsilon: " << epsilon
Giorgio Arena11674872018-02-07 15:38:12 +0000133 << " Activation function: " << act_info.activation()
134 << " a: " << act_info.a()
135 << " b: " << act_info.b()
Georgios Pinitas407c3e62017-10-25 18:26:46 +0100136 << std::endl);
137
138 return std::move(batch_norm);
139}
140
Giorgio Arena04a8f8c2017-11-23 11:45:24 +0000141/* DepthConvertLayer Layer */
Michalis Spyrou27c9efb2017-10-09 15:46:30 +0100142REGISTER_SIMPLE_OPERATION(CLDepthConvertLayerOperation, OPENCL, OperationType::DepthConvertLayer)
143{
144 ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1);
145 ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1);
146 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0)) == nullptr);
147 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0)) == nullptr);
148
149 // Extract IO and info
150 auto *in = dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0));
151 auto *out = dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0));
152 const auto conv_policy = ctx.parameter<ConvertPolicy>("ConvertPolicy");
153 const auto shift = ctx.parameter<uint32_t>("shift");
154
155 // Create and configure function
Giorgio Arena04a8f8c2017-11-23 11:45:24 +0000156 auto depthconvert = arm_compute::support::cpp14::make_unique<arm_compute::CLDepthConvertLayer>();
Michalis Spyrou27c9efb2017-10-09 15:46:30 +0100157 depthconvert->configure(in, out, conv_policy, shift);
158
159 // Log info
160 ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLDepthConvertLayer"
161 << " Data Type: " << in->info()->data_type()
162 << " Input shape: " << in->info()->tensor_shape()
163 << " Output shape: " << out->info()->tensor_shape()
164 << " shift: " << shift
165 << std::endl);
166
167 return std::move(depthconvert);
168}
169
Michalis Spyrou7bfe4c52017-11-24 09:54:20 +0000170/* DepthwiseConvolutionLayer Layer */
171REGISTER_SIMPLE_OPERATION(CLDepthwiseConvolutionOperation, OPENCL, OperationType::DepthwiseConvolutionLayer)
172{
Georgios Pinitas236bfe72017-11-23 15:59:55 +0000173 ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 2 && ctx.num_inputs() != 3);
Michalis Spyrou7bfe4c52017-11-24 09:54:20 +0000174 ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1);
175 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0)) == nullptr);
176 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0)) == nullptr);
177
178 // Extract IO and info
179 auto *in = dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0));
180 auto *weights = dynamic_cast<arm_compute::ICLTensor *>(ctx.input(1));
181 auto *biases = ctx.num_inputs() == 3 ? dynamic_cast<arm_compute::ICLTensor *>(ctx.input(2)) : nullptr;
182 auto *out = dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0));
183 const auto conv_info = ctx.parameter<PadStrideInfo>("ConvolutionInfo");
184 const auto opt3x3 = ctx.parameter<bool>("Optimized3x3");
185
186 // Create and configure function
187 std::unique_ptr<arm_compute::IFunction> func;
188 bool run_3x3_opt = opt3x3 && weights->info()->dimension(0) == 3;
189 if(run_3x3_opt)
190 {
Georgios Pinitas1250a5a2018-01-02 13:27:37 +0000191 auto depwthwise_conv = arm_compute::support::cpp14::make_unique<arm_compute::CLDepthwiseConvolutionLayer3x3>();
Michalis Spyrou7bfe4c52017-11-24 09:54:20 +0000192 depwthwise_conv->configure(in, weights, biases, out, conv_info);
193 func = std::move(depwthwise_conv);
194 }
195 else
196 {
Georgios Pinitas1250a5a2018-01-02 13:27:37 +0000197 auto depwthwise_conv = arm_compute::support::cpp14::make_unique<arm_compute::CLDepthwiseConvolutionLayer>();
Michalis Spyrou7bfe4c52017-11-24 09:54:20 +0000198 depwthwise_conv->configure(in, weights, biases, out, conv_info);
199 func = std::move(depwthwise_conv);
200 }
201
202 // Log info
203 ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLDepthwiseConvolutionLayer"
204 << " Data Type: " << in->info()->data_type()
205 << " Input shape: " << in->info()->tensor_shape()
206 << " Weights shape: " << weights->info()->tensor_shape()
207 << " Output shape: " << out->info()->tensor_shape());
208 if(biases == nullptr)
209 {
210 ARM_COMPUTE_LOG_GRAPH_INFO(" Biases shape: No biases provided" << std::endl);
211 }
212 else
213 {
214 ARM_COMPUTE_LOG_GRAPH_INFO(" Biases shape: " << biases->info()->tensor_shape() << std::endl);
215 }
216
217 return func;
218}
219
Michalis Spyrou27c9efb2017-10-09 15:46:30 +0100220/* DeQuantizationLayer Layer */
221REGISTER_SIMPLE_OPERATION(CLDequantizationLayerOperation, OPENCL, OperationType::DequantizationLayer)
222{
223 ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1);
224 ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 2);
225 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0)) == nullptr);
226 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0)) == nullptr);
227 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.output(1)) == nullptr);
228
229 // Extract IO and info
230 auto *in = dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0));
231 auto *out = dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0));
232 auto *min_max = dynamic_cast<arm_compute::ICLTensor *>(ctx.output(1));
233
234 // Create and configure function
235 auto dequantization = arm_compute::support::cpp14::make_unique<arm_compute::CLDequantizationLayer>();
236 dequantization->configure(in, out, min_max);
237
238 // Log info
239 ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLDequantizationLayer"
240 << " Data Type: " << in->info()->data_type()
241 << " Input shape: " << in->info()->tensor_shape()
242 << " Output shape: " << out->info()->tensor_shape()
243 << " Min max shape: " << min_max->info()->tensor_shape()
244 << std::endl);
245
246 return std::move(dequantization);
247}
248
249/* Flatten Layer */
250REGISTER_SIMPLE_OPERATION(CLFlattenLayerOperation, OPENCL, OperationType::FlattenLayer)
251{
252 ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1);
253 ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1);
254 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0)) == nullptr);
255 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0)) == nullptr);
256
257 // Extract IO and info
258 auto *in = dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0));
259 auto *out = dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0));
260
261 // Create and configure function
262 auto flatten = arm_compute::support::cpp14::make_unique<arm_compute::CLFlattenLayer>();
263 flatten->configure(in, out);
264
265 // Log info
Isabella Gottardid0f70992017-11-03 14:48:14 +0000266 ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLFlattenLayer"
Michalis Spyrou27c9efb2017-10-09 15:46:30 +0100267 << " Data Type: " << in->info()->data_type()
268 << " Input shape: " << in->info()->tensor_shape()
269 << " Output shape: " << out->info()->tensor_shape()
270 << std::endl);
271
272 return std::move(flatten);
273}
274
Georgios Pinitas407c3e62017-10-25 18:26:46 +0100275/* Floor Layer */
276REGISTER_SIMPLE_OPERATION(CLFloorLayerOperation, OPENCL, OperationType::FloorLayer)
277{
278 ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1);
279 ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1);
280 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0)) == nullptr);
281 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0)) == nullptr);
282
283 // Extract IO and info
284 auto *in = dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0));
285 auto *out = dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0));
286
287 // Create and configure function
288 auto floor = arm_compute::support::cpp14::make_unique<arm_compute::CLFloor>();
289 floor->configure(in, out);
290
291 // Log info
292 ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLFloorLayer"
293 << " Data Type: " << in->info()->data_type()
294 << " Input shape: " << in->info()->tensor_shape()
295 << " Output shape: " << out->info()->tensor_shape()
296 << std::endl);
297
298 return std::move(floor);
299}
300
301/* Fully Connected Layer */
302REGISTER_SIMPLE_OPERATION(CLFullyConnectedLayer, OPENCL, OperationType::FullyConnectedLayer)
303{
304 ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 3);
305 ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1);
306 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0)) == nullptr);
307 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.input(1)) == nullptr);
308 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.input(2)) == nullptr);
309 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0)) == nullptr);
310
311 // Extract IO and info
312 auto *in = dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0));
313 auto *weights = dynamic_cast<arm_compute::ICLTensor *>(ctx.input(1));
314 auto *biases = dynamic_cast<arm_compute::ICLTensor *>(ctx.input(2));
315 auto *out = dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0));
316
317 // Create and configure function
318 auto fc = arm_compute::support::cpp14::make_unique<arm_compute::CLFullyConnectedLayer>();
319 fc->configure(in, weights, biases, out);
320
321 // Log info
Isabella Gottardid0f70992017-11-03 14:48:14 +0000322 ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLFullyConnectedLayer"
Georgios Pinitas407c3e62017-10-25 18:26:46 +0100323 << " Data Type: " << in->info()->data_type()
324 << " Input shape: " << in->info()->tensor_shape()
325 << " Weights shape: " << weights->info()->tensor_shape()
326 << " Biases Shape: " << biases->info()->tensor_shape()
327 << " Output shape: " << out->info()->tensor_shape()
328 << std::endl);
329
330 return std::move(fc);
331}
332
333/* L2 Normalize Layer */
334REGISTER_SIMPLE_OPERATION(CLL2NormalizeLayerOperation, OPENCL, OperationType::L2NormalizeLayer)
335{
336 ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1);
337 ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1);
338 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0)) == nullptr);
339 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0)) == nullptr);
340
341 // Extract IO and info
342 auto *in = dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0));
343 auto *out = dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0));
344 const auto axis = ctx.parameter<unsigned int>("axis");
345 const auto epsilon = ctx.parameter<float>("epsilon");
346
347 // Create and configure function
Giorgio Arena04a8f8c2017-11-23 11:45:24 +0000348 auto l2_norm = arm_compute::support::cpp14::make_unique<arm_compute::CLL2NormalizeLayer>();
Georgios Pinitas407c3e62017-10-25 18:26:46 +0100349 l2_norm->configure(in, out, axis, epsilon);
350
351 // Log info
352 ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLL2NormalizeLayer"
353 << " Data Type: " << in->info()->data_type()
354 << " Input shape: " << in->info()->tensor_shape()
355 << " Output shape: " << out->info()->tensor_shape()
356 << " Axis: " << axis
357 << " Epsilon: " << epsilon
358 << std::endl);
359
360 return std::move(l2_norm);
361}
362
363/* Normalization Layer */
364REGISTER_SIMPLE_OPERATION(CLNormalizationLayerOperation, OPENCL, OperationType::NormalizationLayer)
365{
366 ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1);
367 ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1);
368 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0)) == nullptr);
369 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0)) == nullptr);
370
371 // Extract IO and info
372 auto *in = dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0));
373 auto *out = dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0));
374 const auto norm_info = ctx.parameter<NormalizationLayerInfo>("NormalizationLayerInfo");
375
376 // Create and configure function
377 auto norm = arm_compute::support::cpp14::make_unique<arm_compute::CLNormalizationLayer>();
378 norm->configure(in, out, norm_info);
379
380 // Log info
381 ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLNormalizationLayer"
382 << " Data Type: " << in->info()->data_type()
383 << " Input shape: " << in->info()->tensor_shape()
384 << " Output shape: " << out->info()->tensor_shape()
385 << " Normalization info: " << norm_info
386 << std::endl);
387
388 return std::move(norm);
389}
390
391/* Pooling Layer */
392REGISTER_SIMPLE_OPERATION(CLPoolingLayerOperation, OPENCL, OperationType::PoolingLayer)
393{
394 ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1);
395 ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1);
396 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0)) == nullptr);
397 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0)) == nullptr);
398
399 // Extract IO and info
400 auto *in = dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0));
401 auto *out = dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0));
402 const auto pool_info = ctx.parameter<PoolingLayerInfo>("PoolingLayerInfo");
403
404 // Create and configure function
405 auto pool = arm_compute::support::cpp14::make_unique<arm_compute::CLPoolingLayer>();
406 pool->configure(in, out, pool_info);
407
408 // Log info
409 ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLPoolingLayer"
410 << " Data Type: " << in->info()->data_type()
411 << " Input shape: " << in->info()->tensor_shape()
412 << " Output shape: " << out->info()->tensor_shape()
413 << " Pooling info: " << pool_info
414 << std::endl);
415
416 return std::move(pool);
417}
418
Michalis Spyrou27c9efb2017-10-09 15:46:30 +0100419/* Quantization Layer */
420REGISTER_SIMPLE_OPERATION(CLQuantizationLayerOperation, OPENCL, OperationType::QuantizationLayer)
421{
422 ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1);
423 ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1);
424 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0)) == nullptr);
425 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0)) == nullptr);
426
427 // Extract IO and info
428 auto *in = dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0));
429 auto *out = dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0));
430
431 // Create and configure function
432 auto quantization = arm_compute::support::cpp14::make_unique<arm_compute::CLQuantizationLayer>();
433 quantization->configure(in, out);
434
435 // Log info
Isabella Gottardid0f70992017-11-03 14:48:14 +0000436 ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLQuantizationLayer"
Michalis Spyrou27c9efb2017-10-09 15:46:30 +0100437 << " Data Type: " << in->info()->data_type()
438 << " Input shape: " << in->info()->tensor_shape()
439 << " Output shape: " << out->info()->tensor_shape()
440 << std::endl);
441
442 return std::move(quantization);
443}
444
445/* Reshape Layer */
446REGISTER_SIMPLE_OPERATION(CLReshapeLayerOperation, OPENCL, OperationType::ReshapeLayer)
447{
448 ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1);
449 ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1);
450 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0)) == nullptr);
451 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0)) == nullptr);
452
453 // Extract IO and info
454 auto *in = dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0));
455 auto *out = dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0));
456
457 // Create and configure function
458 auto reshape = arm_compute::support::cpp14::make_unique<arm_compute::CLReshapeLayer>();
459 reshape->configure(in, out);
460
461 // Log info
Isabella Gottardid0f70992017-11-03 14:48:14 +0000462 ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLReshapeLayer"
Michalis Spyrou27c9efb2017-10-09 15:46:30 +0100463 << " Data Type: " << in->info()->data_type()
464 << " Input shape: " << in->info()->tensor_shape()
465 << " Output shape: " << out->info()->tensor_shape()
466 << std::endl);
467
468 return std::move(reshape);
469}
470
Georgios Pinitas407c3e62017-10-25 18:26:46 +0100471/* Softmax Layer */
472REGISTER_SIMPLE_OPERATION(CLSoftmaxLayerOperation, OPENCL, OperationType::SoftmaxLayer)
473{
474 ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1);
475 ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1);
476 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0)) == nullptr);
477 ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0)) == nullptr);
478
479 // Extract IO and info
480 auto *in = dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0));
481 auto *out = dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0));
482
483 // Create and configure function
484 auto smx = arm_compute::support::cpp14::make_unique<arm_compute::CLSoftmaxLayer>();
485 smx->configure(in, out);
486
487 // Log info
488 ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLSoftmaxLayer"
489 << " Data Type: " << in->info()->data_type()
490 << " Input shape: " << in->info()->tensor_shape()
491 << " Output shape: " << out->info()->tensor_shape()
492 << std::endl);
493
494 return std::move(smx);
Alex Gilday8913d8d2018-02-15 11:07:18 +0000495}