static void dft_apply(dofft_closure *k_, bench_complex *in, bench_complex *out)
{
     dofft_dft_closure *k = (dofft_dft_closure *)k_;
     bench_problem *p = k->p;
     bench_tensor *totalsz, *pckdsz;
     bench_tensor *totalsz_swap, *pckdsz_swap;
     bench_real *ri, *ii, *ro, *io;
     int totalscale;

     totalsz = tensor_append(p->vecsz, p->sz);
     pckdsz = verify_pack(totalsz, 2);
     ri = (bench_real *) p->in;
     ro = (bench_real *) p->out;

     totalsz_swap = tensor_copy_swapio(totalsz);
     pckdsz_swap = tensor_copy_swapio(pckdsz);

     /* confusion: the stride is the distance between complex elements
	when using interleaved format, but it is the distance between
	real elements when using split format */
     if (p->split) {
	  ii = p->ini ? (bench_real *) p->ini : ri + p->iphyssz;
	  io = p->outi ? (bench_real *) p->outi : ro + p->ophyssz;
	  totalscale = 1;
     } else {
	  ii = p->ini ? (bench_real *) p->ini : ri + 1;
	  io = p->outi ? (bench_real *) p->outi : ro + 1;
	  totalscale = 2;
     }

     cpy(&c_re(in[0]), &c_im(in[0]), pckdsz, 1,
	    ri, ii, totalsz, totalscale);
     after_problem_ccopy_from(p, ri, ii);
     doit(1, p);
     after_problem_ccopy_to(p, ro, io);
     if (k->k.recopy_input)
	  cpy(ri, ii, totalsz_swap, totalscale,
	      &c_re(in[0]), &c_im(in[0]), pckdsz_swap, 1);
     cpy(ro, io, totalsz, totalscale,
	 &c_re(out[0]), &c_im(out[0]), pckdsz, 1);

     tensor_destroy(totalsz);
     tensor_destroy(pckdsz);
     tensor_destroy(totalsz_swap);
     tensor_destroy(pckdsz_swap);
}
Beispiel #2
0
void verify_r2r(bench_problem *p, int rounds, double tol, errors *e)
{
     R *inA, *inB, *inC, *outA, *outB, *outC, *tmp;
     info nfo;
     int n, vecn, N;
     double impulse_amp = 1.0;
     dim_stuff *d;
     int i;

     if (rounds == 0)
	  rounds = 20;  /* default value */

     n = tensor_sz(p->sz);
     vecn = tensor_sz(p->vecsz);
     N = n * vecn;

     d = (dim_stuff *) bench_malloc(sizeof(dim_stuff) * p->sz->rnk);
     for (i = 0; i < p->sz->rnk; ++i) {
	  int n0, i0, k0;
	  trigfun ti, ts;

	  d[i].n = n0 = p->sz->dims[i].n;
	  if (p->k[i] > R2R_DHT)
	       n0 = 2 * (n0 + (p->k[i] == R2R_REDFT00 ? -1 : 
			       (p->k[i] == R2R_RODFT00 ? 1 : 0)));
	  
	  switch (p->k[i]) {
	      case R2R_R2HC:
		   i0 = k0 = 0;
		   ti = realhalf;
		   ts = coshalf;
		   break;
	      case R2R_DHT:
		   i0 = k0 = 0;
		   ti = unity;
		   ts = cos00;
		   break;
	      case R2R_HC2R:
		   i0 = k0 = 0;
		   ti = unity;
		   ts = cos00;
		   break;
	      case R2R_REDFT00:
		   i0 = k0 = 0;
		   ti = ts = cos00;
		   break;
	      case R2R_REDFT01:
		   i0 = k0 = 0;
		   ti = ts = cos01;
		   break;
	      case R2R_REDFT10:
		   i0 = k0 = 0;
		   ti = cos10; impulse_amp *= 2.0;
		   ts = cos00;
		   break;
	      case R2R_REDFT11:
		   i0 = k0 = 0;
		   ti = cos11; impulse_amp *= 2.0;
		   ts = cos01;
		   break;
	      case R2R_RODFT00:
		   i0 = k0 = 1;
		   ti = sin00; impulse_amp *= 2.0;
		   ts = cos00;
		   break;
	      case R2R_RODFT01:
		   i0 = 1; k0 = 0;
		   ti = sin01; impulse_amp *= n == 1 ? 1.0 : 2.0;
		   ts = cos01;
		   break;
	      case R2R_RODFT10:
		   i0 = 0; k0 = 1;
		   ti = sin10; impulse_amp *= 2.0;
		   ts = cos00;
		   break;
	      case R2R_RODFT11:
		   i0 = k0 = 0;
		   ti = sin11; impulse_amp *= 2.0;
		   ts = cos01;
		   break;
	      default:
		   BENCH_ASSERT(0);
		   return;
	  }

	  d[i].n0 = n0;
	  d[i].i0 = i0;
	  d[i].k0 = k0;
	  d[i].ti = ti;
	  d[i].ts = ts;
     }


     inA = (R *) bench_malloc(N * sizeof(R));
     inB = (R *) bench_malloc(N * sizeof(R));
     inC = (R *) bench_malloc(N * sizeof(R));
     outA = (R *) bench_malloc(N * sizeof(R));
     outB = (R *) bench_malloc(N * sizeof(R));
     outC = (R *) bench_malloc(N * sizeof(R));
     tmp = (R *) bench_malloc(N * sizeof(R));

     nfo.p = p;
     nfo.probsz = p->sz;
     nfo.totalsz = tensor_append(p->vecsz, nfo.probsz);
     nfo.pckdsz = verify_pack(nfo.totalsz, 1);
     nfo.pckdvecsz = verify_pack(p->vecsz, tensor_sz(nfo.probsz));

     e->i = rimpulse(d, impulse_amp, n, vecn, &nfo,
		     inA, inB, inC, outA, outB, outC, tmp, rounds, tol);
     e->l = rlinear(N, &nfo, inA, inB, inC, outA, outB, outC, tmp, rounds,tol);
     e->s = t_shift(n, vecn, &nfo, inA, inB, outA, outB, tmp, 
		    rounds, tol, d);

     /* grr, verify-lib.c:preserves_input() only works for complex */
     if (!p->in_place && !p->destroy_input) {
	  bench_tensor *totalsz_swap, *pckdsz_swap;
	  totalsz_swap = tensor_copy_swapio(nfo.totalsz);
	  pckdsz_swap = tensor_copy_swapio(nfo.pckdsz);

	  for (i = 0; i < rounds; ++i) {
	       rarand(inA, N);
	       dofft(&nfo, inA, outB);
	       cpyr((R *) nfo.p->in, totalsz_swap, inB, pckdsz_swap);
	       racmp(inB, inA, N, "preserves_input", 0.0);
	  }

	  tensor_destroy(totalsz_swap);
	  tensor_destroy(pckdsz_swap);
     }

     tensor_destroy(nfo.totalsz);
     tensor_destroy(nfo.pckdsz);
     tensor_destroy(nfo.pckdvecsz);
     bench_free(tmp);
     bench_free(outC);
     bench_free(outB);
     bench_free(outA);
     bench_free(inC);
     bench_free(inB);
     bench_free(inA);
     bench_free(d);
}
Beispiel #3
0
static void rdft2_apply(dofft_closure *k_, 
			bench_complex *in, bench_complex *out)
{
     dofft_rdft2_closure *k = (dofft_rdft2_closure *)k_;
     bench_problem *p = k->p;
     bench_tensor *totalsz, *pckdsz, *totalsz_swap, *pckdsz_swap;
     bench_tensor *probsz2, *totalsz2, *pckdsz2;
     bench_tensor *probsz2_swap, *totalsz2_swap, *pckdsz2_swap;
     bench_real *ri, *ii, *ro, *io;
     int n2, totalscale;

     totalsz = tensor_append(p->vecsz, p->sz);
     pckdsz = verify_pack(totalsz, 2);
     n2 = tensor_sz(totalsz);
     if (FINITE_RNK(p->sz->rnk) && p->sz->rnk > 0)
	  n2 = (n2 / p->sz->dims[p->sz->rnk - 1].n) * 
	       (p->sz->dims[p->sz->rnk - 1].n / 2 + 1);
     ri = (bench_real *) p->in;
     ro = (bench_real *) p->out;

     if (FINITE_RNK(p->sz->rnk) && p->sz->rnk > 0 && n2 > 0) {
	  probsz2 = tensor_copy_sub(p->sz, p->sz->rnk - 1, 1);
	  totalsz2 = tensor_copy_sub(totalsz, 0, totalsz->rnk - 1);
	  pckdsz2 = tensor_copy_sub(pckdsz, 0, pckdsz->rnk - 1);
     }
     else {
	  probsz2 = mktensor(0);
	  totalsz2 = tensor_copy(totalsz);
	  pckdsz2 = tensor_copy(pckdsz);
     }

     totalsz_swap = tensor_copy_swapio(totalsz);
     pckdsz_swap = tensor_copy_swapio(pckdsz);
     totalsz2_swap = tensor_copy_swapio(totalsz2);
     pckdsz2_swap = tensor_copy_swapio(pckdsz2);
     probsz2_swap = tensor_copy_swapio(probsz2);

     /* confusion: the stride is the distance between complex elements
	when using interleaved format, but it is the distance between
	real elements when using split format */
     if (p->split) {
	  ii = p->ini ? (bench_real *) p->ini : ri + n2;
	  io = p->outi ? (bench_real *) p->outi : ro + n2;
	  totalscale = 1;
     } else {
	  ii = p->ini ? (bench_real *) p->ini : ri + 1;
	  io = p->outi ? (bench_real *) p->outi : ro + 1;
	  totalscale = 2;
     }

     if (p->sign < 0) { /* R2HC */
	  int N, vN, i;
	  cpyr(&c_re(in[0]), pckdsz, ri, totalsz);
	  after_problem_rcopy_from(p, ri);
	  doit(1, p);
	  after_problem_hccopy_to(p, ro, io);
	  if (k->k.recopy_input)
	       cpyr(ri, totalsz_swap, &c_re(in[0]), pckdsz_swap);
	  cpyhc2(ro, io, probsz2, totalsz2, totalscale,
		 &c_re(out[0]), &c_im(out[0]), pckdsz2);
	  N = tensor_sz(p->sz);
	  vN = tensor_sz(p->vecsz);
	  for (i = 0; i < vN; ++i)
	       mkhermitian(out + i*N, p->sz->rnk, p->sz->dims, 1);
     }
     else { /* HC2R */
	  icpyhc2(ri, ii, probsz2, totalsz2, totalscale,
		  &c_re(in[0]), &c_im(in[0]), pckdsz2);
	  after_problem_hccopy_from(p, ri, ii);
	  doit(1, p);
	  after_problem_rcopy_to(p, ro);
	  if (k->k.recopy_input)
	       cpyhc2(ri, ii, probsz2_swap, totalsz2_swap, totalscale,
		      &c_re(in[0]), &c_im(in[0]), pckdsz2_swap);
	  mkreal(out, tensor_sz(pckdsz));
	  cpyr(ro, totalsz, &c_re(out[0]), pckdsz);
     }

     tensor_destroy(totalsz);
     tensor_destroy(pckdsz);
     tensor_destroy(totalsz_swap);
     tensor_destroy(pckdsz_swap);
     tensor_destroy(probsz2);
     tensor_destroy(totalsz2);
     tensor_destroy(pckdsz2);
     tensor_destroy(probsz2_swap);
     tensor_destroy(totalsz2_swap);
     tensor_destroy(pckdsz2_swap);
}