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{
31public:
32 using value_type = std::common_type_t<ValueType<SrcAType>, ValueType<SrcBType>>;
33
34 VCTR_COMMON_BINARY_VEC_VEC_EXPRESSION_MEMBERS (SubtractVectors, srcA, srcB)
35
36 VCTR_FORCEDINLINE constexpr value_type operator[] (size_t i) const
37 {
38 return srcA[i] - srcB[i];
39 }
40
41 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
43 {
44 Expression::Accelerate::sub (srcA.evalNextVectorOpInExpressionChain (dst), srcB.evalNextVectorOpInExpressionChain (dst), dst, size());
45 return dst;
46 }
47
48 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
50 {
51 Expression::IPP::sub (srcA.evalNextVectorOpInExpressionChain (dst), srcB.evalNextVectorOpInExpressionChain (dst), dst, size());
52 return dst;
53 }
54
55 //==============================================================================
56 // AVX Implementation
57 VCTR_FORCEDINLINE VCTR_TARGET ("avx") AVXRegister<value_type> getAVX (size_t i) const
58 requires (archX64 && has::getAVX<SrcAType> && has::getAVX<SrcBType> && Expression::CommonElement::isRealFloat)
59 {
60 return Expression::AVX::sub (srcA.getAVX (i), srcB.getAVX (i));
61 }
62
63 VCTR_FORCEDINLINE VCTR_TARGET ("avx2") AVXRegister<value_type> getAVX (size_t i) const
64 requires (archX64 && has::getAVX<SrcAType> && has::getAVX<SrcBType> && Expression::CommonElement::isUnsigned)
65 {
66 return Expression::AVX::sub (srcA.getAVX (i), srcB.getAVX (i));
67 }
68
69 //==============================================================================
70 // SSE Implementation
71 VCTR_FORCEDINLINE VCTR_TARGET ("sse4.1") SSERegister<value_type> getSSE (size_t i) const
72 requires (archX64 && has::getSSE<SrcAType> && has::getSSE<SrcBType>)
73 {
74 return Expression::SSE::sub (srcA.getSSE (i), srcB.getSSE (i));
75 }
76
77 //==============================================================================
78 // Neon Implementation
79 NeonRegister<value_type> getNeon (size_t i) const
80 requires (archARM && has::getNeon<SrcAType> && has::getNeon<SrcBType>)
81 {
82 return Expression::Neon::sub (srcA.getNeon (i), srcB.getNeon (i));
83 }
84};
85
86//==============================================================================
88template <size_t extent, class SrcType>
90{
91public:
92 using value_type = ValueType<SrcType>;
93
94 VCTR_COMMON_BINARY_SINGLE_VEC_EXPRESSION_MEMBERS (SubtractVecFromSingle, src, single)
95
96 VCTR_FORCEDINLINE constexpr value_type operator[] (size_t i) const
97 {
98 return single - src[i];
99 }
100
101 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
103 {
104 auto fac = value_type (-1);
105 Expression::Accelerate::multiplyAdd (src.evalNextVectorOpInExpressionChain (dst), fac, single, dst, size());
106 return dst;
107 }
108
109 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
111 {
112 Expression::IPP::sub (single, src.evalNextVectorOpInExpressionChain (dst), dst, sizeToInt (size()));
113 return dst;
114 }
115
116 //==============================================================================
117 // AVX Implementation
118 VCTR_FORCEDINLINE VCTR_TARGET ("avx") AVXRegister<value_type> getAVX (size_t i) const
119 requires (archX64 && has::getAVX<SrcType> && Expression::allElementTypesSame && Expression::CommonElement::isRealFloat)
120 {
121 return Expression::AVX::sub (Expression::AVX::fromSSE (singleAsSSE, singleAsSSE), src.getAVX (i));
122 }
123
124 VCTR_FORCEDINLINE VCTR_TARGET ("avx2") AVXRegister<value_type> getAVX (size_t i) const
125 requires (archX64 && has::getAVX<SrcType> && Expression::allElementTypesSame && Expression::CommonElement::isInt)
126 {
127 return Expression::AVX::sub (Expression::AVX::fromSSE (singleAsSSE, singleAsSSE), src.getAVX (i));
128 }
129 //==============================================================================
130 // SSE Implementation
131 VCTR_FORCEDINLINE VCTR_TARGET ("sse4.1") SSERegister<value_type> getSSE (size_t i) const
132 requires (archX64 && has::getSSE<SrcType> && Expression::allElementTypesSame)
133 {
134 return Expression::SSE::sub (singleAsSSE, src.getSSE (i));
135 }
136
137 //==============================================================================
138 // Neon Implementation
139 NeonRegister<value_type> getNeon (size_t i) const
140 requires (archARM && has::getNeon<SrcType> && Expression::allElementTypesSame)
141 {
142 return Expression::Neon::sub (singleAsNeon, src.getNeon (i));
143 }
144};
145
146//==============================================================================
148template <size_t extent, class SrcType>
150{
151public:
152 using value_type = ValueType<SrcType>;
153
154 VCTR_COMMON_BINARY_SINGLE_VEC_EXPRESSION_MEMBERS (SubtractSingleFromVec, src, single)
155
156 VCTR_FORCEDINLINE constexpr value_type operator[] (size_t i) const
157 {
158 return src[i] - single;
159 }
160
161 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
163 {
164 Expression::Accelerate::add (src.evalNextVectorOpInExpressionChain (dst), -single, dst, size());
165 return dst;
166 }
167
168 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
170 {
171 Expression::IPP::sub (src.evalNextVectorOpInExpressionChain (dst), single, dst, sizeToInt (size()));
172 return dst;
173 }
174
175 //==============================================================================
176 // AVX Implementation
177 VCTR_FORCEDINLINE VCTR_TARGET ("avx") AVXRegister<value_type> getAVX (size_t i) const
178 requires (archX64 && has::getAVX<SrcType> && Expression::allElementTypesSame && Expression::CommonElement::isRealFloat)
179 {
180 return Expression::AVX::sub (src.getAVX (i), Expression::AVX::fromSSE (singleAsSSE, singleAsSSE));
181 }
182
183 VCTR_FORCEDINLINE VCTR_TARGET ("avx2") AVXRegister<value_type> getAVX (size_t i) const
184 requires (archX64 && has::getAVX<SrcType> && Expression::allElementTypesSame && Expression::CommonElement::isInt)
185 {
186 return Expression::AVX::sub (src.getAVX (i), Expression::AVX::fromSSE (singleAsSSE, singleAsSSE));
187 }
188 //==============================================================================
189 // SSE Implementation
190 VCTR_FORCEDINLINE VCTR_TARGET ("sse4.1") SSERegister<value_type> getSSE (size_t i) const
191 requires (archX64 && has::getSSE<SrcType> && Expression::allElementTypesSame)
192 {
193 return Expression::SSE::sub (src.getSSE (i), singleAsSSE);
194 }
195
196 //==============================================================================
197 // Neon Implementation
198 NeonRegister<value_type> getNeon (size_t i) const
199 requires (archARM && has::getNeon<SrcType> && Expression::allElementTypesSame)
200 {
201 return Expression::Neon::sub (src.getNeon (i), singleAsNeon);
202 }
203};
204
205} // namespace vctr::expressions
206
207namespace vctr
208{
209
214template <class SrcAType, class SrcBType>
217constexpr auto operator- (SrcAType&& a, SrcBType&& b)
218{
219 assertCommonSize (a, b);
220 constexpr auto extent = getCommonExtent<SrcAType, SrcBType>();
221
222 return expressions::SubtractVectors<extent, SrcAType, SrcBType> (std::forward<SrcAType> (a), std::forward<SrcBType> (b));
223}
224
229template <class Src>
230requires is::anyVctrOrExpression<Src>
231constexpr auto operator- (typename std::remove_cvref_t<Src>::value_type single, Src&& vec)
232{
233 return expressions::SubtractVecFromSingle<extentOf<Src>, Src> (single, std::forward<Src> (vec));
234}
235
240template <class Src>
241requires is::anyVctrOrExpression<Src>
242constexpr auto operator- (Src&& vec, typename std::remove_cvref_t<Src>::value_type single)
243{
244 return expressions::SubtractSingleFromVec<extentOf<Src>, Src> (single, std::forward<Src> (vec));
245}
246
247} // namespace vctr
Subtracts a single value from a vector like type.
Definition: Subtract.h:150
Subtracts a vector like type from a single value.
Definition: Subtract.h:90
Subtracts two vector like types.
Definition: Subtract.h:30
Constrains a type to have a member function getAVX (size_t) const.
Definition: ContainerAndExpressionConcepts.h:78
Constrains a type to have a member function getNeon (size_t) const.
Definition: ContainerAndExpressionConcepts.h:74
Constrains a type to have a member function getSSE (size_t) const.
Definition: ContainerAndExpressionConcepts.h:82
Constrains a type to either be an expression template or any derived instance of VctrBase.
Definition: ContainerAndExpressionConcepts.h:212
A combined concept to check if Apple Accelerate is a suitable option for a real valued floating point...
Definition: ContainerAndExpressionConcepts.h:303
A combined concept to check if Apple Accelerate is a suitable option for a real valued floating point...
Definition: ContainerAndExpressionConcepts.h:242
A combined concept to check if Apple Accelerate is a suitable option for a real or complex valued flo...
Definition: ContainerAndExpressionConcepts.h:250
A combined concept to check if Intel IPP is a suitable option for a real or complex valued floating p...
Definition: ContainerAndExpressionConcepts.h:324
A combined concept to check if Intel IPP is a suitable option for a real or complex valued floating p...
Definition: ContainerAndExpressionConcepts.h:278
constexpr auto operator-(SrcAType &&a, SrcBType &&b)
Returns an expression that subtracts vector or expression b from vector or expression a.
Definition: Subtract.h:217
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:253
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
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