blob: 12cc5d60af71dd52647782b43244a84ee7876900 [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
Michele Di Giorgiod9eaf612020-07-08 11:12:57 +01002 * Copyright (c) 2016-2020 Arm Limited.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003 *
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/CLPixelWiseMultiplication.h"
25
Michele Di Giorgio6259e5f2018-01-17 17:29:33 +000026#include "arm_compute/core/CL/ICLTensor.h"
Michalis Spyrou1009e872020-07-27 12:48:34 +010027#include "arm_compute/runtime/CL/CLScheduler.h"
Sang-Hoon Parkbef7fa22020-10-21 15:58:54 +010028#include "src/core/CL/kernels/CLFillBorderKernel.h"
29#include "src/core/CL/kernels/CLPixelWiseMultiplicationKernel.h"
Matthew Bentham92046462020-03-07 22:15:55 +000030#include "support/MemorySupport.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010031
32#include <utility>
33
Georgios Pinitas8be91482019-03-26 17:23:28 +000034namespace arm_compute
35{
Michalis Spyrou1009e872020-07-27 12:48:34 +010036namespace
Anthony Barbier6ff3b192017-09-04 18:44:23 +010037{
Georgios Pinitas0499dff2020-07-31 22:21:38 +010038ITensorPack select_border_input(ITensorPack &tensors)
Michalis Spyrou1009e872020-07-27 12:48:34 +010039{
Georgios Pinitas0499dff2020-07-31 22:21:38 +010040 ITensorPack pack;
41 if(tensors.get_tensor(TensorType::ACL_DST)->info()->dimension(0) > 1)
Michalis Spyrou1009e872020-07-27 12:48:34 +010042 {
Georgios Pinitas0499dff2020-07-31 22:21:38 +010043 if(tensors.get_const_tensor(TensorType::ACL_SRC_1)->info()->dimension(0) == 1)
Michalis Spyrou1009e872020-07-27 12:48:34 +010044 {
Georgios Pinitas0499dff2020-07-31 22:21:38 +010045 pack.add_tensor(TensorType::ACL_SRC, tensors.get_const_tensor(TensorType::ACL_SRC_1));
Michalis Spyrou1009e872020-07-27 12:48:34 +010046 }
47 else
48 {
Georgios Pinitas0499dff2020-07-31 22:21:38 +010049 pack.add_tensor(TensorType::ACL_SRC, tensors.get_const_tensor(TensorType::ACL_SRC_0));
Michalis Spyrou1009e872020-07-27 12:48:34 +010050 }
51 }
Georgios Pinitas0499dff2020-07-31 22:21:38 +010052 return pack;
Michalis Spyrou1009e872020-07-27 12:48:34 +010053}
54} // namespace
55
56namespace experimental
57{
58CLPixelWiseMultiplication::CLPixelWiseMultiplication()
Sang-Hoon Parkbef7fa22020-10-21 15:58:54 +010059 : _border_handler(support::cpp14::make_unique<CLFillBorderKernel>())
Michalis Spyrou1009e872020-07-27 12:48:34 +010060{
Manuel Bottini2b84be52020-04-08 10:15:51 +010061}
62
Michalis Spyrou1009e872020-07-27 12:48:34 +010063void CLPixelWiseMultiplication::configure(const CLCompileContext &compile_context, ITensorInfo *input1, ITensorInfo *input2, ITensorInfo *output, float scale,
Manuel Bottini2b84be52020-04-08 10:15:51 +010064 ConvertPolicy overflow_policy, RoundingPolicy rounding_policy, const ActivationLayerInfo &act_info)
65{
Moritz Pflanzerd0ae8b82017-06-29 14:51:57 +010066 auto k = arm_compute::support::cpp14::make_unique<CLPixelWiseMultiplicationKernel>();
Manuel Bottini2b84be52020-04-08 10:15:51 +010067 k->configure(compile_context, input1, input2, output, scale, overflow_policy, rounding_policy, act_info);
Anthony Barbier6ff3b192017-09-04 18:44:23 +010068 _kernel = std::move(k);
Michele Di Giorgio6259e5f2018-01-17 17:29:33 +000069
Michalis Spyrou1009e872020-07-27 12:48:34 +010070 if(output->dimension(0) > 1)
Michele Di Giorgio6259e5f2018-01-17 17:29:33 +000071 {
Michalis Spyrou1009e872020-07-27 12:48:34 +010072 ITensorInfo *broadcasted_info = (input1->dimension(0) == 1) ? input1 : input2;
Michele Di Giorgio6259e5f2018-01-17 17:29:33 +000073
Michalis Spyrou1009e872020-07-27 12:48:34 +010074 if(broadcasted_info->dimension(0) == 1)
Michele Di Giorgio6259e5f2018-01-17 17:29:33 +000075 {
Sang-Hoon Parkbef7fa22020-10-21 15:58:54 +010076 _border_handler->configure(compile_context, broadcasted_info, _kernel->border_size(), BorderMode::REPLICATE);
Michele Di Giorgio6259e5f2018-01-17 17:29:33 +000077 }
78 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +010079}
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +000080
Georgios Pinitas631c41a2017-12-06 11:53:03 +000081Status CLPixelWiseMultiplication::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, float scale,
Giorgio Arena8b2a7d32020-02-11 17:21:31 +000082 ConvertPolicy overflow_policy, RoundingPolicy rounding_policy, const ActivationLayerInfo &act_info)
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +000083{
Giorgio Arena8b2a7d32020-02-11 17:21:31 +000084 return CLPixelWiseMultiplicationKernel::validate(input1, input2, output, scale, overflow_policy, rounding_policy, act_info);
Michele Di Giorgio6259e5f2018-01-17 17:29:33 +000085}
Georgios Pinitas8be91482019-03-26 17:23:28 +000086
Georgios Pinitas0499dff2020-07-31 22:21:38 +010087void CLPixelWiseMultiplication::run(ITensorPack &tensors)
Georgios Pinitas8be91482019-03-26 17:23:28 +000088{
Georgios Pinitas0499dff2020-07-31 22:21:38 +010089 auto border_pack = select_border_input(tensors);
Sang-Hoon Parkbef7fa22020-10-21 15:58:54 +010090 CLScheduler::get().enqueue_op(*_border_handler, border_pack);
Georgios Pinitas0499dff2020-07-31 22:21:38 +010091 ICLOperator::run(tensors);
Manuel Bottini2b84be52020-04-08 10:15:51 +010092}
93
Michalis Spyrou1009e872020-07-27 12:48:34 +010094CLComplexPixelWiseMultiplication::CLComplexPixelWiseMultiplication()
Sang-Hoon Parkbef7fa22020-10-21 15:58:54 +010095 : _border_handler(support::cpp14::make_unique<CLFillBorderKernel>())
Michalis Spyrou1009e872020-07-27 12:48:34 +010096{
97}
98
99void CLComplexPixelWiseMultiplication::configure(const CLCompileContext &compile_context, ITensorInfo *input1, ITensorInfo *input2, ITensorInfo *output, const ActivationLayerInfo &act_info)
Manuel Bottini2b84be52020-04-08 10:15:51 +0100100{
Georgios Pinitas8be91482019-03-26 17:23:28 +0000101 auto k = arm_compute::support::cpp14::make_unique<CLComplexPixelWiseMultiplicationKernel>();
Manuel Bottini2b84be52020-04-08 10:15:51 +0100102 k->configure(compile_context, input1, input2, output, act_info);
Georgios Pinitas8be91482019-03-26 17:23:28 +0000103 _kernel = std::move(k);
104
Michalis Spyrou1009e872020-07-27 12:48:34 +0100105 if(output->dimension(0) > 1)
Georgios Pinitas8be91482019-03-26 17:23:28 +0000106 {
Michalis Spyrou1009e872020-07-27 12:48:34 +0100107 ITensorInfo *broadcasted_info = (input1->dimension(0) == 1) ? input1 : input2;
Georgios Pinitas8be91482019-03-26 17:23:28 +0000108
Michalis Spyrou1009e872020-07-27 12:48:34 +0100109 if(broadcasted_info->dimension(0) == 1)
Georgios Pinitas8be91482019-03-26 17:23:28 +0000110 {
Sang-Hoon Parkbef7fa22020-10-21 15:58:54 +0100111 _border_handler->configure(compile_context, broadcasted_info, _kernel->border_size(), BorderMode::REPLICATE);
Georgios Pinitas8be91482019-03-26 17:23:28 +0000112 }
113 }
114}
115
Giorgio Arena8b2a7d32020-02-11 17:21:31 +0000116Status CLComplexPixelWiseMultiplication::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info)
Georgios Pinitas8be91482019-03-26 17:23:28 +0000117{
Giorgio Arena8b2a7d32020-02-11 17:21:31 +0000118 return CLComplexPixelWiseMultiplicationKernel::validate(input1, input2, output, act_info);
Georgios Pinitas8be91482019-03-26 17:23:28 +0000119}
Michalis Spyrou1009e872020-07-27 12:48:34 +0100120
Georgios Pinitas0499dff2020-07-31 22:21:38 +0100121void CLComplexPixelWiseMultiplication::run(ITensorPack &tensors)
Michalis Spyrou1009e872020-07-27 12:48:34 +0100122{
Georgios Pinitas0499dff2020-07-31 22:21:38 +0100123 auto border_pack = select_border_input(tensors);
Sang-Hoon Parkbef7fa22020-10-21 15:58:54 +0100124 CLScheduler::get().enqueue_op(*_border_handler, border_pack);
Georgios Pinitas0499dff2020-07-31 22:21:38 +0100125 ICLOperator::run(tensors);
Michalis Spyrou1009e872020-07-27 12:48:34 +0100126}
127} // namespace experimental
128
129struct CLPixelWiseMultiplication::Impl
130{
131 const ICLTensor *src_0{ nullptr };
132 const ICLTensor *src_1{ nullptr };
133 ICLTensor *dst{ nullptr };
134 std::unique_ptr<experimental::CLPixelWiseMultiplication> op{ nullptr };
135};
136
137CLPixelWiseMultiplication::CLPixelWiseMultiplication()
138 : _impl(support::cpp14::make_unique<Impl>())
139{
140}
141CLPixelWiseMultiplication::CLPixelWiseMultiplication(CLPixelWiseMultiplication &&) = default;
142CLPixelWiseMultiplication &CLPixelWiseMultiplication::operator=(CLPixelWiseMultiplication &&) = default;
143CLPixelWiseMultiplication::~CLPixelWiseMultiplication() = default;
144
145void CLPixelWiseMultiplication::configure(ICLTensor *input1, ICLTensor *input2, ICLTensor *output, float scale,
146 ConvertPolicy overflow_policy, RoundingPolicy rounding_policy, const ActivationLayerInfo &act_info)
147{
148 configure(CLKernelLibrary::get().get_compile_context(), input1, input2, output, scale, overflow_policy, rounding_policy, act_info);
149}
150
151void CLPixelWiseMultiplication::configure(const CLCompileContext &compile_context, ICLTensor *input1, ICLTensor *input2, ICLTensor *output, float scale,
152 ConvertPolicy overflow_policy, RoundingPolicy rounding_policy, const ActivationLayerInfo &act_info)
153{
154 _impl->src_0 = input1;
155 _impl->src_1 = input2;
156 _impl->dst = output;
157 _impl->op = arm_compute::support::cpp14::make_unique<experimental::CLPixelWiseMultiplication>();
158 _impl->op->configure(compile_context, input1->info(), input2->info(), output->info(), scale, overflow_policy, rounding_policy, act_info);
159}
160
161Status CLPixelWiseMultiplication::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, float scale,
162 ConvertPolicy overflow_policy, RoundingPolicy rounding_policy, const ActivationLayerInfo &act_info)
163{
164 return experimental::CLPixelWiseMultiplication::validate(input1, input2, output, scale, overflow_policy, rounding_policy, act_info);
165}
166
167void CLPixelWiseMultiplication::run()
168{
Georgios Pinitas0499dff2020-07-31 22:21:38 +0100169 ITensorPack pack;
170 pack.add_tensor(TensorType::ACL_SRC_0, _impl->src_0);
171 pack.add_tensor(TensorType::ACL_SRC_1, _impl->src_1);
172 pack.add_tensor(TensorType::ACL_DST, _impl->dst);
Michalis Spyrou1009e872020-07-27 12:48:34 +0100173
Georgios Pinitas0499dff2020-07-31 22:21:38 +0100174 _impl->op->run(pack);
Michalis Spyrou1009e872020-07-27 12:48:34 +0100175}
176
177struct CLComplexPixelWiseMultiplication::Impl
178{
179 const ICLTensor *src_0{ nullptr };
180 const ICLTensor *src_1{ nullptr };
181 ICLTensor *dst{ nullptr };
182 std::unique_ptr<experimental::CLComplexPixelWiseMultiplication> op{ nullptr };
183};
184
185CLComplexPixelWiseMultiplication::CLComplexPixelWiseMultiplication()
186 : _impl(support::cpp14::make_unique<Impl>())
187{
188}
189CLComplexPixelWiseMultiplication::CLComplexPixelWiseMultiplication(CLComplexPixelWiseMultiplication &&) = default;
190CLComplexPixelWiseMultiplication &CLComplexPixelWiseMultiplication::operator=(CLComplexPixelWiseMultiplication &&) = default;
191CLComplexPixelWiseMultiplication::~CLComplexPixelWiseMultiplication() = default;
192
193void CLComplexPixelWiseMultiplication::configure(ICLTensor *input1, ICLTensor *input2, ICLTensor *output, const ActivationLayerInfo &act_info)
194{
195 configure(CLKernelLibrary::get().get_compile_context(), input1, input2, output, act_info);
196}
197
198void CLComplexPixelWiseMultiplication::configure(const CLCompileContext &compile_context, ICLTensor *input1, ICLTensor *input2, ICLTensor *output, const ActivationLayerInfo &act_info)
199{
200 _impl->src_0 = input1;
201 _impl->src_1 = input2;
202 _impl->dst = output;
203 _impl->op = arm_compute::support::cpp14::make_unique<experimental::CLComplexPixelWiseMultiplication>();
204 _impl->op->configure(compile_context, input1->info(), input2->info(), output->info(), act_info);
205}
206
207Status CLComplexPixelWiseMultiplication::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info)
208{
209 return experimental::CLComplexPixelWiseMultiplication::validate(input1, input2, output, act_info);
210}
211
212void CLComplexPixelWiseMultiplication::run()
213{
Georgios Pinitas0499dff2020-07-31 22:21:38 +0100214 ITensorPack pack;
215 pack.add_tensor(TensorType::ACL_SRC_0, _impl->src_0);
216 pack.add_tensor(TensorType::ACL_SRC_1, _impl->src_1);
217 pack.add_tensor(TensorType::ACL_DST, _impl->dst);
Michalis Spyrou1009e872020-07-27 12:48:34 +0100218
Georgios Pinitas0499dff2020-07-31 22:21:38 +0100219 _impl->op->run(pack);
Michalis Spyrou1009e872020-07-27 12:48:34 +0100220}
Matthew Bentham92046462020-03-07 22:15:55 +0000221} // namespace arm_compute