summaryrefslogtreecommitdiff
path: root/src/jnt/scimark2/kernel.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jnt/scimark2/kernel.java')
-rw-r--r--src/jnt/scimark2/kernel.java268
1 files changed, 268 insertions, 0 deletions
diff --git a/src/jnt/scimark2/kernel.java b/src/jnt/scimark2/kernel.java
new file mode 100644
index 0000000..e886fa1
--- /dev/null
+++ b/src/jnt/scimark2/kernel.java
@@ -0,0 +1,268 @@
+package jnt.scimark2;
+
+public class kernel
+{
+ // each measurement returns approx Mflops
+
+
+ public static double measureFFT(int N, double mintime, Random R) {
+ // initialize FFT data as complex (N real/img pairs)
+
+ double x[] = RandomVector(2*N, R);
+ double oldx[] = NewVectorCopy(x);
+ long cycles = 1;
+ Stopwatch Q = new Stopwatch();
+
+ while(true) {
+ Q.start();
+ for (int i=0; i<cycles; i++) {
+ FFT.transform(x); // forward transform
+ FFT.inverse(x); // backward transform
+ }
+ Q.stop();
+ if (Q.read() >= mintime)
+ break;
+
+ cycles *= 2;
+ }
+ // approx Mflops
+
+ final double EPS = 1.0e-10;
+ if ( FFT.test(x) / N > EPS )
+ return 0.0;
+
+ return FFT.num_flops(N)*cycles/ Q.read() * 1.0e-6;
+ }
+
+
+ public static double measureSOR(int N, double min_time, Random R) {
+ double G[][] = RandomMatrix(N, N, R);
+
+ Stopwatch Q = new Stopwatch();
+ int cycles=1;
+ while(true) {
+ Q.start();
+ SOR.execute(1.25, G, cycles);
+ Q.stop();
+ if (Q.read() >= min_time) break;
+
+ cycles *= 2;
+ }
+ // approx Mflops
+ return SOR.num_flops(N, N, cycles) / Q.read() * 1.0e-6;
+ }
+
+ public static double measureMonteCarlo(double min_time, Random R) {
+ Stopwatch Q = new Stopwatch();
+
+ int cycles=1;
+ while(true) {
+ Q.start();
+ MonteCarlo.integrate(cycles);
+ Q.stop();
+ if (Q.read() >= min_time) break;
+
+ cycles *= 2;
+ }
+ // approx Mflops
+ return MonteCarlo.num_flops(cycles) / Q.read() * 1.0e-6;
+ }
+
+
+ public static double measureSparseMatmult(int N, int nz,
+ double min_time, Random R) {
+ // initialize vector multipliers and storage for result
+ // y = A*y;
+
+ double x[] = RandomVector(N, R);
+ double y[] = new double[N];
+
+ // initialize square sparse matrix
+ //
+ // for this test, we create a sparse matrix wit M/nz nonzeros
+ // per row, with spaced-out evenly between the begining of the
+ // row to the main diagonal. Thus, the resulting pattern looks
+ // like
+ // +-----------------+
+ // +* +
+ // +*** +
+ // +* * * +
+ // +** * * +
+ // +** * * +
+ // +* * * * +
+ // +* * * * +
+ // +* * * * +
+ // +-----------------+
+ //
+ // (as best reproducible with integer artihmetic)
+ // Note that the first nr rows will have elements past
+ // the diagonal.
+
+ int nr = nz/N; // average number of nonzeros per row
+ int anz = nr *N; // _actual_ number of nonzeros
+
+
+ double val[] = RandomVector(anz, R);
+ int col[] = new int[anz];
+ int row[] = new int[N+1];
+
+ row[0] = 0;
+ for (int r=0; r<N; r++) {
+ // initialize elements for row r
+
+ int rowr = row[r];
+ row[r+1] = rowr + nr;
+ int step = r/ nr;
+ if (step < 1) step = 1; // take at least unit steps
+
+
+ for (int i=0; i<nr; i++)
+ col[rowr+i] = i*step;
+
+ }
+
+ Stopwatch Q = new Stopwatch();
+
+ int cycles=1;
+ while(true) {
+ Q.start();
+ SparseCompRow.matmult(y, val, row, col, x, cycles);
+ Q.stop();
+ if (Q.read() >= min_time) break;
+
+ cycles *= 2;
+ }
+ // approx Mflops
+ return SparseCompRow.num_flops(N, nz, cycles) / Q.read() * 1.0e-6;
+ }
+
+
+ public static double measureLU(int N, double min_time, Random R) {
+ // compute approx Mlfops, or O if LU yields large errors
+
+ double A[][] = RandomMatrix(N, N, R);
+ double lu[][] = new double[N][N];
+ int pivot[] = new int[N];
+
+ Stopwatch Q = new Stopwatch();
+
+ int cycles=1;
+ while(true) {
+ Q.start();
+ for (int i=0; i<cycles; i++) {
+ CopyMatrix(lu, A);
+ LU.factor(lu, pivot);
+ }
+ Q.stop();
+ if (Q.read() >= min_time) break;
+
+ cycles *= 2;
+ }
+
+
+ // verify that LU is correct
+ double b[] = RandomVector(N, R);
+ double x[] = NewVectorCopy(b);
+
+ LU.solve(lu, pivot, x);
+
+ final double EPS = 1.0e-12;
+ if ( normabs(b, matvec(A,x)) / N > EPS )
+ return 0.0;
+
+
+ // else return approx Mflops
+ //
+ return LU.num_flops(N) * cycles / Q.read() * 1.0e-6;
+ }
+
+
+ private static double[] NewVectorCopy(double x[]) {
+ int N = x.length;
+
+ double y[] = new double[N];
+ for (int i=0; i<N; i++)
+ y[i] = x[i];
+
+ return y;
+ }
+
+ private static void CopyVector(double B[], double A[]) {
+ int N = A.length;
+
+ for (int i=0; i<N; i++)
+ B[i] = A[i];
+ }
+
+
+ private static double normabs(double x[], double y[]) {
+ int N = x.length;
+ double sum = 0.0;
+
+ for (int i=0; i<N; i++)
+ sum += Math.abs(x[i]-y[i]);
+
+ return sum;
+ }
+
+ private static void CopyMatrix(double B[][], double A[][]) {
+ int M = A.length;
+ int N = A[0].length;
+
+ int remainder = N & 3; // N mod 4;
+
+ for (int i=0; i<M; i++) {
+ double Bi[] = B[i];
+ double Ai[] = A[i];
+ for (int j=0; j<remainder; j++)
+ Bi[j] = Ai[j];
+ for (int j=remainder; j<N; j+=4) {
+ Bi[j] = Ai[j];
+ Bi[j+1] = Ai[j+1];
+ Bi[j+2] = Ai[j+2];
+ Bi[j+3] = Ai[j+3];
+ }
+ }
+ }
+
+ private static double[][] RandomMatrix(int M, int N, Random R) {
+ double A[][] = new double[M][N];
+
+ for (int i=0; i<N; i++)
+ for (int j=0; j<N; j++)
+ A[i][j] = R.nextDouble();
+ return A;
+ }
+
+ private static double[] RandomVector(int N, Random R) {
+ double A[] = new double[N];
+
+ for (int i=0; i<N; i++)
+ A[i] = R.nextDouble();
+ return A;
+ }
+
+ private static double[] matvec(double A[][], double x[]) {
+ int N = x.length;
+ double y[] = new double[N];
+
+ matvec(A, x, y);
+
+ return y;
+ }
+
+ private static void matvec(double A[][], double x[], double y[]) {
+ int M = A.length;
+ int N = A[0].length;
+
+ for (int i=0; i<M; i++) {
+ double sum = 0.0;
+ double Ai[] = A[i];
+ for (int j=0; j<N; j++)
+ sum += Ai[j] * x[j];
+
+ y[i] = sum;
+ }
+ }
+
+}