• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
24 #include "arm_compute/runtime/CL/functions/CLElementwiseOperations.h"
25 
26 #include "arm_compute/core/CL/CLKernelLibrary.h"
27 #include "arm_compute/core/CL/ICLTensor.h"
28 #include "arm_compute/core/Types.h"
29 #include "src/core/CL/ICLKernel.h"
30 
31 #include "src/gpu/cl/operators/ClAdd.h"
32 #include "src/gpu/cl/operators/ClElementwiseOperations.h"
33 #include "src/gpu/cl/operators/ClSub.h"
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 
CLArithmeticAddition()45 CLArithmeticAddition::CLArithmeticAddition()
46     : _impl(std::make_unique<Impl>())
47 {
48 }
49 CLArithmeticAddition::CLArithmeticAddition(CLArithmeticAddition &&) = default;
50 CLArithmeticAddition &CLArithmeticAddition::operator=(CLArithmeticAddition &&) = default;
51 CLArithmeticAddition::~CLArithmeticAddition()                                  = default;
52 
configure(ICLTensor * input1,ICLTensor * input2,ICLTensor * output,ConvertPolicy policy,const ActivationLayerInfo & act_info)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 
configure(const CLCompileContext & compile_context,const ICLTensor * input1,const ICLTensor * input2,ICLTensor * output,ConvertPolicy policy,const ActivationLayerInfo & act_info)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 
validate(const ITensorInfo * input1,const ITensorInfo * input2,const ITensorInfo * output,ConvertPolicy policy,const ActivationLayerInfo & act_info)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 
run()73 void CLArithmeticAddition::run()
74 {
75     ITensorPack pack;
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 
CLArithmeticSubtraction()91 CLArithmeticSubtraction::CLArithmeticSubtraction()
92     : _impl(std::make_unique<Impl>())
93 {
94 }
95 CLArithmeticSubtraction::CLArithmeticSubtraction(CLArithmeticSubtraction &&) = default;
96 CLArithmeticSubtraction &CLArithmeticSubtraction::operator=(CLArithmeticSubtraction &&) = default;
97 CLArithmeticSubtraction::~CLArithmeticSubtraction()                                     = default;
98 
configure(const ICLTensor * input1,const ICLTensor * input2,ICLTensor * output,ConvertPolicy policy,const ActivationLayerInfo & act_info)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 
configure(const CLCompileContext & compile_context,const ICLTensor * input1,const ICLTensor * input2,ICLTensor * output,ConvertPolicy policy,const ActivationLayerInfo & act_info)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 
validate(const ITensorInfo * input1,const ITensorInfo * input2,const ITensorInfo * output,ConvertPolicy policy,const ActivationLayerInfo & act_info)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 
run()119 void CLArithmeticSubtraction::run()
120 {
121     ITensorPack pack;
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 
CLArithmeticDivision()137 CLArithmeticDivision::CLArithmeticDivision()
138     : _impl(std::make_unique<Impl>())
139 {
140 }
141 CLArithmeticDivision::CLArithmeticDivision(CLArithmeticDivision &&) = default;
142 CLArithmeticDivision &CLArithmeticDivision::operator=(CLArithmeticDivision &&) = default;
143 CLArithmeticDivision::~CLArithmeticDivision()                                  = default;
144 
configure(ICLTensor * input1,ICLTensor * input2,ICLTensor * output,const ActivationLayerInfo & act_info)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 
configure(const CLCompileContext & compile_context,const ICLTensor * input1,const ICLTensor * input2,ICLTensor * output,const ActivationLayerInfo & act_info)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 
validate(const ITensorInfo * input1,const ITensorInfo * input2,const ITensorInfo * output,const ActivationLayerInfo & act_info)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 
run()164 void CLArithmeticDivision::run()
165 {
166     ITensorPack pack;
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 
CLElementwiseMax()182 CLElementwiseMax::CLElementwiseMax()
183     : _impl(std::make_unique<Impl>())
184 {
185 }
186 CLElementwiseMax::CLElementwiseMax(CLElementwiseMax &&) = default;
187 CLElementwiseMax &CLElementwiseMax::operator=(CLElementwiseMax &&) = default;
188 CLElementwiseMax::~CLElementwiseMax()                              = default;
189 
configure(ICLTensor * input1,ICLTensor * input2,ICLTensor * output,const ActivationLayerInfo & act_info)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 
configure(const CLCompileContext & compile_context,ICLTensor * input1,ICLTensor * input2,ICLTensor * output,const ActivationLayerInfo & act_info)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 
validate(const ITensorInfo * input1,const ITensorInfo * input2,const ITensorInfo * output,const ActivationLayerInfo & act_info)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 
run()209 void CLElementwiseMax::run()
210 {
211     ITensorPack pack;
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 
CLElementwiseMin()227 CLElementwiseMin::CLElementwiseMin()
228     : _impl(std::make_unique<Impl>())
229 {
230 }
231 CLElementwiseMin::CLElementwiseMin(CLElementwiseMin &&) = default;
232 CLElementwiseMin &CLElementwiseMin::operator=(CLElementwiseMin &&) = default;
233 CLElementwiseMin::~CLElementwiseMin()                              = default;
234 
configure(ICLTensor * input1,ICLTensor * input2,ICLTensor * output,const ActivationLayerInfo & act_info)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 
configure(const CLCompileContext & compile_context,ICLTensor * input1,ICLTensor * input2,ICLTensor * output,const ActivationLayerInfo & act_info)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 
validate(const ITensorInfo * input1,const ITensorInfo * input2,const ITensorInfo * output,const ActivationLayerInfo & act_info)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 
run()254 void CLElementwiseMin::run()
255 {
256     ITensorPack pack;
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 
CLElementwiseSquaredDiff()272 CLElementwiseSquaredDiff::CLElementwiseSquaredDiff()
273     : _impl(std::make_unique<Impl>())
274 {
275 }
276 CLElementwiseSquaredDiff::CLElementwiseSquaredDiff(CLElementwiseSquaredDiff &&) = default;
277 CLElementwiseSquaredDiff &CLElementwiseSquaredDiff::operator=(CLElementwiseSquaredDiff &&) = default;
278 CLElementwiseSquaredDiff::~CLElementwiseSquaredDiff()                                      = default;
279 
configure(ICLTensor * input1,ICLTensor * input2,ICLTensor * output,const ActivationLayerInfo & act_info)280 void CLElementwiseSquaredDiff::configure(ICLTensor *input1, ICLTensor *input2, ICLTensor *output, const ActivationLayerInfo &act_info)
281 {
282     configure(CLKernelLibrary::get().get_compile_context(), input1, input2, output, act_info);
283 }
284 
configure(const CLCompileContext & compile_context,ICLTensor * input1,ICLTensor * input2,ICLTensor * output,const ActivationLayerInfo & act_info)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 
validate(const ITensorInfo * input1,const ITensorInfo * input2,const ITensorInfo * output,const ActivationLayerInfo & act_info)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 
run()299 void CLElementwiseSquaredDiff::run()
300 {
301     ITensorPack pack;
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 
CLElementwisePower()317 CLElementwisePower::CLElementwisePower()
318     : _impl(std::make_unique<Impl>())
319 {
320 }
321 CLElementwisePower::CLElementwisePower(CLElementwisePower &&) = default;
322 CLElementwisePower &CLElementwisePower::operator=(CLElementwisePower &&) = default;
323 CLElementwisePower::~CLElementwisePower()                                = default;
324 
configure(ICLTensor * input1,ICLTensor * input2,ICLTensor * output,const ActivationLayerInfo & act_info)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 
configure(const CLCompileContext & compile_context,ICLTensor * input1,ICLTensor * input2,ICLTensor * output,const ActivationLayerInfo & act_info)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 
validate(const ITensorInfo * input1,const ITensorInfo * input2,const ITensorInfo * output,const ActivationLayerInfo & act_info)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 
run()344 void CLElementwisePower::run()
345 {
346     ITensorPack pack;
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
354