Loading [MathJax]/extensions/TeX/AMSsymbols.js
LAL 7.7.0.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
CudaComplexFFT.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2010 Karsten Wiesner, Jolien Creighton
3*
4* This program is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License as published by
6* the Free Software Foundation; either version 2 of the License, or
7* (at your option) any later version.
8*
9* This program is distributed in the hope that it will be useful,
10* but WITHOUT ANY WARRANTY; without even the implied warranty of
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12* GNU General Public License for more details.
13*
14* You should have received a copy of the GNU General Public License
15* along with with program; see the file COPYING. If not, write to the
16* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17* MA 02110-1301 USA
18*/
19
20#include <string.h>
21
22#include <lal/LALDatatypes.h>
23#include <lal/LALMalloc.h>
24#include <lal/XLALError.h>
25#include <lal/ComplexFFT.h>
26#include <lal/FFTWMutex.h>
27#include <fftw3.h>
28
29#include "CudaFunctions.h"
30#include "CudaFFT.h"
31#include "CudaPlan.h"
32
33#ifdef __GNUC__
34#define UNUSED __attribute__ ((unused))
35#else
36#define UNUSED
37#endif
38
39/*
40 *
41 * XLAL COMPLEX8 functions
42 *
43 */
44
45
46COMPLEX8FFTPlan * XLALCreateCOMPLEX8FFTPlan( UINT4 size, int fwdflg, UNUSED int measurelvl )
47{
48 COMPLEX8FFTPlan *plan;
49 UINT4 createSize;
50
51 if ( ! size )
53
54 /* "use" measurelvl */
55 measurelvl = 0;
56
57 /* allocate memory for the plan and the temporary arrays */
58 plan = XLALMalloc( sizeof( *plan ) );
59 if ( ! plan )
60 {
61 XLALFree( plan );
63 }
64
65 /* create the plan */
66 /* LAL_FFTW_WISDOM_LOCK; */
67 /*
68 * Change the size to avoid CUDA bug with FFT of size 1
69 */
70 if( size == 1 ) createSize = 2;
71 else createSize = size;
72 cufftPlan1d( &plan->plan, createSize, CUFFT_C2C, 1 );
73 /* LAL_FFTW_WISDOM_UNLOCK; */
74
75 /* "Plan=0" Bugfix by Wiesner, K.: plan->plan is an integer handle not a pointer and 0 is a valid handle
76 So checking against 0 and occasionaly destroy the plan is a bug.
77 if ( ! plan->plan )
78 {
79 XLALFree( plan );
80 XLAL_ERROR_NULL( XLAL_EFAILED );
81 }
82 */
83
84 plan->d_input = XLALCudaMallocComplex(size);
85 plan->d_output = XLALCudaMallocComplex(size);
86 /* now set remaining plan fields */
87 plan->size = size;
88 plan->sign = ( fwdflg ? -1 : 1 );
89
90 return plan;
91}
92
93
94COMPLEX8FFTPlan * XLALCreateForwardCOMPLEX8FFTPlan( UINT4 size, int measurelvl )
95{
96 COMPLEX8FFTPlan *plan;
97 plan = XLALCreateCOMPLEX8FFTPlan( size, 1, measurelvl );
98 if ( ! plan )
100 return plan;
101}
102
103
104COMPLEX8FFTPlan * XLALCreateReverseCOMPLEX8FFTPlan( UINT4 size, int measurelvl )
105{
106 COMPLEX8FFTPlan *plan;
107 plan = XLALCreateCOMPLEX8FFTPlan( size, 0, measurelvl );
108 if ( ! plan )
110 return plan;
111}
112
113
114void XLALDestroyCOMPLEX8FFTPlan( COMPLEX8FFTPlan *plan )
115{
116 if ( ! plan )
118 /* Plan=0 Bugfix
119 if ( ! plan->plan )
120 XLAL_ERROR_VOID( XLAL_EINVAL );
121 */
122 //LAL_FFTW_WISDOM_LOCK;
123 cufftDestroy( plan->plan );
124 XLALCudaFree(plan->d_input);
125 XLALCudaFree(plan->d_output);
126 //LAL_FFTW_WISDOM_UNLOCK;
127 memset( plan, 0, sizeof( *plan ) );
128 XLALFree( plan );
129 return;
130}
131
132
133int XLALCOMPLEX8VectorFFT( COMPLEX8Vector * _LAL_RESTRICT_ output, const COMPLEX8Vector * _LAL_RESTRICT_ input, const COMPLEX8FFTPlan *plan )
134{
135 if ( ! output || ! input || ! plan )
137 /* Plan=0 Bugfix
138 if ( ! plan->plan || ! plan->size )
139 */
140 if (! plan->size )
142 if ( ! output->data || ! input->data || output->data == input->data )
143 XLAL_ERROR( XLAL_EINVAL ); /* note: must be out-of-place */
144 if ( output->length != plan->size || input->length != plan->size )
146
147 /* do the fft */
148 if( plan->size == 1 )
149 {
150 output->data[0] = input->data[0];
151 }
152 else
153 cudafft_execute_c2c( plan->plan,
154 (cufftComplex *)(output->data), (cufftComplex *)(input->data),
155 (cufftComplex *)plan->d_output, (cufftComplex *)plan->d_input,
156 plan->sign, plan->size );
157 return 0;
158}
159
160
161
162/*
163 *
164 * XLAL COMPLEX16 functions
165 *
166 */
167
168
169COMPLEX16FFTPlan * XLALCreateCOMPLEX16FFTPlan( UINT4 size, int fwdflg, int measurelvl )
170{
171 COMPLEX16FFTPlan *plan;
172 COMPLEX16 *tmp1;
173 COMPLEX16 *tmp2;
174 int flags = FFTW_UNALIGNED;
175
176 if ( ! size )
178
179 /* based on measurement level, set fftw3 flags to perform
180 * requested degree of measurement */
181 switch ( measurelvl )
182 {
183 case 0: /* estimate */
184 flags |= FFTW_ESTIMATE;
185 break;
186 default: /* exhaustive measurement */
187 flags |= FFTW_EXHAUSTIVE;
188 /* fall-through */
189 case 2: /* lengthy measurement */
190 flags |= FFTW_PATIENT;
191 /* fall-through */
192 case 1: /* measure the best plan */
193 flags |= FFTW_MEASURE;
194 break;
195 }
196
197 /* allocate memory for the plan and the temporary arrays */
198 plan = XLALMalloc( sizeof( *plan ) );
199 tmp1 = XLALMalloc( size * sizeof( *tmp1 ) );
200 tmp2 = XLALMalloc( size * sizeof( *tmp2 ) );
201 if ( ! plan || ! tmp1 || ! tmp2 )
202 {
203 XLALFree( plan );
204 XLALFree( tmp1 );
205 XLALFree( tmp2 );
207 }
208
209 /* create the plan */
211 plan->plan = fftw_plan_dft_1d( size,
212 (fftw_complex *)tmp1, (fftw_complex *)tmp2,
213 fwdflg ? FFTW_FORWARD : FFTW_BACKWARD, flags );
215
216 /* free temporary arrays */
217 XLALFree( tmp2 );
218 XLALFree( tmp1 );
219
220 /* Plan=0 Bugfix
221 if ( ! plan->plan )
222 {
223 XLALFree( plan );
224 XLAL_ERROR_NULL( XLAL_EFAILED );
225 }
226 */
227
228 /* now set remaining plan fields */
229 plan->size = size;
230 plan->sign = ( fwdflg ? -1 : 1 );
231
232 return plan;
233}
234
235
236COMPLEX16FFTPlan * XLALCreateForwardCOMPLEX16FFTPlan( UINT4 size, int measurelvl )
237{
238 COMPLEX16FFTPlan *plan;
239 plan = XLALCreateCOMPLEX16FFTPlan( size, 1, measurelvl );
240 if ( ! plan )
242 return plan;
243}
244
245
246COMPLEX16FFTPlan * XLALCreateReverseCOMPLEX16FFTPlan( UINT4 size, int measurelvl )
247{
248 COMPLEX16FFTPlan *plan;
249 plan = XLALCreateCOMPLEX16FFTPlan( size, 0, measurelvl );
250 if ( ! plan )
252 return plan;
253}
254
255
256void XLALDestroyCOMPLEX16FFTPlan( COMPLEX16FFTPlan *plan )
257{
258 if ( ! plan )
260 /*Plan=0 Bugfix
261 if ( ! plan->plan )
262 XLAL_ERROR_VOID( XLAL_EINVAL );
263 */
265 fftw_destroy_plan( plan->plan );
267 memset( plan, 0, sizeof( *plan ) );
268 XLALFree( plan );
269 return;
270}
271
272
274{
275 if ( ! output || ! input || ! plan )
277 /* Plan=0 Bugfix
278 if ( ! plan->plan || ! plan->size )
279 */
280 if ( ! plan->size )
282 if ( ! output->data || ! input->data || output->data == input->data )
283 XLAL_ERROR( XLAL_EINVAL ); /* note: must be out-of-place */
284 if ( output->length != plan->size || input->length != plan->size )
286
287 /* do the fft */
288 fftw_execute_dft(
289 plan->plan,
290 (fftw_complex *)input->data,
291 (fftw_complex *)output->data
292 );
293 return 0;
294}
COMPLEX8FFTPlan * XLALCreateCOMPLEX8FFTPlan(UINT4 size, int fwdflg, UNUSED int measurelvl)
int cudafft_execute_c2c(cufftHandle plan, cufftComplex *output, const cufftComplex *input, cufftComplex *d_output, cufftComplex *d_input, INT4 direction, UINT4 size)
Definition: CudaFFT.cu:82
void XLALCudaFree(void *d_data)
Definition: CudaFunctions.c:29
COMPLEX8 * XLALCudaMallocComplex(UINT4 size)
Definition: CudaFunctions.c:18
#define LAL_FFTW_WISDOM_UNLOCK
Definition: FFTWMutex.h:37
#define LAL_FFTW_WISDOM_LOCK
Definition: FFTWMutex.h:36
#define _LAL_RESTRICT_
Definition: LALStddef.h:35
COMPLEX8FFTPlan * XLALCreateReverseCOMPLEX8FFTPlan(UINT4 size, int measurelvl)
Returns a new COMPLEX8FFTPlan for a reverse transform.
COMPLEX8FFTPlan * XLALCreateForwardCOMPLEX8FFTPlan(UINT4 size, int measurelvl)
Returns a new COMPLEX8FFTPlan for a forward transform.
COMPLEX16FFTPlan * XLALCreateReverseCOMPLEX16FFTPlan(UINT4 size, int measurelvl)
Returns a new COMPLEX16FFTPlan for a reverse transform.
COMPLEX16FFTPlan * XLALCreateForwardCOMPLEX16FFTPlan(UINT4 size, int measurelvl)
Returns a new COMPLEX16FFTPlan for a forward transform.
int XLALCOMPLEX8VectorFFT(COMPLEX8Vector *_LAL_RESTRICT_ output, const COMPLEX8Vector *_LAL_RESTRICT_ input, const COMPLEX8FFTPlan *plan)
Perform a COMPLEX8Vector to COMPLEX8Vector FFT.
COMPLEX16FFTPlan * XLALCreateCOMPLEX16FFTPlan(UINT4 size, int fwdflg, int measurelvl)
Returns a new COMPLEX16FFTPlan.
void XLALDestroyCOMPLEX16FFTPlan(COMPLEX16FFTPlan *plan)
Destroys a COMPLEX16FFTPlan.
int XLALCOMPLEX16VectorFFT(COMPLEX16Vector *_LAL_RESTRICT_ output, const COMPLEX16Vector *_LAL_RESTRICT_ input, const COMPLEX16FFTPlan *plan)
Perform a COMPLEX16Vector to COMPLEX16Vector FFT.
void XLALDestroyCOMPLEX8FFTPlan(COMPLEX8FFTPlan *plan)
Destroys a COMPLEX8FFTPlan.
double complex COMPLEX16
Double-precision floating-point complex number (16 bytes total)
uint32_t UINT4
Four-byte unsigned integer.
#define XLALMalloc(n)
Definition: LALMalloc.h:44
#define XLALFree(p)
Definition: LALMalloc.h:47
#define XLAL_ERROR_VOID(...)
Macro to invoke a failure from a XLAL routine returning void.
Definition: XLALError.h:726
#define XLAL_ERROR_NULL(...)
Macro to invoke a failure from a XLAL routine returning a pointer.
Definition: XLALError.h:713
#define XLAL_ERROR(...)
Macro to invoke a failure from a XLAL routine returning an integer.
Definition: XLALError.h:700
@ XLAL_EBADLEN
Inconsistent or invalid length.
Definition: XLALError.h:419
@ XLAL_ENOMEM
Memory allocation error.
Definition: XLALError.h:407
@ XLAL_EFAULT
Invalid pointer.
Definition: XLALError.h:408
@ XLAL_EFUNC
Internal function call failed bit: "or" this with existing error number.
Definition: XLALError.h:462
@ XLAL_EINVAL
Invalid argument.
Definition: XLALError.h:409
Vector of type COMPLEX16, see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:172
Vector of type COMPLEX8, see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:163
void output(int gps_sec, int output_type)
Definition: tconvert.c:440