Compute Library
 23.11
NEConvolutionLayer.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017-2021, 2023 Arm Limited.
3  *
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  */
25 
27 #include "arm_compute/core/Utils.h"
31 
32 #include "src/common/utils/Log.h"
39 
40 namespace arm_compute
41 {
42 using namespace arm_compute::experimental;
43 
44 struct NEConvolutionLayer::Impl
45 {
46  MemoryGroup memory_group{};
47  std::shared_ptr<IMemoryManager> memory_manager{};
48  std::unique_ptr<cpu::ICpuOperator> op{nullptr};
49  ITensorPack run_pack{};
50  ITensorPack prep_pack{};
51  WorkspaceData<Tensor> workspace{};
53  std::unique_ptr<IFunction> func{nullptr};
54 };
55 
56 NEConvolutionLayer::NEConvolutionLayer(std::shared_ptr<IMemoryManager> memory_manager) : _impl(std::make_unique<Impl>())
57 {
58  _impl->memory_manager = std::move(memory_manager);
59 }
60 
62 
64  const ITensor *weights,
65  const ITensor *biases,
66  ITensor *output,
67  const PadStrideInfo &conv_info,
69  const Size2D &dilation,
71  bool enable_fast_math,
72  unsigned int num_groups)
73 {
74  // Perform validate step
75  ARM_COMPUTE_ERROR_ON_NULLPTR(input, weights, output);
78  input->info(), weights->info(), ((biases != nullptr) ? biases->info() : nullptr), output->info(), conv_info,
79  weights_info, dilation, act_info, enable_fast_math, num_groups));
80  ARM_COMPUTE_LOG_PARAMS(input, weights, biases, output, conv_info, weights_info, dilation, act_info,
81  enable_fast_math, num_groups);
82 
83  const Conv2dInfo info(conv_info, dilation, act_info, enable_fast_math, num_groups);
84  switch (cpu::CpuConv2d::get_convolution_method(input->info(), weights->info(), output->info(), conv_info,
85  weights_info, dilation, act_info, enable_fast_math))
86  {
91  {
92  auto f = std::make_unique<cpu::CpuConv2d>();
93  f->configure(input->info(), weights->info(), ((biases != nullptr) ? biases->info() : nullptr),
94  output->info(), conv_info, weights_info, dilation, act_info, enable_fast_math, num_groups);
95  _impl->op = std::move(f);
96  break;
97  }
99  {
100  auto f = std::make_unique<NEFFTConvolutionLayer>(_impl->memory_manager);
101  f->configure(input, weights, biases, output, conv_info, act_info);
102  _impl->func = std::move(f);
103  break;
104  }
105  default:
106  ARM_COMPUTE_ERROR("Not supported.");
107  break;
108  }
109 
110  if (_impl->op)
111  {
112  _impl->memory_group = MemoryGroup(std::move(_impl->memory_manager));
113  _impl->aux_mem_req = _impl->op->workspace();
114  _impl->run_pack = {{ACL_SRC_0, input}, {ACL_SRC_1, weights}, {ACL_SRC_2, biases}, {ACL_DST, output}};
115  _impl->prep_pack = {{ACL_SRC_1, weights}, {ACL_SRC_2, biases}};
116  _impl->workspace =
117  manage_workspace<Tensor>(_impl->aux_mem_req, _impl->memory_group, _impl->run_pack, _impl->prep_pack);
118  }
119 }
120 
122  const ITensorInfo *weights,
123  const ITensorInfo *biases,
124  const ITensorInfo *output,
125  const PadStrideInfo &conv_info,
126  const WeightsInfo &weights_info,
127  const Size2D &dilation,
129  bool enable_fast_math,
130  unsigned int num_groups)
131 {
132  const Conv2dInfo info(conv_info, dilation, act_info, enable_fast_math, num_groups);
133 
134  ARM_COMPUTE_RETURN_ERROR_ON_MSG(!weights->are_values_constant(), "Dynamic weights are not supported");
135 
136  // Biases with dynamic values are not supported with quantized inputs.
137  if (biases)
138  {
140  "Dynamic Biases are not supported with quantized input data.");
141  }
142 
143  switch (cpu::CpuConv2d::get_convolution_method(input, weights, output, conv_info, weights_info, dilation, act_info,
144  enable_fast_math))
145  {
151  weights_info, dilation, act_info, enable_fast_math,
152  num_groups));
153  break;
156  NEFFTConvolutionLayer::validate(input, weights, biases, output, conv_info, act_info));
157  break;
158  default:
159  ARM_COMPUTE_ERROR("Not supported.");
160  break;
161  }
162  return Status{};
163 }
164 
166  const ITensorInfo *weights,
167  const ITensorInfo *output,
168  const PadStrideInfo &conv_info,
169  const WeightsInfo &weights_info,
170  const Size2D &dilation,
172  bool enable_fast_math)
173 {
174  return cpu::CpuConv2d::get_convolution_method(input, weights, output, conv_info, weights_info, dilation, act_info,
175  enable_fast_math);
176 }
177 
179 {
180  prepare();
181 
182  MemoryGroupResourceScope scope_mg(_impl->memory_group);
183 
184  if (_impl->func)
185  {
186  _impl->func->run();
187  }
188  else
189  {
190  _impl->op->run(_impl->run_pack);
191  }
192 }
193 
195 {
196  if (_impl->func)
197  {
198  _impl->func->prepare();
199  }
200  else
201  {
202  _impl->op->prepare(_impl->prep_pack);
203 
204  // Release temporary tensors that are only used in prepare stage
205  release_temporaries<Tensor>(_impl->aux_mem_req, _impl->workspace);
206  }
207 }
208 } // namespace arm_compute
arm_compute::experimental::MemoryRequirements
std::vector< MemoryInfo > MemoryRequirements
Definition: Types.h:123
arm_compute::NEConvolutionLayer::configure
void configure(ITensor *input, const ITensor *weights, const ITensor *biases, ITensor *output, const PadStrideInfo &conv_info, const WeightsInfo &weights_info=WeightsInfo(), const Size2D &dilation=Size2D(1U, 1U), const ActivationLayerInfo &act_info=ActivationLayerInfo(), bool enable_fast_math=false, unsigned int num_groups=1)
Set the input and output tensors.
Definition: NEConvolutionLayer.cpp:63
DataTypeUtils.h
arm_compute::WeightsInfo
Convolution Layer Weights Information class.
Definition: Types.h:1670
arm_compute::ConvolutionMethod::FFT
@ FFT
Convolution using FFT.
arm_compute::test::validation::weights_info
weights_info
Definition: BatchNormalizationLayer.cpp:165
CpuGemmDirectConv2d.h
arm_compute::NEConvolutionLayer::~NEConvolutionLayer
~NEConvolutionLayer()
Default destructor.
arm_compute::NEConvolutionLayer::prepare
void prepare() override
Prepare the function for executing.
Definition: NEConvolutionLayer.cpp:194
ARM_COMPUTE_ERROR
#define ARM_COMPUTE_ERROR(msg)
Print the given message then throw an std::runtime_error.
Definition: Error.h:354
arm_compute::Size2D
Class for specifying the size of an image or rectangle.
Definition: Size2D.h:34
NEConvolutionLayer.h
arm_compute::ITensor
Interface for CPU tensor.
Definition: ITensor.h:36
arm_compute::ACL_SRC_0
@ ACL_SRC_0
Definition: Types.h:45
arm_compute::ACL_SRC_1
@ ACL_SRC_1
Definition: Types.h:46
arm_compute::ACL_SRC_2
@ ACL_SRC_2
Definition: Types.h:47
CpuGemmConv2d.h
arm_compute::Conv2dInfo
Descriptor used by the 2d Convolution function.
Definition: FunctionDescriptors.h:57
ARM_COMPUTE_RETURN_ON_ERROR
#define ARM_COMPUTE_RETURN_ON_ERROR(status)
Checks if a status contains an error and returns it.
Definition: Error.h:205
arm_compute::ConvolutionMethod
ConvolutionMethod
Available ConvolutionMethod.
Definition: Types.h:91
arm_compute::ActivationLayerInfo
Activation Layer Information class.
Definition: ActivationLayerInfo.h:55
arm_compute::test::validation::act_info
act_info
Definition: DirectConvolutionLayer.cpp:547
ARM_COMPUTE_ERROR_ON_NULLPTR
#define ARM_COMPUTE_ERROR_ON_NULLPTR(...)
Definition: Validate.h:159
arm_compute::ITensor::info
virtual ITensorInfo * info() const =0
Interface to be implemented by the child class to return the tensor's metadata.
NEFFTConvolutionLayer.h
ARM_COMPUTE_ERROR_THROW_ON
#define ARM_COMPUTE_ERROR_THROW_ON(status)
Definition: Error.h:455
arm_compute::cpu::CpuConv2d::get_convolution_method
static ConvolutionMethod get_convolution_method(const ITensorInfo *src, const ITensorInfo *weights, const ITensorInfo *dst, const PadStrideInfo &conv_info, const WeightsInfo &weights_info=WeightsInfo(), const Size2D &dilation=Size2D(1U, 1U), const ActivationLayerInfo &act_info=ActivationLayerInfo(), bool enable_fast_math=false)
Static function to check if given info will return the convolution called by CpuConv2d.
Definition: CpuConv2d.cpp:145
arm_compute::ACL_DST
@ ACL_DST
Definition: Types.h:55
arm_compute::Status
Status class.
Definition: Error.h:52
CpuWinogradConv2d.h
arm_compute::ConvolutionMethod::WINOGRAD
@ WINOGRAD
Convolution using Winograd.
arm_compute::ConvolutionMethod::GEMM_CONV2D
@ GEMM_CONV2D
Direct 2D GEMM convolution.
arm_compute::ConvolutionMethod::GEMM
@ GEMM
Convolution using GEMM.
arm_compute::NEConvolutionLayer::get_convolution_method
static ConvolutionMethod get_convolution_method(const ITensorInfo *input, const ITensorInfo *weights, const ITensorInfo *output, const PadStrideInfo &conv_info, const WeightsInfo &weights_info=WeightsInfo(), const Size2D &dilation=Size2D(1U, 1U), const ActivationLayerInfo &act_info=ActivationLayerInfo(), bool enable_fast_math=false)
Static function to check if given info will return the convolution called by NEConvolutionLayer.
Definition: NEConvolutionLayer.cpp:165
ARM_COMPUTE_UNUSED
#define ARM_COMPUTE_UNUSED(...)
To avoid unused variables warnings.
Definition: Error.h:151
PixelValue.h
arm_compute::PadStrideInfo
Definition: CoreTypes.h:139
arm_compute::ConvolutionMethod::DIRECT
@ DIRECT
Direct convolution.
MemoryHelpers.h
arm_compute::experimental
Definition: Types.h:83
Utils.h
arm_compute::test::validation::num_groups
const unsigned int num_groups
Definition: Im2Col.cpp:153
ARM_COMPUTE_RETURN_ERROR_ON_MSG
#define ARM_COMPUTE_RETURN_ERROR_ON_MSG(cond, msg)
If the condition is true, an error is returned.
Definition: Error.h:245
arm_compute::MemoryGroupResourceScope
Memory group resources scope handling class.
Definition: IMemoryGroup.h:82
arm_compute
Copyright (c) 2017-2023 Arm Limited.
Definition: introduction.dox:24
arm_compute::test::validation::conv_info
conv_info
Definition: DirectConvolutionLayer.cpp:547
arm_compute::NEConvolutionLayer::run
void run() override
Run the kernels contained in the function.
Definition: NEConvolutionLayer.cpp:178
Log.h
arm_compute::NEConvolutionLayer::NEConvolutionLayer
NEConvolutionLayer(std::shared_ptr< IMemoryManager > memory_manager=nullptr)
Constructor.
Definition: NEConvolutionLayer.cpp:56
arm_compute::is_data_type_quantized
bool is_data_type_quantized(DataType dt)
Check if a given data type is of quantized type.
Definition: DataTypeUtils.h:324
arm_compute::ITensorInfo
Store the tensor's metadata.
Definition: ITensorInfo.h:44
arm_compute::NEFFTConvolutionLayer::validate
static Status validate(const ITensorInfo *input, const ITensorInfo *weights, const ITensorInfo *biases, const ITensorInfo *output, const PadStrideInfo &conv_info, const ActivationLayerInfo &act_info=ActivationLayerInfo(), bool enable_fast_math=false)
Static function to check if given info will lead to a valid configuration of NEFFTConvolutionLayer.
Definition: NEFFTConvolutionLayer.cpp:276
arm_compute::ITensorInfo::are_values_constant
virtual bool are_values_constant() const =0
Flag indicating whether the values of the tensor are constant, meaning that they can change on kernel...
arm_compute::test::validation::info
ScaleKernelInfo info(interpolation_policy, default_border_mode, PixelValue(), sampling_policy, false)
CpuConv2d.h
ARM_COMPUTE_LOG_PARAMS
#define ARM_COMPUTE_LOG_PARAMS(...)
Definition: Log.h:35
Validate.h
CpuDirectConv2d.h
arm_compute::MemoryGroup
Memory group.
Definition: MemoryGroup.h:42
arm_compute::test::validation::input
auto input
Definition: LSTMLayerQuantized.cpp:486
arm_compute::cpu::CpuConv2d::validate
static Status validate(const ITensorInfo *src, const ITensorInfo *weights, const ITensorInfo *biases, const ITensorInfo *output, const PadStrideInfo &conv_info, const WeightsInfo &weights_info=WeightsInfo(), const Size2D &dilation=Size2D(1U, 1U), const ActivationLayerInfo &act_info=ActivationLayerInfo(), bool enable_fast_math=false, unsigned int num_groups=1)
Static function to check if given info will lead to a valid configuration of CpuConv2d.
Definition: CpuConv2d.cpp:106
arm_compute::NEConvolutionLayer::validate
static Status validate(const ITensorInfo *input, const ITensorInfo *weights, const ITensorInfo *biases, const ITensorInfo *output, const PadStrideInfo &conv_info, const WeightsInfo &weights_info=WeightsInfo(), const Size2D &dilation=Size2D(1U, 1U), const ActivationLayerInfo &act_info=ActivationLayerInfo(), bool enable_fast_math=false, unsigned int num_groups=1)
Static function to check if given info will lead to a valid configuration of NEConvolutionLayer.
Definition: NEConvolutionLayer.cpp:121