--- /dev/null
+public class JGFInstrumentor{
+
+ private HashMap timers;
+ private HashMap data;
+
+ public JGFInstrumentor() {
+ timers = new HashMap();
+ data = new HashMap();
+ }
+ public static void addTimer (String name, String opname, int size){
+
+ if (timers.containsKey(name)) {
+ System.printString("JGFInstrumentor.addTimer: warning - timer " + name +
+ " already exists");
+ }
+ else {
+ timers.put(name, new JGFTimer(name,opname,size));
+ }
+
+ }
+
+ public static void startTimer(String name){
+ if (timers.containsKey(name)) {
+ ((JGFTimer) timers.get(name)).start();
+ }
+ else {
+ System.printString("JGFInstrumentor.startTimer: failed - timer " + name +
+ " does not exist");
+ }
+
+ }
+
+ public static void stopTimer(String name){
+ if (timers.containsKey(name)) {
+ ((JGFTimer) timers.get(name)).stop();
+ }
+ else {
+ System.printString("JGFInstrumentor.stopTimer: failed - timer " + name +
+ " does not exist");
+ }
+ }
+
+ public static void addOpsToTimer(String name, double count){
+ if (timers.containsKey(name)) {
+ ((JGFTimer) timers.get(name)).addops(count);
+ }
+ else {
+ System.printString("JGFInstrumentor.addOpsToTimer: failed - timer " + name +
+ " does not exist");
+ }
+ }
+
+ public static void printTimer(String name){
+ if (timers.containsKey(name)) {
+ ((JGFTimer) timers.get(name)).print();
+ }
+ else {
+ System.printString("JGFInstrumentor.printTimer: failed - timer " + name +
+ " does not exist");
+ }
+ }
+
+ public static void printHeader(int section, int size,int nthreads) {
+
+ String header = new String("");
+ String base = new String("Java Grande Forum Thread Benchmark Suite - Version 1.0 - Section ");
+
+ if(section == 1) {
+ header = base + "1";
+ } else if(section ==2) {
+ if(size == 0) {
+ header = base + "2 - Size A";
+ } else if(size == 1) {
+ header = base + "2 - Size B";
+ } else if(size == 2) {
+ header = base + "2 - Size C";
+ }
+ } else if(section == 3) {
+ if(size == 0) {
+ header = base + "3 - Size A";
+ } else if(size == 1) {
+ header = base + "3 - Size B";
+ }
+ } else {
+ System.printString("Error\n");
+ }
+
+ System.printString(header);
+
+ if (nthreads == 1) {
+ System.printString("Executing on " + nthreads + " thread");
+ }
+ else {
+ System.printString("Executing on " + nthreads + " threads");
+ }
+
+ System.printString("");
+
+ }
+
+ /*
+ public static void addTimeToTimer(String name, double added_time){
+ if (timers.containsKey(name)) {
+ ((JGFTimer) timers.get(name)).addtime(added_time);
+ }
+ else {
+ System.printString("JGFInstrumentor.addTimeToTimer: failed - timer " + name +
+ " does not exist");
+ }
+
+
+
+ }
+
+ public static double readTimer(String name){
+ double time;
+ if (timers.containsKey(name)) {
+ time = ((JGFTimer) timers.get(name)).time;
+ }
+ else {
+ System.printString("JGFInstrumentor.readTimer: failed - timer " + name +
+ " does not exist");
+ time = 0.0;
+ }
+ return time;
+ }
+
+ public static void resetTimer(String name){
+ if (timers.containsKey(name)) {
+ ((JGFTimer) timers.get(name)).reset();
+ }
+ else {
+ System.printString("JGFInstrumentor.resetTimer: failed - timer " + name +
+ " does not exist");
+ }
+ }
+
+
+ public static void printperfTimer(String name){
+ if (timers.containsKey(name)) {
+ ((JGFTimer) timers.get(name)).printperf();
+ }
+ else {
+ System.printString("JGFInstrumentor.printTimer: failed - timer " + name +
+ " does not exist");
+ }
+ }
+
+ public static void storeData(String name, Object obj){
+ data.put(name,obj);
+ }
+
+ public static void retrieveData(String name, Object obj){
+ obj = data.get(name);
+ }
+ public static void addTimer (String name){
+
+ if (timers.containsKey(name)) {
+ System.printString("JGFInstrumentor.addTimer: warning - timer " + name +
+ " already exists");
+ }
+ else {
+ timers.put(name, new JGFTimer(name));
+ }
+ }
+
+ public static void addTimer (String name, String opname){
+ if (timers.containsKey(name)) {
+ System.printString("JGFInstrumentor.addTimer: warning - timer " + name +
+ " already exists");
+ }
+ else {
+ timers.put(name, new JGFTimer(name,opname));
+ }
+
+ }
+ */
+}
--- /dev/null
+public class JGFSORBench extends SOR{
+
+ private int size;
+ private int[] datasize;
+ private final int JACOBI_NUM_ITER;
+ private final long RANDOM_SEED;
+ public int nthreads;
+ Random R;
+
+ public JGFSORBench() {
+ JACOBI_NUM_ITER = 100;
+ RANDOM_SEED = 10101010;
+ R = new Random(RANDOM_SEED);
+ }
+
+ public JGFSORBench(int nthreads){
+ this.nthreads = nthreads;
+ int datasizes[] = new int[3];
+ datasizes[0]= 1000;
+ datasizes[1]= 1500;
+ datasizes[2]= 2000;
+ }
+
+ public void JGFsetsize(int size){
+ this.size = size;
+ }
+
+ public void JGFinitialise(){
+
+ }
+
+ public void JGFkernel(){
+
+ double G[][] = RandomMatrix(datasizes[size], datasizes[size],R);
+
+ SORrun(1.25, G, JACOBI_NUM_ITER, nthreads);
+
+
+ }
+
+ public void JGFvalidate(){
+
+ double refval[] = new double[3];
+ refval[0] = 0.498574406322512;
+ refval[1] = 1.1234778980135105;
+ refval[2] = 1.9954895063582696;
+ double dev = Math.abs(Gtotal - refval[size]);
+ if (dev > 1.0e-12 ){
+ System.out.println("Validation failed");
+ System.out.println("Gtotal = " + Gtotal + " " + dev + " " + size);
+ }
+ }
+
+ public void JGFtidyup(){
+ //System.gc();
+ }
+
+ public void JGFrun(int size){
+
+
+ JGFInstrumentor.addTimer("Section2:SOR:Kernel", "Iterations",size);
+
+ JGFsetsize(size);
+ JGFinitialise();
+ JGFkernel();
+ JGFvalidate();
+ JGFtidyup();
+
+
+ JGFInstrumentor.addOpsToTimer("Section2:SOR:Kernel", (double) (JACOBI_NUM_ITER));
+
+ JGFInstrumentor.printTimer("Section2:SOR:Kernel");
+ }
+
+ private static double[][] RandomMatrix(int M, int N, java.util.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() * 1e-6;
+ }
+ return A;
+ }
+
+
+}
--- /dev/null
+public class JGFSORBenchSizeA{
+ public int nthreads;
+ public static void main(String argv[]){
+
+ if(argv.length != 0 ) {
+ nthreads = Integer.parseInt(argv[0]);
+ } else {
+ System.printString("The no of threads has not been specified, defaulting to 1");
+ System.printString(" ");
+ nthreads = 1;
+ }
+
+ JGFInstrumentor.printHeader(2,0,nthreads);
+ JGFSORBench sor = null;
+ atomic {
+ sor = global new JGFSORBench(nthreads);
+ sor.JGFrun(0);
+ }
+
+ }
+}
+
--- /dev/null
+public class JGFTimer {
+
+ public String name;
+ public String opname;
+ public double time;
+ public double opcount;
+ public long calls;
+ public int size;
+
+ private long start_time;
+ private boolean on;
+
+ public JGFTimer(String name, String opname){
+ this.name = name;
+ this.opname = opname;
+ this.size = -1;
+ reset();
+ }
+
+ public JGFTimer(String name, String opname, int size){
+ this.name = name;
+ this.opname = opname;
+ this.size = size;
+ reset();
+ }
+
+ /*
+ public JGFTimer(String name){
+ this(name,"");
+ }
+ */
+
+ public void start(){
+ if (on)
+ System.printString("Warning timer " + name + " was already turned on");
+ on = true;
+ start_time = System.currentTimeMillis();
+ }
+
+ public void stop(){
+ time += (double) (System.currentTimeMillis()-start_time) / 1000.;
+ if (!on) System.printString("Warning timer " + name + " wasn't turned on");
+ calls++;
+ on = false;
+ }
+
+ public void addops(double count){
+ opcount += count;
+ }
+
+ public void addtime(double added_time){
+ time += added_time;
+ }
+
+ public void reset(){
+ time = 0.0;
+ calls = 0;
+ opcount = 0;
+ on = false;
+ }
+
+ public double perf(){
+ return opcount / time;
+ }
+
+ public void longprint(){
+ System.printString("Timer Calls Time(s) Performance("+opname+"/s)");
+ System.printString(name + " " + calls + " " + time + " " + this.perf());
+ }
+
+ public void print(){
+ if (opname.equals("")) {
+ System.printString(name + " " + time + " (s)");
+ }
+ else {
+
+ if(size == 0) {
+ System.printString(name + ":SizeA" + "\t" + time + " (s) \t " + (float)this.perf() + "\t"
+ + " ("+opname+"/s)");
+ } else if(size == 1) {
+ System.printString(name + ":SizeB" + "\t" + time + " (s) \t " + (float)this.perf() + "\t"
+ + " ("+opname+"/s)");
+ } else if(size ==2) {
+ System.printString(name + ":SizeC" + "\t" + time + " (s) \t " + (float)this.perf() + "\t"
+ + " ("+opname+"/s)");
+ } else {
+ System.printString(name + "\t" + time + " (s) \t " + (float)this.perf() + "\t"
+ + " ("+opname+"/s)");
+ }
+
+ }
+ }
+
+
+ public void printperf(){
+
+ String name;
+ name = this.name;
+
+ // pad name to 40 characters
+ while ( name.length() < 40 )
+ name = name + " ";
+
+ System.printString(name + "\t" + (float)this.perf() + "\t"
+ + " ("+opname+"/s)");
+ }
+
+}
--- /dev/null
+public class SOR{
+ public double Gtotal;
+ public final int cachelinesize;
+ public long[][] sync;
+
+ public SOR() {
+ Gtotal = 0.0;
+ cachelinesize = 128;
+ sync = null;
+ }
+
+ public static final void SORrun(double omega, double G[][], int num_iterations)
+ {
+ int M = G.length;
+ int N = G[0].length;
+
+ double omega_over_four = omega * 0.25;
+ double one_minus_omega = 1.0 - omega;
+
+
+ // update interior points
+ //
+ int Mm1 = M-1;
+ int Nm1 = N-1;
+
+ SORRunner thobjects[] = new SORRunner[JGFSORBench.nthreads];
+ Thread th[] = new Thread[JGFSORBench.nthreads];
+ sync = init_sync(JGFSORBench.nthreads);
+
+ JGFInstrumentor.startTimer("Section2:SOR:Kernel");
+
+ for(int i=1;i<JGFSORBench.nthreads;i++) {
+ thobjects[i] = new SORRunner(i,omega,G,num_iterations,sync);
+ th[i] = new Thread(thobjects[i]);
+ th[i].start();
+ }
+
+ thobjects[0] = new SORRunner(0,omega,G,num_iterations,sync);
+ thobjects[0].run();
+
+
+ for(int i=1;i<JGFSORBench.nthreads;i++) {
+ th[i].join();
+ }
+
+
+
+ JGFInstrumentor.stopTimer("Section2:SOR:Kernel");
+
+ for (int i=1; i<Nm1; i++) {
+ for (int j=1; j<Nm1; j++) {
+ Gtotal += G[i][j];
+ }
+ }
+
+ }
+
+ private static long[][] init_sync(int nthreads) {
+ long sync[][] = new long [JGFSORBench.nthreads][cachelinesize];
+ for (int i = 0; i<JGFSORBench.nthreads; i++)
+ sync[i][0] = 0;
+ return sync;
+ }
+
+}
+
+
+class SORRunner extends Thread {
+
+ int id,num_iterations;
+ double[][] G;
+ double omega;
+ long[][] sync;
+
+ public SORRunner(int id, double omega, double G[][], int num_iterations,long[][] sync) {
+ this.id = id;
+ this.omega=omega;
+ this.G=G;
+ this.num_iterations=num_iterations;
+ this.sync=sync;
+ }
+
+ public void run() {
+
+ int M = G.length;
+ int N = G[0].length;
+
+ double omega_over_four = omega * 0.25;
+ double one_minus_omega = 1.0 - omega;
+
+ // update interior points
+ //
+ int Mm1 = M-1;
+ int Nm1 = N-1;
+
+
+ int ilow, iupper, slice, tslice, ttslice;
+
+ tslice = (Mm1) / 2;
+ ttslice = (tslice + JGFSORBench.nthreads-1)/JGFSORBench.nthreads;
+ slice = ttslice*2;
+
+ ilow=id*slice+1;
+ iupper = ((id+1)*slice)+1;
+ if (iupper > Mm1) iupper = Mm1+1;
+ if (id == (JGFSORBench.nthreads-1)) iupper = Mm1+1;
+
+ for (int p=0; p<2*num_iterations; p++) {
+ for (int i=ilow+(p%2); i<iupper; i=i+2) {
+
+
+ double [] Gi = G[i];
+ double [] Gim1 = G[i-1];
+
+
+ if(i == 1) {
+ double [] Gip1 = G[i+1];
+
+ for (int j=1; j<Nm1; j=j+2){
+ Gi[j] = omega_over_four * (Gim1[j] + Gip1[j] + Gi[j-1]
+ + Gi[j+1]) + one_minus_omega * Gi[j];
+
+ }
+ } else if (i == Mm1) {
+
+ double [] Gim2 = G[i-2];
+
+ for (int j=1; j<Nm1; j=j+2){
+ if((j+1) != Nm1) {
+ Gim1[j+1]=omega_over_four * (Gim2[j+1] + Gi[j+1] + Gim1[j]
+ + Gim1[j+2]) + one_minus_omega * Gim1[j+1];
+ }
+ }
+
+ } else {
+
+ double [] Gip1 = G[i+1];
+ double [] Gim2 = G[i-2];
+
+ for (int j=1; j<Nm1; j=j+2){
+ Gi[j] = omega_over_four * (Gim1[j] + Gip1[j] + Gi[j-1]
+ + Gi[j+1]) + one_minus_omega * Gi[j];
+
+ if((j+1) != Nm1) {
+ Gim1[j+1]=omega_over_four * (Gim2[j+1] + Gi[j+1] + Gim1[j]
+ + Gim1[j+2]) + one_minus_omega * Gim1[j+1];
+ }
+ }
+ }
+
+ }
+
+ // Signal this thread has done iteration
+ sync[id][0]++;
+
+ // Wait for neighbours;
+ if (id > 0) {
+ while (sync[id-1][0] < sync[id][0]) ;
+ }
+ if (id < JGFSORBench.nthreads -1) {
+ while (sync[id+1][0] < sync[id][0]) ;
+ }
+ }
+
+ }
+}
--- /dev/null
+MAINCLASS=JGFSORBenchSizeA
+SRC=${MAINCLASS}.java JGFInstrumentor.java JGFTimer.java JGFSORBench.java SOR.java Random.java
+FLAGS=-dsm -prefetch -nooptimize -debug -mainclass ${MAINCLASS} -o ${MAINCLASS}
+default:
+ ../../../buildscript ${FLAGS} ${SRC}