LAL  7.5.0.1-ec27e42
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 
46 COMPLEX8FFTPlan * 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 
94 COMPLEX8FFTPlan * XLALCreateForwardCOMPLEX8FFTPlan( UINT4 size, int measurelvl )
95 {
96  COMPLEX8FFTPlan *plan;
97  plan = XLALCreateCOMPLEX8FFTPlan( size, 1, measurelvl );
98  if ( ! plan )
100  return plan;
101 }
102 
103 
104 COMPLEX8FFTPlan * XLALCreateReverseCOMPLEX8FFTPlan( UINT4 size, int measurelvl )
105 {
106  COMPLEX8FFTPlan *plan;
107  plan = XLALCreateCOMPLEX8FFTPlan( size, 0, measurelvl );
108  if ( ! plan )
110  return plan;
111 }
112 
113 
114 void 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 
133 int 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 
169 COMPLEX16FFTPlan * 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 
236 COMPLEX16FFTPlan * XLALCreateForwardCOMPLEX16FFTPlan( UINT4 size, int measurelvl )
237 {
238  COMPLEX16FFTPlan *plan;
239  plan = XLALCreateCOMPLEX16FFTPlan( size, 1, measurelvl );
240  if ( ! plan )
242  return plan;
243 }
244 
245 
246 COMPLEX16FFTPlan * XLALCreateReverseCOMPLEX16FFTPlan( UINT4 size, int measurelvl )
247 {
248  COMPLEX16FFTPlan *plan;
249  plan = XLALCreateCOMPLEX16FFTPlan( size, 0, measurelvl );
250  if ( ! plan )
252  return plan;
253 }
254 
255 
256 void 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 
273 int XLALCOMPLEX16VectorFFT( COMPLEX16Vector * _LAL_RESTRICT_ output, const COMPLEX16Vector * _LAL_RESTRICT_ input, const COMPLEX16FFTPlan *plan )
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
COMPLEX8 * XLALCudaMallocComplex(UINT4 size)
Definition: CudaFunctions.c:18
void XLALCudaFree(void *d_data)
Definition: CudaFunctions.c:29
#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.
int XLALCOMPLEX8VectorFFT(COMPLEX8Vector *_LAL_RESTRICT_ output, const COMPLEX8Vector *_LAL_RESTRICT_ input, const COMPLEX8FFTPlan *plan)
Perform a COMPLEX8Vector to COMPLEX8Vector FFT.
void XLALDestroyCOMPLEX16FFTPlan(COMPLEX16FFTPlan *plan)
Destroys a COMPLEX16FFTPlan.
COMPLEX8FFTPlan * XLALCreateForwardCOMPLEX8FFTPlan(UINT4 size, int measurelvl)
Returns a new COMPLEX8FFTPlan for a forward transform.
COMPLEX16FFTPlan * XLALCreateForwardCOMPLEX16FFTPlan(UINT4 size, int measurelvl)
Returns a new COMPLEX16FFTPlan for a forward transform.
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.
COMPLEX16FFTPlan * XLALCreateCOMPLEX16FFTPlan(UINT4 size, int fwdflg, int measurelvl)
Returns a new COMPLEX16FFTPlan.
COMPLEX16FFTPlan * XLALCreateReverseCOMPLEX16FFTPlan(UINT4 size, int measurelvl)
Returns a new COMPLEX16FFTPlan for a reverse transform.
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