VCTR
Loading...
Searching...
No Matches
Multiply.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 (MultiplyVectors, 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::mul (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::mul (srcA.evalNextVectorOpInExpressionChain (dst), srcB.evalNextVectorOpInExpressionChain (dst), dst, size());
52 return dst;
53 }
54
55
56 VCTR_FORCEDINLINE void evalVectorOpMultiplyAccumulate (value_type* dst) const
58 {
59 Expression::Accelerate::multiplyAdd (srcA.data(), srcB.data(), dst, dst, size());
60 }
61
62 VCTR_FORCEDINLINE void evalVectorOpMultiplyAccumulate (value_type* dst) const
64 {
65 Expression::IPP::multiplyAccumulate (srcA.data(), srcB.data(), dst, sizeToInt (size()));
66 }
67
68 //==============================================================================
69 // AVX Implementation
70 VCTR_FORCEDINLINE VCTR_TARGET ("avx") AVXRegister<value_type> getAVX (size_t i) const
71 requires (archX64 && has::getAVX<SrcAType> && has::getAVX<SrcBType> && Expression::allElementTypesSame && Expression::CommonElement::isRealFloat)
72 {
73 return Expression::AVX::mul (srcA.getAVX (i), srcB.getAVX (i));
74 }
75};
76
77//==============================================================================
79template <size_t extent, class SrcType>
81{
82public:
83 using value_type = ValueType<SrcType>;
84
85 VCTR_COMMON_BINARY_SINGLE_VEC_EXPRESSION_MEMBERS (MultiplyVecBySingle, src, single)
86
87 VCTR_FORCEDINLINE constexpr value_type operator[] (size_t i) const
88 {
89 return single * src[i];
90 }
91
92 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
94 {
95 Expression::Accelerate::mul (src.evalNextVectorOpInExpressionChain (dst), single, dst, size());
96 return dst;
97 }
98
99 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
101 {
102 Expression::IPP::mul (src.evalNextVectorOpInExpressionChain (dst), single, dst, sizeToInt (size()));
103 return dst;
104 }
105
106 VCTR_FORCEDINLINE void evalVectorOpMultiplyAccumulate (value_type* dst) const
108 {
109 Expression::Accelerate::multiplyAdd (src.data(), single, dst, dst, size());
110 }
111
112 VCTR_FORCEDINLINE void evalVectorOpMultiplyAccumulate (value_type* dst) const
114 {
115 Expression::IPP::multiplyAccumulate (src.data(), single, dst, sizeToInt (size()));
116 }
117
118 //==============================================================================
119 // AVX Implementation
120 VCTR_FORCEDINLINE VCTR_TARGET ("avx") AVXRegister<value_type> getAVX (size_t i) const
121 requires (archX64 && has::getAVX<SrcType> && Expression::allElementTypesSame && Expression::CommonElement::isRealFloat)
122 {
123 return Expression::AVX::mul (Expression::AVX::fromSSE (singleAsSSE, singleAsSSE), src.getAVX (i));
124 }
125
126 //==============================================================================
127 // SSE Implementation
128 VCTR_FORCEDINLINE VCTR_TARGET ("sse4.1") SSERegister<value_type> getSSE (size_t i) const
129 requires (archX64 && has::getSSE<SrcType> && Expression::allElementTypesSame && Expression::CommonElement::isRealFloat)
130 {
131 return Expression::SSE::mul (singleAsSSE, src.getSSE (i));
132 }
133};
134
135//==============================================================================
137template <size_t extent, class SrcType, is::constant ConstantType>
139{
140public:
141 using value_type = ValueType<SrcType>;
142
143 static constexpr auto constant = value_type (ConstantType::value);
144
145 VCTR_COMMON_UNARY_EXPRESSION_MEMBERS (MultiplyVecByConstant, src)
146
147 void applyRuntimeArgs()
148 {
149 asSSE = Expression::SSESrc::broadcast (constant);
150 asNeon = Expression::NeonSrc::broadcast (constant);
151 }
152
153 VCTR_FORCEDINLINE constexpr value_type operator[] (size_t i) const
154 {
155 return constant * src[i];
156 }
157
158 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
160 {
161 Expression::Accelerate::mul (src.evalNextVectorOpInExpressionChain (dst), constant, dst, size());
162 return dst;
163 }
164
165 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
167 {
168 Expression::IPP::mul (src.evalNextVectorOpInExpressionChain (dst), constant, dst, size());
169 return dst;
170 }
171
172 VCTR_FORCEDINLINE void evalVectorOpMultiplyAccumulate (value_type* dst) const
174 {
175 Expression::Accelerate::multiplyAdd (src.data(), constant, dst, dst, size());
176 }
177
178 VCTR_FORCEDINLINE void evalVectorOpMultiplyAccumulate (value_type* dst) const
180 {
181 Expression::IPP::multiplyAccumulate (src.data(), constant, dst, sizeToInt (size()));
182 }
183
184 //==============================================================================
185 // AVX Implementation
186 VCTR_FORCEDINLINE VCTR_TARGET ("avx") AVXRegister<value_type> getAVX (size_t i) const
187 requires (archX64 && has::getAVX<SrcType> && Expression::allElementTypesSame && Expression::CommonElement::isRealFloat)
188 {
189 return Expression::AVX::mul (Expression::AVX::fromSSE (asSSE, asSSE), src.getAVX (i));
190 }
191
192 //==============================================================================
193 // SSE Implementation
194 VCTR_FORCEDINLINE VCTR_TARGET ("sse4.1") SSERegister<value_type> getSSE (size_t i) const
195 requires (archX64 && has::getSSE<SrcType> && Expression::allElementTypesSame && Expression::CommonElement::isRealFloat)
196 {
197 return Expression::SSE::mul (asSSE, src.getSSE (i));
198 }
199
200private:
201
202 typename Expression::SSESrc asSSE;
203 typename Expression::NeonSrc asNeon;
204};
205
206} // namespace vctr::expressions
207
208namespace vctr::detail
209{
210template <class T>
211struct IsMultiplicationExpression : std::false_type {};
212
213template <size_t e, class A, class B>
214struct IsMultiplicationExpression<expressions::MultiplyVectors<e, A, B>> : std::true_type {};
215
216template <size_t e, class A>
217struct IsMultiplicationExpression<expressions::MultiplyVecBySingle<e, A>> : std::true_type {};
218} // namespace vctr::detail
219
220namespace vctr
221{
222
227template <class SrcAType, class SrcBType>
228requires (is::anyVctrOrExpression<std::remove_cvref_t<SrcAType>> &&
229 is::anyVctrOrExpression<std::remove_cvref_t<SrcBType>>)
230constexpr auto operator* (SrcAType&& a, SrcBType&& b)
231{
232 assertCommonSize (a, b);
233 constexpr auto extent = getCommonExtent<SrcAType, SrcBType>();
234
235 return expressions::MultiplyVectors<extent, SrcAType, SrcBType> (std::forward<SrcAType> (a), std::forward<SrcBType> (b));
236}
237
242template <class Src>
243requires is::anyVctrOrExpression<Src>
244constexpr auto operator* (typename std::remove_cvref_t<Src>::value_type single, Src&& vec)
245{
246 return expressions::MultiplyVecBySingle<extentOf<Src>, Src> (single, std::forward<Src> (vec));
247}
248
253template <class Src>
254requires is::anyVctrOrExpression<Src>
255constexpr auto operator* (Src&& vec, typename std::remove_cvref_t<Src>::value_type single)
256{
257 return expressions::MultiplyVecBySingle<extentOf<Src>, Src> (single, std::forward<Src> (vec));
258}
259
260
265template <auto constantValue>
267} // namespace vctr
Multiplies a vector like type by a single compile time constant value.
Definition: Multiply.h:139
Multiplies a vector like type by a single value.
Definition: Multiply.h:81
Multiplies two vector like types.
Definition: Multiply.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 getSSE (size_t) const.
Definition: ContainerAndExpressionConcepts.h:82
Constrains a type to be any derived instance of VctrBase.
Definition: ContainerAndExpressionConcepts.h:192
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:311
A combined concept to check if Intel IPP is a suitable option for a real valued floating point vector...
Definition: ContainerAndExpressionConcepts.h:266
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 ExpressionChainBuilder< expressions::MultiplyVecByConstant, Constant< constantValue > > multiplyByConstant
Returns an expression that multiplies a vector or expression source with a compile time constant.
Definition: Multiply.h:266
constexpr auto operator*(SrcAType &&a, SrcBType &&b)
Returns an expression that multiplies vector or expression a with vector or expression b.
Definition: Multiply.h:230
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
An expression chain builder is an object which supplies various operator<< overloads which build chai...
Definition: ExpressionChainBuilder.h:136
The base class to every expression template.
Definition: ExpressionTemplate.h:37
Definition: SSERegister.h:28