Start documenting the FFTW_MT test case

Start documenting the FFTW_MT test case

/* An example of using the multithreaded FFTW routines.

   For the simplest usage, all that the user needs to do is to "use FFTW_MT",
   and then proceed as follows. This automatically initializes the multithreaded
   version of FFTW, and sets plans to use here.maxTaskPar threads.

   If the user would like to change the number of threads used, plan_with_nthreads
   changes this.

   If the user does not want the module to auto-initialize, compile with
   autoInitFFTW_MT=false (-sautoInitFFTW_MT=false).

   // TODO : Should give compilation examples below.

*/

/* Note that there is no need to also use FFTW; that is automatically included.

   This test case just calls the routines in testFFTW; see documentation there.
*/
use FFTW_MT, testFFTW;

config var nthread = 2; // Number of threads

proc main() {
  plan_with_nthreads(nthread);
  testAllDims();
  cleanup_threads();
  cleanup();
}


Changed array type to scalar type to avoid seg fault while maintaining the
spirit of this test.

git-svn-id: 88467cb1fb04b8a755be7e1ee1026be4190196ef@12501 3a8e244f-b0f2-452b-bcba-4c88e055c3ca

def f(x) {
    if x == 0 {
        var y : int;
        return y;
    }
}

var x = f(10);

def f(x) {
    if x == 0 {
        var y : [1..10] int;
        return y;
    }
}

var x = f(10);


Start making the testing routine generic

use FFTW;

var err : real;

/* 1D tests go below */
param ndim : int = 1;
var dims : ndim*int(32);
var D : domain(ndim);
var A,B,goodA,goodB : [D] fftw_complex;
{
	var f = open("arr1d.dat",iomode.r).reader(kind=iokind.little);
	for ii in 1..ndim {
		f.read(dims(ii));
	}
	D = 0.. #dims(1);
	for (r,c) in goodA {
		f.read(r);
		c = 0;
	}
	for (r,c) in goodB {
		f.read(r); f.read(c);
	}
	f.close();
}
var fwd = plan_dft_1d(dims(1), A[0],B[0],FFTW_FORWARD,FFTW_ESTIMATE);
var rev = plan_dft_1d(dims(1), B[0],A[0],FFTW_BACKWARD,FFTW_ESTIMATE);
// Test forward and reverse transform
A = goodA;
execute(fwd);
err = max reduce abs(B-goodB);
writeln(err);
execute(rev);
A /= * reduce dims; // FFTW does an unnormalized transform
err = max reduce abs(A-goodA);
writeln(err);
destroy_plan(fwd);
destroy_plan(rev);

// Test in-place transforms
fwd = plan_dft_1d(dims(1),A[0],A[0],FFTW_FORWARD,FFTW_ESTIMATE);
rev = plan_dft_1d(dims(1),A[0],A[0],FFTW_BACKWARD,FFTW_ESTIMATE);
A = goodA;
// Test forward and reverse transform
A = goodA;
execute(fwd);
err = max reduce abs(A-goodB);
writeln(err);
execute(rev);
A /= * reduce dims; // FFTW does an unnormalized transform
err = max reduce abs(A-goodA);
writeln(err);
destroy_plan(fwd);
destroy_plan(rev);

// Testing r2c and c2r
var rD : domain(1) = 0.. #(2*(dims(1)/2 + 1)); // Padding to do in place transforms
var cD : domain(1) = 0.. #(dims(1)/2 + 1);
var rA : [rD] real(64);
var cB : [cD] fftw_complex;
fwd = plan_dft_r2c_1d(dims(1),rA[0],cB[0],FFTW_ESTIMATE);
rev = plan_dft_c2r_1d(dims(1),cB[0],rA[0],FFTW_ESTIMATE);
rA[D] = re(goodA);
execute(fwd);
err = max reduce abs(cB - goodB[cD]);
writeln(err);
execute(rev);
rA /= * reduce dims;
err = max reduce abs(rA[D] - re(goodA));
writeln(err);
destroy_plan(fwd);
destroy_plan(rev);

use FFTW;

var err : real;

/* 1D tests go below */
var D = 0.. #100;
var A,B,goodA,goodB : [D] fftw_complex;
{
	var f = open("arr1d.dat",iomode.r).reader(kind=iokind.little);
	var n : int(32);
	f.read(n);
	assert(n==100);
	for (r,c) in goodA {
		f.read(r);
		c = 0;
	}
	for (r,c) in goodB {
		f.read(r); f.read(c);
	}
	f.close();
}
var fwd = plan_dft_1d(100, A[0],B[0],FFTW_FORWARD,FFTW_ESTIMATE);
var rev = plan_dft_1d(100, B[0],A[0],FFTW_BACKWARD,FFTW_ESTIMATE);
// Test forward and reverse transform
A = goodA;
execute(fwd);
err = max reduce abs(B-goodB);
writeln(err);
execute(rev);
A /= 100; // FFTW does an unnormalized transform
err = max reduce abs(A-goodA);
writeln(err);
destroy_plan(fwd);
destroy_plan(rev);

// Test in-place transforms
fwd = plan_dft_1d(100,A[0],A[0],FFTW_FORWARD,FFTW_ESTIMATE);
rev = plan_dft_1d(100,A[0],A[0],FFTW_BACKWARD,FFTW_ESTIMATE);
A = goodA;
// Test forward and reverse transform
A = goodA;
execute(fwd);
err = max reduce abs(A-goodB);
writeln(err);
execute(rev);
A /= 100; // FFTW does an unnormalized transform
err = max reduce abs(A-goodA);
writeln(err);
destroy_plan(fwd);
destroy_plan(rev);

