Compute Library
 22.08
Conv2dContent Struct Reference

#include <OperatorGraphImpl.h>

Collaboration diagram for Conv2dContent:
[legend]

Public Member Functions

 Conv2dContent ()=default
 
 Conv2dContent (const OperatorGraph::Implementation *graph, Id id, const Conv2dDescriptor &desc, const ITensorDescPack< OpTensorContent > &tensors)
 
 Conv2dContent (const OperatorGraph::Implementation *graph, Id id, const Conv2dDescriptor &desc, const ITensorDescPack< OpTensorContent > &tensors, ConvolutionMethod method)
 
 ~Conv2dContent ()=default
 
 Conv2dContent (const Conv2dContent &)=default
 
Conv2dContentoperator= (const Conv2dContent &)=default
 
 Conv2dContent (Conv2dContent &&)=default
 
Conv2dContentoperator= (Conv2dContent &&)=default
 
bool operator== (const OperatorContent &other) const override
 
OperatorComplexity complexity () const override
 
void set_method (ConvolutionMethod method)
 
Status translate (ClKernelGraph &kernel_graph) const override
 
- Public Member Functions inherited from OperatorContent
 OperatorContent ()=default
 
 OperatorContent (const OperatorGraph::Implementation *graph, Id id, const ITensorDescPack< OpTensorContent > &tensors)
 
 OperatorContent (const OperatorContent &op)=default
 
OperatorContentoperator= (const OperatorContent &op)=default
 
 OperatorContent (OperatorContent &&op)=default
 
OperatorContentoperator= (OperatorContent &&op)=default
 
virtual ~OperatorContent ()=default
 

Static Public Member Functions

static ConvolutionMethod select_conv_method (const ITensorInfo *src, const ITensorInfo *weights, const ITensorInfo *dst, const Conv2dDescriptor &conv2d_desc, const GPUTarget gpu_target)
 Replicate heuristics of ClConv2d::get_convolution_method(), except that non-supported data types and data layouts are removed from the heuristics. More...
 

Data Fields

Conv2dDescriptor desc {}
 
ConvolutionMethod forced_method { ConvolutionMethod::GEMM_CONV2D }
 
bool forced_method_enabled { false }
 

Additional Inherited Members

- Public Types inherited from OperatorContent
using Id = DependencyGraph::Id
 

Detailed Description

Definition at line 111 of file OperatorGraphImpl.h.

Constructor & Destructor Documentation

◆ Conv2dContent() [1/5]

Conv2dContent ( )
default

◆ Conv2dContent() [2/5]

◆ Conv2dContent() [3/5]

◆ ~Conv2dContent()

~Conv2dContent ( )
default

◆ Conv2dContent() [4/5]

Conv2dContent ( const Conv2dContent )
default

◆ Conv2dContent() [5/5]

Conv2dContent ( Conv2dContent &&  )
default

Member Function Documentation

◆ complexity()

OperatorComplexity complexity ( ) const
inlineoverridevirtual

◆ operator=() [1/2]

Conv2dContent& operator= ( const Conv2dContent )
default

◆ operator=() [2/2]

Conv2dContent& operator= ( Conv2dContent &&  )
default

◆ operator==()

bool operator== ( const OperatorContent other) const
overridevirtual

Implements OperatorContent.

Definition at line 126 of file OperatorGraphImpl.cpp.

References Conv2dContent::desc.

127 {
128  const auto converted = *utils::cast::polymorphic_downcast<const Conv2dContent *>(&other);
129  return desc == converted.desc;
130 }

◆ select_conv_method()

ConvolutionMethod select_conv_method ( const ITensorInfo src,
const ITensorInfo weights,
const ITensorInfo dst,
const Conv2dDescriptor conv2d_desc,
const GPUTarget  gpu_target 
)
static

Replicate heuristics of ClConv2d::get_convolution_method(), except that non-supported data types and data layouts are removed from the heuristics.

Parameters
src
weights
dst
conv2d_desc
gpu_target
Returns
ConvolutionMethod

Definition at line 144 of file OperatorGraphImpl.cpp.

