VCTR
Loading...
Searching...
No Matches
Divide.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 (DivideVectors, srcA, srcB)
38
39 VCTR_FORCEDINLINE constexpr value_type 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::div (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::div (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::div (srcA.getAVX (i), srcB.getAVX (i));
66 }
67
68 // SSE Implementation
69 VCTR_FORCEDINLINE VCTR_TARGET ("sse4.1") SSERegister<value_type> getSSE (size_t i) const
70 requires (archX64 && has::getSSE<SrcAType> && has::getSSE<SrcBType> && Expression::CommonElement::isRealFloat)
71 {
72 return Expression::SSE::div (srcA.getSSE (i), srcB.getSSE (i));
73 }
74};
75
76//==============================================================================
78template <size_t extent, class SrcType>
80{
81public:
82 using value_type = ValueType<SrcType>;
83
84 VCTR_COMMON_BINARY_SINGLE_VEC_EXPRESSION_MEMBERS (DivideSingleByVec, src, single)
85
86 VCTR_FORCEDINLINE constexpr value_type operator[] (size_t i) const
87 {
88 return single / src[i];
89 }
90
91 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
92 requires is::suitableForIppRealFloatVectorOp<SrcType, value_type> && std::same_as<float, value_type>
93 {
94 Expression::IPP::div (single, src.evalNextVectorOpInExpressionChain (dst), dst, sizeToInt (size()));
95 return dst;
96 }
97
98 //==============================================================================
99 // AVX Implementation
100 VCTR_FORCEDINLINE VCTR_TARGET ("avx") void prepareAVXEvaluation() const
102 {
103 src.prepareAVXEvaluation();
104 singleSIMD.avx = Expression::AVX::broadcast (single);
105 }
106
107 VCTR_FORCEDINLINE VCTR_TARGET ("fma") AVXRegister<value_type> getAVX (size_t i) const
108 requires (archX64 && has::getAVX<SrcType> && Expression::allElementTypesSame && Expression::CommonElement::isRealFloat)
109 {
110 return Expression::AVX::div (singleSIMD.avx, src.getAVX (i));
111 }
112
113 // SSE Implementation
114 VCTR_FORCEDINLINE VCTR_TARGET ("sse4.1") void prepareSSEEvaluation() const
116 {
117 src.prepareSSEEvaluation();
118 singleSIMD.sse = Expression::SSE::broadcast (single);
119 }
120
121 VCTR_FORCEDINLINE VCTR_TARGET ("sse4.1") SSERegister<value_type> getSSE (size_t i) const
122 requires (archX64 && has::getSSE<SrcType> && Expression::allElementTypesSame && Expression::CommonElement::isRealFloat)
123 {
124 return Expression::SSE::div (singleSIMD.sse, src.getSSE (i));
125 }
126
127private:
128 mutable SIMDRegisterUnion<Expression> singleSIMD {};
129};
130
131//==============================================================================
133template <size_t extent, class SrcType>
135{
136public:
137 using value_type = ValueType<SrcType>;
138
139 VCTR_COMMON_BINARY_SINGLE_VEC_EXPRESSION_MEMBERS (DivideVecBySingle, src, single)
140
141 VCTR_FORCEDINLINE constexpr auto operator[] (size_t i) const
142 {
143 return src[i] / single;
144 }
145
146 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
148 {
149 Expression::Accelerate::div (src.evalNextVectorOpInExpressionChain (dst), single, dst, size());
150 return dst;
151 }
152
153 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
155 {
156 Expression::IPP::div (src.evalNextVectorOpInExpressionChain (dst), single, dst, sizeToInt (size()));
157 return dst;
158 }
159
160 //==============================================================================
161 // AVX Implementation
162 VCTR_FORCEDINLINE VCTR_TARGET ("avx") void prepareAVXEvaluation() const
164 {
165 src.prepareAVXEvaluation();
166 singleSIMD.avx = Expression::AVX::broadcast (single);
167 }
168
169 VCTR_FORCEDINLINE VCTR_TARGET ("fma") AVXRegister<value_type> getAVX (size_t i) const
170 requires (archX64 && has::getAVX<SrcType> && Expression::allElementTypesSame && Expression::CommonElement::isRealFloat)
171 {
172 return Expression::AVX::div (src.getAVX (i), singleSIMD.avx);
173 }
174
175 // SSE Implementation
176 VCTR_FORCEDINLINE VCTR_TARGET ("sse4.1") void prepareSSEEvaluation() const
178 {
179 src.prepareSSEEvaluation();
180 singleSIMD.sse = Expression::SSE::broadcast (single);
181 }
182
183 VCTR_FORCEDINLINE VCTR_TARGET ("sse4.1") SSERegister<value_type> getSSE (size_t i) const
184 requires (archX64 && has::getSSE<SrcType> && Expression::allElementTypesSame && Expression::CommonElement::isRealFloat)
185 {
186 return Expression::SSE::div (src.getSSE (i), singleSIMD.sse);
187 }
188
189private:
190 mutable SIMDRegisterUnion<Expression> singleSIMD {};
191};
192
193} // namespace vctr::expressions
194
195namespace vctr
196{
197
202template <class SrcAType, class SrcBType>
205constexpr auto operator/ (SrcAType&& a, SrcBType&& b)
206{
207 assertCommonSize (a, b);
208 constexpr auto extent = getCommonExtent<SrcAType, SrcBType>();
209
210 return expressions::DivideVectors<extent, SrcAType, SrcBType> (std::forward<SrcAType> (a), std::forward<SrcBType> (b));
211}
212
217template <class Src>
218requires is::anyVctrOrExpression<Src>
219constexpr auto operator/ (typename std::remove_cvref_t<Src>::value_type single, Src&& vec)
220{
221 return expressions::DivideSingleByVec<extentOf<Src>, Src> (single, std::forward<Src> (vec));
222}
223
228template <class Src>
229requires is::anyVctrOrExpression<Src>
230constexpr auto operator/ (Src&& vec, typename std::remove_cvref_t<Src>::value_type single)
231{
232 return expressions::DivideVecBySingle<extentOf<Src>, Src> (single, std::forward<Src> (vec));
233}
234
235} // namespace vctr
Divides a single value by a vector.
Definition: Divide.h:80
Divides a vector like type by a single value.
Definition: Divide.h:135
Divides two vector like types.
Definition: Divide.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 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
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: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 Intel IPP is a suitable option for a real valued floating point vector...
Definition: ContainerAndExpressionConcepts.h:284
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 divides vector or expression a by vector or expression b.
Definition: Divide.h:205
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: SSERegister.h:28
Helper template to define a union of all supported SIMD types.
Definition: ExpressionTemplate.h:123