| 242 | |
| 243 | template<typename Tr, typename Tc> |
| 244 | Array<Tr> fft_c2r(const Array<Tc> &in, const dim4 &odims, const int rank) { |
| 245 | const dim4 idims = in.dims(); |
| 246 | const dim4 istrides = in.strides(); |
| 247 | Array<Tr> out = createEmptyArray<Tr>(odims); |
| 248 | const dim4 ostrides = out.strides(); |
| 249 | |
| 250 | constexpr bool is_single = std::is_same_v<Tr, float>; |
| 251 | constexpr auto precision = (is_single) |
| 252 | ? ::oneapi::mkl::dft::precision::SINGLE |
| 253 | : ::oneapi::mkl::dft::precision::DOUBLE; |
| 254 | using desc_ty = |
| 255 | ::oneapi::mkl::dft::descriptor<precision, |
| 256 | ::oneapi::mkl::dft::domain::REAL>; |
| 257 | |
| 258 | std::vector<std::int64_t> fft_input_strides = |
| 259 | computeStrides(rank, istrides, in.getOffset()); |
| 260 | std::vector<std::int64_t> fft_output_strides = |
| 261 | computeStrides(rank, ostrides, out.getOffset()); |
| 262 | |
| 263 | int batch = 1; |
| 264 | for (int i = rank; i < 4; i++) { batch *= odims[i]; } |
| 265 | |
| 266 | const bool isInPlace = false; |
| 267 | PlanType descP = findPlan<precision, ::oneapi::mkl::dft::domain::REAL>( |
| 268 | rank, isInPlace, odims.get(), fft_input_strides.data(), ostrides[rank], |
| 269 | fft_output_strides.data(), istrides[rank], batch); |
| 270 | |
| 271 | desc_ty *desc = (desc_ty *)descP.get(); |
| 272 | |
| 273 | ::oneapi::mkl::dft::compute_backward(*desc, *in.get(), *out.get()); |
| 274 | return out; |
| 275 | } |
| 276 | |
| 277 | #define INSTANTIATE(T) \ |
| 278 | template void fft_inplace<T>(Array<T> &, const int, const bool); |
nothing calls this directly
no test coverage detected