References ARM_COMPUTE_ERROR, ARM_COMPUTE_ERROR_ON_NULLPTR, Padding2D::bottom, arm_compute::CHANNEL, arm_compute::misc::shape_calculator::compute_deep_convolution_shape(), ITensorInfo::data_layout(), arm_compute::test::validation::data_layout, ITensorInfo::data_type(), Conv2dDescriptor::dilation, ITensorInfo::dimension(), arm_compute::DIRECT, arm_compute::FLOOR, arm_compute::G71, arm_compute::G72, arm_compute::GEMM, arm_compute::get_data_layout_dimension_index(), arm_compute::HEIGHT, arm_compute::test::validation::info, arm_compute::is_data_type_float(), Padding2D::left, arm_compute::MIDGARD, arm_compute::NCHW, arm_compute::NHWC, arm_compute::test::validation::output_shape, Conv2dDescriptor::pad, PadStrideInfo::pad_bottom(), PadStrideInfo::pad_left(), PadStrideInfo::pad_right(), PadStrideInfo::pad_top(), Padding2D::right, Conv2dDescriptor::stride, PadStrideInfo::stride(), Padding2D::top, arm_compute::utils::cast::U, ClDirectConv2dKernel::validate(), arm_compute::WIDTH, Size2D::x(), and Size2D::y().

Referenced by Conv2dContent::translate().

