blob: 9f8064e9241f0db2465b6f538dd7ca8b9d7aa083 [file] [log] [blame]
Georgios Pinitasd8734b52017-12-22 15:27:52 +00001/*
Giuseppe Rossinibb365de2019-02-15 10:24:47 +00002 * Copyright (c) 2018-2019 ARM Limited.
Georgios Pinitasd8734b52017-12-22 15:27:52 +00003 *
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 */
Georgios Pinitasd9eb2752018-04-03 13:44:29 +010024#include "arm_compute/graph/backends/CL/CLFunctionFactory.h"
Georgios Pinitasd8734b52017-12-22 15:27:52 +000025
26#include "arm_compute/core/utils/misc/Cast.h"
Georgios Pinitasd9eb2752018-04-03 13:44:29 +010027#include "arm_compute/graph/Graph.h"
Georgios Pinitasda2491f2018-06-01 17:49:09 +010028#include "arm_compute/graph/backends/FunctionHelpers.h"
Georgios Pinitasd8734b52017-12-22 15:27:52 +000029#include "arm_compute/runtime/CL/CLFunctions.h"
Isabella Gottardi7234ed82018-11-27 08:51:10 +000030#include "arm_compute/runtime/CPP/CPPFunctions.h"
Georgios Pinitasd8734b52017-12-22 15:27:52 +000031
Georgios Pinitasd8734b52017-12-22 15:27:52 +000032using namespace arm_compute::utils::cast;
33
34namespace arm_compute
35{
Georgios Pinitasd9eb2752018-04-03 13:44:29 +010036namespace graph
Georgios Pinitasd8734b52017-12-22 15:27:52 +000037{
38namespace backends
39{
Georgios Pinitasda2491f2018-06-01 17:49:09 +010040/** Target specific information structure used to pass information to the layer templates */
41struct CLTargetInfo
Georgios Pinitasd8734b52017-12-22 15:27:52 +000042{
giuros01acce5042019-02-21 17:32:34 +000043 using TensorType = arm_compute::ICLTensor;
44 using TensorConcreteType = CLTensor;
Georgios Pinitasda2491f2018-06-01 17:49:09 +010045 static Target TargetType;
46};
47
48Target CLTargetInfo::TargetType = Target::CL;
49
50/** Collection of CL convolution functions */
51struct CLConvolutionLayerFunctions
Georgios Pinitasd8734b52017-12-22 15:27:52 +000052{
Georgios Pinitasda2491f2018-06-01 17:49:09 +010053 using GenericConvolutionLayer = CLConvolutionLayer;
54 using GEMMConvolutionLayer = CLGEMMConvolutionLayer;
55 using DirectConvolutionLayer = CLDirectConvolutionLayer;
56 using WinogradConvolutionLayer = CLWinogradConvolutionLayer;
57};
Georgios Pinitasd8734b52017-12-22 15:27:52 +000058
Georgios Pinitasda2491f2018-06-01 17:49:09 +010059/** Collection of CL depthwise convolution functions */
60struct CLDepthwiseConvolutionLayerFunctions
Georgios Pinitasd8734b52017-12-22 15:27:52 +000061{
Georgios Pinitasda2491f2018-06-01 17:49:09 +010062 using GenericDepthwiseConvolutionLayer = CLDepthwiseConvolutionLayer;
63 using DepthwiseConvolutionLayer3x3 = CLDepthwiseConvolutionLayer3x3;
64};
Georgios Pinitasd8734b52017-12-22 15:27:52 +000065
Georgios Pinitasda2491f2018-06-01 17:49:09 +010066/** Collection of CL element-wise functions */
67struct CLEltwiseFunctions
Georgios Pinitasd8734b52017-12-22 15:27:52 +000068{
Georgios Pinitasda2491f2018-06-01 17:49:09 +010069 using Addition = CLArithmeticAddition;
70 using Subtraction = CLArithmeticSubtraction;
71 using Multiplication = CLPixelWiseMultiplication;
72};
giuros01acce5042019-02-21 17:32:34 +000073
74/** Function and tensor types to be used inside a CL fused convolution/batch normalization layer */
75struct CLFusedLayerTypes
76{
77 using ConvolutionLayer = CLConvolutionLayer;
78 using FuseBatchNormalization = CLFuseBatchNormalization;
79};
80
Isabella Gottardi7234ed82018-11-27 08:51:10 +000081// TODO (isagot01): Remove once we support heterogeneous scheduling at function level
82/** Wrapper for the CPP Function in the OpenCL backend **/
83class CPPWrapperFunction : public IFunction
84{
85public:
86 /* Default constructor */
87 CPPWrapperFunction()
88 : _tensors(), _func(nullptr)
89 {
90 }
91
92 void run() override
93 {
94 for(auto &tensor : _tensors)
95 {
96 tensor->map(CLScheduler::get().queue());
97 }
98 _func->run();
99
100 for(auto &tensor : _tensors)
101 {
102 tensor->unmap(CLScheduler::get().queue());
103 }
104 }
105
106 void register_tensor(ICLTensor *tensor)
107 {
108 _tensors.push_back(tensor);
109 }
110
111 void register_function(std::unique_ptr<IFunction> function)
112 {
113 _func = std::move(function);
114 }
115
116private:
117 std::vector<arm_compute::ICLTensor *> _tensors;
118 std::unique_ptr<IFunction> _func;
119};
120
121namespace detail
122{
123// Specialized functions
124template <>
125std::unique_ptr<IFunction> create_detection_output_layer<CPPDetectionOutputLayer, CLTargetInfo>(DetectionOutputLayerNode &node)
126{
127 validate_node<CLTargetInfo>(node, 3 /* expected inputs */, 1 /* expected outputs */);
128
129 // Extract IO and info
130 CLTargetInfo::TensorType *input0 = get_backing_tensor<CLTargetInfo>(node.input(0));
131 CLTargetInfo::TensorType *input1 = get_backing_tensor<CLTargetInfo>(node.input(1));
132 CLTargetInfo::TensorType *input2 = get_backing_tensor<CLTargetInfo>(node.input(2));
133 CLTargetInfo::TensorType *output = get_backing_tensor<CLTargetInfo>(node.output(0));
134 const DetectionOutputLayerInfo detect_info = node.detection_output_info();
135
136 ARM_COMPUTE_ERROR_ON(input0 == nullptr);
137 ARM_COMPUTE_ERROR_ON(input1 == nullptr);
138 ARM_COMPUTE_ERROR_ON(input2 == nullptr);
139 ARM_COMPUTE_ERROR_ON(output == nullptr);
140
141 // Create and configure function
142 auto func = support::cpp14::make_unique<CPPDetectionOutputLayer>();
143 func->configure(input0, input1, input2, output, detect_info);
144
145 // Log info
146 ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated "
147 << node.name()
148 << " Type: " << node.type()
149 << " Target: " << CLTargetInfo::TargetType
150 << " Data Type: " << input0->info()->data_type()
151 << " Input0 shape: " << input0->info()->tensor_shape()
152 << " Input1 shape: " << input1->info()->tensor_shape()
153 << " Input2 shape: " << input2->info()->tensor_shape()
154 << " Output shape: " << output->info()->tensor_shape()
155 << " DetectionOutputLayer info: " << detect_info
156 << std::endl);
157
158 auto wrap_function = support::cpp14::make_unique<CPPWrapperFunction>();
159 ;
160 wrap_function->register_function(std::move(func));
161 wrap_function->register_tensor(input0);
162 wrap_function->register_tensor(input1);
163 wrap_function->register_tensor(input2);
164 wrap_function->register_tensor(output);
165
166 return std::move(wrap_function);
167}
168} // namespace detail
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000169
170std::unique_ptr<IFunction> CLFunctionFactory::create(INode *node, GraphContext &ctx)
171{
172 if(node == nullptr)
173 {
174 return nullptr;
175 }
176
177 NodeType type = node->type();
178 switch(type)
179 {
180 case NodeType::ActivationLayer:
Georgios Pinitasda2491f2018-06-01 17:49:09 +0100181 return detail::create_activation_layer<CLActivationLayer, CLTargetInfo>(*polymorphic_downcast<ActivationLayerNode *>(node));
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000182 case NodeType::BatchNormalizationLayer:
Georgios Pinitasda2491f2018-06-01 17:49:09 +0100183 return detail::create_batch_normalization_layer<CLBatchNormalizationLayer, CLTargetInfo>(*polymorphic_downcast<BatchNormalizationLayerNode *>(node));
Manuel Bottinid2048ce2018-10-23 17:00:42 +0100184 case NodeType::BoundingBoxTransformLayer:
185 return detail::create_bounding_box_transform_layer<CLBoundingBoxTransform, CLTargetInfo>(*polymorphic_downcast<BoundingBoxTransformLayerNode *>(node));
Georgios Pinitas087eaf62018-05-16 15:52:35 +0100186 case NodeType::ChannelShuffleLayer:
Georgios Pinitasda2491f2018-06-01 17:49:09 +0100187 return detail::create_channel_shuffle_layer<CLChannelShuffleLayer, CLTargetInfo>(*polymorphic_downcast<ChannelShuffleLayerNode *>(node));
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000188 case NodeType::ConvolutionLayer:
Georgios Pinitasda2491f2018-06-01 17:49:09 +0100189 return detail::create_convolution_layer<CLConvolutionLayerFunctions, CLTargetInfo>(*polymorphic_downcast<ConvolutionLayerNode *>(node), ctx);
Georgios Pinitas087eaf62018-05-16 15:52:35 +0100190 case NodeType::DeconvolutionLayer:
Georgios Pinitasda2491f2018-06-01 17:49:09 +0100191 return detail::create_deconvolution_layer<CLDeconvolutionLayer, CLTargetInfo>(*polymorphic_downcast<DeconvolutionLayerNode *>(node), ctx);
Georgios Pinitase2220552018-07-20 13:23:44 +0100192 case NodeType::ConcatenateLayer:
193 return detail::create_concatenate_layer<CLConcatenateLayer, CLTargetInfo>(*polymorphic_downcast<ConcatenateLayerNode *>(node));
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000194 case NodeType::DepthwiseConvolutionLayer:
Georgios Pinitasda2491f2018-06-01 17:49:09 +0100195 return detail::create_depthwise_convolution_layer<CLDepthwiseConvolutionLayerFunctions, CLTargetInfo>(*polymorphic_downcast<DepthwiseConvolutionLayerNode *>(node));
Isabella Gottardi7234ed82018-11-27 08:51:10 +0000196 case NodeType::DetectionOutputLayer:
197 return detail::create_detection_output_layer<CPPDetectionOutputLayer, CLTargetInfo>(*polymorphic_downcast<DetectionOutputLayerNode *>(node));
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000198 case NodeType::EltwiseLayer:
Georgios Pinitasda2491f2018-06-01 17:49:09 +0100199 return detail::create_eltwise_layer<CLEltwiseFunctions, CLTargetInfo>(*polymorphic_downcast<EltwiseLayerNode *>(node));
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000200 case NodeType::FlattenLayer:
Georgios Pinitasda2491f2018-06-01 17:49:09 +0100201 return detail::create_flatten_layer<CLFlattenLayer, CLTargetInfo>(*polymorphic_downcast<FlattenLayerNode *>(node));
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000202 case NodeType::FullyConnectedLayer:
Georgios Pinitasda2491f2018-06-01 17:49:09 +0100203 return detail::create_fully_connected_layer<CLFullyConnectedLayer, CLTargetInfo>(*polymorphic_downcast<FullyConnectedLayerNode *>(node), ctx);
giuros01acce5042019-02-21 17:32:34 +0000204 case NodeType::FusedConvolutionBatchNormalizationLayer:
205 return detail::create_fused_convolution_batch_normalization_layer<CLFusedLayerTypes, CLTargetInfo>(*polymorphic_downcast<FusedConvolutionBatchNormalizationNode *>(node));
Manuel Bottini5209be52019-02-13 16:34:56 +0000206 case NodeType::GenerateProposalsLayer:
207 return detail::create_generate_proposals_layer<CLGenerateProposalsLayer, CLTargetInfo>(*polymorphic_downcast<GenerateProposalsLayerNode *>(node), ctx);
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000208 case NodeType::NormalizationLayer:
Georgios Pinitasda2491f2018-06-01 17:49:09 +0100209 return detail::create_normalization_layer<CLNormalizationLayer, CLTargetInfo>(*polymorphic_downcast<NormalizationLayerNode *>(node), ctx);
Michele Di Giorgio555d1102018-09-12 13:51:59 +0100210 case NodeType::NormalizePlanarYUVLayer:
211 return detail::create_normalize_planar_yuv_layer<CLNormalizePlanarYUVLayer, CLTargetInfo>(*polymorphic_downcast<NormalizePlanarYUVLayerNode *>(node));
Michele Di Giorgio4bb17332018-09-26 13:56:51 +0100212 case NodeType::PadLayer:
213 return detail::create_pad_layer<CLPadLayer, CLTargetInfo>(*polymorphic_downcast<PadLayerNode *>(node));
Georgios Pinitas57c48242018-08-02 13:41:49 +0100214 case NodeType::PermuteLayer:
215 return detail::create_permute_layer<CLPermute, CLTargetInfo>(*polymorphic_downcast<PermuteLayerNode *>(node));
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000216 case NodeType::PoolingLayer:
Georgios Pinitasda2491f2018-06-01 17:49:09 +0100217 return detail::create_pooling_layer<CLPoolingLayer, CLTargetInfo>(*polymorphic_downcast<PoolingLayerNode *>(node));
Pablo Tello32521432018-11-15 14:43:10 +0000218 case NodeType::PriorBoxLayer:
219 return detail::create_priorbox_layer<CLPriorBoxLayer, CLTargetInfo>(*polymorphic_downcast<PriorBoxLayerNode *>(node));
Isabella Gottardi3db1ba92019-05-17 12:35:20 +0100220 case NodeType::QuantizationLayer:
221 return detail::create_quantization_layer<CLQuantizationLayer, CLTargetInfo>(*polymorphic_downcast<QuantizationLayerNode *>(node));
Gian Marco Iodice23e24792018-09-07 15:32:14 +0100222 case NodeType::ReorgLayer:
223 return detail::create_reorg_layer<CLReorgLayer, CLTargetInfo>(*polymorphic_downcast<ReorgLayerNode *>(node));
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000224 case NodeType::ReshapeLayer:
Georgios Pinitasda2491f2018-06-01 17:49:09 +0100225 return detail::create_reshape_layer<CLReshapeLayer, CLTargetInfo>(*polymorphic_downcast<ReshapeLayerNode *>(node));
Georgios Pinitas087eaf62018-05-16 15:52:35 +0100226 case NodeType::ResizeLayer:
Georgios Pinitasda2491f2018-06-01 17:49:09 +0100227 return detail::create_resize_layer<CLScale, CLTargetInfo>(*polymorphic_downcast<ResizeLayerNode *>(node));
Manuel Bottini3f9d4d72018-10-19 14:04:42 +0100228 case NodeType::ROIAlignLayer:
229 return detail::create_roi_align_layer<CLROIAlignLayer, CLTargetInfo>(*polymorphic_downcast<ROIAlignLayerNode *>(node));
Michele Di Giorgioc30b6682018-09-12 17:44:08 +0100230 case NodeType::SliceLayer:
231 return detail::create_slice_layer<CLSlice, CLTargetInfo>(*polymorphic_downcast<SliceLayerNode *>(node));
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000232 case NodeType::SoftmaxLayer:
Georgios Pinitasda2491f2018-06-01 17:49:09 +0100233 return detail::create_softmax_layer<CLSoftmaxLayer, CLTargetInfo>(*polymorphic_downcast<SoftmaxLayerNode *>(node), ctx);
Michele Di Giorgioec699752019-03-22 15:25:32 +0000234 case NodeType::StackLayer:
235 return detail::create_stack_layer<CLStackLayer, CLTargetInfo>(*polymorphic_downcast<StackLayerNode *>(node));
Michalis Spyrou4e1c3f32018-09-20 17:14:03 +0100236 case NodeType::UpsampleLayer:
237 return detail::create_upsample_layer<CLUpsampleLayer, CLTargetInfo>(*polymorphic_downcast<UpsampleLayerNode *>(node), ctx);
Michalis Spyrou96f67692018-09-13 11:39:28 +0100238 case NodeType::YOLOLayer:
239 return detail::create_yolo_layer<CLYOLOLayer, CLTargetInfo>(*polymorphic_downcast<YOLOLayerNode *>(node), ctx);
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000240 default:
241 return nullptr;
242 }
243}
244} // namespace backends
Georgios Pinitasd9eb2752018-04-03 13:44:29 +0100245} // namespace graph
Michele Di Giorgio555d1102018-09-12 13:51:59 +0100246} // namespace arm_compute