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);
220 "FFT input/output array dimensions/pointers are not valid. Aborting transform." << eom);
224 msg_error(
"operators",
"FFT intialization failed. Aborting transform." << eom);
230 if(HaveSameAlignment(in->GetData(), fInPtr))
235 fCurrentPlan = &fPlanForwardInPlace;
239 fCurrentPlan = &fPlanBackwardInPlace;
252 fCurrentPlan = &fPlanForward;
256 fCurrentPlan = &fPlanBackward;
260 std::memcpy(fInPtr, in->GetData(),
263 std::memcpy(in->GetData(), fOutPtr,
267 for(
size_t d = 0; d < XArgType::rank::value; d++)
289 if(in && out && in != out)
303 virtual void AllocateWorkspace(std::size_t total_array_size)
314 virtual void DeallocateWorkspace()
316 MHO_FFTWTypes< floating_point_value_type >::free_func(fInPtr);
317 MHO_FFTWTypes< floating_point_value_type >::free_func(fOutPtr);
318 MHO_FFTWTypes< floating_point_value_type >::free_func(fInPlacePtr);
328 MHO_FFTWTypes< floating_point_value_type >::destroy_plan_func(fPlanForward);
330 MHO_FFTWTypes< floating_point_value_type >::destroy_plan_func(fPlanBackward);
331 fPlanBackward = NULL;
332 MHO_FFTWTypes< floating_point_value_type >::destroy_plan_func(fPlanForwardInPlace);
333 fPlanForwardInPlace = NULL;
334 MHO_FFTWTypes< floating_point_value_type >::destroy_plan_func(fPlanBackwardInPlace);
335 fPlanBackwardInPlace = NULL;
346 if(fInPtr == NULL || fOutPtr == NULL || fInPlacePtr == NULL)
353 for(
size_t d = 0; d < XArgType::rank::value; d++)
363 int howmany_rank = XArgType::rank::value - rank;
369 for(
size_t d = 0; d < XArgType::rank::value; d++)
376 MHO_NDArrayMath::StrideFromRowMajorIndex< XArgType::rank::value >(d, this->
fDimensionSize);
378 MHO_NDArrayMath::StrideFromRowMajorIndex< XArgType::rank::value >(d, this->
fDimensionSize);
384 for(
size_t d = 0; d < XArgType::rank::value; d++)
390 fHowManyDims[count].is =
391 MHO_NDArrayMath::StrideFromRowMajorIndex< XArgType::rank::value >(d, this->
fDimensionSize);
392 fHowManyDims[count].os =
393 MHO_NDArrayMath::StrideFromRowMajorIndex< XArgType::rank::value >(d, this->
fDimensionSize);
398 fPlanForward = MHO_FFTWTypes< floating_point_value_type >::plan_guru_func(
399 rank, fDims, howmany_rank, fHowManyDims, fInPtr, fOutPtr, FFTW_FORWARD,
HOPS_FFTW_PLAN_ALGO);
401 fPlanBackward = MHO_FFTWTypes< floating_point_value_type >::plan_guru_func(
402 rank, fDims, howmany_rank, fHowManyDims, fInPtr, fOutPtr, FFTW_BACKWARD,
HOPS_FFTW_PLAN_ALGO);
404 fPlanForwardInPlace = MHO_FFTWTypes< floating_point_value_type >::plan_guru_func(
405 rank, fDims, howmany_rank, fHowManyDims, fInPlacePtr, fInPlacePtr, FFTW_FORWARD,
HOPS_FFTW_PLAN_ALGO);
407 fPlanBackwardInPlace = MHO_FFTWTypes< floating_point_value_type >::plan_guru_func(
408 rank, fDims, howmany_rank, fHowManyDims, fInPlacePtr, fInPlacePtr, FFTW_BACKWARD,
HOPS_FFTW_PLAN_ALGO);
410 if(fPlanForward != NULL && fPlanBackward != NULL && fPlanBackwardInPlace != NULL && fPlanForwardInPlace != NULL)
416 msg_warn(
"operators",
"could not construct FFTW transform plan." << eom);
428 template<
typename XPtrType1,
typename XPtrType2 >
bool HaveSameAlignment(XPtrType1 ptr1, XPtrType2 ptr2)
430 if(!fHaveAlignmentFuncs){
return false;}
431 return (MHO_FFTWTypes< floating_point_value_type >::alignment_of_func(
433 MHO_FFTWTypes< floating_point_value_type >::alignment_of_func(
438 size_t fTotalArraySize;
439 typename MHO_FFTWTypes< floating_point_value_type >::plan_type* fCurrentPlan;
440 typename MHO_FFTWTypes< floating_point_value_type >::iodim_type fDims[XArgType::rank::value];
441 typename MHO_FFTWTypes< floating_point_value_type >::iodim_type fHowManyDims[XArgType::rank::value];
442 typename MHO_FFTWTypes< floating_point_value_type >::plan_type fPlanForward;
443 typename MHO_FFTWTypes< floating_point_value_type >::plan_type fPlanBackward;
444 typename MHO_FFTWTypes< floating_point_value_type >::plan_type fPlanForwardInPlace;
445 typename MHO_FFTWTypes< floating_point_value_type >::plan_type fPlanBackwardInPlace;
446 typename MHO_FFTWTypes< floating_point_value_type >::fftw_complex_type_ptr fInPtr;
447 typename MHO_FFTWTypes< floating_point_value_type >::fftw_complex_type_ptr fOutPtr;
448 typename MHO_FFTWTypes< floating_point_value_type >::fftw_complex_type_ptr fInPlacePtr;
451 bool fHaveAlignmentFuncs;
#define msg_debug(xKEY, xCONTENT)
Definition: MHO_Message.hh:297
#define msg_warn(xKEY, xCONTENT)
Definition: MHO_Message.hh:254
#define msg_error(xKEY, xCONTENT)
Definition: MHO_Message.hh:244
static int get_fftw_version_major()
Retrieves the major version number of FFTW3.
Definition: MHO_FFTWTypes.hh:228
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:264
Class MHO_UnaryOperator.
Definition: MHO_UnaryOperator.hh:24
Definition: MHO_ChannelLabeler.hh:17
Class MHO_FFTWTypes.
Definition: MHO_FFTWTypes.hh:59
Definition: MHO_Meta.hh:341