MCPcopy Create free account
hub / github.com/arrayfire/arrayfire / fft_c2r

Function fft_c2r

src/backend/cpu/fft.cpp:155–216  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

153
154template<typename Tr, typename Tc>
155Array<Tr> fft_c2r(const Array<Tc> &in, const dim4 &odims, const int rank) {
156 Array<Tr> out = createEmptyArray<Tr>(odims);
157
158 auto func = [=](Param<Tr> out, const af::dim4 oDataDims, CParam<Tc> in,
159 const af::dim4 iDataDims, const af::dim4 odims) {
160 auto t_dims = computeDims(rank, odims);
161 auto in_embed = computeDims(rank, iDataDims);
162 auto out_embed = computeDims(rank, oDataDims);
163
164 const af::dim4 istrides = in.strides();
165 const af::dim4 ostrides = out.strides();
166
167 using ctype_t = typename fftw_real_transform<Tr, Tc>::ctype_t;
168 using plan_t = typename fftw_real_transform<Tr, Tc>::plan_t;
169 plan_t plan;
170
171 fftw_real_transform<Tr, Tc> transform;
172
173 int batch = 1;
174 for (int i = rank; i < 4; i++) { batch *= odims[i]; }
175
176 // By default, fftw estimate flag is sufficient for most transforms.
177 // However, complex to real transforms modify the input data memory
178 // while performing the transformation. To avoid that, we need to pass
179 // FFTW_PRESERVE_INPUT also. This flag however only works for 1D
180 // transforms and for higher level transformations, a copy of input
181 // data is passed onto the upstream FFTW calls.
182 unsigned int flags = FFTW_ESTIMATE; // NOLINT(hicpp-signed-bitwise)
183 if (rank == 1) {
184 flags |= FFTW_PRESERVE_INPUT; // NOLINT(hicpp-signed-bitwise)
185 }
186
187 plan = transform.create(
188 rank, t_dims.data(), batch,
189 reinterpret_cast<ctype_t *>(const_cast<Tc *>(in.get())),
190 in_embed.data(), static_cast<int>(istrides[0]),
191 static_cast<int>(istrides[rank]), out.get(), out_embed.data(),
192 static_cast<int>(ostrides[0]), static_cast<int>(ostrides[rank]),
193 flags);
194
195 transform.execute(plan);
196 transform.destroy(plan);
197 };
198
199#ifdef USE_MKL
200 getQueue().enqueue(func, out, out.getDataDims(), in, in.getDataDims(),
201 odims);
202#else
203 if (rank > 1 || odims.ndims() > 1) {
204 // FFTW does not have a input preserving algorithm for multidimensional
205 // c2r FFTs
206 Array<Tc> in_ = copyArray<Tc>(in);
207 getQueue().enqueue(func, out, out.getDataDims(), in_, in.getDataDims(),
208 odims);
209 } else {
210 getQueue().enqueue(func, out, out.getDataDims(), in, in.getDataDims(),
211 odims);
212 }

Callers

nothing calls this directly

Calls 8

computeDimsFunction · 0.70
getQueueFunction · 0.50
stridesMethod · 0.45
createMethod · 0.45
getMethod · 0.45
enqueueMethod · 0.45
getDataDimsMethod · 0.45
ndimsMethod · 0.45

Tested by

no test coverage detected