Commit b0c14995 authored by Kipp Cannon's avatar Kipp Cannon
Browse files

redmine #972: rework FFTW wisdom mutex

- make the mutex itself static data (not part of the exported api)
- export lock/unlock functions unconditionally (but they're no-ops if locking and/or fftw is not enabled)
- those first two changes allow the swig bindings to expose the mutex reliably
- rename the preprocessor macros wrapping the lock/unlock functions to better reflect their purpose
Original: 755e4d0d1f3caa425abc34a1ab1a07ce8344d63d
parent ceb7c61b
......@@ -26,14 +26,15 @@
extern "C" {
#endif
void XLALFFTWWisdomLock(void);
void XLALFFTWWisdomUnlock(void);
#if defined(LAL_PTHREAD_LOCK) && defined(LAL_FFTW3_ENABLED)
# include <pthread.h>
extern pthread_mutex_t lalFFTWMutex;
# define LAL_FFTW_PTHREAD_MUTEX_LOCK pthread_mutex_lock( &lalFFTWMutex )
# define LAL_FFTW_PTHREAD_MUTEX_UNLOCK pthread_mutex_unlock( &lalFFTWMutex )
# define LAL_FFTW_WISDOM_LOCK XLALFFTWWisdomLock()
# define LAL_FFTW_WISDOM_UNLOCK XLALFFTWWisdomUnlock()
#else
# define LAL_FFTW_PTHREAD_MUTEX_LOCK
# define LAL_FFTW_PTHREAD_MUTEX_UNLOCK
# define LAL_FFTW_WISDOM_LOCK
# define LAL_FFTW_WISDOM_UNLOCK
#endif
#ifdef __cplusplus
......
......@@ -184,11 +184,11 @@ COMPLEX8FFTPlan * XLALCreateCOMPLEX8FFTPlan( UINT4 size, int fwdflg, int measure
}
/* create the plan */
LAL_FFTW_PTHREAD_MUTEX_LOCK;
LAL_FFTW_WISDOM_LOCK;
plan->plan = fftwf_plan_dft_1d( size,
(fftwf_complex *)tmp1, (fftwf_complex *)tmp2,
fwdflg ? FFTW_FORWARD : FFTW_BACKWARD, flags );
LAL_FFTW_PTHREAD_MUTEX_UNLOCK;
LAL_FFTW_WISDOM_UNLOCK;
/* free temporary arrays */
XLALFree( tmp2 );
......@@ -235,9 +235,9 @@ void XLALDestroyCOMPLEX8FFTPlan( COMPLEX8FFTPlan *plan )
{
if ( plan->plan )
{
LAL_FFTW_PTHREAD_MUTEX_LOCK;
LAL_FFTW_WISDOM_LOCK;
fftwf_destroy_plan( plan->plan );
LAL_FFTW_PTHREAD_MUTEX_UNLOCK;
LAL_FFTW_WISDOM_UNLOCK;
}
memset( plan, 0, sizeof( *plan ) );
XLALFree( plan );
......@@ -317,11 +317,11 @@ COMPLEX16FFTPlan * XLALCreateCOMPLEX16FFTPlan( UINT4 size, int fwdflg, int measu
}
/* create the plan */
LAL_FFTW_PTHREAD_MUTEX_LOCK;
LAL_FFTW_WISDOM_LOCK;
plan->plan = fftw_plan_dft_1d( size,
(fftw_complex *)tmp1, (fftw_complex *)tmp2,
fwdflg ? FFTW_FORWARD : FFTW_BACKWARD, flags );
LAL_FFTW_PTHREAD_MUTEX_UNLOCK;
LAL_FFTW_WISDOM_UNLOCK;
/* free temporary arrays */
XLALFree( tmp2 );
......@@ -368,9 +368,9 @@ void XLALDestroyCOMPLEX16FFTPlan( COMPLEX16FFTPlan *plan )
{
if ( plan->plan )
{
LAL_FFTW_PTHREAD_MUTEX_LOCK;
LAL_FFTW_WISDOM_LOCK;
fftw_destroy_plan( plan->plan );
LAL_FFTW_PTHREAD_MUTEX_UNLOCK;
LAL_FFTW_WISDOM_UNLOCK;
}
memset( plan, 0, sizeof( *plan ) );
XLALFree( plan );
......
......@@ -59,14 +59,14 @@ COMPLEX8FFTPlan * XLALCreateCOMPLEX8FFTPlan( UINT4 size, int fwdflg, int measure
}
/* create the plan */
/* LAL_FFTW_PTHREAD_MUTEX_LOCK; */
/* LAL_FFTW_WISDOM_LOCK; */
/*
* Change the size to avoid CUDA bug with FFT of size 1
*/
if( size == 1 ) createSize = 2;
else createSize = size;
cufftPlan1d( &plan->plan, createSize, CUFFT_C2C, 1 );
/* LAL_FFTW_PTHREAD_MUTEX_UNLOCK; */
/* LAL_FFTW_WISDOM_UNLOCK; */
/* "Plan=0" Bugfix by Wiesner, K.: plan->plan is an integer handle not a pointer and 0 is a valid handle
So checking against 0 and occasionaly destroy the plan is a bug.
......@@ -115,11 +115,11 @@ void XLALDestroyCOMPLEX8FFTPlan( COMPLEX8FFTPlan *plan )
if ( ! plan->plan )
XLAL_ERROR_VOID( XLAL_EINVAL );
*/
//LAL_FFTW_PTHREAD_MUTEX_LOCK;
//LAL_FFTW_WISDOM_LOCK;
cufftDestroy( plan->plan );
XLALCudaFree(plan->d_input);
XLALCudaFree(plan->d_output);
//LAL_FFTW_PTHREAD_MUTEX_UNLOCK;
//LAL_FFTW_WISDOM_UNLOCK;
memset( plan, 0, sizeof( *plan ) );
XLALFree( plan );
return;
......@@ -205,11 +205,11 @@ COMPLEX16FFTPlan * XLALCreateCOMPLEX16FFTPlan( UINT4 size, int fwdflg, int measu
}
/* create the plan */
LAL_FFTW_PTHREAD_MUTEX_LOCK;
LAL_FFTW_WISDOM_LOCK;
plan->plan = fftw_plan_dft_1d( size,
(fftw_complex *)tmp1, (fftw_complex *)tmp2,
fwdflg ? FFTW_FORWARD : FFTW_BACKWARD, flags );
LAL_FFTW_PTHREAD_MUTEX_UNLOCK;
LAL_FFTW_WISDOM_UNLOCK;
/* free temporary arrays */
XLALFree( tmp2 );
......@@ -259,9 +259,9 @@ void XLALDestroyCOMPLEX16FFTPlan( COMPLEX16FFTPlan *plan )
if ( ! plan->plan )
XLAL_ERROR_VOID( XLAL_EINVAL );
*/
LAL_FFTW_PTHREAD_MUTEX_LOCK;
LAL_FFTW_WISDOM_LOCK;
fftw_destroy_plan( plan->plan );
LAL_FFTW_PTHREAD_MUTEX_UNLOCK;
LAL_FFTW_WISDOM_UNLOCK;
memset( plan, 0, sizeof( *plan ) );
XLALFree( plan );
return;
......
......@@ -85,12 +85,12 @@ REAL4FFTPlan * XLALCreateREAL4FFTPlan( UINT4 size, int fwdflg, int measurelvl )
if( size == 1 ) createSize = 2;
else createSize = size;
/* LAL_FFTW_PTHREAD_MUTEX_LOCK; */
/* LAL_FFTW_WISDOM_LOCK; */
if ( fwdflg ) /* forward */
retval= cufftPlan1d( &plan->plan, createSize, CUFFT_R2C, 1 );
else /* reverse */
retval= cufftPlan1d( &plan->plan, createSize, CUFFT_C2R, 1 );
/* LAL_FFTW_PTHREAD_MUTEX_UNLOCK; */
/* LAL_FFTW_WISDOM_UNLOCK; */
/* check to see success of plan creation */
/* "Plan=0" Bugfix by Wiesner, K.: plan->plan is an integer handle not a pointer and 0 is a valid handle
......@@ -145,12 +145,12 @@ void XLALDestroyREAL4FFTPlan( REAL4FFTPlan *plan )
XLAL_ERROR_VOID( XLAL_EINVAL );
*/
/* LAL_FFTW_PTHREAD_MUTEX_LOCK; */
/* LAL_FFTW_WISDOM_LOCK; */
/* Free the Cuda specific variables */
XLALCudaFree( plan->d_real );
cufftDestroy( plan->plan );
XLALCudaFree( plan->d_complex );
/* LAL_FFTW_PTHREAD_MUTEX_UNLOCK; */
/* LAL_FFTW_WISDOM_UNLOCK; */
memset( plan, 0, sizeof( *plan ) );
XLALFree( plan );
return;
......@@ -408,12 +408,12 @@ REAL8FFTPlan * XLALCreateREAL8FFTPlan( UINT4 size, int fwdflg, int measurelvl )
XLAL_ERROR_NULL( XLAL_ENOMEM );
}
LAL_FFTW_PTHREAD_MUTEX_LOCK;
LAL_FFTW_WISDOM_LOCK;
if ( fwdflg ) /* forward */
plan->plan = fftw_plan_r2r_1d( size, tmp1, tmp2, FFTW_R2HC, flags );
else /* reverse */
plan->plan = fftw_plan_r2r_1d( size, tmp1, tmp2, FFTW_HC2R, flags );
LAL_FFTW_PTHREAD_MUTEX_UNLOCK;
LAL_FFTW_WISDOM_UNLOCK;
/* free temporary arrays */
XLALFree( tmp2 );
......@@ -464,9 +464,9 @@ void XLALDestroyREAL8FFTPlan( REAL8FFTPlan *plan )
if ( ! plan->plan )
XLAL_ERROR_VOID( XLAL_EINVAL );
*/
LAL_FFTW_PTHREAD_MUTEX_LOCK;
LAL_FFTW_WISDOM_LOCK;
fftw_destroy_plan( plan->plan );
LAL_FFTW_PTHREAD_MUTEX_UNLOCK;
LAL_FFTW_WISDOM_UNLOCK;
memset( plan, 0, sizeof( *plan ) );
XLALFree( plan );
......
......@@ -19,6 +19,38 @@
#include <lal/FFTWMutex.h>
#ifdef LAL_PTHREAD_LOCK
pthread_mutex_t lalFFTWMutex = PTHREAD_MUTEX_INITIALIZER;
#if defined(LAL_PTHREAD_LOCK) && defined(LAL_FFTW3_ENABLED)
static pthread_mutex_t lalFFTWMutex = PTHREAD_MUTEX_INITIALIZER;
#endif
/**
* Aquire LAL's FFTW wisdom lock. This lock must be held when creating or
* destroying FFTW plans. This function is a no-op if LAL has been
* compiled without pthread support or with an FFT backend other than FFTW.
*
* See also: XLALFFTWWisdomUnlock()
*/
void XLALFFTWWisdomLock(void)
{
#if defined(LAL_PTHREAD_LOCK) && defined(LAL_FFTW3_ENABLED)
pthread_mutex_lock( &lalFFTWMutex );
#endif
}
/**
* Release LAL's FFTW wisdom lock. This function is a no-op if LAL has
* been compiled without pthread support or with an FFT backend other than
* FFTW.
*
* See also: XLALFFTWWisdomLock()
*/
void XLALFFTWWisdomUnlock(void)
{
#if defined(LAL_PTHREAD_LOCK) && defined(LAL_FFTW3_ENABLED)
pthread_mutex_unlock( &lalFFTWMutex );
#endif
}
......@@ -212,12 +212,12 @@ REAL4FFTPlan * XLALCreateREAL4FFTPlan( UINT4 size, int fwdflg, int measurelvl )
XLAL_ERROR_NULL( XLAL_ENOMEM );
}
LAL_FFTW_PTHREAD_MUTEX_LOCK;
LAL_FFTW_WISDOM_LOCK;
if ( fwdflg ) /* forward */
plan->plan = fftwf_plan_r2r_1d( size, tmp1, tmp2, FFTW_R2HC, flags );
else /* reverse */
plan->plan = fftwf_plan_r2r_1d( size, tmp1, tmp2, FFTW_HC2R, flags );
LAL_FFTW_PTHREAD_MUTEX_UNLOCK;
LAL_FFTW_WISDOM_UNLOCK;
/* free temporary arrays */
XLALFree( tmp2 );
......@@ -264,9 +264,9 @@ void XLALDestroyREAL4FFTPlan( REAL4FFTPlan *plan )
{
if ( plan->plan )
{
LAL_FFTW_PTHREAD_MUTEX_LOCK;
LAL_FFTW_WISDOM_LOCK;
fftwf_destroy_plan( plan->plan );
LAL_FFTW_PTHREAD_MUTEX_UNLOCK;
LAL_FFTW_WISDOM_UNLOCK;
}
memset( plan, 0, sizeof( *plan ) );
XLALFree( plan );
......@@ -478,12 +478,12 @@ REAL8FFTPlan * XLALCreateREAL8FFTPlan( UINT4 size, int fwdflg, int measurelvl )
XLAL_ERROR_NULL( XLAL_ENOMEM );
}
LAL_FFTW_PTHREAD_MUTEX_LOCK;
LAL_FFTW_WISDOM_LOCK;
if ( fwdflg ) /* forward */
plan->plan = fftw_plan_r2r_1d( size, tmp1, tmp2, FFTW_R2HC, flags );
else /* reverse */
plan->plan = fftw_plan_r2r_1d( size, tmp1, tmp2, FFTW_HC2R, flags );
LAL_FFTW_PTHREAD_MUTEX_UNLOCK;
LAL_FFTW_WISDOM_UNLOCK;
/* free temporary arrays */
XLALFree( tmp2 );
......@@ -530,9 +530,9 @@ void XLALDestroyREAL8FFTPlan( REAL8FFTPlan *plan )
{
if ( plan->plan )
{
LAL_FFTW_PTHREAD_MUTEX_LOCK;
LAL_FFTW_WISDOM_LOCK;
fftw_destroy_plan( plan->plan );
LAL_FFTW_PTHREAD_MUTEX_UNLOCK;
LAL_FFTW_WISDOM_UNLOCK;
}
memset( plan, 0, sizeof( *plan ) );
XLALFree( plan );
......
......@@ -521,9 +521,9 @@ int main( int argc, char *argv[] )
/* Import system wide FFTW wisdom file, if it exists. Only single precision used. */
#ifdef LAL_FFTW3_ENABLED
LAL_FFTW_PTHREAD_MUTEX_LOCK;
LAL_FFTW_WISDOM_LOCK;
fftwf_import_system_wisdom();
LAL_FFTW_PTHREAD_MUTEX_UNLOCK;
LAL_FFTW_WISDOM_UNLOCK;
#endif
/* can use LALMalloc() and LALCalloc() from here onwards */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment