VCTR
Loading...
Searching...
No Matches
Subtract.h
1/*
2 ==============================================================================
3 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
5 Copyright 2022- by sonible GmbH.
6
7 This file is part of VCTR - Versatile Container Templates Reconceptualized.
8
9 VCTR is free software: you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License version 3
11 only, as published by the Free Software Foundation.
12
13 VCTR is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU Lesser General Public License version 3 for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 version 3 along with VCTR. If not, see <https://www.gnu.org/licenses/>.
20 ==============================================================================
21*/
22
23namespace vctr::expressions
24{
25
26//==============================================================================
28template <size_t extent, class SrcAType, class SrcBType>
30{
31private:
32 static auto op (const ValueType<SrcAType>& a, const ValueType<SrcBType>& b) { return a - b; }
33
34public:
36
37 VCTR_COMMON_BINARY_VEC_VEC_EXPRESSION_MEMBERS (SubtractVectors, srcA, srcB)
38
39 VCTR_FORCEDINLINE constexpr auto operator[] (size_t i) const
40 {
41 return srcA[i] - srcB[i];
42 }
43
44 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
46 {
47 Expression::Accelerate::sub (srcA.evalNextVectorOpInExpressionChain (dst), srcB.evalNextVectorOpInExpressionChain (dst), dst, size());
48 return dst;
49 }
50
51 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
53 {
54 Expression::IPP::sub (srcA.evalNextVectorOpInExpressionChain (dst), srcB.evalNextVectorOpInExpressionChain (dst), dst, sizeToInt (size()));
55 return dst;
56 }
57
58 //==============================================================================
59 VCTR_FORWARD_PREPARE_SIMD_EVALUATION_BINARY_EXPRESSION_MEMBER_FUNCTIONS (srcA, srcB)
60
61 // AVX Implementation
62 VCTR_FORCEDINLINE VCTR_TARGET ("fma") AVXRegister<value_type> getAVX (size_t i) const
63 requires (archX64 && has::getAVX<SrcAType> && has::getAVX<SrcBType> && Expression::CommonElement::isRealFloat)
64 {
65 return Expression::AVX::sub (srcA.getAVX (i), srcB.getAVX (i));
66 }
67
68 VCTR_FORCEDINLINE VCTR_TARGET ("avx2") AVXRegister<value_type> getAVX (size_t i) const
69 requires (archX64 && has::getAVX<SrcAType> && has::getAVX<SrcBType> && Expression::CommonElement::isUnsigned)
70 {
71 return Expression::AVX::sub (srcA.getAVX (i), srcB.getAVX (i));
72 }
73
74 // SSE Implementation
75 VCTR_FORCEDINLINE VCTR_TARGET ("sse4.1") SSERegister<value_type> getSSE (size_t i) const
76 requires (archX64 && has::getSSE<SrcAType> && has::getSSE<SrcBType>)
77 {
78 return Expression::SSE::sub (srcA.getSSE (i), srcB.getSSE (i));
79 }
80
81 // Neon Implementation
82 NeonRegister<value_type> getNeon (size_t i) const
83 requires (archARM && has::getNeon<SrcAType> && has::getNeon<SrcBType>)
84 {
85 return Expression::Neon::sub (srcA.getNeon (i), srcB.getNeon (i));
86 }
87};
88
89//==============================================================================
91template <size_t extent, class SrcType>
93{
94public:
95 using value_type = ValueType<SrcType>;
96
97 VCTR_COMMON_BINARY_SINGLE_VEC_EXPRESSION_MEMBERS (SubtractVecFromSingle, src, single)
98
99 VCTR_FORCEDINLINE constexpr value_type operator[] (size_t i) const
100 {
101 return single - src[i];
102 }
103
104 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
106 {
107 auto fac = value_type (-1);
108 Expression::Accelerate::multiplyAdd (src.evalNextVectorOpInExpressionChain (dst), fac, single, dst, size());
109 return dst;
110 }
111
112 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
114 {
115 Expression::IPP::sub (single, src.evalNextVectorOpInExpressionChain (dst), dst, sizeToInt (size()));
116 return dst;
117 }
118
119 //==============================================================================
120 // AVX Implementation
121 VCTR_FORCEDINLINE VCTR_TARGET ("avx") void prepareAVXEvaluation() const
123 {
124 src.prepareAVXEvaluation();
125 singleSIMD.avx = Expression::AVX::broadcast (single);
126 }
127
128 VCTR_FORCEDINLINE VCTR_TARGET ("fma") AVXRegister<value_type> getAVX (size_t i) const
129 requires (archX64 && has::getAVX<SrcType> && Expression::allElementTypesSame && Expression::CommonElement::isRealFloat)
130 {
131 return Expression::AVX::sub (singleSIMD.avx, src.getAVX (i));
132 }
133
134 VCTR_FORCEDINLINE VCTR_TARGET ("avx2") AVXRegister<value_type> getAVX (size_t i) const
135 requires (archX64 && has::getAVX<SrcType> && Expression::allElementTypesSame && Expression::CommonElement::isInt)
136 {
137 return Expression::AVX::sub (singleSIMD.avx, src.getAVX (i));
138 }
139
140 // SSE Implementation
141 VCTR_FORCEDINLINE VCTR_TARGET ("sse4.1") void prepareSSEEvaluation() const
143 {
144 src.prepareSSEEvaluation();
145 singleSIMD.sse = Expression::SSE::broadcast (single);
146 }
147
148 VCTR_FORCEDINLINE VCTR_TARGET ("sse4.1") SSERegister<value_type> getSSE (size_t i) const
149 requires (archX64 && has::getSSE<SrcType> && Expression::allElementTypesSame)
150 {
151 return Expression::SSE::sub (singleSIMD.sse, src.getSSE (i));
152 }
153
154 // Neon Implementation
155 void prepareNeonEvaluation() const
157 {
158 src.prepareNeonEvaluation();
159 singleSIMD.neon = Expression::Neon::broadcast (single);
160 }
161
162 NeonRegister<value_type> getNeon (size_t i) const
163 requires (archARM && has::getNeon<SrcType> && Expression::allElementTypesSame)
164 {
165 return Expression::Neon::sub (singleSIMD.neon, src.getNeon (i));
166 }
167
168private:
169 mutable SIMDRegisterUnion<Expression> singleSIMD {};
170};
171
172//==============================================================================
174template <size_t extent, class SrcType>
176{
177public:
178 using value_type = ValueType<SrcType>;
179
180 VCTR_COMMON_BINARY_SINGLE_VEC_EXPRESSION_MEMBERS (SubtractSingleFromVec, src, single)
181
182 VCTR_FORCEDINLINE constexpr value_type operator[] (size_t i) const
183 {
184 return src[i] - single;
185 }
186
187 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
189 {
190 Expression::Accelerate::add (src.evalNextVectorOpInExpressionChain (dst), -single, dst, size());
191 return dst;
192 }
193
194 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
196 {
197 Expression::IPP::sub (src.evalNextVectorOpInExpressionChain (dst), single, dst, sizeToInt (size()));
198 return dst;
199 }
200
201 //==============================================================================
202 VCTR_FORCEDINLINE VCTR_TARGET ("avx") void prepareAVXEvaluation() const
204 {
205 src.prepareAVXEvaluation();
206 singleSIMD.avx = Expression::AVX::broadcast (single);
207 }
208
209 VCTR_FORCEDINLINE VCTR_TARGET ("sse4.1") void prepareSSEEvaluation() const
211 {
212 src.prepareSSEEvaluation();
213 singleSIMD.sse = Expression::SSE::broadcast (single);
214 }
215
216 void prepareNeonEvaluation() const
218 {
219 src.prepareNeonEvaluation();
220 singleSIMD.neon = Expression::Neon::broadcast (single);
221 }
222
223 // AVX Implementation
224 VCTR_FORCEDINLINE VCTR_TARGET ("fma") AVXRegister<value_type> getAVX (size_t i) const
225 requires (archX64 && has::getAVX<SrcType> && Expression::allElementTypesSame && Expression::CommonElement::isRealFloat)
226 {
227 return Expression::AVX::sub (src.getAVX (i), singleSIMD.avx);
228 }
229
230 VCTR_FORCEDINLINE VCTR_TARGET ("avx2") AVXRegister<value_type> getAVX (size_t i) const
231 requires (archX64 && has::getAVX<SrcType> && Expression::allElementTypesSame && Expression::CommonElement::isInt)
232 {
233 return Expression::AVX::sub (src.getAVX (i), singleSIMD.avx);
234 }
235
236 // SSE Implementation
237 VCTR_FORCEDINLINE VCTR_TARGET ("sse4.1") SSERegister<value_type> getSSE (size_t i) const
238 requires (archX64 && has::getSSE<SrcType> && Expression::allElementTypesSame)
239 {
240 return Expression::SSE::sub (src.getSSE (i), singleSIMD.sse);
241 }
242
243 // Neon Implementation
244 NeonRegister<value_type> getNeon (size_t i) const
245 requires (archARM && has::getNeon<SrcType> && Expression::allElementTypesSame)
246 {
247 return Expression::Neon::sub (src.getNeon (i), singleSIMD.neon);
248 }
249
250private:
251 mutable SIMDRegisterUnion<Expression> singleSIMD {};
252};
253
254} // namespace vctr::expressions
255
256namespace vctr
257{
258
263template <class SrcAType, class SrcBType>
266constexpr auto operator- (SrcAType&& a, SrcBType&& b)
267{
268 assertCommonSize (a, b);
269 constexpr auto extent = getCommonExtent<SrcAType, SrcBType>();
270
271 return expressions::SubtractVectors<extent, SrcAType, SrcBType> (std::forward<SrcAType> (a), std::forward<SrcBType> (b));
272}
273
278template <class Src>
279requires is::anyVctrOrExpression<Src>
280constexpr auto operator- (typename std::remove_cvref_t<Src>::value_type single, Src&& vec)
281{
282 return expressions::SubtractVecFromSingle<extentOf<Src>, Src> (single, std::forward<Src> (vec));
283}
284
289template <class Src>
290requires is::anyVctrOrExpression<Src>
291constexpr auto operator- (Src&& vec, typename std::remove_cvref_t<Src>::value_type single)
292{
293 return expressions::SubtractSingleFromVec<extentOf<Src>, Src> (single, std::forward<Src> (vec));
294}
295
296} // namespace vctr
Subtracts a single value from a vector like type.
Definition: Subtract.h:176
Subtracts a vector like type from a single value.
Definition: Subtract.h:93
Subtracts two vector like types.
Definition: Subtract.h:30
Constrains a type to have a member function getAVX (size_t) const.
Definition: ContainerAndExpressionConcepts.h:92
Constrains a type to have a member function getNeon (size_t) const.
Definition: ContainerAndExpressionConcepts.h:84
Constrains a type to have a member function getSSE (size_t) const.
Definition: ContainerAndExpressionConcepts.h:100
Constrains a type to have a member function prepareAVXEvaluation() const.
Definition: ContainerAndExpressionConcepts.h:88
Constrains a type to have a member function prepareNeonEvaluation() const.
Definition: ContainerAndExpressionConcepts.h:80
Constrains a type to have a member function prepareSSEEvaluation() const.
Definition: ContainerAndExpressionConcepts.h:96
Constrains a type to either be an expression template or any derived instance of VctrBase.
Definition: ContainerAndExpressionConcepts.h:230
A combined concept to check if Apple Accelerate is a suitable option for a real valued floating point...
Definition: ContainerAndExpressionConcepts.h:321
A combined concept to check if Apple Accelerate is a suitable option for a real valued floating point...
Definition: ContainerAndExpressionConcepts.h:260
A combined concept to check if Apple Accelerate is a suitable option for a real or complex valued flo...
Definition: ContainerAndExpressionConcepts.h:268
A combined concept to check if Intel IPP is a suitable option for a real or complex valued floating p...
Definition: ContainerAndExpressionConcepts.h:342
A combined concept to check if Intel IPP is a suitable option for a real or complex valued floating p...
Definition: ContainerAndExpressionConcepts.h:296
constexpr auto operator-(SrcAType &&a, SrcBType &&b)
Returns an expression that subtracts vector or expression b from vector or expression a.
Definition: Subtract.h:266
The main namespace of the VCTR project.
Definition: Array.h:24
constexpr void assertCommonSize(const A &a, const B &b)
Ensures that both sources have the same size.
Definition: Traits.h:256
typename detail::ValueType< std::remove_cvref_t< T > >::Type ValueType
If T is an expression template, it equals its return type, if it's a type that defines value_type as ...
Definition: Traits.h:201
typename detail::CommonVecExpressionType< A, B, op >::type CommonVecExpressionType
Used to figure out the value_type for binary vector-vector operations.
Definition: ExpressionTemplate.h:177
int sizeToInt(size_t size)
Casts the size_t argument to an int.
Definition: PlatformVectorOpsHelpers.h:27
Definition: AVXRegister.h:28
The base class to every expression template.
Definition: ExpressionTemplate.h:37
Definition: NeonRegister.h:28
Definition: SSERegister.h:28
Helper template to define a union of all supported SIMD types.
Definition: ExpressionTemplate.h:123