blob: 883ce68536a39ca8387600c1b813e2cf0f942aae [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"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010027#include "arm_compute/core/CL/kernels/CLPixelWiseMultiplicationKernel.h"
Michalis Spyrou1009e872020-07-27 12:48:34 +010028#include "arm_compute/runtime/CL/CLScheduler.h"
Matthew Bentham92046462020-03-07 22:15:55 +000029#include "support/MemorySupport.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010030
31#include <utility>
32
Georgios Pinitas8be91482019-03-26 17:23:28 +000033namespace arm_compute
34{
Michalis Spyrou1009e872020-07-27 12:48:34 +010035namespace
Anthony Barbier6ff3b192017-09-04 18:44:23 +010036{
Georgios Pinitas0499dff2020-07-31 22:21:38 +010037ITensorPack select_border_input(ITensorPack &tensors)
Michalis Spyrou1009e872020-07-27 12:48:34 +010038{
Georgios Pinitas0499dff2020-07-31 22:21:38 +010039 ITensorPack pack;
40 if(tensors.get_tensor(TensorType::ACL_DST)->info()->dimension(0) > 1)
Michalis Spyrou1009e872020-07-27 12:48:34 +010041 {
Georgios Pinitas0499dff2020-07-31 22:21:38 +010042 if(tensors.get_const_tensor(TensorType::ACL_SRC_1)->info()->dimension(0) == 1)
Michalis Spyrou1009e872020-07-27 12:48:34 +010043 {
Georgios Pinitas0499dff2020-07-31 22:21:38 +010044 pack.add_tensor(TensorType::ACL_SRC, tensors.get_const_tensor(TensorType::ACL_SRC_1));
Michalis Spyrou1009e872020-07-27 12:48:34 +010045 }
46 else
47 {
Georgios Pinitas0499dff2020-07-31 22:21:38 +010048 pack.add_tensor(TensorType::ACL_SRC, tensors.get_const_tensor(TensorType::ACL_SRC_0));
Michalis Spyrou1009e872020-07-27 12:48:34 +010049 }
50 }
Georgios Pinitas0499dff2020-07-31 22:21:38 +010051 return pack;
Michalis Spyrou1009e872020-07-27 12:48:34 +010052}
53} // namespace
54
55namespace experimental
56{
57CLPixelWiseMultiplication::CLPixelWiseMultiplication()
58 : _border_handler()
59{
Manuel Bottini2b84be52020-04-08 10:15:51 +010060}
61
Michalis Spyrou1009e872020-07-27 12:48:34 +010062void CLPixelWiseMultiplication::configure(const CLCompileContext &compile_context, ITensorInfo *input1, ITensorInfo *input2, ITensorInfo *output, float scale,
Manuel Bottini2b84be52020-04-08 10:15:51 +010063 ConvertPolicy overflow_policy, RoundingPolicy rounding_policy, const ActivationLayerInfo &act_info)
64{
Moritz Pflanzerd0ae8b82017-06-29 14:51:57 +010065 auto k = arm_compute::support::cpp14::make_unique<CLPixelWiseMultiplicationKernel>();
Manuel Bottini2b84be52020-04-08 10:15:51 +010066 k->configure(compile_context, input1, input2, output, scale, overflow_policy, rounding_policy, act_info);
Anthony Barbier6ff3b192017-09-04 18:44:23 +010067 _kernel = std::move(k);
Michele Di Giorgio6259e5f2018-01-17 17:29:33 +000068
Michalis Spyrou1009e872020-07-27 12:48:34 +010069 if(output->dimension(0) > 1)
Michele Di Giorgio6259e5f2018-01-17 17:29:33 +000070 {
Michalis Spyrou1009e872020-07-27 12:48:34 +010071 ITensorInfo *broadcasted_info = (input1->dimension(0) == 1) ? input1 : input2;
Michele Di Giorgio6259e5f2018-01-17 17:29:33 +000072
Michalis Spyrou1009e872020-07-27 12:48:34 +010073 if(broadcasted_info->dimension(0) == 1)
Michele Di Giorgio6259e5f2018-01-17 17:29:33 +000074 {
Manuel Bottini2b84be52020-04-08 10:15:51 +010075 _border_handler.configure(compile_context, broadcasted_info, _kernel->border_size(), BorderMode::REPLICATE);
Michele Di Giorgio6259e5f2018-01-17 17:29:33 +000076 }
77 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +010078}
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +000079
Georgios Pinitas631c41a2017-12-06 11:53:03 +000080Status CLPixelWiseMultiplication::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, float scale,
Giorgio Arena8b2a7d32020-02-11 17:21:31 +000081 ConvertPolicy overflow_policy, RoundingPolicy rounding_policy, const ActivationLayerInfo &act_info)
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +000082{
Giorgio Arena8b2a7d32020-02-11 17:21:31 +000083 return CLPixelWiseMultiplicationKernel::validate(input1, input2, output, scale, overflow_policy, rounding_policy, act_info);
Michele Di Giorgio6259e5f2018-01-17 17:29:33 +000084}
Georgios Pinitas8be91482019-03-26 17:23:28 +000085
Georgios Pinitas0499dff2020-07-31 22:21:38 +010086void CLPixelWiseMultiplication::run(ITensorPack &tensors)
Georgios Pinitas8be91482019-03-26 17:23:28 +000087{
Georgios Pinitas0499dff2020-07-31 22:21:38 +010088 auto border_pack = select_border_input(tensors);
89 CLScheduler::get().enqueue_op(_border_handler, border_pack);
90 ICLOperator::run(tensors);
Manuel Bottini2b84be52020-04-08 10:15:51 +010091}
92
Michalis Spyrou1009e872020-07-27 12:48:34 +010093CLComplexPixelWiseMultiplication::CLComplexPixelWiseMultiplication()
94 : _border_handler()
95{
96}
97
98void CLComplexPixelWiseMultiplication::configure(const CLCompileContext &compile_context, ITensorInfo *input1, ITensorInfo *input2, ITensorInfo *output, const ActivationLayerInfo &act_info)
Manuel Bottini2b84be52020-04-08 10:15:51 +010099{
Georgios Pinitas8be91482019-03-26 17:23:28 +0000100 auto k = arm_compute::support::cpp14::make_unique<CLComplexPixelWiseMultiplicationKernel>();
Manuel Bottini2b84be52020-04-08 10:15:51 +0100101 k->configure(compile_context, input1, input2, output, act_info);
Georgios Pinitas8be91482019-03-26 17:23:28 +0000102 _kernel = std::move(k);
103
Michalis Spyrou1009e872020-07-27 12:48:34 +0100104 if(output->dimension(0) > 1)
Georgios Pinitas8be91482019-03-26 17:23:28 +0000105 {
Michalis Spyrou1009e872020-07-27 12:48:34 +0100106 ITensorInfo *broadcasted_info = (input1->dimension(0) == 1) ? input1 : input2;
Georgios Pinitas8be91482019-03-26 17:23:28 +0000107
Michalis Spyrou1009e872020-07-27 12:48:34 +0100108 if(broadcasted_info->dimension(0) == 1)
Georgios Pinitas8be91482019-03-26 17:23:28 +0000109 {
Manuel Bottini2b84be52020-04-08 10:15:51 +0100110 _border_handler.configure(compile_context, broadcasted_info, _kernel->border_size(), BorderMode::REPLICATE);
Georgios Pinitas8be91482019-03-26 17:23:28 +0000111 }
112 }
113}
114
Giorgio Arena8b2a7d32020-02-11 17:21:31 +0000115Status CLComplexPixelWiseMultiplication::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info)
Georgios Pinitas8be91482019-03-26 17:23:28 +0000116{
Giorgio Arena8b2a7d32020-02-11 17:21:31 +0000117 return CLComplexPixelWiseMultiplicationKernel::validate(input1, input2, output, act_info);
Georgios Pinitas8be91482019-03-26 17:23:28 +0000118}
Michalis Spyrou1009e872020-07-27 12:48:34 +0100119
Georgios Pinitas0499dff2020-07-31 22:21:38 +0100120void CLComplexPixelWiseMultiplication::run(ITensorPack &tensors)
Michalis Spyrou1009e872020-07-27 12:48:34 +0100121{
Georgios Pinitas0499dff2020-07-31 22:21:38 +0100122 auto border_pack = select_border_input(tensors);
123 CLScheduler::get().enqueue_op(_border_handler, border_pack);
124 ICLOperator::run(tensors);
Michalis Spyrou1009e872020-07-27 12:48:34 +0100125}
126} // namespace experimental
127
128struct CLPixelWiseMultiplication::Impl
129{
130 const ICLTensor *src_0{ nullptr };
131 const ICLTensor *src_1{ nullptr };
132 ICLTensor *dst{ nullptr };
133 std::unique_ptr<experimental::CLPixelWiseMultiplication> op{ nullptr };
134};
135
136CLPixelWiseMultiplication::CLPixelWiseMultiplication()
137 : _impl(support::cpp14::make_unique<Impl>())
138{
139}
140CLPixelWiseMultiplication::CLPixelWiseMultiplication(CLPixelWiseMultiplication &&) = default;
141CLPixelWiseMultiplication &CLPixelWiseMultiplication::operator=(CLPixelWiseMultiplication &&) = default;
142CLPixelWiseMultiplication::~CLPixelWiseMultiplication() = default;
143
144void CLPixelWiseMultiplication::configure(ICLTensor *input1, ICLTensor *input2, ICLTensor *output, float scale,
145 ConvertPolicy overflow_policy, RoundingPolicy rounding_policy, const ActivationLayerInfo &act_info)
146{
147 configure(CLKernelLibrary::get().get_compile_context(), input1, input2, output, scale, overflow_policy, rounding_policy, act_info);
148}
149
150void CLPixelWiseMultiplication::configure(const CLCompileContext &compile_context, ICLTensor *input1, ICLTensor *input2, ICLTensor *output, float scale,
151 ConvertPolicy overflow_policy, RoundingPolicy rounding_policy, const ActivationLayerInfo &act_info)
152{
153 _impl->src_0 = input1;
154 _impl->src_1 = input2;
155 _impl->dst = output;
156 _impl->op = arm_compute::support::cpp14::make_unique<experimental::CLPixelWiseMultiplication>();
157 _impl->op->configure(compile_context, input1->info(), input2->info(), output->info(), scale, overflow_policy, rounding_policy, act_info);
158}
159
160Status CLPixelWiseMultiplication::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, float scale,
161 ConvertPolicy overflow_policy, RoundingPolicy rounding_policy, const ActivationLayerInfo &act_info)
162{
163 return experimental::CLPixelWiseMultiplication::validate(input1, input2, output, scale, overflow_policy, rounding_policy, act_info);
164}
165
166void CLPixelWiseMultiplication::run()
167{
Georgios Pinitas0499dff2020-07-31 22:21:38 +0100168 ITensorPack pack;
169 pack.add_tensor(TensorType::ACL_SRC_0, _impl->src_0);
170 pack.add_tensor(TensorType::ACL_SRC_1, _impl->src_1);
171 pack.add_tensor(TensorType::ACL_DST, _impl->dst);
Michalis Spyrou1009e872020-07-27 12:48:34 +0100172
Georgios Pinitas0499dff2020-07-31 22:21:38 +0100173 _impl->op->run(pack);
Michalis Spyrou1009e872020-07-27 12:48:34 +0100174}
175
176struct CLComplexPixelWiseMultiplication::Impl
177{
178 const ICLTensor *src_0{ nullptr };
179 const ICLTensor *src_1{ nullptr };
180 ICLTensor *dst{ nullptr };
181 std::unique_ptr<experimental::CLComplexPixelWiseMultiplication> op{ nullptr };
182};
183
184CLComplexPixelWiseMultiplication::CLComplexPixelWiseMultiplication()
185 : _impl(support::cpp14::make_unique<Impl>())
186{
187}
188CLComplexPixelWiseMultiplication::CLComplexPixelWiseMultiplication(CLComplexPixelWiseMultiplication &&) = default;
189CLComplexPixelWiseMultiplication &CLComplexPixelWiseMultiplication::operator=(CLComplexPixelWiseMultiplication &&) = default;
190CLComplexPixelWiseMultiplication::~CLComplexPixelWiseMultiplication() = default;
191
192void CLComplexPixelWiseMultiplication::configure(ICLTensor *input1, ICLTensor *input2, ICLTensor *output, const ActivationLayerInfo &act_info)
193{
194 configure(CLKernelLibrary::get().get_compile_context(), input1, input2, output, act_info);
195}
196
197void CLComplexPixelWiseMultiplication::configure(const CLCompileContext &compile_context, ICLTensor *input1, ICLTensor *input2, ICLTensor *output, const ActivationLayerInfo &act_info)
198{
199 _impl->src_0 = input1;
200 _impl->src_1 = input2;
201 _impl->dst = output;
202 _impl->op = arm_compute::support::cpp14::make_unique<experimental::CLComplexPixelWiseMultiplication>();
203 _impl->op->configure(compile_context, input1->info(), input2->info(), output->info(), act_info);
204}
205
206Status CLComplexPixelWiseMultiplication::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info)
207{
208 return experimental::CLComplexPixelWiseMultiplication::validate(input1, input2, output, act_info);
209}
210
211void CLComplexPixelWiseMultiplication::run()
212{
Georgios Pinitas0499dff2020-07-31 22:21:38 +0100213 ITensorPack pack;
214 pack.add_tensor(TensorType::ACL_SRC_0, _impl->src_0);
215 pack.add_tensor(TensorType::ACL_SRC_1, _impl->src_1);
216 pack.add_tensor(TensorType::ACL_DST, _impl->dst);
Michalis Spyrou1009e872020-07-27 12:48:34 +0100217
Georgios Pinitas0499dff2020-07-31 22:21:38 +0100218 _impl->op->run(pack);
Michalis Spyrou1009e872020-07-27 12:48:34 +0100219}
Matthew Bentham92046462020-03-07 22:15:55 +0000220} // namespace arm_compute