// Testing r2c and c2r
var rD : domain(1) = 0.. #(2*(100/2 + 1)); // Padding to do in place transforms
var cD : domain(1) = 0.. #(100/2 + 1);
var rA : [rD] real(64);
var cB : [cD] fftw_complex;
fwd = plan_dft_r2c_1d(100,rA[0],cB[0],FFTW_ESTIMATE);
rev = plan_dft_c2r_1d(100,cB[0],rA[0],FFTW_ESTIMATE);
rA[D] = re(goodA);
execute(fwd);
err = max reduce abs(cB - goodB[cD]);
writeln(err);
execute(rev);
rA /= 100;
err = max reduce abs(rA[D] - re(goodA));
writeln(err);
destroy_plan(fwd);
destroy_plan(rev);


cleaned up the syntax a bit, still a lot of optimization to do


Cleaning up conditional example.

Cleaning up conditional example.

git-svn-id: 88467cb1fb04b8a755be7e1ee1026be4190196ef@8292 3a8e244f-b0f2-452b-bcba-4c88e055c3ca

const D = [1..5];

var x, y: [D] real;
var alpha = 2.0;

[i in D] y(i) = 3.0*i;
scale(x, y, alpha);
writeln(x);

def scale(x, y, alpha: real) {
  if (x.numElements != y.numElements) then
    writeln("Error:  Inputs are not the same length.");
  else {
    if (alpha == 0.0) {
      x = 0.0;
    } else if (alpha == 1.0) {
      x = y;
    } else {
      x = alpha*y;
    }
  }
}

const D = [1..5];

var x, y: [D] real;
var alpha = 2.0;

[i in D] y(i) = 3.0*i;
scale(x, y, alpha);
writeln(x);

def scale(x, y, alpha: real) {
  if (x.numElements != y.numElements) {
    writeln("Error:  Input vectors are not the same length.");
    return;
  }
  if (alpha == 0.0) {
    x = 0.0;
  } else if (alpha == 1.0) {
    x = y;
  } else {
    x = alpha*y;
  }
}


Change atomictest to prevent range iterator overflow

[ok'd by brad]

quote from brad:

"Elliot says he doesn't think this is a particularly compelling example,
which I'd agree with.  We can just set n to be something smaller. "

config const n = 100000;
config const showRace = false;

proc test(param width, n_max:int ) {
  var n:uint(width) = max(uint(width));
  n -= 1; // don't go to max(type) since that will overflow the range iterator
  if n_max:uint(64) < n:uint(64) then n = n_max:uint(width);

  const mult:uint(width) = 10;
  const one:uint(width) = 1;
  const zero:uint(width) = 0;

  writeln("Testing " + width:string + " - bit atomics");

  if showRace {
    var x:uint(width);
    x = zero;
    forall i in one..n {
      x += one;
    }
    writeln("X is ", x," (vs. ", n, ")");
  }

  var aint:atomic uint(width);

  //aint.init(0);

  forall i in one..n {
    aint.fetchAdd(one);
  }

  assert(aint.read() == n);
  writeln("Increment OK");

  forall i in one..n {
    aint.fetchSub(one);
  }

  assert(aint.read() == zero);

  writeln("Decrement OK");

  forall i in one..n {
    aint.fetchAdd(mult);
  }

  assert(aint.read() == (mult*n):uint(width));
  writeln("Add OK");

  forall i in one..n {
    aint.fetchSub(mult);
  }

  assert(aint.read() == zero);
  writeln("Subtract OK");

  aint.compareExchangeStrong(zero, mult);

  assert(aint.read() == mult);

  writeln("Compare and Swap OK");

  //aint.destroy();
}

test(8,  n);
test(16, n);
test(32, n);
//test(64, n);

config const n = 100000;
config const showRace = false;

proc test(param width, n_max:int ) {
  var n:uint(width) = max(uint(width));
  if n_max:uint(64) < n:uint(64) then n = n_max:uint(width);

  const mult:uint(width) = 10;
  const one:uint(width) = 1;
  const zero:uint(width) = 0;

  writeln("Testing " + width:string + " - bit atomics");

  if showRace {
    var x:uint(width);
    x = zero;
    forall i in one..n {
      x += one;
    }
    writeln("X is ", x," (vs. ", n, ")");
  }

  var aint:atomic uint(width);

  //aint.init(0);

  forall i in one..n {
    aint.fetchAdd(one);
  }

  assert(aint.read() == n);
  writeln("Increment OK");

  forall i in one..n {
    aint.fetchSub(one);
  }

  assert(aint.read() == zero);

  writeln("Decrement OK");

  forall i in one..n {
    aint.fetchAdd(mult);
  }

  assert(aint.read() == (mult*n):uint(width));
  writeln("Add OK");

  forall i in one..n {
    aint.fetchSub(mult);
  }

  assert(aint.read() == zero);
  writeln("Subtract OK");

  aint.compareExchangeStrong(zero, mult);

  assert(aint.read() == mult);

  writeln("Compare and Swap OK");

  //aint.destroy();
}

test(8,  n);
test(16, n);
test(32, n);
//test(64, n);