VCTR
Loading...
Searching...
No Matches
AppleAccelerate.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::PlatformVectorOps
24{
25
26template <class T>
27class AppleAccelerate
28{
29};
30
31#if VCTR_APPLE
32
33template <>
34class AppleAccelerate<float>
35{
36public:
37 //==============================================================================
38 // vForce functions
39 //==============================================================================
40 // clang-format off
41 static void abs (const float* src, float* dst, int len) { vvfabsf (dst, src, &len); }
42 static void ln (const float* src, float* dst, int len) { vvlogf (dst, src, &len); }
43 static void log10 (const float* src, float* dst, int len) { vvlog10f (dst, src, &len); }
44 static void log2 (const float* src, float* dst, int len) { vvlog2f (dst, src, &len); }
45 static void exp (const float* src, float* dst, int len) { vvexpf (dst, src, &len); }
46 static void exp2 (const float* src, float* dst, int len) { vvexp2f (dst, src, &len); }
47 static void pow (const float* base, const float* exp, float* dst, int len) { vvpowf (dst, exp, base, &len); }
48 static void sqrt (const float* src, float* dst, int len) { vvsqrtf (dst, src, &len); }
49 static void sin (const float* src, float* dst, int len) { vvsinf (dst, src, &len); }
50 static void cos (const float* src, float* dst, int len) { vvcosf (dst, src, &len); }
51 static void tan (const float* src, float* dst, int len) { vvtanf (dst, src, &len); }
52 static void asin (const float* src, float* dst, int len) { vvasinf (dst, src, &len); }
53 static void acos (const float* src, float* dst, int len) { vvacosf (dst, src, &len); }
54 static void atan (const float* src, float* dst, int len) { vvatanf (dst, src, &len); }
55 static void sinh (const float* src, float* dst, int len) { vvsinhf (dst, src, &len); }
56 static void cosh (const float* src, float* dst, int len) { vvcoshf (dst, src, &len); }
57 static void tanh (const float* src, float* dst, int len) { vvtanhf (dst, src, &len); }
58 static void asinh (const float* src, float* dst, int len) { vvasinhf (dst, src, &len); }
59 static void acosh (const float* src, float* dst, int len) { vvacoshf (dst, src, &len); }
60 static void atanh (const float* src, float* dst, int len) { vvatanhf (dst, src, &len); }
61 // clang-format on
62
63 //==============================================================================
64 // vDSP functions
65 //==============================================================================
66 // clang-format off
67 static void abs (const float* src, float* dst, size_t len) { vDSP_vabs (src, 1, dst, 1, len); }
68 static void add (const float* srcA, const float* srcB, float* dst, size_t len) { vDSP_vadd (srcA, 1, srcB, 1, dst, 1, len); }
69 static void add (const float* srcA, float srcB, float* dst, size_t len) { vDSP_vsadd (srcA, 1, &srcB, dst, 1, len); }
70 static void sub (const float* srcA, const float* srcB, float* dst, size_t len) { vDSP_vsub (srcB, 1, srcA, 1, dst, 1, len); }
71 static void mul (const float* srcA, const float* srcB, float* dst, size_t len) { vDSP_vmul (srcA, 1, srcB, 1, dst, 1, len); }
72 static void mul (const float* srcA, float srcB, float* dst, size_t len) { vDSP_vsmul (srcA, 1, &srcB, dst, 1, len); }
73 static void div (const float* srcA, const float* srcB, float* dst, size_t len) { vDSP_vdiv (srcB, 1, srcA, 1, dst, 1, len); }
74 static void div (const float* srcA, float srcB, float* dst, size_t len) { vDSP_vsdiv (srcA, 1, &srcB, dst, 1, len); }
75
76 static void multiplyAdd (const float* srcA, float srcB, float srcC, float* dst, size_t len) { vDSP_vsmsa (srcA, 1, &srcB, &srcC, dst, 1, len); }
77 static void multiplyAdd (const float* srcA, const float* srcB, const float* srcC, float* dst, size_t len) { vDSP_vma (srcA, 1, srcB, 1, srcC, 1, dst, 1, len); }
78 static void multiplyAdd (const float* srcA, float srcB, const float* srcC, float* dst, size_t len) { vDSP_vsma (srcA, 1, &srcB, srcC, 1, dst, 1, len); }
79
80 static void clampLow (const float* src, float thresh, float* dst, size_t len) { vDSP_vthr (src, 1, &thresh, dst, 1, len); }
81 static void clamp (const float* src, float l, float h, float* dst, size_t len) { vDSP_vclip (src, 1, &l, &h, dst, 1, len); }
82 static void square (const float* src, float* dst, size_t len) { vDSP_vsq (src, 1, dst, 1, len); }
83
84 static void intToFloat (const int32_t* src, float* dst, size_t len) { vDSP_vflt32 (src, 1, dst, 1, len); }
85 static void intToFloat (const uint32_t* src, float* dst, size_t len) { vDSP_vfltu32 (src, 1, dst, 1, len); }
86
87 static float max (const float* src, size_t len) { float r; vDSP_maxv (src, 1, &r, len); return r; }
88 static float min (const float* src, size_t len) { float r; vDSP_minv (src, 1, &r, len); return r; }
89 static float sum (const float* src, size_t len) { float r; vDSP_sve (src, 1, &r, len); return r; }
90 static float mean (const float* src, size_t len) { float r; vDSP_meanv (src, 1, &r, len); return r; }
91 static float meanSquare (const float* src, size_t len) { float r; vDSP_measqv (src, 1, &r, len); return r; }
92 static float rms (const float* src, size_t len) { float r; vDSP_rmsqv (src, 1, &r, len); return r; }
93 // clang-format on
94};
95
96template <>
97class AppleAccelerate<double>
98{
99public:
100 //==============================================================================
101 // vForce functions
102 //==============================================================================
103 // clang-format off
104 static void abs (const double* src, double* dst, int len) { vvfabs (dst, src, &len); }
105 static void ln (const double* src, double* dst, int len) { vvlog (dst, src, &len); }
106 static void log10 (const double* src, double* dst, int len) { vvlog10 (dst, src, &len); }
107 static void log2 (const double* src, double* dst, int len) { vvlog2 (dst, src, &len); }
108 static void exp (const double* src, double* dst, int len) { vvexp (dst, src, &len); }
109 static void exp2 (const double* src, double* dst, int len) { vvexp2 (dst, src, &len); }
110 static void pow (const double* base, const double* exp, double* dst, int len) { vvpow (dst, exp, base, &len); }
111 static void sqrt (const double* src, double* dst, int len) { vvsqrt (dst, src, &len); }
112 static void sin (const double* src, double* dst, int len) { vvsin (dst, src, &len); }
113 static void cos (const double* src, double* dst, int len) { vvcos (dst, src, &len); }
114 static void tan (const double* src, double* dst, int len) { vvtan (dst, src, &len); }
115 static void asin (const double* src, double* dst, int len) { vvasin (dst, src, &len); }
116 static void acos (const double* src, double* dst, int len) { vvacos (dst, src, &len); }
117 static void atan (const double* src, double* dst, int len) { vvatan (dst, src, &len); }
118 static void sinh (const double* src, double* dst, int len) { vvsinh (dst, src, &len); }
119 static void cosh (const double* src, double* dst, int len) { vvcosh (dst, src, &len); }
120 static void tanh (const double* src, double* dst, int len) { vvtanh (dst, src, &len); }
121 static void asinh (const double* src, double* dst, int len) { vvasinh (dst, src, &len); }
122 static void acosh (const double* src, double* dst, int len) { vvacosh (dst, src, &len); }
123 static void atanh (const double* src, double* dst, int len) { vvatanh (dst, src, &len); }
124 // clang-format on
125
126 //==============================================================================
127 // vDSP functions
128 //==============================================================================
129 // clang-format off
130 static void abs (const double* src, double* dst, size_t len) { vDSP_vabsD (src, 1, dst, 1, len); }
131 static void add (const double* srcA, const double* srcB, double* dst, size_t len) { vDSP_vaddD (srcA, 1, srcB, 1, dst, 1, len); }
132 static void add (const double* srcA, double srcB, double* dst, size_t len) { vDSP_vsaddD (srcA, 1, &srcB, dst, 1, len); }
133 static void sub (const double* srcA, const double* srcB, double* dst, size_t len) { vDSP_vsubD (srcB, 1, srcA, 1, dst, 1, len); }
134 static void mul (const double* srcA, const double* srcB, double* dst, size_t len) { vDSP_vmulD (srcA, 1, srcB, 1, dst, 1, len); }
135 static void mul (const double* srcA, double srcB, double* dst, size_t len) { vDSP_vsmulD (srcA, 1, &srcB, dst, 1, len); }
136 static void div (const double* srcA, const double* srcB, double* dst, size_t len) { vDSP_vdivD (srcB, 1, srcA, 1, dst, 1, len); }
137 static void div (const double* srcA, double srcB, double* dst, size_t len) { vDSP_vsdivD (srcA, 1, &srcB, dst, 1, len); }
138
139 static void multiplyAdd (const double* srcA, double srcB, double srcC, double* dst, size_t len) { vDSP_vsmsaD (srcA, 1, &srcB, &srcC, dst, 1, len); }
140 static void multiplyAdd (const double* srcA, const double* srcB, const double* srcC, double* dst, size_t len) { vDSP_vmaD (srcA, 1, srcB, 1, srcC, 1, dst, 1, len); }
141 static void multiplyAdd (const double* srcA, double srcB, const double* srcC, double* dst, size_t len) { vDSP_vsmaD (srcA, 1, &srcB, srcC, 1, dst, 1, len); }
142 // clang-format on
143
144 static void clampLow (const double* src, double thresh, double* dst, size_t len) { vDSP_vthrD (src, 1, &thresh, dst, 1, len); }
145 static void clamp (const double* src, double l, double h, double* dst, size_t len) { vDSP_vclipD (src, 1, &l, &h, dst, 1, len); }
146 static void square (const double* src, double* dst, size_t len) { vDSP_vsqD (src, 1, dst, 1, len); }
147
148 static void intToFloat (const int32_t* src, double* dst, size_t len)
149 {
150 VCTR_ASSERT ((void*) src != (void*) dst);
151 vDSP_vflt32D (src, 1, dst, 1, len);
152 }
153
154 static void intToFloat (const uint32_t* src, double* dst, size_t len)
155 {
156 VCTR_ASSERT ((void*) src != (void*) dst);
157 vDSP_vfltu32D (src, 1, dst, 1, len);
158 }
159
160 static double max (const double* src, size_t len) { double r; vDSP_maxvD (src, 1, &r, len); return r; }
161 static double min (const double* src, size_t len) { double r; vDSP_minvD (src, 1, &r, len); return r; }
162 static double sum (const double* src, size_t len) { double r; vDSP_sveD (src, 1, &r, len); return r; }
163 static double mean (const double* src, size_t len) { double r; vDSP_meanvD (src, 1, &r, len); return r; }
164 static double meanSquare (const double* src, size_t len) { double r; vDSP_measqvD (src, 1, &r, len); return r; }
165 static double rms (const double* src, size_t len) { double r; vDSP_rmsqvD (src, 1, &r, len); return r; }
166};
167
168template <>
169class AppleAccelerate<std::complex<float>>
170{
171private:
172 // clang-format off
173 static auto sp (std::complex<float>* c) { return DSPSplitComplex { reinterpret_cast<float*> (c), reinterpret_cast<float*> (c) + 1 }; }
174 static const auto sp (const std::complex<float>* c) { return sp (const_cast<std::complex<float>*> (c)); }
175 static auto sp (std::complex<float>& c) { return DSPSplitComplex { &reinterpret_cast<float&> (c), &reinterpret_cast<float&> (c) + 1 }; }
176 static const auto sp (const std::complex<float>& c) { return sp (const_cast<std::complex<float>&> (c)); }
177 // clang-format on
178
179public:
180 //==============================================================================
181 // vDSP functions
182 //==============================================================================
183 static void abs (const std::complex<float>* src, float* dst, size_t len)
184 {
185 auto s = sp (src);
186 vDSP_zvabs (&s, 2, dst, 1, len);
187 }
188
189 static void add (const std::complex<float>* srcA, const std::complex<float>* srcB, std::complex<float>* dst, size_t len)
190 {
191 auto sa = sp (srcA);
192 auto sb = sp (srcB);
193 auto d = sp (dst);
194 vDSP_zvadd (&sa, 2, &sb, 2, &d, 2, len);
195 }
196
197 static void add (const std::complex<float>* srcA, std::complex<float> srcB, std::complex<float>* dst, size_t len)
198 {
199 auto sa = sp (srcA);
200 auto sb = sp (srcB);
201 auto d = sp (dst);
202 vDSP_vsadd (sa.realp, 2, sb.realp, d.realp, 2, len);
203 vDSP_vsadd (sa.imagp, 2, sb.imagp, d.imagp, 2, len);
204 }
205
206 static void sub (const std::complex<float>* srcA, const std::complex<float>* srcB, std::complex<float>* dst, size_t len)
207 {
208 auto sa = sp (srcA);
209 auto sb = sp (srcB);
210 auto d = sp (dst);
211 vDSP_zvsub (&sa, 2, &sb, 2, &d, 2, len);
212 }
213
214 static void mul (const std::complex<float>* srcA, const std::complex<float>* srcB, std::complex<float>* dst, size_t len)
215 {
216 auto sa = sp (srcA);
217 auto sb = sp (srcB);
218 auto d = sp (dst);
219 vDSP_zvmul (&sa, 2, &sb, 2, &d, 2, len, 1);
220 }
221
222 static void div (const std::complex<float>* srcA, const std::complex<float>* srcB, std::complex<float>* dst, size_t len)
223 {
224 auto sa = sp (srcA);
225 auto sb = sp (srcB);
226 auto d = sp (dst);
227 vDSP_zvdiv (&sb, 2, &sa, 2, &d, 2, len);
228 }
229
230 static void conj (const std::complex<float>* src, std::complex<float>* dst, size_t len)
231 {
232 auto s = sp (src);
233 auto d = sp (dst);
234 vDSP_zvconj (&s, 2, &d, 2, len);
235 }
236
237 static void angle (const std::complex<float>* src, float* dst, size_t len)
238 {
239 auto s = sp (src);
240 vDSP_zvphas (&s, 2, dst, 1, len);
241 }
242
243 static void powerSpectrum (const std::complex<float>* src, float* dst, size_t len)
244 {
245 auto s = sp (src);
246 vDSP_zvmags (&s, 2, dst, 1, len);
247 }
248
249 //==============================================================================
250 // BLAS functions
251 //==============================================================================
252
253 static void copyReal (const std::complex<float>* src, float* dst, int len) { cblas_scopy (len, reinterpret_cast<const float*> (src), 2, dst, 1); }
254 static void copyImag (const std::complex<float>* src, float* dst, int len) { cblas_scopy (len, reinterpret_cast<const float*> (src) + 1, 2, dst, 1); }
255};
256
257template <>
258class AppleAccelerate<std::complex<double>>
259{
260private:
261 // clang-format off
262 static auto sp (std::complex<double>* c) { return DSPDoubleSplitComplex { reinterpret_cast<double*> (c), reinterpret_cast<double*> (c) + 1}; }
263 static const auto sp (const std::complex<double>* c) { return sp (const_cast<std::complex<double>*> (c)); }
264 static auto sp (std::complex<double>& c) { return DSPDoubleSplitComplex { &reinterpret_cast<double&> (c), &reinterpret_cast<double&> (c) + 1 }; }
265 static const auto sp (const std::complex<double>& c) { return sp (const_cast<std::complex<double>&> (c)); }
266 // clang-format on
267
268public:
269 //==============================================================================
270 // vDSP functions
271 //==============================================================================
272 static void abs (const std::complex<double>* src, double* dst, size_t len)
273 {
274 auto sc = sp (src);
275 vDSP_zvabsD (&sc, 2, dst, 1, len);
276 }
277
278 static void add (const std::complex<double>* srcA, const std::complex<double>* srcB, std::complex<double>* dst, size_t len)
279 {
280 auto sa = sp (srcA);
281 auto sb = sp (srcB);
282 auto d = sp (dst);
283 vDSP_zvaddD (&sa, 2, &sb, 2, &d, 2, len);
284 }
285
286 static void add (const std::complex<double>* srcA, std::complex<double> srcB, std::complex<double>* dst, size_t len)
287 {
288 auto sa = sp (srcA);
289 auto sb = sp (srcB);
290 auto d = sp (dst);
291 vDSP_vsaddD (sa.realp, 2, sb.realp, d.realp, 2, len);
292 vDSP_vsaddD (sa.imagp, 2, sb.imagp, d.imagp, 2, len);
293 }
294
295 static void sub (const std::complex<double>* srcA, const std::complex<double>* srcB, std::complex<double>* dst, size_t len)
296 {
297 auto sa = sp (srcA);
298 auto sb = sp (srcB);
299 auto d = sp (dst);
300 vDSP_zvsubD (&sa, 2, &sb, 2, &d, 2, len);
301 }
302
303 static void mul (const std::complex<double>* srcA, const std::complex<double>* srcB, std::complex<double>* dst, size_t len)
304 {
305 auto sa = sp (srcA);
306 auto sb = sp (srcB);
307 auto d = sp (dst);
308 vDSP_zvmulD (&sa, 2, &sb, 2, &d, 2, len, 1);
309 }
310
311 static void div (const std::complex<double>* srcA, const std::complex<double>* srcB, std::complex<double>* dst, size_t len)
312 {
313 auto sa = sp (srcA);
314 auto sb = sp (srcB);
315 auto d = sp (dst);
316 vDSP_zvdivD (&sb, 2, &sa, 2, &d, 2, len);
317 }
318
319 static void conj (const std::complex<double>* src, std::complex<double>* dst, size_t len)
320 {
321 auto s = sp (src);
322 auto d = sp (dst);
323 vDSP_zvconjD (&s, 2, &d, 2, len);
324 }
325
326 static void angle (const std::complex<double>* src, double* dst, size_t len)
327 {
328 auto s = sp (src);
329 vDSP_zvphasD (&s, 2, dst, 1, len);
330 }
331
332 static void powerSpectrum (const std::complex<double>* src, double* dst, size_t len)
333 {
334 auto s = sp (src);
335 vDSP_zvmagsD (&s, 2, dst, 1, len);
336 }
337
338 //==============================================================================
339 // BLAS functions
340 //==============================================================================
341
342 static void copyReal (const std::complex<double>* src, double* dst, int len) { cblas_dcopy (len, reinterpret_cast<const double*> (src), 2, dst, 1); }
343 static void copyImag (const std::complex<double>* src, double* dst, int len) { cblas_dcopy (len, reinterpret_cast<const double*> (src) + 1, 2, dst, 1); }
344};
345
346#endif
347} // namespace vctr::PlatformVectorOps
constexpr ExpressionChainBuilder< expressions::Log10 > log10
Computes the logarithm to the base of ten of the source values.
Definition: Log10.h:84
constexpr ExpressionChainBuilder< expressions::Sin > sin
Computes the sine of each source element.
Definition: Sin.h:88
constexpr ExpressionChainBuilder< expressions::Asinh > asinh
Computes the inverse hyperbolic sine of each source element.
Definition: Asinh.h:88
constexpr ExpressionChainBuilder< expressions::Exp > exp
Computes e (Euler's number, 2.7182818...) raised to the source vector elements power.
Definition: Exp.h:84
constexpr ExpressionChainBuilder< expressions::Asin > asin
Computes the inverse sine of each source element.
Definition: Asin.h:88
constexpr ExpressionChainBuilder< expressions::Acosh > acosh
Computes the inverse hyperbolic cosine of each source element.
Definition: Acosh.h:88
constexpr ExpressionChainBuilder< expressions::RootMeanSquare > rms
Computes the square root of the mean value of the squared source values.
Definition: Mean.h:254
constexpr ExpressionChainBuilder< expressions::Mean > mean
Computes the mean value of the source values.
Definition: Mean.h:242
constexpr ExpressionChainBuilder< expressions::Atan > atan
Computes the inverse tangent of each source element.
Definition: Atan.h:88
constexpr ExpressionChainBuilder< expressions::Ln > ln
Computes the natural logarithm of the source values.
Definition: Ln.h:84
constexpr auto clampLow(T lowerBound)
Ensures that the elements are not lower than lowerBound.
Definition: Clamp.h:199
constexpr ExpressionChainBuilder< expressions::Cosh > cosh
Computes the hyperbolic cosine of each source element.
Definition: Cosh.h:88
constexpr ExpressionChainBuilder< expressions::Acos > acos
Computes the inverse cosine of each source element.
Definition: Acos.h:88
constexpr ExpressionChainBuilder< expressions::Cos > cos
Computes the cosine of each source element.
Definition: Cos.h:88
constexpr ExpressionChainBuilder< expressions::Tan > tan
Computes the tangent of each source element.
Definition: Tan.h:88
constexpr ExpressionChainBuilder< expressions::Sqrt > sqrt
Computes the square root of the source values.
Definition: Sqrt.h:83
constexpr ExpressionChainBuilder< expressions::Atanh > atanh
Computes the inverse hyperbolic tangent of each source element.
Definition: Atanh.h:88
constexpr auto pow(SrcBaseType &&bases, SrcExpType &&exponents)
Returns an expression that raises the elements in bases element-wise to the power of the elements in ...
Definition: Pow.h:211
constexpr ExpressionChainBuilder< expressions::Sum > sum
Computes the sum of the source values.
Definition: Sum.h:116
constexpr ExpressionChainBuilder< expressions::Max > max
Computes the maximum value of the source values.
Definition: Max.h:194
constexpr ExpressionChainBuilder< expressions::Abs > abs
Computes the absolute value of the source values.
Definition: Abs.h:133
constexpr ExpressionChainBuilder< expressions::Angle > angle
Computes the phase angles of the complex source values.
Definition: Angle.h:67
constexpr ExpressionChainBuilder< expressions::Log2 > log2
Computes the logarithm to the base of two of the source values.
Definition: Log2.h:91
constexpr ExpressionChainBuilder< expressions::Square > square
Squares the source values.
Definition: Square.h:93
constexpr auto clamp(T lowerBound, T upperBound)
Ensures that the elements are not lower than lowerBound and not higher than upperBound.
Definition: Clamp.h:225
constexpr ExpressionChainBuilder< expressions::Sinh > sinh
Computes the hyperbolic sine of each source element.
Definition: Sinh.h:88
constexpr ExpressionChainBuilder< expressions::Min > min
Computes the minimum value of the source values.
Definition: Min.h:194
constexpr ExpressionChainBuilder< expressions::MeanSquare > meanSquare
Computes the mean value of the squared source values.
Definition: Mean.h:248
constexpr ExpressionChainBuilder< expressions::PowerSpectrum > powerSpectrum
Computes the power spectrum of the complex source values.
Definition: PowerSpectrum.h:72
constexpr ExpressionChainBuilder< expressions::Tanh > tanh
Computes the hyperbolic tangent of each source element.
Definition: Tanh.h:88