145 {
146  // Modified from ClConv2d::get_convolution_method
147 
151 
152  const PadStrideInfo legacy_pad_stride(conv2d_desc.stride.x(), conv2d_desc.stride.y(), conv2d_desc.pad.left, conv2d_desc.pad.right, conv2d_desc.pad.top, conv2d_desc.pad.bottom, DimensionRoundingType{});
153  const Size2D dilation = conv2d_desc.dilation;
154 
155  const size_t idx_w = get_data_layout_dimension_index(src->data_layout(), DataLayoutDimension::WIDTH);
156  const size_t idx_h = get_data_layout_dimension_index(src->data_layout(), DataLayoutDimension::HEIGHT);
157  const size_t idx_c = get_data_layout_dimension_index(src->data_layout(), DataLayoutDimension::CHANNEL);
158 
159  /* Input spatial dims, kernel size, IFM/OFM, conv info*/
160  using ConvolutionConfiguration = std::tuple<Size2D, Size2D, Size2D, PadStrideInfo, DataLayout>;
161  using ConfigurationMethod = std::pair<ConvolutionConfiguration, ConvolutionMethod>;
162 
163  const std::vector<ConfigurationMethod> known_configs =
164  {
165  // Alexnet
166  ConfigurationMethod(ConvolutionConfiguration(Size2D(27U, 27U), Size2D(5U, 5U), Size2D(48U, 128U), PadStrideInfo(1U, 1U, 2U, 2U), DataLayout::NCHW), ConvolutionMethod::DIRECT),
167  // VGG16 / VGG19
168  ConfigurationMethod(ConvolutionConfiguration(Size2D(224U, 224U), Size2D(3U, 3U), Size2D(3U, 64U), PadStrideInfo(1U, 1U, 1U, 1U), DataLayout::NCHW), ConvolutionMethod::DIRECT),
169  // Mobilenet 224
170  ConfigurationMethod(ConvolutionConfiguration(Size2D(224U, 224U), Size2D(3U, 3U), Size2D(3U, 32U), PadStrideInfo(2U, 2U, 0U, 1U, 0U, 1U, DimensionRoundingType::FLOOR), DataLayout::NCHW), ConvolutionMethod::GEMM),
171  // Mobilenet 160
172  ConfigurationMethod(ConvolutionConfiguration(Size2D(160U, 160U), Size2D(3U, 3U), Size2D(3U, 24U), PadStrideInfo(2U, 2U, 0U, 1U, 0U, 1U, DimensionRoundingType::FLOOR), DataLayout::NCHW), ConvolutionMethod::GEMM),
173  // Mobilenet 224
174  ConfigurationMethod(ConvolutionConfiguration(Size2D(224U, 224U), Size2D(3U, 3U), Size2D(3U, 32U), PadStrideInfo(2U, 2U, 0U, 1U, 0U, 1U, DimensionRoundingType::FLOOR), DataLayout::NHWC), ConvolutionMethod::GEMM),
175  // Mobilenet 160
176  ConfigurationMethod(ConvolutionConfiguration(Size2D(160U, 160U), Size2D(3U, 3U), Size2D(3U, 24U), PadStrideInfo(2U, 2U, 0U, 1U, 0U, 1U, DimensionRoundingType::FLOOR), DataLayout::NHWC), ConvolutionMethod::GEMM),
177  };
178 
179  const auto find_config = [&](ConfigurationMethod c)
180  {
181  const ConvolutionConfiguration config = c.first;
182  const PadStrideInfo info = std::get<3>(config);
183  const DataLayout data_layout = std::get<4>(config);
184 
185  return std::get<0>(config) == Size2D(src->dimension(idx_w), src->dimension(idx_h)) && std::get<1>(config) == Size2D(weights->dimension(idx_w), weights->dimension(idx_h))
186  && std::get<2>(config) == Size2D(weights->dimension(idx_c), weights->dimension(3)) && info.pad_top() == legacy_pad_stride.pad_top() && info.pad_right() == legacy_pad_stride.pad_right()
187  && info.pad_bottom() == legacy_pad_stride.pad_bottom() && info.pad_left() == legacy_pad_stride.pad_left() && info.stride() == legacy_pad_stride.stride() && (data_layout == src->data_layout());
188  };
189 
190  std::vector<ConfigurationMethod>::const_iterator found;
191  if((found = std::find_if(known_configs.begin(), known_configs.end(), find_config)) != known_configs.end())
192  {
193  return (*found).second;
194  }
195 
196  if(dilation != Size2D(1U, 1U))
197  {
199  }
200  else
201  {
202  if(src->data_layout() == DataLayout::NCHW)
203  {
204  ARM_COMPUTE_ERROR("NCHW not supported");
205  }
206  else
207  {
208  const bool is_direct_valid = bool(ClDirectConv2dKernel::validate(src, weights, nullptr, dst, ClDirectConv2dKernelDescriptor{ conv2d_desc }));
209  const size_t kernel_sz_direct_conv_thr = get_direct_conv_kernel_threshold_nhwc(gpu_target);
210 
211  // SRGAN case
212  if((src->dimension(idx_h) > 720U) && (dst->dimension(idx_h) > 720U) && (weights->dimension(idx_h) == 9) && (conv2d_desc.pad.top < 3)
213  && is_direct_valid)
214  {
216  }
217 
218  // Floating-point case: GeMM/Direct
219  if(is_data_type_float(src->data_type()))
220  {
221  // Get dst shape
222  TensorShape output_shape = misc::shape_calculator::compute_deep_convolution_shape(*src, *weights, legacy_pad_stride);
223  const bool is_large_kernel_sz = (weights->dimension(idx_w) >= kernel_sz_direct_conv_thr) && (weights->dimension(idx_h) >= kernel_sz_direct_conv_thr);
224  const bool is_ifm_ge_16 = src->dimension(idx_c) >= 16;
225  const bool is_ofm_lte_8 = weights->dimension(3U) <= 8;
226  const bool workload_gte_8192 = (output_shape[0] * output_shape[1] * output_shape[2]) / 16 >= 8192;
227  const bool is_ifm_gt_ofm = src->dimension(idx_c) > weights->dimension(3U);
228 
229  // Direct convolution case
230  if(is_direct_valid)
231  {
232  if((gpu_target == arm_compute::GPUTarget::G71 || gpu_target == arm_compute::GPUTarget::G72 || gpu_target == arm_compute::GPUTarget::MIDGARD))
233  {
234  if(is_large_kernel_sz && is_ifm_ge_16 && is_ifm_gt_ofm)
235  {
237  }
238  }
239  else
240  {
241  if((is_large_kernel_sz && workload_gte_8192 && is_ifm_ge_16) || (is_ofm_lte_8 && is_ifm_ge_16))
242  {
244  }
245  }
246  }
247 
248  // Default case
250  }
251 
252  // Generic case for quantized. Only GeMM
254  }
255  }
257 }
#define ARM_COMPUTE_ERROR(msg)
Print the given message then throw an std::runtime_error.
Definition: Error.h:352
DimensionRoundingType
Dimension rounding type when down-scaling on CNNs.
Definition: Types.h:550
static Status validate(const ITensorInfo *src, const ITensorInfo *weights, const ITensorInfo *biases, const ITensorInfo *dst, const ClDirectConv2dKernelDescriptor &conv2d_desc)
SimpleTensor< float > src
Definition: DFT.cpp:155
Num samples, channels, height, width.
ScaleKernelInfo info(interpolation_policy, default_border_mode, PixelValue(), sampling_policy, false)
size_t get_data_layout_dimension_index(const DataLayout &data_layout, const DataLayoutDimension &data_layout_dimension)
Get the index of the given dimension.
Definition: Helpers.inl:193
Num samples, height, width, channels.
#define ARM_COMPUTE_ERROR_ON_NULLPTR(...)
Definition: Validate.h:157
DataLayout
[DataLayout enum definition]
Definition: Types.h:113
Convolution using GEMM.
TensorShape compute_deep_convolution_shape(const TensorShape &input_shape, DataLayout input_data_layout, const TensorShape &weights_shape, const PadStrideInfo &conv_info)
Calculate the deep convolution shape output shape of a tensor.
bool is_data_type_float(DataType dt)
Check if a given data type is of floating point type.
Definition: Utils.h:1010

