| 169 | |
| 170 | template<typename T> |
| 171 | void fft_inplace(Array<T> &in, const int rank, const bool direction) { |
| 172 | const dim4 idims = in.dims(); |
| 173 | const dim4 istrides = in.strides(); |
| 174 | |
| 175 | constexpr bool is_single = std::is_same_v<T, cfloat>; |
| 176 | constexpr auto precision = (is_single) |
| 177 | ? ::oneapi::mkl::dft::precision::SINGLE |
| 178 | : ::oneapi::mkl::dft::precision::DOUBLE; |
| 179 | using desc_ty = |
| 180 | ::oneapi::mkl::dft::descriptor<precision, |
| 181 | ::oneapi::mkl::dft::domain::COMPLEX>; |
| 182 | |
| 183 | // TODO[STF]: WTF |
| 184 | // getOffset() for s0 throwing Invalid Descriptor when targeting gpu |
| 185 | // on CPU, results are wrong but does not throw |
| 186 | // strides not working? TODO: test standalone oneMKL |
| 187 | // perhaps in.getDataDims() needed instead of in.dims()? |
| 188 | std::vector<std::int64_t> fft_input_strides = |
| 189 | computeStrides(rank, istrides, 0); |
| 190 | // computeStrides(rank, istrides, in.getOffset()); //TODO[STF]: WTF, |
| 191 | int batch = 1; |
| 192 | for (int i = rank; i < 4; i++) { batch *= idims[i]; } |
| 193 | |
| 194 | const bool isInPlace = true; |
| 195 | PlanType descP = findPlan<precision, ::oneapi::mkl::dft::domain::COMPLEX>( |
| 196 | rank, isInPlace, idims.get(), fft_input_strides.data(), istrides[rank], |
| 197 | fft_input_strides.data(), istrides[rank], batch); |
| 198 | |
| 199 | desc_ty *desc = (desc_ty *)descP.get(); |
| 200 | |
| 201 | if (direction) |
| 202 | ::oneapi::mkl::dft::compute_forward(*desc, *in.get()); |
| 203 | else |
| 204 | ::oneapi::mkl::dft::compute_backward(*desc, *in.get()); |
| 205 | } |
| 206 | |
| 207 | template<typename Tc, typename Tr> |
| 208 | Array<Tc> fft_r2c(const Array<Tr> &in, const int rank) { |
nothing calls this directly
no test coverage detected