Compute Library
 21.08
CLElementwiseOperations.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-2021 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 
28 #include "arm_compute/core/Types.h"
29 #include "src/core/CL/ICLKernel.h"
30 
34 
35 namespace arm_compute
36 {
37 struct CLArithmeticAddition::Impl
38 {
39  const ICLTensor *src_0{ nullptr };
40  const ICLTensor *src_1{ nullptr };
41  ICLTensor *dst{ nullptr };
42  std::unique_ptr<opencl::ClAdd> op{ nullptr };
43 };
44 
46  : _impl(std::make_unique<Impl>())
47 {
48 }
52 
53 void CLArithmeticAddition::configure(ICLTensor *input1, ICLTensor *input2, ICLTensor *output, ConvertPolicy policy, const ActivationLayerInfo &act_info)
54 {
55  configure(CLKernelLibrary::get().get_compile_context(), input1, input2, output, policy, act_info);
56 }
57 
58 void CLArithmeticAddition::configure(const CLCompileContext &compile_context, const ICLTensor *input1, const ICLTensor *input2, ICLTensor *output, ConvertPolicy policy,
59  const ActivationLayerInfo &act_info)
60 {
61  _impl->src_0 = input1;
62  _impl->src_1 = input2;
63  _impl->dst = output;
64  _impl->op = std::make_unique<opencl::ClAdd>();
65  _impl->op->configure(compile_context, input1->info(), input2->info(), output->info(), policy, act_info);
66 }
67 
68 Status CLArithmeticAddition::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, ConvertPolicy policy, const ActivationLayerInfo &act_info)
69 {
70  return opencl::ClAdd::validate(input1, input2, output, policy, act_info);
71 }
72 
74 {
76  pack.add_tensor(TensorType::ACL_SRC_0, _impl->src_0);
77  pack.add_tensor(TensorType::ACL_SRC_1, _impl->src_1);
78  pack.add_tensor(TensorType::ACL_DST, _impl->dst);
79 
80  _impl->op->run(pack);
81 }
82 
83 struct CLArithmeticSubtraction::Impl
84 {
85  const ICLTensor *src_0{ nullptr };
86  const ICLTensor *src_1{ nullptr };
87  ICLTensor *dst{ nullptr };
88  std::unique_ptr<opencl::ClSub> op{ nullptr };
89 };
90 
92  : _impl(std::make_unique<Impl>())
93 {
94 }
98 
99 void CLArithmeticSubtraction::configure(const ICLTensor *input1, const ICLTensor *input2, ICLTensor *output, ConvertPolicy policy, const ActivationLayerInfo &act_info)
100 {
101  configure(CLKernelLibrary::get().get_compile_context(), input1, input2, output, policy, act_info);
102 }
103 
104 void CLArithmeticSubtraction::configure(const CLCompileContext &compile_context, const ICLTensor *input1, const ICLTensor *input2, ICLTensor *output, ConvertPolicy policy,
105  const ActivationLayerInfo &act_info)
106 {
107  _impl->src_0 = input1;
108  _impl->src_1 = input2;
109  _impl->dst = output;
110  _impl->op = std::make_unique<opencl::ClSub>();
111  _impl->op->configure(compile_context, input1->info(), input2->info(), output->info(), policy, act_info);
112 }
113 
114 Status CLArithmeticSubtraction::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, ConvertPolicy policy, const ActivationLayerInfo &act_info)
115 {
116  return opencl::ClSub::validate(input1, input2, output, policy, act_info);
117 }
118 
120 {
122  pack.add_tensor(TensorType::ACL_SRC_0, _impl->src_0);
123  pack.add_tensor(TensorType::ACL_SRC_1, _impl->src_1);
124  pack.add_tensor(TensorType::ACL_DST, _impl->dst);
125 
126  _impl->op->run(pack);
127 }
128 
129 struct CLArithmeticDivision::Impl
130 {
131  const ICLTensor *src_0{ nullptr };
132  const ICLTensor *src_1{ nullptr };
133  ICLTensor *dst{ nullptr };
134  std::unique_ptr<opencl::ClElementwiseDivision> op{ nullptr };
135 };
136 
138  : _impl(std::make_unique<Impl>())
139 {
140 }
144 
145 void CLArithmeticDivision::configure(ICLTensor *input1, ICLTensor *input2, ICLTensor *output, const ActivationLayerInfo &act_info)
146 {
147  configure(CLKernelLibrary::get().get_compile_context(), input1, input2, output, act_info);
148 }
149 
150 void CLArithmeticDivision::configure(const CLCompileContext &compile_context, const ICLTensor *input1, const ICLTensor *input2, ICLTensor *output, const ActivationLayerInfo &act_info)
151 {
152  _impl->src_0 = input1;
153  _impl->src_1 = input2;
154  _impl->dst = output;
155  _impl->op = std::make_unique<opencl::ClElementwiseDivision>();
156  _impl->op->configure(compile_context, input1->info(), input2->info(), output->info(), act_info);
157 }
158 
159 Status CLArithmeticDivision::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info)
160 {
161  return opencl::ClElementwiseDivision::validate(input1, input2, output, act_info);
162 }
163 
165 {
167  pack.add_tensor(TensorType::ACL_SRC_0, _impl->src_0);
168  pack.add_tensor(TensorType::ACL_SRC_1, _impl->src_1);
169  pack.add_tensor(TensorType::ACL_DST, _impl->dst);
170 
171  _impl->op->run(pack);
172 }
173 
174 struct CLElementwiseMax::Impl
175 {
176  const ICLTensor *src_0{ nullptr };
177  const ICLTensor *src_1{ nullptr };
178  ICLTensor *dst{ nullptr };
179  std::unique_ptr<opencl::ClElementwiseMax> op{ nullptr };
180 };
181 
183  : _impl(std::make_unique<Impl>())
184 {
185 }
189 
190 void CLElementwiseMax::configure(ICLTensor *input1, ICLTensor *input2, ICLTensor *output, const ActivationLayerInfo &act_info)
191 {
192  configure(CLKernelLibrary::get().get_compile_context(), input1, input2, output, act_info);
193 }
194 
195 void CLElementwiseMax::configure(const CLCompileContext &compile_context, ICLTensor *input1, ICLTensor *input2, ICLTensor *output, const ActivationLayerInfo &act_info)
196 {
197  _impl->src_0 = input1;
198  _impl->src_1 = input2;
199  _impl->dst = output;
200  _impl->op = std::make_unique<opencl::ClElementwiseMax>();
201  _impl->op->configure(compile_context, input1->info(), input2->info(), output->info(), act_info);
202 }
203 
204 Status CLElementwiseMax::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info)
205 {
206  return opencl::ClElementwiseMax::validate(input1, input2, output, act_info);
207 }
208 
210 {
212  pack.add_tensor(TensorType::ACL_SRC_0, _impl->src_0);
213  pack.add_tensor(TensorType::ACL_SRC_1, _impl->src_1);
214  pack.add_tensor(TensorType::ACL_DST, _impl->dst);
215 
216  _impl->op->run(pack);
217 }
218 
219 struct CLElementwiseMin::Impl
220 {
221  const ICLTensor *src_0{ nullptr };
222  const ICLTensor *src_1{ nullptr };
223  ICLTensor *dst{ nullptr };
224  std::unique_ptr<opencl::ClElementwiseMin> op{ nullptr };
225 };
226 
228  : _impl(std::make_unique<Impl>())
229 {
230 }
234 
235 void CLElementwiseMin::configure(ICLTensor *input1, ICLTensor *input2, ICLTensor *output, const ActivationLayerInfo &act_info)
236 {
237  configure(CLKernelLibrary::get().get_compile_context(), input1, input2, output, act_info);
238 }
239 
240 void CLElementwiseMin::configure(const CLCompileContext &compile_context, ICLTensor *input1, ICLTensor *input2, ICLTensor *output, const ActivationLayerInfo &act_info)
241 {
242  _impl->src_0 = input1;
243  _impl->src_1 = input2;
244  _impl->dst = output;
245  _impl->op = std::make_unique<opencl::ClElementwiseMin>();
246  _impl->op->configure(compile_context, input1->info(), input2->info(), output->info(), act_info);
247 }
248 
249 Status CLElementwiseMin::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info)
250 {
251  return opencl::ClElementwiseMin::validate(input1, input2, output, act_info);
252 }
253 
255 {
257  pack.add_tensor(TensorType::ACL_SRC_0, _impl->src_0);
258  pack.add_tensor(TensorType::ACL_SRC_1, _impl->src_1);
259  pack.add_tensor(TensorType::ACL_DST, _impl->dst);
260 
261  _impl->op->run(pack);
262 }
263 
264 struct CLElementwiseSquaredDiff::Impl
265 {
266  const ICLTensor *src_0{ nullptr };
267  const ICLTensor *src_1{ nullptr };
268  ICLTensor *dst{ nullptr };
269  std::unique_ptr<opencl::ClElementwiseSquaredDiff> op{ nullptr };
270 };
271 
273  : _impl(std::make_unique<Impl>())
274 {
275 }
279 
281 {
282  configure(CLKernelLibrary::get().get_compile_context(), input1, input2, output, act_info);
283 }
284 
285 void CLElementwiseSquaredDiff::configure(const CLCompileContext &compile_context, ICLTensor *input1, ICLTensor *input2, ICLTensor *output, const ActivationLayerInfo &act_info)
286 {
287  _impl->src_0 = input1;
288  _impl->src_1 = input2;
289  _impl->dst = output;
290  _impl->op = std::make_unique<opencl::ClElementwiseSquaredDiff>();
291  _impl->op->configure(compile_context, input1->info(), input2->info(), output->info(), act_info);
292 }
293 
294 Status CLElementwiseSquaredDiff::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info)
295 {
296  return opencl::ClElementwiseSquaredDiff::validate(input1, input2, output, act_info);
297 }
298 
300 {
302  pack.add_tensor(TensorType::ACL_SRC_0, _impl->src_0);
303  pack.add_tensor(TensorType::ACL_SRC_1, _impl->src_1);
304  pack.add_tensor(TensorType::ACL_DST, _impl->dst);
305 
306  _impl->op->run(pack);
307 }
308 
309 struct CLElementwisePower::Impl
310 {
311  const ICLTensor *src_0{ nullptr };
312  const ICLTensor *src_1{ nullptr };
313  ICLTensor *dst{ nullptr };
314  std::unique_ptr<opencl::ClElementwisePower> op{ nullptr };
315 };
316 
318  : _impl(std::make_unique<Impl>())
319 {
320 }
324 
325 void CLElementwisePower::configure(ICLTensor *input1, ICLTensor *input2, ICLTensor *output, const ActivationLayerInfo &act_info)
326 {
327  configure(CLKernelLibrary::get().get_compile_context(), input1, input2, output, act_info);
328 }
329 
330 void CLElementwisePower::configure(const CLCompileContext &compile_context, ICLTensor *input1, ICLTensor *input2, ICLTensor *output, const ActivationLayerInfo &act_info)
331 {
332  _impl->src_0 = input1;
333  _impl->src_1 = input2;
334  _impl->dst = output;
335  _impl->op = std::make_unique<opencl::ClElementwisePower>();
336  _impl->op->configure(compile_context, input1->info(), input2->info(), output->info(), act_info);
337 }
338 
339 Status CLElementwisePower::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info)
340 {
341  return opencl::ClElementwisePower::validate(input1, input2, output, act_info);
342 }
343 
345 {
347  pack.add_tensor(TensorType::ACL_SRC_0, _impl->src_0);
348  pack.add_tensor(TensorType::ACL_SRC_1, _impl->src_1);
349  pack.add_tensor(TensorType::ACL_DST, _impl->dst);
350 
351  _impl->op->run(pack);
352 }
353 } // namespace arm_compute
static Status validate(const ITensorInfo *src1, const ITensorInfo *src2, const ITensorInfo *dst, const ActivationLayerInfo &act_info=ActivationLayerInfo())
Static function to check if given info will lead to a valid configuration.
void run() override
Run the kernels contained in the function.
static Status validate(const ITensorInfo *src1, const ITensorInfo *src2, const ITensorInfo *dst, const ActivationLayerInfo &act_info=ActivationLayerInfo())
Static function to check if given info will lead to a valid configuration.
Basic function to run opencl::kernels::ClSaturatedArithmeticKernel for division.
void run() override
Run the kernels contained in the function.
~CLElementwisePower()
Default Destructor.
void run() override
Run the kernels contained in the function.
Basic function to run opencl::kernels::ClArithmeticKernel for power.
Basic function to run opencl::kernels::ClArithmeticKernel for min.
Basic function to run opencl::kernels::ClSaturatedArithmeticKernel for addition.
static Status validate(const ITensorInfo *src1, const ITensorInfo *src2, const ITensorInfo *dst, const ActivationLayerInfo &act_info=ActivationLayerInfo())
Static function to check if given info will lead to a valid configuration.
static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info=ActivationLayerInfo())
Static function to check if given info will lead to a valid configuration of opencl::kernels::ClArith...
static CLKernelLibrary & get()
Access the KernelLibrary singleton.
Store the tensor&#39;s metadata.
Definition: ITensorInfo.h:40
void run() override
Run the kernels contained in the function.
Manages all the OpenCL kernels compilation and caching, provides accessors for the OpenCL Context...
Status class.
Definition: Error.h:52
CLArithmeticDivision & operator=(const CLArithmeticDivision &)=delete
Prevent instances of this class from being copied (As this class contains pointers) ...
static Status validate(const ITensorInfo *src1, const ITensorInfo *src2, const ITensorInfo *dst, ConvertPolicy policy, const ActivationLayerInfo &act_info=ActivationLayerInfo())
Static function to check if given info will lead to a valid configuration.
Definition: ClSub.cpp:41
Activation Layer Information class.
Definition: Types.h:1475
~CLElementwiseSquaredDiff()
Default Destructor.
void run() override
Run the kernels contained in the function.
static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info=ActivationLayerInfo())
Static function to check if given info will lead to a valid configuration of CLArithmeticDivision.
~CLArithmeticAddition()
Default Destructor.
Copyright (c) 2017-2021 Arm Limited.
CLArithmeticSubtraction & operator=(const CLArithmeticSubtraction &)=delete
Prevent instances of this class from being copied (As this class contains pointers) ...
static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info=ActivationLayerInfo())
Static function to check if given info will lead to a valid configuration of opencl::kernels::ClArith...
void run() override
Run the kernels contained in the function.
CLArithmeticAddition & operator=(const CLArithmeticAddition &)=delete
Prevent instances of this class from being copied (As this class contains pointers) ...
~CLElementwiseMin()
Default Destructor.
static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info=ActivationLayerInfo())
Static function to check if given info will lead to a valid configuration of opencl::kernels::ClArith...
static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, ConvertPolicy policy, const ActivationLayerInfo &act_info=ActivationLayerInfo())
Static function to check if given info will lead to a valid configuration of opencl::kernels::ClSatur...
void configure(ICLTensor *input1, ICLTensor *input2, ICLTensor *output, const ActivationLayerInfo &act_info=ActivationLayerInfo())
Initialise the kernel&#39;s inputs, output and conversion policy.
void configure(ICLTensor *input1, ICLTensor *input2, ICLTensor *output, const ActivationLayerInfo &act_info=ActivationLayerInfo())
Initialise the kernel&#39;s inputs, output and conversion policy.
virtual ITensorInfo * info() const =0
Interface to be implemented by the child class to return the tensor&#39;s metadata.
void run() override
Run the kernels contained in the function.
void configure(ICLTensor *input1, ICLTensor *input2, ICLTensor *output, ConvertPolicy policy, const ActivationLayerInfo &act_info=ActivationLayerInfo())
Initialise the kernel&#39;s inputs, output and conversion policy.
static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, ConvertPolicy policy, const ActivationLayerInfo &act_info=ActivationLayerInfo())
Static function to check if given info will lead to a valid configuration of opencl::kernels::ClSatur...
CLCompileContext class.
CLElementwiseSquaredDiff & operator=(const CLElementwiseSquaredDiff &)=delete
Prevent instances of this class from being copied (As this class contains pointers) ...
void configure(const ICLTensor *input1, const ICLTensor *input2, ICLTensor *output, ConvertPolicy policy, const ActivationLayerInfo &act_info=ActivationLayerInfo())
Initialise the kernel&#39;s inputs, output and conversion policy.
Basic function to run opencl::kernels::ClArithmeticKernel for max.
Interface for OpenCL tensor.
Definition: ICLTensor.h:42
~CLArithmeticSubtraction()
Default Destructor.
void configure(ICLTensor *input1, ICLTensor *input2, ICLTensor *output, const ActivationLayerInfo &act_info=ActivationLayerInfo())
Initialise the kernel&#39;s inputs, output and conversion policy.
Basic function to run opencl::kernels::ClArithmeticKernel for squared difference. ...
~CLArithmeticDivision()
Default Destructor.
static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info=ActivationLayerInfo())
Static function to check if given info will lead to a valid configuration of opencl::kernels::ClArith...
CLElementwiseMax & operator=(const CLElementwiseMax &)=delete
Prevent instances of this class from being copied (As this class contains pointers) ...
Tensor packing service.
Definition: ITensorPack.h:39
void configure(ICLTensor *input1, ICLTensor *input2, ICLTensor *output, const ActivationLayerInfo &act_info=ActivationLayerInfo())
Initialise the kernel&#39;s inputs, output and conversion policy.
static Status validate(const ITensorInfo *src1, const ITensorInfo *src2, const ITensorInfo *dst, ConvertPolicy policy, const ActivationLayerInfo &act_info=ActivationLayerInfo())
Static function to check if given info will lead to a valid configuration.
Definition: ClAdd.cpp:41
CLElementwiseMin & operator=(const CLElementwiseMin &)=delete
Prevent instances of this class from being copied (As this class contains pointers) ...
void configure(ICLTensor *input1, ICLTensor *input2, ICLTensor *output, const ActivationLayerInfo &act_info=ActivationLayerInfo())
Initialise the kernel&#39;s inputs, output.
CLElementwisePower & operator=(const CLElementwisePower &)=delete
Prevent instances of this class from being copied (As this class contains pointers) ...
Basic function to run opencl::kernels::ClSaturatedArithmeticKernel for subtraction.
static Status validate(const ITensorInfo *src1, const ITensorInfo *src2, const ITensorInfo *dst, const ActivationLayerInfo &act_info=ActivationLayerInfo())
Static function to check if given info will lead to a valid configuration.
static Status validate(const ITensorInfo *src1, const ITensorInfo *src2, const ITensorInfo *dst, const ActivationLayerInfo &act_info=ActivationLayerInfo())
Static function to check if given info will lead to a valid configuration.
ConvertPolicy
Policy to handle overflow.
Definition: Types.h:382
~CLElementwiseMax()
Default Destructor.
void add_tensor(int id, ITensor *tensor)
Add tensor to the pack.
Definition: ITensorPack.cpp:39