GNSS-SDR  0.0.19
An Open Source GNSS Software Defined Receiver
fft_base_kernels.h
Go to the documentation of this file.
1 /*!
2  * \file fft_base_kernels.h
3  * \brief FFT base kernels for OpenCL
4  *
5  *
6  * Version: <1.0>
7  *
8  * Copyright ( C ) 2008 Apple Inc. All Rights Reserved.
9  * SPDX-License-Identifier: LicenseRef-Apple-Permissive
10  *
11  */
12 
13 
14 #ifndef __CL_FFT_BASE_KERNELS_
15 #define __CL_FFT_BASE_KERNELS_
16 
17 #include <string>
18 
19 using namespace std;
20 
21 static string baseKernels = string(
22  "#ifndef M_PI\n"
23  "#define M_PI 0x1.921fb54442d18p+1\n"
24  "#endif\n"
25  "#define complexMul(a,b) ((float2)(mad(-(a).y, (b).y, (a).x * (b).x), mad((a).y, (b).x, (a).x * (b).y)))\n"
26  "#define conj(a) ((float2)((a).x, -(a).y))\n"
27  "#define conjTransp(a) ((float2)(-(a).y, (a).x))\n"
28  "\n"
29  "#define fftKernel2(a,dir) \\\n"
30  "{ \\\n"
31  " float2 c = (a)[0]; \\\n"
32  " (a)[0] = c + (a)[1]; \\\n"
33  " (a)[1] = c - (a)[1]; \\\n"
34  "}\n"
35  "\n"
36  "#define fftKernel2S(d1,d2,dir) \\\n"
37  "{ \\\n"
38  " float2 c = (d1); \\\n"
39  " (d1) = c + (d2); \\\n"
40  " (d2) = c - (d2); \\\n"
41  "}\n"
42  "\n"
43  "#define fftKernel4(a,dir) \\\n"
44  "{ \\\n"
45  " fftKernel2S((a)[0], (a)[2], dir); \\\n"
46  " fftKernel2S((a)[1], (a)[3], dir); \\\n"
47  " fftKernel2S((a)[0], (a)[1], dir); \\\n"
48  " (a)[3] = (float2)(dir)*(conjTransp((a)[3])); \\\n"
49  " fftKernel2S((a)[2], (a)[3], dir); \\\n"
50  " float2 c = (a)[1]; \\\n"
51  " (a)[1] = (a)[2]; \\\n"
52  " (a)[2] = c; \\\n"
53  "}\n"
54  "\n"
55  "#define fftKernel4s(a0,a1,a2,a3,dir) \\\n"
56  "{ \\\n"
57  " fftKernel2S((a0), (a2), dir); \\\n"
58  " fftKernel2S((a1), (a3), dir); \\\n"
59  " fftKernel2S((a0), (a1), dir); \\\n"
60  " (a3) = (float2)(dir)*(conjTransp((a3))); \\\n"
61  " fftKernel2S((a2), (a3), dir); \\\n"
62  " float2 c = (a1); \\\n"
63  " (a1) = (a2); \\\n"
64  " (a2) = c; \\\n"
65  "}\n"
66  "\n"
67  "#define bitreverse8(a) \\\n"
68  "{ \\\n"
69  " float2 c; \\\n"
70  " c = (a)[1]; \\\n"
71  " (a)[1] = (a)[4]; \\\n"
72  " (a)[4] = c; \\\n"
73  " c = (a)[3]; \\\n"
74  " (a)[3] = (a)[6]; \\\n"
75  " (a)[6] = c; \\\n"
76  "}\n"
77  "\n"
78  "#define fftKernel8(a,dir) \\\n"
79  "{ \\\n"
80  " const float2 w1 = (float2)(0x1.6a09e6p-1f, dir*0x1.6a09e6p-1f); \\\n"
81  " const float2 w3 = (float2)(-0x1.6a09e6p-1f, dir*0x1.6a09e6p-1f); \\\n"
82  " float2 c; \\\n"
83  " fftKernel2S((a)[0], (a)[4], dir); \\\n"
84  " fftKernel2S((a)[1], (a)[5], dir); \\\n"
85  " fftKernel2S((a)[2], (a)[6], dir); \\\n"
86  " fftKernel2S((a)[3], (a)[7], dir); \\\n"
87  " (a)[5] = complexMul(w1, (a)[5]); \\\n"
88  " (a)[6] = (float2)(dir)*(conjTransp((a)[6])); \\\n"
89  " (a)[7] = complexMul(w3, (a)[7]); \\\n"
90  " fftKernel2S((a)[0], (a)[2], dir); \\\n"
91  " fftKernel2S((a)[1], (a)[3], dir); \\\n"
92  " fftKernel2S((a)[4], (a)[6], dir); \\\n"
93  " fftKernel2S((a)[5], (a)[7], dir); \\\n"
94  " (a)[3] = (float2)(dir)*(conjTransp((a)[3])); \\\n"
95  " (a)[7] = (float2)(dir)*(conjTransp((a)[7])); \\\n"
96  " fftKernel2S((a)[0], (a)[1], dir); \\\n"
97  " fftKernel2S((a)[2], (a)[3], dir); \\\n"
98  " fftKernel2S((a)[4], (a)[5], dir); \\\n"
99  " fftKernel2S((a)[6], (a)[7], dir); \\\n"
100  " bitreverse8((a)); \\\n"
101  "}\n"
102  "\n"
103  "#define bitreverse4x4(a) \\\n"
104  "{ \\\n"
105  " float2 c; \\\n"
106  " c = (a)[1]; (a)[1] = (a)[4]; (a)[4] = c; \\\n"
107  " c = (a)[2]; (a)[2] = (a)[8]; (a)[8] = c; \\\n"
108  " c = (a)[3]; (a)[3] = (a)[12]; (a)[12] = c; \\\n"
109  " c = (a)[6]; (a)[6] = (a)[9]; (a)[9] = c; \\\n"
110  " c = (a)[7]; (a)[7] = (a)[13]; (a)[13] = c; \\\n"
111  " c = (a)[11]; (a)[11] = (a)[14]; (a)[14] = c; \\\n"
112  "}\n"
113  "\n"
114  "#define fftKernel16(a,dir) \\\n"
115  "{ \\\n"
116  " const float w0 = 0x1.d906bcp-1f; \\\n"
117  " const float w1 = 0x1.87de2ap-2f; \\\n"
118  " const float w2 = 0x1.6a09e6p-1f; \\\n"
119  " fftKernel4s((a)[0], (a)[4], (a)[8], (a)[12], dir); \\\n"
120  " fftKernel4s((a)[1], (a)[5], (a)[9], (a)[13], dir); \\\n"
121  " fftKernel4s((a)[2], (a)[6], (a)[10], (a)[14], dir); \\\n"
122  " fftKernel4s((a)[3], (a)[7], (a)[11], (a)[15], dir); \\\n"
123  " (a)[5] = complexMul((a)[5], (float2)(w0, dir*w1)); \\\n"
124  " (a)[6] = complexMul((a)[6], (float2)(w2, dir*w2)); \\\n"
125  " (a)[7] = complexMul((a)[7], (float2)(w1, dir*w0)); \\\n"
126  " (a)[9] = complexMul((a)[9], (float2)(w2, dir*w2)); \\\n"
127  " (a)[10] = (float2)(dir)*(conjTransp((a)[10])); \\\n"
128  " (a)[11] = complexMul((a)[11], (float2)(-w2, dir*w2)); \\\n"
129  " (a)[13] = complexMul((a)[13], (float2)(w1, dir*w0)); \\\n"
130  " (a)[14] = complexMul((a)[14], (float2)(-w2, dir*w2)); \\\n"
131  " (a)[15] = complexMul((a)[15], (float2)(-w0, dir*-w1)); \\\n"
132  " fftKernel4((a), dir); \\\n"
133  " fftKernel4((a) + 4, dir); \\\n"
134  " fftKernel4((a) + 8, dir); \\\n"
135  " fftKernel4((a) + 12, dir); \\\n"
136  " bitreverse4x4((a)); \\\n"
137  "}\n"
138  "\n"
139  "#define bitreverse32(a) \\\n"
140  "{ \\\n"
141  " float2 c1, c2; \\\n"
142  " c1 = (a)[2]; (a)[2] = (a)[1]; c2 = (a)[4]; (a)[4] = c1; c1 = (a)[8]; (a)[8] = c2; c2 = (a)[16]; (a)[16] = c1; (a)[1] = c2; \\\n"
143  " c1 = (a)[6]; (a)[6] = (a)[3]; c2 = (a)[12]; (a)[12] = c1; c1 = (a)[24]; (a)[24] = c2; c2 = (a)[17]; (a)[17] = c1; (a)[3] = c2; \\\n"
144  " c1 = (a)[10]; (a)[10] = (a)[5]; c2 = (a)[20]; (a)[20] = c1; c1 = (a)[9]; (a)[9] = c2; c2 = (a)[18]; (a)[18] = c1; (a)[5] = c2; \\\n"
145  " c1 = (a)[14]; (a)[14] = (a)[7]; c2 = (a)[28]; (a)[28] = c1; c1 = (a)[25]; (a)[25] = c2; c2 = (a)[19]; (a)[19] = c1; (a)[7] = c2; \\\n"
146  " c1 = (a)[22]; (a)[22] = (a)[11]; c2 = (a)[13]; (a)[13] = c1; c1 = (a)[26]; (a)[26] = c2; c2 = (a)[21]; (a)[21] = c1; (a)[11] = c2; \\\n"
147  " c1 = (a)[30]; (a)[30] = (a)[15]; c2 = (a)[29]; (a)[29] = c1; c1 = (a)[27]; (a)[27] = c2; c2 = (a)[23]; (a)[23] = c1; (a)[15] = c2; \\\n"
148  "}\n"
149  "\n"
150  "#define fftKernel32(a,dir) \\\n"
151  "{ \\\n"
152  " fftKernel2S((a)[0], (a)[16], dir); \\\n"
153  " fftKernel2S((a)[1], (a)[17], dir); \\\n"
154  " fftKernel2S((a)[2], (a)[18], dir); \\\n"
155  " fftKernel2S((a)[3], (a)[19], dir); \\\n"
156  " fftKernel2S((a)[4], (a)[20], dir); \\\n"
157  " fftKernel2S((a)[5], (a)[21], dir); \\\n"
158  " fftKernel2S((a)[6], (a)[22], dir); \\\n"
159  " fftKernel2S((a)[7], (a)[23], dir); \\\n"
160  " fftKernel2S((a)[8], (a)[24], dir); \\\n"
161  " fftKernel2S((a)[9], (a)[25], dir); \\\n"
162  " fftKernel2S((a)[10], (a)[26], dir); \\\n"
163  " fftKernel2S((a)[11], (a)[27], dir); \\\n"
164  " fftKernel2S((a)[12], (a)[28], dir); \\\n"
165  " fftKernel2S((a)[13], (a)[29], dir); \\\n"
166  " fftKernel2S((a)[14], (a)[30], dir); \\\n"
167  " fftKernel2S((a)[15], (a)[31], dir); \\\n"
168  " (a)[17] = complexMul((a)[17], (float2)(0x1.f6297cp-1f, dir*0x1.8f8b84p-3f)); \\\n"
169  " (a)[18] = complexMul((a)[18], (float2)(0x1.d906bcp-1f, dir*0x1.87de2ap-2f)); \\\n"
170  " (a)[19] = complexMul((a)[19], (float2)(0x1.a9b662p-1f, dir*0x1.1c73b4p-1f)); \\\n"
171  " (a)[20] = complexMul((a)[20], (float2)(0x1.6a09e6p-1f, dir*0x1.6a09e6p-1f)); \\\n"
172  " (a)[21] = complexMul((a)[21], (float2)(0x1.1c73b4p-1f, dir*0x1.a9b662p-1f)); \\\n"
173  " (a)[22] = complexMul((a)[22], (float2)(0x1.87de2ap-2f, dir*0x1.d906bcp-1f)); \\\n"
174  " (a)[23] = complexMul((a)[23], (float2)(0x1.8f8b84p-3f, dir*0x1.f6297cp-1f)); \\\n"
175  " (a)[24] = complexMul((a)[24], (float2)(0x0p+0f, dir*0x1p+0f)); \\\n"
176  " (a)[25] = complexMul((a)[25], (float2)(-0x1.8f8b84p-3f, dir*0x1.f6297cp-1f)); \\\n"
177  " (a)[26] = complexMul((a)[26], (float2)(-0x1.87de2ap-2f, dir*0x1.d906bcp-1f)); \\\n"
178  " (a)[27] = complexMul((a)[27], (float2)(-0x1.1c73b4p-1f, dir*0x1.a9b662p-1f)); \\\n"
179  " (a)[28] = complexMul((a)[28], (float2)(-0x1.6a09e6p-1f, dir*0x1.6a09e6p-1f)); \\\n"
180  " (a)[29] = complexMul((a)[29], (float2)(-0x1.a9b662p-1f, dir*0x1.1c73b4p-1f)); \\\n"
181  " (a)[30] = complexMul((a)[30], (float2)(-0x1.d906bcp-1f, dir*0x1.87de2ap-2f)); \\\n"
182  " (a)[31] = complexMul((a)[31], (float2)(-0x1.f6297cp-1f, dir*0x1.8f8b84p-3f)); \\\n"
183  " fftKernel16((a), dir); \\\n"
184  " fftKernel16((a) + 16, dir); \\\n"
185  " bitreverse32((a)); \\\n"
186  "}\n\n");
187 
188 static string twistKernelInterleaved = string(
189  "__kernel void \\\n"
190  "clFFT_1DTwistInterleaved(__global float2 *in, unsigned int startRow, unsigned int numCols, unsigned int N, unsigned int numRowsToProcess, int dir) \\\n"
191  "{ \\\n"
192  " float2 a, w; \\\n"
193  " float ang; \\\n"
194  " unsigned int j; \\\n"
195  " unsigned int i = get_global_id(0); \\\n"
196  " unsigned int startIndex = i; \\\n"
197  " \\\n"
198  " if(i < numCols) \\\n"
199  " { \\\n"
200  " for(j = 0; j < numRowsToProcess; j++) \\\n"
201  " { \\\n"
202  " a = in[startIndex]; \\\n"
203  " ang = 2.0f * M_PI * dir * i * (startRow + j) / N; \\\n"
204  " w = (float2)(native_cos(ang), native_sin(ang)); \\\n"
205  " a = complexMul(a, w); \\\n"
206  " in[startIndex] = a; \\\n"
207  " startIndex += numCols; \\\n"
208  " } \\\n"
209  " } \\\n"
210  "} \\\n");
211 
212 static string twistKernelPlannar = string(
213  "__kernel void \\\n"
214  "clFFT_1DTwistSplit(__global float *in_real, __global float *in_imag , unsigned int startRow, unsigned int numCols, unsigned int N, unsigned int numRowsToProcess, int dir) \\\n"
215  "{ \\\n"
216  " float2 a, w; \\\n"
217  " float ang; \\\n"
218  " unsigned int j; \\\n"
219  " unsigned int i = get_global_id(0); \\\n"
220  " unsigned int startIndex = i; \\\n"
221  " \\\n"
222  " if(i < numCols) \\\n"
223  " { \\\n"
224  " for(j = 0; j < numRowsToProcess; j++) \\\n"
225  " { \\\n"
226  " a = (float2)(in_real[startIndex], in_imag[startIndex]); \\\n"
227  " ang = 2.0f * M_PI * dir * i * (startRow + j) / N; \\\n"
228  " w = (float2)(native_cos(ang), native_sin(ang)); \\\n"
229  " a = complexMul(a, w); \\\n"
230  " in_real[startIndex] = a.x; \\\n"
231  " in_imag[startIndex] = a.y; \\\n"
232  " startIndex += numCols; \\\n"
233  " } \\\n"
234  " } \\\n"
235  "} \\\n");
236 
237 
238 #endif
STL namespace.