blob: c958adf97c1a21292fbd9b80b9e6db9e97b16dc2 [file] [log] [blame]
Sang-Hoon Park63001ac2021-01-18 14:20:27 +00001/*
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/NEON/functions/NEElementwiseOperations.h"
25#include "arm_compute/core/Validate.h"
Georgios Pinitas7891a732021-08-20 21:39:25 +010026#include "src/cpu/operators/CpuElementwise.h"
Sang-Hoon Park63001ac2021-01-18 14:20:27 +000027
28#include "arm_compute/core/ITensor.h"
29
30#include <utility>
31
32namespace arm_compute
33{
34struct NEElementwiseMax::Impl
35{
36 const ITensor *src_0{ nullptr };
37 const ITensor *src_1{ nullptr };
38 ITensor *dst{ nullptr };
39 std::unique_ptr<cpu::CpuElementwiseMax> op{ nullptr };
40};
41
42NEElementwiseMax::NEElementwiseMax()
43 : _impl(std::make_unique<Impl>())
44{
45}
46NEElementwiseMax::NEElementwiseMax(NEElementwiseMax &&) = default;
47NEElementwiseMax &NEElementwiseMax::operator=(NEElementwiseMax &&) = default;
48NEElementwiseMax::~NEElementwiseMax() = default;
49
50void NEElementwiseMax::configure(ITensor *input1, ITensor *input2, ITensor *output, const ActivationLayerInfo &act_info)
51{
52 ARM_COMPUTE_UNUSED(act_info);
53 _impl->src_0 = input1;
54 _impl->src_1 = input2;
55 _impl->dst = output;
56 _impl->op = std::make_unique<cpu::CpuElementwiseMax>();
57 _impl->op->configure(input1->info(), input2->info(), output->info());
58}
59
60Status NEElementwiseMax::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info)
61{
62 ARM_COMPUTE_RETURN_ERROR_ON(act_info.enabled());
63 return cpu::CpuElementwiseMax::validate(input1, input2, output);
64}
65
66void NEElementwiseMax::run()
67{
68 ITensorPack pack;
69 pack.add_tensor(TensorType::ACL_SRC_0, _impl->src_0);
70 pack.add_tensor(TensorType::ACL_SRC_1, _impl->src_1);
71 pack.add_tensor(TensorType::ACL_DST, _impl->dst);
72 _impl->op->run(pack);
73}
74
75struct NEElementwiseMin::Impl
76{
77 const ITensor *src_0{ nullptr };
78 const ITensor *src_1{ nullptr };
79 ITensor *dst{ nullptr };
80 std::unique_ptr<cpu::CpuElementwiseMin> op{ nullptr };
81};
82
83NEElementwiseMin::NEElementwiseMin()
84 : _impl(std::make_unique<Impl>())
85{
86}
87NEElementwiseMin::NEElementwiseMin(NEElementwiseMin &&) = default;
88NEElementwiseMin &NEElementwiseMin::operator=(NEElementwiseMin &&) = default;
89NEElementwiseMin::~NEElementwiseMin() = default;
90
91void NEElementwiseMin::configure(ITensor *input1, ITensor *input2, ITensor *output, const ActivationLayerInfo &act_info)
92{
93 ARM_COMPUTE_UNUSED(act_info);
94 _impl->src_0 = input1;
95 _impl->src_1 = input2;
96 _impl->dst = output;
97 _impl->op = std::make_unique<cpu::CpuElementwiseMin>();
98 _impl->op->configure(input1->info(), input2->info(), output->info());
99}
100
101Status NEElementwiseMin::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info)
102{
103 ARM_COMPUTE_RETURN_ERROR_ON(act_info.enabled());
104 return cpu::CpuElementwiseMin::validate(input1, input2, output);
105}
106
107void NEElementwiseMin::run()
108{
109 ITensorPack pack;
110 pack.add_tensor(TensorType::ACL_SRC_0, _impl->src_0);
111 pack.add_tensor(TensorType::ACL_SRC_1, _impl->src_1);
112 pack.add_tensor(TensorType::ACL_DST, _impl->dst);
113 _impl->op->run(pack);
114}
115
116struct NEElementwiseSquaredDiff::Impl
117{
118 const ITensor *src_0{ nullptr };
119 const ITensor *src_1{ nullptr };
120 ITensor *dst{ nullptr };
121 std::unique_ptr<cpu::CpuElementwiseSquaredDiff> op{ nullptr };
122};
123
124NEElementwiseSquaredDiff::NEElementwiseSquaredDiff()
125 : _impl(std::make_unique<Impl>())
126{
127}
128NEElementwiseSquaredDiff::NEElementwiseSquaredDiff(NEElementwiseSquaredDiff &&) = default;
129NEElementwiseSquaredDiff &NEElementwiseSquaredDiff::operator=(NEElementwiseSquaredDiff &&) = default;
130NEElementwiseSquaredDiff::~NEElementwiseSquaredDiff() = default;
131
132void NEElementwiseSquaredDiff::configure(ITensor *input1, ITensor *input2, ITensor *output, const ActivationLayerInfo &act_info)
133{
134 ARM_COMPUTE_UNUSED(act_info);
135 _impl->src_0 = input1;
136 _impl->src_1 = input2;
137 _impl->dst = output;
138 _impl->op = std::make_unique<cpu::CpuElementwiseSquaredDiff>();
139 _impl->op->configure(input1->info(), input2->info(), output->info());
140}
141
142Status NEElementwiseSquaredDiff::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info)
143{
144 ARM_COMPUTE_RETURN_ERROR_ON(act_info.enabled());
145 return cpu::CpuElementwiseSquaredDiff::validate(input1, input2, output);
146}
147
148void NEElementwiseSquaredDiff::run()
149{
150 ITensorPack pack;
151 pack.add_tensor(TensorType::ACL_SRC_0, _impl->src_0);
152 pack.add_tensor(TensorType::ACL_SRC_1, _impl->src_1);
153 pack.add_tensor(TensorType::ACL_DST, _impl->dst);
154 _impl->op->run(pack);
155}
156
157struct NEElementwiseDivision::Impl
158{
159 const ITensor *src_0{ nullptr };
160 const ITensor *src_1{ nullptr };
161 ITensor *dst{ nullptr };
162 std::unique_ptr<cpu::CpuElementwiseDivision> op{ nullptr };
163};
164
165NEElementwiseDivision::NEElementwiseDivision()
166 : _impl(std::make_unique<Impl>())
167{
168}
169NEElementwiseDivision::NEElementwiseDivision(NEElementwiseDivision &&) = default;
170NEElementwiseDivision &NEElementwiseDivision::operator=(NEElementwiseDivision &&) = default;
171NEElementwiseDivision::~NEElementwiseDivision() = default;
172
173void NEElementwiseDivision::configure(ITensor *input1, ITensor *input2, ITensor *output, const ActivationLayerInfo &act_info)
174{
175 ARM_COMPUTE_UNUSED(act_info);
176 _impl->src_0 = input1;
177 _impl->src_1 = input2;
178 _impl->dst = output;
179 _impl->op = std::make_unique<cpu::CpuElementwiseDivision>();
180 _impl->op->configure(input1->info(), input2->info(), output->info());
181}
182
183Status NEElementwiseDivision::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info)
184{
185 ARM_COMPUTE_RETURN_ERROR_ON(act_info.enabled());
186 return cpu::CpuElementwiseDivision::validate(input1, input2, output);
187}
188
189void NEElementwiseDivision::run()
190{
191 ITensorPack pack;
192 pack.add_tensor(TensorType::ACL_SRC_0, _impl->src_0);
193 pack.add_tensor(TensorType::ACL_SRC_1, _impl->src_1);
194 pack.add_tensor(TensorType::ACL_DST, _impl->dst);
195 _impl->op->run(pack);
196}
197
198struct NEElementwisePower::Impl
199{
200 const ITensor *src_0{ nullptr };
201 const ITensor *src_1{ nullptr };
202 ITensor *dst{ nullptr };
203 std::unique_ptr<cpu::CpuElementwisePower> op{ nullptr };
204};
205
206NEElementwisePower::NEElementwisePower()
207 : _impl(std::make_unique<Impl>())
208{
209}
210NEElementwisePower::NEElementwisePower(NEElementwisePower &&) = default;
211NEElementwisePower &NEElementwisePower::operator=(NEElementwisePower &&) = default;
212NEElementwisePower::~NEElementwisePower() = default;
213
214void NEElementwisePower::configure(ITensor *input1, ITensor *input2, ITensor *output, const ActivationLayerInfo &act_info)
215{
216 ARM_COMPUTE_UNUSED(act_info);
217 _impl->src_0 = input1;
218 _impl->src_1 = input2;
219 _impl->dst = output;
220 _impl->op = std::make_unique<cpu::CpuElementwisePower>();
221 _impl->op->configure(input1->info(), input2->info(), output->info());
222}
223
224Status NEElementwisePower::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info)
225{
226 ARM_COMPUTE_RETURN_ERROR_ON(act_info.enabled());
227 return cpu::CpuElementwisePower::validate(input1, input2, output);
228}
229
230void NEElementwisePower::run()
231{
232 ITensorPack pack;
233 pack.add_tensor(TensorType::ACL_SRC_0, _impl->src_0);
234 pack.add_tensor(TensorType::ACL_SRC_1, _impl->src_1);
235 pack.add_tensor(TensorType::ACL_DST, _impl->dst);
236 _impl->op->run(pack);
237}
238
239template <ComparisonOperation COP>
240struct NEElementwiseComparisonStatic<COP>::Impl
241{
242 const ITensor *src_0{ nullptr };
243 const ITensor *src_1{ nullptr };
244 ITensor *dst{ nullptr };
245 std::unique_ptr<cpu::CpuElementwiseComparisonStatic<COP>> op{ nullptr };
246};
247
248template <ComparisonOperation COP>
249NEElementwiseComparisonStatic<COP>::NEElementwiseComparisonStatic()
250 : _impl(std::make_unique<Impl>())
251{
252}
253template <ComparisonOperation COP>
254NEElementwiseComparisonStatic<COP>::NEElementwiseComparisonStatic(NEElementwiseComparisonStatic &&) = default;
255template <ComparisonOperation COP>
256NEElementwiseComparisonStatic<COP> &NEElementwiseComparisonStatic<COP>::operator=(NEElementwiseComparisonStatic &&) = default;
257template <ComparisonOperation COP>
258NEElementwiseComparisonStatic<COP>::~NEElementwiseComparisonStatic() = default;
259
260template <ComparisonOperation COP>
261void NEElementwiseComparisonStatic<COP>::configure(ITensor *input1, ITensor *input2, ITensor *output)
262{
263 _impl->src_0 = input1;
264 _impl->src_1 = input2;
265 _impl->dst = output;
266 _impl->op = std::make_unique<cpu::CpuElementwiseComparisonStatic<COP>>();
267 _impl->op->configure(input1->info(), input2->info(), output->info());
268}
269
270template <ComparisonOperation COP>
271Status NEElementwiseComparisonStatic<COP>::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output)
272{
273 return cpu::CpuElementwiseComparisonStatic<COP>::validate(input1, input2, output);
274}
275
276template <ComparisonOperation COP>
277void NEElementwiseComparisonStatic<COP>::run()
278{
279 ITensorPack pack;
280 pack.add_tensor(TensorType::ACL_SRC_0, _impl->src_0);
281 pack.add_tensor(TensorType::ACL_SRC_1, _impl->src_1);
282 pack.add_tensor(TensorType::ACL_DST, _impl->dst);
283 _impl->op->run(pack);
284}
285
286struct NEElementwiseComparison::Impl
287{
288 const ITensor *src_0{ nullptr };
289 const ITensor *src_1{ nullptr };
290 ITensor *dst{ nullptr };
291 std::unique_ptr<cpu::CpuElementwiseComparison> op{ nullptr };
292};
293
294NEElementwiseComparison::NEElementwiseComparison()
295 : _impl(std::make_unique<Impl>())
296{
297}
298NEElementwiseComparison::NEElementwiseComparison(NEElementwiseComparison &&) = default;
299NEElementwiseComparison &NEElementwiseComparison::operator=(NEElementwiseComparison &&) = default;
300NEElementwiseComparison::~NEElementwiseComparison() = default;
301
302void NEElementwiseComparison::configure(ITensor *input1, ITensor *input2, ITensor *output, ComparisonOperation op)
303{
304 _impl->src_0 = input1;
305 _impl->src_1 = input2;
306 _impl->dst = output;
307 _impl->op = std::make_unique<cpu::CpuElementwiseComparison>();
308 _impl->op->configure(input1->info(), input2->info(), output->info(), op);
309}
310
311Status NEElementwiseComparison::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, ComparisonOperation op)
312{
313 return cpu::CpuElementwiseComparison::validate(input1, input2, output, op);
314}
315
316void NEElementwiseComparison::run()
317{
318 ITensorPack pack;
319 pack.add_tensor(TensorType::ACL_SRC_0, _impl->src_0);
320 pack.add_tensor(TensorType::ACL_SRC_1, _impl->src_1);
321 pack.add_tensor(TensorType::ACL_DST, _impl->dst);
322 _impl->op->run(pack);
323}
324
325// Supported Specializations
326template class NEElementwiseComparisonStatic<ComparisonOperation::Equal>;
327template class NEElementwiseComparisonStatic<ComparisonOperation::NotEqual>;
328template class NEElementwiseComparisonStatic<ComparisonOperation::Greater>;
329template class NEElementwiseComparisonStatic<ComparisonOperation::GreaterEqual>;
330template class NEElementwiseComparisonStatic<ComparisonOperation::Less>;
331template class NEElementwiseComparisonStatic<ComparisonOperation::LessEqual>;
332} // namespace arm_compute