1 #ifndef MHO_MultidimensionalFastFourierTransformFFTW_HH__
2 #define MHO_MultidimensionalFastFourierTransformFFTW_HH__
16 #define HOPS_FFTW_PLAN_ALGO FFTW_ESTIMATE
34 template<
typename XArgType >
40 "Array element type must be a complex floating point type.");
54 fPlanForwardInPlace = NULL;
55 fPlanBackwardInPlace = NULL;
56 AllocateWorkspace(16);
57 fHaveAlignmentFuncs =
false;
66 fHaveAlignmentFuncs =
true;
68 else if(fftw3_minor == 3)
72 fHaveAlignmentFuncs =
true;
79 DeallocateWorkspace();
105 bool need_to_resize =
false;
106 for(std::size_t i = 0; i < XArgType::rank::value; i++)
110 need_to_resize =
true;
117 fTotalArraySize = MHO_NDArrayMath::TotalArraySize< XArgType::rank::value >(this->
fDimensionSize);
118 bool aligned = HaveSameAlignment(in->GetData(), fInPtr);
121 DeallocateWorkspace();
122 AllocateWorkspace(fTotalArraySize);
126 #ifdef HOPS_ENABLE_DEBUG_MSG
127 msg_debug(
"operators",
"initialized an in-place FFTW3 FFT plan." << eom);
128 for(std::size_t i = 0; i < XArgType::rank::value; i++)
131 <<
", enabled? " << this->
fAxesToXForm[i] <<
"." << eom);
153 if(in !=
nullptr && out !=
nullptr)
165 if(!HaveSameDimensions(in, out))
168 out->Resize(in->GetDimensions());
171 bool need_to_resize =
false;
172 for(std::size_t i = 0; i < XArgType::rank::value; i++)
176 need_to_resize =
true;
183 fTotalArraySize = MHO_NDArrayMath::TotalArraySize< XArgType::rank::value >(this->
fDimensionSize);
184 DeallocateWorkspace();
185 AllocateWorkspace(fTotalArraySize);
188 #ifdef HOPS_ENABLE_DEBUG_MSG
189 msg_debug(
"operators",
"initialized an out-of-place FFTW3 FFT plan." << eom);
190 for(std::size_t i = 0; i < XArgType::rank::value; i++)
193 <<
", enabled? " << this->
fAxesToXForm[i] <<
"." << eom);
221 "FFT input/output array dimensions/pointers are not valid. Aborting transform." << eom);
225 msg_error(
"operators",
"FFT intialization failed. Aborting transform." << eom);
231 if(HaveSameAlignment(in->GetData(), fInPtr))
236 fCurrentPlan = &fPlanForwardInPlace;
240 fCurrentPlan = &fPlanBackwardInPlace;
253 fCurrentPlan = &fPlanForward;
257 fCurrentPlan = &fPlanBackward;
261 std::memcpy(fInPtr, in->GetData(),
264 std::memcpy(in->GetData(), fOutPtr,
268 for(
size_t d = 0; d < XArgType::rank::value; d++)
290 if(in && out && in != out)
304 virtual void AllocateWorkspace(std::size_t total_array_size)
315 virtual void DeallocateWorkspace()
317 MHO_FFTWTypes< floating_point_value_type >::free_func(fInPtr);
318 MHO_FFTWTypes< floating_point_value_type >::free_func(fOutPtr);
319 MHO_FFTWTypes< floating_point_value_type >::free_func(fInPlacePtr);
329 MHO_FFTWTypes< floating_point_value_type >::destroy_plan_func(fPlanForward);
331 MHO_FFTWTypes< floating_point_value_type >::destroy_plan_func(fPlanBackward);
332 fPlanBackward = NULL;
333 MHO_FFTWTypes< floating_point_value_type >::destroy_plan_func(fPlanForwardInPlace);
334 fPlanForwardInPlace = NULL;
335 MHO_FFTWTypes< floating_point_value_type >::destroy_plan_func(fPlanBackwardInPlace);
336 fPlanBackwardInPlace = NULL;
347 if(fInPtr == NULL || fOutPtr == NULL || fInPlacePtr == NULL)
354 for(
size_t d = 0; d < XArgType::rank::value; d++)
364 int howmany_rank = XArgType::rank::value - rank;
370 for(
size_t d = 0; d < XArgType::rank::value; d++)
377 MHO_NDArrayMath::StrideFromRowMajorIndex< XArgType::rank::value >(d, this->
fDimensionSize);
379 MHO_NDArrayMath::StrideFromRowMajorIndex< XArgType::rank::value >(d, this->
fDimensionSize);
385 for(
size_t d = 0; d < XArgType::rank::value; d++)
391 fHowManyDims[count].is =
392 MHO_NDArrayMath::StrideFromRowMajorIndex< XArgType::rank::value >(d, this->
fDimensionSize);
393 fHowManyDims[count].os =
394 MHO_NDArrayMath::StrideFromRowMajorIndex< XArgType::rank::value >(d, this->
fDimensionSize);
399 fPlanForward = MHO_FFTWTypes< floating_point_value_type >::plan_guru_func(
400 rank, fDims, howmany_rank, fHowManyDims, fInPtr, fOutPtr, FFTW_FORWARD,
HOPS_FFTW_PLAN_ALGO);
402 fPlanBackward = MHO_FFTWTypes< floating_point_value_type >::plan_guru_func(
403 rank, fDims, howmany_rank, fHowManyDims, fInPtr, fOutPtr, FFTW_BACKWARD,
HOPS_FFTW_PLAN_ALGO);
405 fPlanForwardInPlace = MHO_FFTWTypes< floating_point_value_type >::plan_guru_func(
406 rank, fDims, howmany_rank, fHowManyDims, fInPlacePtr, fInPlacePtr, FFTW_FORWARD,
HOPS_FFTW_PLAN_ALGO);
408 fPlanBackwardInPlace = MHO_FFTWTypes< floating_point_value_type >::plan_guru_func(
409 rank, fDims, howmany_rank, fHowManyDims, fInPlacePtr, fInPlacePtr, FFTW_BACKWARD,
HOPS_FFTW_PLAN_ALGO);
411 if(fPlanForward != NULL && fPlanBackward != NULL && fPlanBackwardInPlace != NULL && fPlanForwardInPlace != NULL)
417 msg_warn(
"operators",
"could not construct FFTW transform plan." << eom);
429 template<
typename XPtrType1,
typename XPtrType2 >
bool HaveSameAlignment(XPtrType1 ptr1, XPtrType2 ptr2)
431 if(!fHaveAlignmentFuncs)
435 return (MHO_FFTWTypes< floating_point_value_type >::alignment_of_func(
437 MHO_FFTWTypes< floating_point_value_type >::alignment_of_func(
442 size_t fTotalArraySize;
443 typename MHO_FFTWTypes< floating_point_value_type >::plan_type* fCurrentPlan;
444 typename MHO_FFTWTypes< floating_point_value_type >::iodim_type fDims[XArgType::rank::value];
445 typename MHO_FFTWTypes< floating_point_value_type >::iodim_type fHowManyDims[XArgType::rank::value];
446 typename MHO_FFTWTypes< floating_point_value_type >::plan_type fPlanForward;
447 typename MHO_FFTWTypes< floating_point_value_type >::plan_type fPlanBackward;
448 typename MHO_FFTWTypes< floating_point_value_type >::plan_type fPlanForwardInPlace;
449 typename MHO_FFTWTypes< floating_point_value_type >::plan_type fPlanBackwardInPlace;
450 typename MHO_FFTWTypes< floating_point_value_type >::fftw_complex_type_ptr fInPtr;
451 typename MHO_FFTWTypes< floating_point_value_type >::fftw_complex_type_ptr fOutPtr;
452 typename MHO_FFTWTypes< floating_point_value_type >::fftw_complex_type_ptr fInPlacePtr;
455 bool fHaveAlignmentFuncs;
#define msg_debug(xKEY, xCONTENT)
Definition: MHO_Message.hh:291
#define msg_warn(xKEY, xCONTENT)
Definition: MHO_Message.hh:248
#define msg_error(xKEY, xCONTENT)
Definition: MHO_Message.hh:238
static int get_fftw_version_major()
Retrieves the major version number of FFTW3.
Definition: MHO_FFTWTypes.hh:225
static int get_fftw_version_minor()
Retrieves the minor version number of FFTW3.
Definition: MHO_FFTWTypes.hh:246
static int get_fftw_version_patch()
Retrieves the patch version number from FFTW library.
Definition: MHO_FFTWTypes.hh:267
Class MHO_UnaryOperator.
Definition: MHO_UnaryOperator.hh:24
Definition: MHO_AdhocFlagging.hh:18
Class MHO_FFTWTypes.
Definition: MHO_FFTWTypes.hh:58
Definition: MHO_Meta.hh:372