◆ set_method()

◆ translate()

Status translate ( ClKernelGraph kernel_graph) const
overridevirtual

Implements OperatorContent.

Definition at line 259 of file OperatorGraphImpl.cpp.

References arm_compute::ACL_DST_0, arm_compute::ACL_SRC_0, arm_compute::ACL_SRC_1, arm_compute::ACL_SRC_2, ITensorDescPack< TDesc >::add_const_tensor(), ClKernelGraph::add_kernel(), ARM_COMPUTE_ERROR_ON_NULLPTR, ARM_COMPUTE_RETURN_ERROR_MSG, ARM_COMPUTE_RETURN_ON_ERROR, ARM_COMPUTE_UNUSED, bias, Conv2dContent::desc, arm_compute::DIRECT, arm_compute::test::validation::dst, Conv2dContent::forced_method, Conv2dContent::forced_method_enabled, CLScheduler::get(), ClKernelGraph::get_tensor(), arm_compute::test::validation::input, UnitWorkloadStage::Run, Conv2dContent::select_conv_method(), CLScheduler::target(), arm_compute::experimental::dynamic_fusion::TStoreIndirectWidthSelect, and ClDirectConv2dKernel::validate().

260 {
261  const auto input = _tensors.get_const_tensor(TensorType::ACL_SRC_0);
262  const auto weight = _tensors.get_const_tensor(TensorType::ACL_SRC_1);
263  const auto dst = _tensors.get_const_tensor(TensorType::ACL_DST_0);
264  const auto method = forced_method_enabled ? forced_method : Conv2dContent::select_conv_method(input->desc, weight->desc, dst->desc, desc, CLScheduler::get().target());
265  switch(method)
266  {
268  {
269  return translate_direct_conv2d(kernel_graph);
270  }
271  default:
272  {
273  ARM_COMPUTE_RETURN_ERROR_MSG("Not implemented");
274  }
275  }
276  return Status{};
277 }
static CLScheduler & get()
Access the scheduler singleton.
GPUTarget target() const
Get the target GPU.
Definition: CLScheduler.cpp:49
#define ARM_COMPUTE_RETURN_ERROR_MSG(...)
An error is returned with the given description.
Definition: Error.h:194
static ConvolutionMethod select_conv_method(const ITensorInfo *src, const ITensorInfo *weights, const ITensorInfo *dst, const Conv2dDescriptor &conv2d_desc, const GPUTarget gpu_target)
Replicate heuristics of ClConv2d::get_convolution_method(), except that non-supported data types and ...

Field Documentation

◆ desc

◆ forced_method

Definition at line 153 of file OperatorGraphImpl.h.

Referenced by Conv2dContent::translate().

◆ forced_method_enabled

bool forced_method_enabled { false }

Definition at line 154 of file OperatorGraphImpl.h.

Referenced by Conv2dContent::translate().


The documentation for this struct was generated from the following files: