VCTR
Loading...
Searching...
No Matches
Add.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 (AddVectors, 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::add (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::add (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::add (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::add (srcA.getAVX (i), srcB.getAVX (i));
72 }
73
74 //==============================================================================
75 // SSE Implementation
76 VCTR_FORCEDINLINE VCTR_TARGET ("sse4.1") SSERegister<value_type> getSSE (size_t i) const
77 requires (archX64 && has::getSSE<SrcAType> && has::getSSE<SrcBType>)
78 {
79 return Expression::SSE::add (srcA.getSSE (i), srcB.getSSE (i));
80 }
81
82 //==============================================================================
83 // NEON Implementation
84 NeonRegister<value_type> getNeon (size_t i) const
85 requires (archARM && has::getNeon<SrcAType> && has::getNeon<SrcBType>)
86 {
87 return Expression::Neon::add (srcA.getNeon (i), srcB.getNeon (i));
88 }
89};
90
91//==============================================================================
93template <size_t extent, class SrcType>
95{
96public:
97 using value_type = ValueType<SrcType>;
98
99 VCTR_COMMON_BINARY_SINGLE_VEC_EXPRESSION_MEMBERS (AddSingleToVec, src, single)
100
101 VCTR_FORCEDINLINE constexpr value_type operator[] (size_t i) const
102 {
103 return single + src[i];
104 }
105
106 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
108 {
109 Expression::Accelerate::add (src.evalNextVectorOpInExpressionChain (dst), single, dst, size());
110 return dst;
111 }
112
113 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
115 {
116 Expression::IPP::add (src.evalNextVectorOpInExpressionChain (dst), single, dst, sizeToInt (size()));
117 return dst;
118 }
119
120 //==============================================================================
121 // AVX Implementation
122 VCTR_FORCEDINLINE VCTR_TARGET ("avx") void prepareAVXEvaluation() const
124 {
125 src.prepareAVXEvaluation();
126 singleSIMD.avx = Expression::AVX::broadcast (single);
127 }
128
129 VCTR_FORCEDINLINE VCTR_TARGET ("fma") AVXRegister<value_type> getAVX (size_t i) const
130 requires (archX64 && has::getAVX<SrcType> && Expression::allElementTypesSame && Expression::CommonElement::isRealFloat)
131 {
132 return Expression::AVX::add (singleSIMD.avx, src.getAVX (i));
133 }
134
135 VCTR_FORCEDINLINE VCTR_TARGET ("avx2") AVXRegister<value_type> getAVX (size_t i) const
136 requires (archX64 && has::getAVX<SrcType> && Expression::allElementTypesSame && Expression::CommonElement::isInt)
137 {
138 return Expression::AVX::add (singleSIMD.avx, src.getAVX (i));
139 }
140
141 // SSE Implementation
142 VCTR_FORCEDINLINE VCTR_TARGET ("sse4.1") void prepareSSEEvaluation() const
144 {
145 src.prepareSSEEvaluation();
146 singleSIMD.sse = Expression::SSE::broadcast (single);
147 }
148
149 VCTR_FORCEDINLINE VCTR_TARGET ("sse4.1") SSERegister<value_type> getSSE (size_t i) const
150 requires (archX64 && has::getSSE<SrcType> && Expression::allElementTypesSame)
151 {
152 return Expression::SSE::add (singleSIMD.sse, src.getSSE (i));
153 }
154
155private:
156 mutable SIMDRegisterUnion<Expression> singleSIMD {};
157};
158
159//==============================================================================
161template <size_t extent, class SrcType, is::constant ConstantType>
163{
164public:
165 using value_type = ValueType<SrcType>;
166
167 static constexpr auto constant = value_type (ConstantType::value);
168
169 VCTR_COMMON_UNARY_EXPRESSION_MEMBERS (AddConstantToVec, src)
170
171 VCTR_FORCEDINLINE constexpr value_type operator[] (size_t i) const
172 {
173 return constant + src[i];
174 }
175
176 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
178 {
179 Expression::Accelerate::add (src.evalNextVectorOpInExpressionChain (dst), constant, dst, size());
180 return dst;
181 }
182
183 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
185 {
186 Expression::IPP::add (src.evalNextVectorOpInExpressionChain (dst), constant, dst, sizeToInt (size()));
187 return dst;
188 }
189
190 //==============================================================================
191 // AVX Implementation
192 VCTR_FORCEDINLINE VCTR_TARGET ("avx") void prepareAVXEvaluation() const
194 {
195 src.prepareAVXEvaluation();
196 constantSIMD.avx = Expression::AVX::broadcast (constant);
197 }
198
199 VCTR_FORCEDINLINE VCTR_TARGET ("fma") AVXRegister<value_type> getAVX (size_t i) const
200 requires (archX64 && has::getAVX<SrcType> && Expression::allElementTypesSame && Expression::CommonElement::isRealFloat)
201 {
202 return Expression::AVX::add (constantSIMD.avx, src.getAVX (i));
203 }
204
205 // SSE Implementation
206 VCTR_FORCEDINLINE VCTR_TARGET ("sse4.1") void prepareSSEEvaluation() const
208 {
209 src.prepareSSEEvaluation();
210 constantSIMD.sse = Expression::SSE::broadcast (constant);
211 }
212
213 VCTR_FORCEDINLINE VCTR_TARGET ("sse4.1") SSERegister<value_type> getSSE (size_t i) const
214 requires (archX64 && has::getSSE<SrcType> && Expression::allElementTypesSame && Expression::CommonElement::isRealFloat)
215 {
216 return Expression::SSE::add (constantSIMD.sse, src.getSSE (i));
217 }
218
219private:
220 mutable SIMDRegisterUnion<Expression> constantSIMD {};
221};
222
223} // namespace vctr::expressions
224
225namespace vctr
226{
227
232template <is::anyVctrOrExpression SrcAType, is::anyVctrOrExpression SrcBType>
233constexpr auto operator+ (SrcAType&& a, SrcBType&& b)
234{
235 assertCommonSize (a, b);
236 constexpr auto extent = getCommonExtent<SrcAType, SrcBType>();
237
238 return expressions::AddVectors<extent, SrcAType, SrcBType> (std::forward<SrcAType> (a), std::forward<SrcBType> (b));
239}
240
245template <is::anyVctrOrExpression Src>
246constexpr auto operator+ (typename std::remove_cvref_t<Src>::value_type single, Src&& vec)
247{
248 return expressions::AddSingleToVec<extentOf<Src>, Src> (single, std::forward<Src> (vec));
249}
250
255template <is::anyVctrOrExpression Src>
256constexpr auto operator+ (Src&& vec, typename std::remove_cvref_t<Src>::value_type single)
257{
258 return expressions::AddSingleToVec<extentOf<Src>, Src> (single, std::forward<Src> (vec));
259}
260
265template <auto constantValue>
267
268} // namespace vctr
Adds a single compile time constant value to a vector like type.
Definition: Add.h:163
Adds a single value to a vector like type.
Definition: Add.h:95
Adds two vector like types.
Definition: Add.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 prepareSSEEvaluation() const.
Definition: ContainerAndExpressionConcepts.h:96
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:329
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 ExpressionChainBuilder< expressions::AddConstantToVec, Constant< constantValue > > addConstant
Returns an expression that adds a compile time constant to a vector or expression source.
Definition: Add.h:266
constexpr auto operator+(SrcAType &&a, SrcBType &&b)
Returns an expression that adds two vector or expression sources.
Definition: Add.h:233
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
An expression chain builder is an object which supplies various operator<< overloads which build chai...
Definition: ExpressionChainBuilder.h:157
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