const struct operator_s* fft_create2(unsigned int D, const long dimensions[D], unsigned long flags, const long ostrides[D], complex float* dst, const long istrides[D], const complex float* src, bool backwards) { PTR_ALLOC(struct fft_plan_s, plan); SET_TYPEID(fft_plan_s, plan); plan->fftw = fft_fftwf_plan(D, dimensions, flags, ostrides, dst, istrides, src, backwards, false); #ifdef USE_CUDA plan->cuplan = NULL; #ifndef LAZY_CUDA if (cuda_ondevice(src)) plan->cuplan = fft_cuda_plan(D, dimensions, flags, ostrides, istrides, backwards); #else plan->D = D; plan->flags = flags; plan->backwards = backwards; PTR_ALLOC(long[D], dims); md_copy_dims(D, *dims, dimensions); plan->dims = *PTR_PASS(dims); PTR_ALLOC(long[D], istrs); md_copy_strides(D, *istrs, istrides); plan->istrs = *PTR_PASS(istrs); PTR_ALLOC(long[D], ostrs); md_copy_strides(D, *ostrs, ostrides); plan->ostrs = *PTR_PASS(ostrs); #endif #endif return operator_create2(D, dimensions, ostrides, D, dimensions, istrides, CAST_UP(PTR_PASS(plan)), fft_apply, fft_free_plan); }
const struct operator_s* fft_measure_create(unsigned int D, const long dimensions[D], unsigned long flags, bool inplace, bool backwards) { PTR_ALLOC(struct fft_plan_s, plan); SET_TYPEID(fft_plan_s, plan); complex float* src = md_alloc(D, dimensions, CFL_SIZE); complex float* dst = inplace ? src : md_alloc(D, dimensions, CFL_SIZE); long strides[D]; md_calc_strides(D, strides, dimensions, CFL_SIZE); plan->fftw = fft_fftwf_plan(D, dimensions, flags, strides, dst, strides, src, backwards, true); md_free(src); if (!inplace) md_free(dst); #ifdef USE_CUDA plan->cuplan = NULL; #ifndef LAZY_CUDA if (cuda_ondevice(src)) plan->cuplan = fft_cuda_plan(D, dimensions, flags, strides, strides, backwards); #else plan->D = D; plan->flags = flags; plan->backwards = backwards; PTR_ALLOC(long[D], dims); md_copy_dims(D, *dims, dimensions); plan->dims = *PTR_PASS(dims); PTR_ALLOC(long[D], istrs); md_copy_strides(D, *istrs, strides); plan->istrs = *PTR_PASS(istrs); PTR_ALLOC(long[D], ostrs); md_copy_strides(D, *ostrs, strides); plan->ostrs = *PTR_PASS(ostrs); #endif #endif return operator_create2(D, dimensions, strides, D, dimensions, strides, CAST_UP(PTR_PASS(plan)), fft_apply, fft_free_plan); }
static complex float* compute_psf2(unsigned int N, const long psf_dims[N + 3], const long trj_dims[N + 3], const complex float* traj, const complex float* weights) { unsigned int ND = N + 3; long img_dims[ND]; long img_strs[ND]; md_select_dims(ND, ~MD_BIT(N + 0), img_dims, psf_dims); md_calc_strides(ND, img_strs, img_dims, CFL_SIZE); // PSF 2x size long img2_dims[ND]; long img2_strs[ND]; md_copy_dims(ND, img2_dims, img_dims); for (int i = 0; i < 3; i++) img2_dims[i] = (1 == img_dims[i]) ? 1 : (2 * img_dims[i]); md_calc_strides(ND, img2_strs, img2_dims, CFL_SIZE); complex float* traj2 = md_alloc(ND, trj_dims, CFL_SIZE); md_zsmul(ND, trj_dims, traj2, traj, 2.); complex float* psft = compute_psf(ND, img2_dims, trj_dims, traj2, weights); md_free(traj2); fftuc(ND, img2_dims, FFT_FLAGS, psft, psft); // reformat long sub2_strs[ND]; md_copy_strides(ND, sub2_strs, img2_strs); for(int i = 0; i < 3; i++) sub2_strs[i] *= 2;; complex float* psf = md_alloc(ND, psf_dims, CFL_SIZE); long factors[N]; for (unsigned int i = 0; i < N; i++) factors[i] = ((img_dims[i] > 1) && (i < 3)) ? 2 : 1; md_decompose(N + 0, factors, psf_dims, psf, img2_dims, psft, CFL_SIZE); md_free(psft); return psf; }