int srslte_dft_plan_guru_c(srslte_dft_plan_t *plan, const int dft_points, srslte_dft_dir_t dir, cf_t *in_buffer, cf_t *out_buffer, int istride, int ostride, int how_many, int idist, int odist) { int sign = (dir == SRSLTE_DFT_FORWARD) ? FFTW_FORWARD : FFTW_BACKWARD; const fftwf_iodim iodim = {dft_points, istride, ostride}; const fftwf_iodim howmany_dims = {how_many, idist, odist}; plan->p = fftwf_plan_guru_dft(1, &iodim, 1, &howmany_dims, in_buffer, out_buffer, sign, FFTW_TYPE); if (!plan->p) { return -1; } plan->size = dft_points; plan->init_size = plan->size; plan->mode = SRSLTE_DFT_COMPLEX; plan->dir = dir; plan->forward = (dir==SRSLTE_DFT_FORWARD)?true:false; plan->mirror = false; plan->db = false; plan->norm = false; plan->dc = false; plan->is_guru = true; return 0; }
int srslte_dft_replan_guru_c(srslte_dft_plan_t *plan, const int new_dft_points, cf_t *in_buffer, cf_t *out_buffer, int istride, int ostride, int how_many, int idist, int odist) { int sign = (plan->forward) ? FFTW_FORWARD : FFTW_BACKWARD; const fftwf_iodim iodim = {new_dft_points, istride, ostride}; const fftwf_iodim howmany_dims = {how_many, idist, odist}; pthread_mutex_lock(&fft_mutex); /* Destroy current plan */ fftwf_destroy_plan(plan->p); plan->p = fftwf_plan_guru_dft(1, &iodim, 1, &howmany_dims, in_buffer, out_buffer, sign, FFTW_TYPE); pthread_mutex_unlock(&fft_mutex); if (!plan->p) { return -1; } plan->size = new_dft_points; plan->init_size = plan->size; return 0; }
/*--------------------------------------------------------------------------*/ fftwf_plan _fftwfP (fftwf_complex *in, /* plan */ fftwf_complex *out, long ft_rank, long *ft_dims, long *ft_strides, long ft_loop, long *loop_dims, long *loop_strides, long dir) /* forward (1) or reverse (-1) */ { /* Declarations */ int i; int sign= -1*dir; fftwf_plan p; long plan_mode; fftwf_iodim *id_fft; fftwf_iodim *id_loop; plan_mode = FFTW_PATIENT; /* FFTW_ESTIMATE FFTW_MEASURE FFTW_PATIENT FFTW_EXHAUSTIVE;*/ id_fft = (fftwf_iodim *)fftwf_malloc(sizeof(fftwf_iodim) * ft_rank); id_loop = (fftwf_iodim *)fftwf_malloc(sizeof(fftwf_iodim) * ft_loop); for (i = 0 ; i < ft_rank ; i++) { id_fft[i].n = ft_dims[i]; id_fft[i].is = ft_strides[i]; id_fft[i].os = ft_strides[i]; } for (i = 0 ; i < ft_loop ; i++) { id_loop[i].n = loop_dims[i]; id_loop[i].is = loop_strides[i]; id_loop[i].os = loop_strides[i]; } if (in == out){ /*in place*/ p = fftwf_plan_guru_dft((int)ft_rank, id_fft, (int)ft_loop, id_loop, in, in, sign, plan_mode); }else{ p = fftwf_plan_guru_dft((int)ft_rank, id_fft, (int)ft_loop, id_loop, in, out, sign, plan_mode); } fftwf_free(id_fft); fftwf_free(id_loop); return p; }
static fftwf_plan fft_fftwf_plan(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) { unsigned int N = D; fftwf_iodim dims[N]; fftwf_iodim hmdims[N]; unsigned int k = 0; unsigned int l = 0; //FFTW seems to be fine with this //assert(0 != flags); for (unsigned int i = 0; i < N; i++) { if (MD_IS_SET(flags, i)) { dims[k].n = dimensions[i]; dims[k].is = istrides[i] / CFL_SIZE; dims[k].os = ostrides[i] / CFL_SIZE; k++; } else { hmdims[l].n = dimensions[i]; hmdims[l].is = istrides[i] / CFL_SIZE; hmdims[l].os = ostrides[i] / CFL_SIZE; l++; } } fftwf_plan fftwf; #pragma omp critical fftwf = fftwf_plan_guru_dft(k, dims, l, hmdims, (complex float*)src, dst, backwards ? 1 : (-1), FFTW_ESTIMATE); return fftwf; }