tom::fftw::Plan<T>::Plan(tom::Volume<T> &vsrc, tom::Volume<std::complex<T> > &vdst, unsigned flags){ const int type = this->is_valid_dft_r2c(vsrc, vdst); if (type == TOM_FFTW_PLAN_INVALID) { throw std::invalid_argument("tom::fftw::Plan() - The input volumes have not the right size or alignment for dft_r2c"); } int rank = (type==TOM_FFTW_PLAN_3D ? 3 : 2); int howmany_rank = 0; fftw_iodim iodim[3]; iodim[0].n = vsrc.getSizeX(); iodim[0].is = vsrc.getStrideX()/sizeof(T); iodim[0].os = vdst.getStrideX()/sizeof(std::complex<T>); iodim[1].n = vsrc.getSizeY(); iodim[1].is = vsrc.getStrideY()/sizeof(T); iodim[1].os = vdst.getStrideY()/sizeof(std::complex<T>); iodim[2].n = vsrc.getSizeZ(); iodim[2].is = vsrc.getStrideZ()/sizeof(T); iodim[2].os = vdst.getStrideZ()/sizeof(std::complex<T>); fftw_iodim *howmany_dims = NULL; boost::shared_ptr<void> p(static_cast<void *>(0), ::plan_destroyer<T>()); if (tom::is_float<T>()) { p = boost::shared_ptr<void>(static_cast<void *>(fftwf_plan_guru_dft_r2c(rank, iodim, howmany_rank, howmany_dims, (float *)&vsrc.get(), (fftwf_complex *)&vdst.get(), flags)), ::plan_destroyer<T>()); } else { p = boost::shared_ptr<void>(static_cast<void *>(fftw_plan_guru_dft_r2c (rank, iodim, howmany_rank, howmany_dims, (double *)&vsrc.get(), (fftw_complex *)&vdst.get(), flags)), ::plan_destroyer<T>()); } if (!p.get()) { throw std::runtime_error("tom::fftw::Plan() - could not create fftw plan dft_r2c"); } std::auto_ptr<tom::Volume<std::complex<T> > > p_freq0(new tom::Volume<std::complex<T> >(vdst, NULL, vdst.getSizeX(), vdst.getSizeY(), vdst.getSizeZ(), vdst.getStrideX(), vdst.getStrideY(), vdst.getStrideZ())); std::auto_ptr<tom::Volume<T > > p_time0(new tom::Volume<T >(vsrc, NULL, vsrc.getSizeX(), vsrc.getSizeY(), vsrc.getSizeZ(), vsrc.getStrideX(), vsrc.getStrideY(), vsrc.getStrideZ())); this->plan.swap(p); this->type = tom::fftw::Plan<T>::FFTW_DFT_R2C; this->p_freq0 = p_freq0.release(); this->p_time0 = p_time0.release(); this->p_freq1 = NULL; this->p_time1 = NULL; }
/* =======================================================================* Public Functions * =======================================================================*/ void s_ncc_fft_compile (FATM_Options* fopt) { fftw_plan pat_plan; double* temp; int i, j; Image_Rect* prv = &fopt->pat_rect_valid; fftw_iodim fftw_dims[2]; int fft_nx = fopt->sig_rect_scan.dims[1]; /* In fftw3, nx is rows */ int fft_ny = fopt->sig_rect_scan.dims[0]; /* In fftw3, ny is cols */ /* Allocate memory */ S_Ncc_Fft_Data* udp = (S_Ncc_Fft_Data*) malloc (sizeof(S_Ncc_Fft_Data)); fopt->alg_data = (void*) udp; /* Alloc memory for integral images */ s_ncc_fft_scorewin_alloc (fopt); /* Compute pattern statistics */ // s_pattern_statistics (&udp->p_stats, fopt); /* Alloc memory for fft of pat */ udp->pat_fft = (fftw_complex*) fftw_malloc (sizeof(fftw_complex) * fft_nx * (fft_ny/2+1)); memset (udp->pat_fft, 0, sizeof(fftw_complex) * fft_nx * (fft_ny/2+1)); /* Copy pattern into fft memory. Flip it so that convolution becomes correlation */ temp = (double*) udp->pat_fft + (fft_nx-1) * (2*(fft_ny/2+1)) + fft_ny - 1; for (j = 0; j < prv->dims[0]; j++) { for (i = 0; i < prv->dims[1]; i++) { *temp-- = image_data(&fopt->pat)[image_index(prv->dims, j, i)]; } temp -= (2*(fft_ny/2+1)) - prv->dims[1]; } /* Peform fft */ pat_plan = fftw_plan_dft_r2c_2d (fft_nx, fft_ny, (double*) udp->pat_fft, udp->pat_fft, FFTW_ESTIMATE); fftw_execute (pat_plan); fftw_destroy_plan (pat_plan); /* Debugging info */ dump_fft (udp->pat_fft, fft_nx, fft_ny, "pat_fft.txt"); /* Alloc memory for fft of sig */ udp->sig_fft = (fftw_complex*) fftw_malloc (sizeof(fftw_complex) * fft_nx * (fft_ny/2+1)); /* Create plan for sig -> sig_fft */ fftw_dims[0].n = fft_nx; fftw_dims[0].is = fopt->sig.dims[0]; fftw_dims[0].os = (fft_ny/2+1); fftw_dims[1].n = fft_ny; fftw_dims[1].is = 1; fftw_dims[1].os = 1; /* NOTE: Using FFTW_MEASURE overwrites input. So I need to allocate a temporary array. */ udp->sig_fftw3_plan = fftw_plan_guru_dft_r2c ( 2, fftw_dims, 0, 0, (double*) fopt->sig.data, udp->sig_fft, FFTW_ESTIMATE | FFTW_UNALIGNED | FFTW_PRESERVE_INPUT); if (udp->sig_fftw3_plan == 0) { printf ("Error: couldn't make plan\n"); } printf ("SRS: %d %d\n", fopt->sig_rect_scan.dims[0], fopt->sig_rect_scan.dims[1]); printf ("SIG: %d %d\n", fopt->sig.dims[0], fopt->sig.dims[1]); /* Alloc memory for temporary score */ udp->padded_score = (double*) fftw_malloc (sizeof(double) * fft_nx * fft_ny); /* Create plan for pat_fft * sig_fft -> score */ udp->sco_fftw3_plan = fftw_plan_dft_c2r_2d (fft_nx, fft_ny, udp->sig_fft, udp->padded_score, FFTW_MEASURE); if (udp->sco_fftw3_plan == 0) { printf ("Error: couldn't make plan\n"); } }
Transformer_CPU::Transformer_CPU(int dim_x, int dim_y, int dim_z, int exp_x, int exp_y, int exp_z) : dim_x(dim_x), dim_y(dim_y), dim_z(dim_z), exp_x(exp_x), exp_y(exp_y), exp_z(exp_z) { if (os::disable_SSE_for_FFTW()) { fftw_strategy |= FFTW_UNALIGNED; // see os.h for explanation } Matrix tmp(Shape(2, exp_x, exp_y, exp_z)); Matrix::rw_accessor tmp_acc(tmp); double *tmp_inout = tmp_acc.ptr(); // Create fftw plans fftw_iodim dims, loop; // X-Transform: (dim_y*dim_z) x 1d-C2C-FFT (length: exp_x) in x-direction, in-place transform dims.n = exp_x; dims.is = 1; dims.os = 1; loop.n = dim_y*dim_z; loop.is = exp_x; loop.os = exp_x/2+1; plan_x_r2c = fftw_plan_guru_dft_r2c( 1, &dims, 1, &loop, ( double*)tmp_inout, (fftw_complex*)tmp_inout, fftw_strategy ); assert(plan_x_r2c); dims.n = exp_x; dims.is = 1; dims.os = 1; loop.n = dim_y*dim_z; loop.is = exp_x/2+1; loop.os = exp_x; plan_x_c2r = fftw_plan_guru_dft_c2r( 1, &dims, 1, &loop, (fftw_complex*)tmp_inout, ( double*)tmp_inout, fftw_strategy ); assert(plan_x_c2r); // Y-Transform: (dim_z*exp_x/2+1) x 1d-C2C-FFT (length: exp_y) in x-direction, in-place transform dims.n = exp_y; dims.is = 1; dims.os = 1; loop.n = dim_z*(exp_x/2+1); loop.is = exp_y; loop.os = exp_y; plan_y_forw = fftw_plan_guru_dft( 1, &dims, 1, &loop, (fftw_complex*)tmp_inout, // in (fftw_complex*)tmp_inout, // out (-> in-place transform) FFTW_FORWARD, fftw_strategy ); assert(plan_y_forw); plan_y_inv = fftw_plan_guru_dft( 1, &dims, 1, &loop, (fftw_complex*)tmp_inout, // in (fftw_complex*)tmp_inout, // out (-> in-place transform) FFTW_BACKWARD, fftw_strategy ); assert(plan_y_inv); // Z-Transform: (exp_x/2+1*exp_y) x 1d-C2C-FFT (length: exp_z) in x-direction, in-place transform dims.n = exp_z; dims.is = 1; dims.os = 1; loop.n = (exp_x/2+1)*exp_y; loop.is = exp_z; loop.os = exp_z; plan_z_forw = fftw_plan_guru_dft( 1, &dims, 1, &loop, (fftw_complex*)tmp_inout, // in (fftw_complex*)tmp_inout, // out (-> in-place transform) FFTW_FORWARD, fftw_strategy ); assert(plan_z_forw); plan_z_inv = fftw_plan_guru_dft( 1, &dims, 1, &loop, (fftw_complex*)tmp_inout, // in (fftw_complex*)tmp_inout, // out (-> in-place transform) FFTW_BACKWARD, fftw_strategy ); assert(plan_z_inv); }