HOPS
HOPS class reference
MHO_MultidimensionalFastFourierTransform.hh
Go to the documentation of this file.
1 #ifndef MHO_MultidimensionalFastFourierTransform_HH__
2 #define MHO_MultidimensionalFastFourierTransform_HH__
3 
4 #include <cstring>
5 
6 #include "MHO_Message.hh"
7 #include "MHO_Meta.hh"
8 #include "MHO_NDArrayWrapper.hh"
9 #include "MHO_UnaryOperator.hh"
10 
14 
16 #include "MHO_TableContainer.hh"
17 
18 namespace hops
19 {
20 
32 template< typename XArgType >
35 {
36  public:
38  "Array element type must be a complex floating point type.");
39  using complex_value_type = typename XArgType::value_type;
40  using floating_point_value_type = typename XArgType::value_type::value_type;
41 
43 
45 
46  protected:
54  virtual bool InitializeInPlace(XArgType* in) override
55  {
56  this->fInitialized = false;
57  if(in == nullptr)
58  {
59  return false;
60  }
61  in->GetDimensions(this->fDimensionSize);
62  AllocateWorkspace();
63  this->fInitialized = true;
64 #ifdef HOPS_ENABLE_DEBUG_MSG
65  msg_debug("operators", "initialized a native FFT plan." << eom);
66  for(std::size_t i = 0; i < XArgType::rank::value; i++)
67  {
68  msg_debug("operators", "fft plan dimension: " << i << " has size: " << this->fDimensionSize[i] << ", enabled? "
69  << this->fAxesToXForm[i] << "." << eom);
70  }
71 #endif
72  return true;
73  }
74 
83  virtual bool InitializeOutOfPlace(const XArgType* in, XArgType* out) override
84  {
85  this->fInitialized = false;
86  if(in == nullptr || out == nullptr)
87  {
88  return false;
89  }
90  if(!HaveSameDimensions(in, out))
91  {
92  out->Resize(in->GetDimensions());
93  }
94  in->GetDimensions(this->fDimensionSize);
95  AllocateWorkspace();
96  this->fInitialized = true;
97 #ifdef HOPS_ENABLE_DEBUG_MSG
98  msg_debug("operators", "initialized a native FFT plan." << eom);
99  for(std::size_t i = 0; i < XArgType::rank::value; i++)
100  {
101  msg_debug("operators", "fft plan dimension: " << i << " has size: " << this->fDimensionSize[i] << ", enabled? "
102  << this->fAxesToXForm[i] << "." << eom);
103  }
104 #endif
105  return true;
106  }
107 
115  virtual bool ExecuteInPlace(XArgType* in) override
116  {
117  if(this->fInitialized)
118  {
119  profiler_scope();
120  size_t total_size = 1;
121  for(size_t i = 0; i < XArgType::rank::value; i++)
122  {
123  total_size *= this->fDimensionSize[i];
124  }
125 
126  size_t index[XArgType::rank::value];
127  size_t non_active_dimension_size[XArgType::rank::value - 1];
128  size_t non_active_dimension_value[XArgType::rank::value - 1];
129  size_t non_active_dimension_index[XArgType::rank::value - 1];
130 
131  //select the dimension on which to perform the FFT
132  for(size_t d = 0; d < XArgType::rank::value; d++)
133  {
134  if(this->fAxesToXForm[d])
135  {
136  //now we loop over all dimensions not specified by d
137  //first compute the number of FFTs to perform
138  size_t n_fft = 1;
139  size_t count = 0;
140  for(size_t i = 0; i < XArgType::rank::value; i++)
141  {
142  if(i != d)
143  {
144  n_fft *= this->fDimensionSize[i];
145  non_active_dimension_index[count] = i;
146  non_active_dimension_size[count] = this->fDimensionSize[i];
147  count++;
148  }
149  }
150 
151  //loop over the number of FFTs to perform
152  for(size_t n = 0; n < n_fft; n++)
153  {
154  //invert place in list to obtain indices of block in array
155  MHO_NDArrayMath::RowMajorIndexFromOffset< XArgType::rank::value - 1 >(n, non_active_dimension_size,
156  non_active_dimension_value);
157 
158  //copy the value of the non-active dimensions in to index
159  for(size_t i = 0; i < XArgType::rank::value - 1; i++)
160  {
161  index[non_active_dimension_index[i]] = non_active_dimension_value[i];
162  }
163 
164  size_t data_location;
166  index[d] = 0;
167  data_location =
168  MHO_NDArrayMath::OffsetFromRowMajorIndex< XArgType::rank::value >(this->fDimensionSize, index);
169  data = &((in->GetData())[data_location]);
170 
171  //compute the FFT of the row selected
172  unsigned int stride =
173  MHO_NDArrayMath::StrideFromRowMajorIndex< XArgType::rank::value >(d, this->fDimensionSize);
174  if(fW[d].IsRadix2())
175  {
176  FFTRadix2(data, fW[d], this->fForward, stride);
177  }
178  else
179  {
180  FFTBluestein(data, fW[d], this->fForward, stride);
181  }
182  }
183  }
184 
185  this->IfTableTransformAxis(in, d);
186  }
187  //successful
188 
189  return true;
190  }
191  else
192  {
193  //error
194  msg_error("math", "FFT input/output array dimensions are not valid or intialization failed. Aborting transform."
195  << eom);
196 
197  return false;
198  }
199  }
200 
209  virtual bool ExecuteOutOfPlace(const XArgType* in, XArgType* out) override
210  {
211  //if input and output point to the same array, don't bother copying data over
212  if(in && out && in != out)
213  {
214  out->Copy(*in);
215  }
216  return ExecuteInPlace(out);
217  }
218 
219  private:
223  void AllocateWorkspace()
224  {
225  for(size_t i = 0; i < XArgType::rank::value; i++)
226  {
227  if(fW[i].fN != this->fDimensionSize[i])
228  {
229  fW[i].Resize(this->fDimensionSize[i]);
230  }
231  }
232  }
233 
234  //workspace for transforms
236 };
237 
238 } // namespace hops
239 
240 #endif
#define msg_debug(xKEY, xCONTENT)
Definition: MHO_Message.hh:291
#define msg_error(xKEY, xCONTENT)
Definition: MHO_Message.hh:238
template meta-programming helper functions, mostly tuple access/modification
#define profiler_scope()
Definition: MHO_Profiler.hh:237
void Resize(unsigned int n)
Resizes the internal data structure to a new size and fills it.
Definition: MHO_FastFourierTransformWorkspace.hh:72
Class MHO_MultidimensionalFastFourierTransformInterface.
Definition: MHO_MultidimensionalFastFourierTransformInterface.hh:25
size_t fDimensionSize[XArgType::rank::value]
Definition: MHO_MultidimensionalFastFourierTransformInterface.hh:236
std::enable_if< !std::is_base_of< MHO_TableContainerBase, XCheckType >::value, void >::type IfTableTransformAxis(XArgType *, std::size_t)
Transforms axis of input data if transformation is enabled and axis was transformed.
Definition: MHO_MultidimensionalFastFourierTransformInterface.hh:129
bool fForward
Definition: MHO_MultidimensionalFastFourierTransformInterface.hh:232
bool fAxesToXForm[XArgType::rank::value]
Definition: MHO_MultidimensionalFastFourierTransformInterface.hh:237
bool fInitialized
Definition: MHO_MultidimensionalFastFourierTransformInterface.hh:233
Class MHO_MultidimensionalFastFourierTransform.
Definition: MHO_MultidimensionalFastFourierTransform.hh:35
virtual bool ExecuteInPlace(XArgType *in) override
Function ExecuteInPlace, does FFT in-place.
Definition: MHO_MultidimensionalFastFourierTransform.hh:115
typename XArgType::value_type complex_value_type
Definition: MHO_MultidimensionalFastFourierTransform.hh:39
virtual bool InitializeInPlace(XArgType *in) override
Initializes in-place operation and allocates workspace.
Definition: MHO_MultidimensionalFastFourierTransform.hh:54
typename XArgType::value_type::value_type floating_point_value_type
Definition: MHO_MultidimensionalFastFourierTransform.hh:40
MHO_MultidimensionalFastFourierTransform()
Definition: MHO_MultidimensionalFastFourierTransform.hh:42
virtual ~MHO_MultidimensionalFastFourierTransform()
Definition: MHO_MultidimensionalFastFourierTransform.hh:44
virtual bool ExecuteOutOfPlace(const XArgType *in, XArgType *out) override
Copies input data to output if they're not the same array and executes FFT in-place on output.
Definition: MHO_MultidimensionalFastFourierTransform.hh:209
virtual bool InitializeOutOfPlace(const XArgType *in, XArgType *out) override
Function InitializeOutOfPlace.
Definition: MHO_MultidimensionalFastFourierTransform.hh:83
static void RowMajorIndexFromOffset(std::size_t offset, const std::size_t *DimSize, std::size_t *Index)
Function RowMajorIndexFromOffset.
Definition: MHO_NDArrayMath.hh:117
Class MHO_UnaryOperator.
Definition: MHO_UnaryOperator.hh:24
Definition: fit_gsl.h:54
Definition: MHO_AdhocFlagging.hh:18
void FFTBluestein(std::complex< XFloatType > *data, MHO_FastFourierTransformWorkspace< XFloatType > &work, bool isForward, unsigned int stride=1)
Performs Bluestein's FFT algorithm on complex data using a workspace for arbitrary N....
Definition: MHO_FastFourierTransformCalls.hh:65
void FFTRadix2(std::complex< XFloatType > *data, MHO_FastFourierTransformWorkspace< XFloatType > &work, bool isForward, unsigned int stride=1)
Performs a Radix-2 Decimation-in-time (DIT) FFT algorithm on complex data using a workspace for arbit...
Definition: MHO_FastFourierTransformCalls.hh:35
Definition: MHO_Meta.hh:372