Example #1
0
void rfftwnd_real2c_aux_howmany(fftwnd_plan p, int cur_dim,
				int howmany,
				fftw_real *in, int istride, int idist,
				fftw_complex *out, int ostride, int odist,
				fftw_complex *work)
{
     int n_after = p->n_after[cur_dim], n = p->n[cur_dim];
     int k;

     if (cur_dim == p->rank - 2) {
	  /* just do the last dimension directly: */
	  if (p->is_in_place)
	       for (k = 0; k < n; ++k)
		    rfftw_real2c_overlap_aux(p->plans[p->rank - 1], howmany,
					in + (k * n_after * istride) * 2,
					     istride, idist,
					   out + (k * n_after * ostride),
					     ostride, odist,
					     (fftw_real *) work);
	  else {
	       int nlast = p->plans[p->rank - 1]->n;
	       for (k = 0; k < n; ++k)
		    rfftw_real2c_aux(p->plans[p->rank - 1], howmany,
				     in + k * nlast * istride,
				     istride, idist,
				     out + k * n_after * ostride,
				     ostride, odist,
				     (fftw_real *) work);
	  }
     } else {			/* we have at least two dimensions to go */
	  int nr = p->plans[p->rank - 1]->n;
	  int n_after_r = p->is_in_place ? n_after * 2 : 
	       nr * (n_after / (nr/2 + 1));
	  int i;

	  /* 
	   * process the subsequent dimensions recursively, in hyperslabs,
	   * to get maximum locality: 
	   */
	  for (i = 0; i < n; ++i)
	       rfftwnd_real2c_aux_howmany(p, cur_dim + 1, howmany,
			    in + i * n_after_r * istride, istride, idist,
			     out + i * n_after * ostride, ostride, odist,
					  work);
     }

     /* do the current dimension (in-place): */
     for (k = 0; k < n_after; ++k)
	  fftw(p->plans[cur_dim], howmany,
	       out + k * ostride, n_after * ostride, odist,
	       work, 1, 0);
}
Example #2
0
static void *r2c_overlap_howmany_thread(fftw_loop_data *ldata)
{
     int min = ldata->min, max = ldata->max;
     howmany_aux_data *d = (howmany_aux_data *) ldata->data;
     fftw_plan p = d->p;
     int howmany = d->howmany;
     fftw_real *in = (fftw_real *) d->in;
     int istride = d->istride, idist = d->idist, idist0 = d->idist0;
     fftw_complex *out = (fftw_complex *) d->out;
     int ostride = d->ostride, odist = d->odist, odist0 = d->odist0;
     fftw_real *work = d->work + d->wdist * ldata->thread_num;

     for (; min < max; ++min)
	  rfftw_real2c_overlap_aux(p, howmany,
				   in + min * idist0, istride, idist,
				   out + min * odist0, ostride, odist,
				   work);

     return 0;
}
Example #3
0
void rfftwnd_real_to_complex(fftwnd_plan p, int howmany,
			     fftw_real *in, int istride, int idist,
			     fftw_complex *out, int ostride, int odist)
{
     fftw_complex *work = p->work;
     int rank = p->rank;
     int free_work = 0;

     if (p->dir != FFTW_REAL_TO_COMPLEX)
	  fftw_die("rfftwnd_real_to_complex with complex-to-real plan");

#ifdef FFTW_DEBUG
     if (p->rank > 0 && (p->plans[0]->flags & FFTW_THREADSAFE)
	 && p->nwork && p->work)
	  fftw_die("bug with FFTW_THREADSAFE flag");
#endif

     if (p->is_in_place) {
	  ostride = istride;
	  odist = (idist == 1 && idist < istride) ? 1 : (idist / 2);  /* ugh */
	  out = (fftw_complex *) in;
	  if (howmany > 1 && istride > idist && rank > 0) {
	       int new_nwork;

	       new_nwork = p->n[rank - 1] * howmany;
	       if (new_nwork > p->nwork) {
		    work = (fftw_complex *)
			fftw_malloc(sizeof(fftw_complex) * new_nwork);
		    if (!work)
			 fftw_die("error allocating work array");
		    free_work = 1;
	       }
	  }
     }
     if (p->nwork && !work) {
	  work = (fftw_complex *) fftw_malloc(sizeof(fftw_complex) * p->nwork);
	  free_work = 1;
     }
     switch (rank) {
	 case 0:
	      break;
	 case 1:
	      if (p->is_in_place && howmany > 1 && istride > idist)
		   rfftw_real2c_overlap_aux(p->plans[0], howmany,
					    in, istride, idist,
					    out, ostride, odist,
					    (fftw_real *) work);
	      else
		   rfftw_real2c_aux(p->plans[0], howmany,
				    in, istride, idist,
				    out, ostride, odist,
				    (fftw_real *) work);
	      break;
	 default:		/* rank >= 2 */
	      {
		   if (howmany > 1 && ostride > odist)
			rfftwnd_real2c_aux_howmany(p, 0, howmany,
						   in, istride, idist,
						   out, ostride, odist,
						   work);
		   else {
			int i;

			for (i = 0; i < howmany; ++i)
			     rfftwnd_real2c_aux(p, 0,
						in + i * idist, istride,
						out + i * odist, ostride,
						(fftw_real *) work);
		   }
	      }
     }

     if (free_work)
	  fftw_free(work);
}