Highly Efficient FFT for Exascale: HeFFTe v2.4
Loading...
Searching...
No Matches
heffte_stock_complex.h
1/*
2 -- heFFTe --
3 Univ. of Tennessee, Knoxville
4 @date
5*/
6
7#ifndef HEFFTE_STOCK_COMPLEX_H
8#define HEFFTE_STOCK_COMPLEX_H
9
10#include <type_traits>
11#include <iostream>
12
13#include "heffte_stock_vec_types.h"
14
19namespace heffte {
20namespace stock {
28template<typename F, int L>
29class alignas(L*sizeof(F)) Complex {
30 public:
31 // One 64-bit Complex-- 2 doubles-- pack<double, 2>::type == _m128d
32 // Two 64-bit Complex-- 4 doubles-- pack<double, 4>::type == _m256d
33 // Two 64-bit Complex-- 4 floats -- pack<float, 4>::type == _m128
34 // Four 64-bit Complex-- 8 floats -- pack<float, 8>::type == _m256
35
36 // Constructors for the Complex class
38 explicit Complex(F* const f): var(mm_load<F,L>(f)) {}
40 explicit Complex(std::initializer_list<F> il): var(mm_load<F,L>(il.begin())) {};
42 explicit Complex(typename pack<F,L>::type v): var(v) {}
44 explicit Complex(F x, F y): var(mm_pair_set<F,L>(x, y)) {}
46 explicit Complex(std::complex<F> const *c): var(mm_complex_load<F,L>(c)) {}
48 explicit Complex(std::complex<F> const *c, int stride): var(mm_complex_load<F,L>(c, stride)) {}
50 explicit Complex(std::initializer_list<std::complex<F>> il): var(il.size() == 1 ? mm_pair_set<F,L>((*il.begin()).real(), (*il.begin()).imag()) : mm_complex_load<F,L>(il.begin())) {};
52 explicit Complex(): var(mm_zero<F,L>()) {}
53
55 /* Basic operations with another pack of complex numbers */
57
60 return Complex(mm_add(var, o.var));
61 }
62
65 return Complex(mm_sub(var, o.var));
66 }
67
70 return Complex(mm_complex_mul(var, o.var));
71 }
72
75 return Complex(mm_complex_div(var, o.var));
76 }
77
80 var = mm_add(var, o.var);
81 return *this;
82 }
83
86 var = mm_sub(var, o.var);
87 return *this;
88 }
89
92 var = mm_complex_mul(var, o.var);
93 return *this;
94 }
95
98 var = mm_complex_div(var, o.var);
99 return *this;
100 }
101
103 /* Basic operations with a single real floating point number */
105
108 return Complex(mm_add(var, mm_pair_set<F,L>(o, 0)));
109 }
110
113 return Complex(mm_sub(var, mm_pair_set<F,L>(o, 0)));
114 }
115
118 return Complex(mm_mul(var, mm_set1<F,L>(o)));
119 }
120
123 return Complex(mm_div(var, mm_set1<F,L>(o)));
124 }
125
128 var = mm_add(var, mm_pair_set<F,L>(o, 0));
129 return *this;
130 }
131
134 var = mm_sub(var, mm_pair_set<F,L>(o, 0));
135 return *this;
136 }
137
140 var = mm_mul(var, mm_set1<F,L>(o));
141 return *this;
142 }
143
144 // Divide by and assign a floating point number
146 var = mm_div(var, mm_set1<F,L>(o));
147 return *this;
148 }
149
151 /* Other methods */
153
156 return Complex(mm_complex_fmadd(var, y.var, z.var));
157 }
158
161 return Complex(mm_complex_fmsub(var, y.var, z.var));
162 }
163
166 return Complex<F,L>(mm_neg(var));
167 }
168
170 void modulus(F* dest) {
171 typename pack<F, L>::type res = mm_complex_mod(var);
172 for(int i = 0; i < L/2; i++) {
173 dest[i] = res[i*2];
174 }
175 }
176
179 return mm_complex_mod(var);
180 }
181
184 return Complex(mm_complex_conj(var));
185 }
186
189 return Complex(mm_complex_mul_i(var));
190 }
191
194 return Complex(mm_complex_mul_neg_i(var));
195 }
196
198 void get(F* dest) {
199 mm_store<F,L>(dest, var);
200 }
201
203 std::complex<F> operator[](std::size_t idx) {
204 return std::complex<F>(reinterpret_cast<F*>(&var)[2*idx], reinterpret_cast<F*>(&var)[2*idx + 1]);
205 }
206
208 typename pack<F,L>::type get() const {
209 return var;
210 }
211
212 private:
214 typename pack<F,L>::type var;
215};
216
217
218
219
221template<typename F, int L>
222inline std::ostream& operator<<(std::ostream& os, const Complex<F,L>& dt){
223 typename pack<F, L>::type var = dt.get();
224 os << "( ";
225 for(int i = 0; i < L; i+=2) {
226 os << var[i];
227 if(var[i+1] < 0) os << " - " << -var[i+1] << "i";
228 else os << " + " << var[i+1] << "i";
229 if(i+2 < L) os << ", ";
230 }
231 os << " )";
232 return os;
233}
234
235}
236}
237
238#endif // HEFFTE_STOCK_COMPLEX_H
Custom complex type taking advantage of vectorization A Complex Type intrinsic to HeFFTe that takes a...
Definition heffte_stock_complex.h:29
Complex< F, L > operator*(Complex< F, L > const &o)
Multiply by another pack of complex number.
Definition heffte_stock_complex.h:69
Complex(std::initializer_list< std::complex< F > > il)
Load from initializer list of existing std::complex numbers.
Definition heffte_stock_complex.h:50
Complex< F, L > fmadd(Complex< F, L > const &y, Complex< F, L > const &z)
Fused multiply add.
Definition heffte_stock_complex.h:155
Complex(F x, F y)
Load from real and imaginary parts (repeating for all numbers in pack)
Definition heffte_stock_complex.h:44
Complex(std::complex< F > const *c)
Load from pointer to existing std::complex numbers.
Definition heffte_stock_complex.h:46
Complex< F, L > conjugate()
Conjugate the current complex number.
Definition heffte_stock_complex.h:183
pack< F, L >::type get() const
Return a vector pack representation of this number.
Definition heffte_stock_complex.h:208
Complex< F, L > operator-=(F o)
Subtract and assign a floating point number.
Definition heffte_stock_complex.h:133
Complex< F, L > __mul_neg_i()
Multiply the complex number by i.
Definition heffte_stock_complex.h:193
Complex< F, L > operator/=(Complex< F, L > const &o)
Divide by and assign another complex number.
Definition heffte_stock_complex.h:97
Complex< F, L > operator-(F o)
Subtract a floating point number.
Definition heffte_stock_complex.h:112
Complex< F, L > operator/(F o)
Divide by a floating point number.
Definition heffte_stock_complex.h:122
Complex(F *const f)
Load from an array of primitives.
Definition heffte_stock_complex.h:38
Complex()
Default constructor of zeros.
Definition heffte_stock_complex.h:52
Complex< F, L > __mul_i()
Multiply the complex number by i.
Definition heffte_stock_complex.h:188
void modulus(F *dest)
Store the modulus of the complex number in an array of size L/2.
Definition heffte_stock_complex.h:170
Complex< F, L > operator*=(F o)
Multiply by and assign a floating point number.
Definition heffte_stock_complex.h:139
Complex< F, L > operator*=(Complex< F, L > const &o)
Multiply by and assign another complex number.
Definition heffte_stock_complex.h:91
Complex(std::complex< F > const *c, int stride)
Load from strided pointer to existing std::complex numbers.
Definition heffte_stock_complex.h:48
Complex< F, L > operator+=(Complex< F, L > const &o)
Add with and assign another complex number.
Definition heffte_stock_complex.h:79
Complex< F, L > operator*(F o)
Multiply by a floating point number.
Definition heffte_stock_complex.h:117
Complex< F, L > operator/(Complex< F, L > const &o)
Divide by another pack of complex number.
Definition heffte_stock_complex.h:74
Complex< F, L > operator+=(F o)
Add with and assign a floating point number.
Definition heffte_stock_complex.h:127
pack< F, L >::type modulus()
Return the modulus of the complex number in a vector pack.
Definition heffte_stock_complex.h:178
Complex< F, L > fmsub(Complex< F, L > const &y, Complex< F, L > const &z)
Fused multiply add.
Definition heffte_stock_complex.h:160
Complex< F, L > operator-()
Negate the complex number.
Definition heffte_stock_complex.h:165
Complex(typename pack< F, L >::type v)
Load from an existing vector pack.
Definition heffte_stock_complex.h:42
void get(F *dest)
Store the Complex number in an array of length L.
Definition heffte_stock_complex.h:198
Complex< F, L > operator+(F o)
Add with a floating point number.
Definition heffte_stock_complex.h:107
Complex< F, L > operator-(Complex< F, L > const &o)
Subtract another pack of complex number.
Definition heffte_stock_complex.h:64
std::complex< F > operator[](std::size_t idx)
Access the ith Complex number as a std::complex.
Definition heffte_stock_complex.h:203
Complex< F, L > operator-=(Complex< F, L > const &o)
Subtract and assign another complex number from this.
Definition heffte_stock_complex.h:85
Complex< F, L > operator+(Complex< F, L > const &o)
Add with another pack of complex number.
Definition heffte_stock_complex.h:59
Complex(std::initializer_list< F > il)
Load from an initializer list of primitives.
Definition heffte_stock_complex.h:40
Namespace containing all HeFFTe methods and classes.
Definition heffte_backend_cuda.h:38
Wrapper around cufftHandle plans, set for float or double complex.
Definition heffte_backend_cuda.h:346
Struct to retrieve the vector type associated with the number of elements stored "per unit".
Definition heffte_stock_vec_types.h:43