00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030  
00031 package org.objectweb.proactive.ext.security.test.jacobi;
00032 
00033 import org.objectweb.proactive.ProActive;
00034 import org.objectweb.proactive.core.group.Group;
00035 import org.objectweb.proactive.core.group.ProActiveGroup;
00036 import org.objectweb.proactive.core.group.spmd.ProSPMD;
00037 import org.objectweb.proactive.core.group.topology.Plan;
00038 import org.objectweb.proactive.core.mop.ClassNotReifiableException;
00039 import org.objectweb.proactive.core.mop.ConstructionOfReifiedObjectFailedException;
00040 
00041 
00045 public class SubMatrix {
00046 
00048     public static final int DEFAULT_WIDTH = 200;
00049 
00051     public static final int DEFAULT_HEIGHT = 200;
00052 
00054     private int iterationsToStop = Jacobi.ITERATIONS;
00055 
00057     private double minDiff = Jacobi.MINDIFF + 1;
00058 
00060     private String[] methodsToWaitFor = new String[4];
00061 
00063     private String name;
00064 
00066     private int width;
00067 
00069     private int height;
00070 
00072     private double[] current;
00073 
00075     private double[] old;
00076 
00078     private SubMatrix north;
00079 
00081     private SubMatrix south;
00082 
00084     private SubMatrix west;
00085 
00087     private SubMatrix east;
00088 
00090     private SubMatrix me;
00091 
00093     private SubMatrix matrix;
00094 
00096     private double[] northNeighborBorder;
00097 
00099     private double[] southNeighborBorder;
00100 
00102     private double[] westNeighborBorder;
00103 
00105     private double[] eastNeighborBorder;
00106     private SubMatrix neighbors;
00107     private long startTime;
00108     private long endTime;
00109     private long startComp;
00110     private long totalComp;
00111     private int nbComp = 0;
00112 
00114     public SubMatrix() {
00115         this(SubMatrix.DEFAULT_WIDTH, SubMatrix.DEFAULT_HEIGHT);
00116     }
00117 
00118     public SubMatrix(String name) {
00119         this();
00120         this.name = name;
00121     }
00122 
00128     public SubMatrix(int x, int y) {
00129         this.width = x;
00130         this.height = y;
00131         this.current = new double[x * y];
00132         this.old = new double[x * y];
00133         for (int i = 0; i < this.old.length; i++) {
00134             this.old[i] = Math.random() * 10000;
00135         }
00136     }
00137 
00144     public double get(int x, int y) {
00145         return this.old[(x * this.width) + y];
00146     }
00147 
00152     public void internalCompute() {
00153         this.nbComp++;
00154         this.startComp = System.currentTimeMillis();
00155         int index = this.width + 2;
00156         double current;
00157         double diff = Jacobi.MINDIFF + 1;
00158         double b;
00159         double n;
00160         double a;
00161         b = this.old[index - 1];
00162         n = this.old[index];
00163         a = this.old[index + 1];
00164         for (int y = 1; y < (this.height - 1); y++) {
00165             for (int x = 1; x < (this.width - 1); x++) {
00166                 current = (b + a + this.old[index - this.width] +
00167                     this.old[index + this.width]) / 4;
00168                 this.current[index] = current;
00169                 diff = Math.abs(current - n);
00170                 if (diff < this.minDiff) {
00171                     this.minDiff = diff;
00172                 }
00173                 b = n;
00174                 n = a;
00175                 a = this.old[index + 1];
00176                 index++;
00177             }
00178             index += 2;
00179         }
00180         this.totalComp += (System.currentTimeMillis() - this.startComp);
00181     }
00182 
00187     public void borderCompute() {
00188         this.startComp = System.currentTimeMillis();
00189 
00190         int index;
00191         double current;
00192         double diff = Jacobi.MINDIFF + 1;
00193 
00194         
00195         index = 0;
00196         current = (this.northNeighborBorder[0] + this.old[index + this.width] +
00197             this.westNeighborBorder[0] + this.old[index + 1]) / 4;
00198         this.current[index] = current;
00199         diff = Math.abs(current - this.old[index]);
00200         if (diff < this.minDiff) {
00201             this.minDiff = diff;
00202         }
00203 
00204         
00205         index = this.width - 1;
00206         current = (this.northNeighborBorder[this.width - 1] +
00207             this.old[index + this.width] + this.old[index - 1] +
00208             this.eastNeighborBorder[0]) / 4;
00209         this.current[index] = current;
00210         diff = Math.abs(current - this.old[index]);
00211         if (diff < this.minDiff) {
00212             this.minDiff = diff;
00213         }
00214 
00215         
00216         for (index = 1; index < (this.width - 1); index++) {
00217             current = (this.northNeighborBorder[index] +
00218                 this.old[this.width + index] + this.old[index - 1] +
00219                 this.old[index + 1]) / 4;
00220             this.current[index] = current;
00221             diff = Math.abs(current - this.old[index]);
00222             if (diff < this.minDiff) {
00223                 this.minDiff = diff;
00224             }
00225         }
00226 
00227         
00228         index = (this.width - 1) * this.height;
00229         current = (this.old[index - this.width] + this.southNeighborBorder[0] +
00230             this.westNeighborBorder[this.height - 1] + this.old[index + 1]) / 4;
00231         this.current[index] = current;
00232         diff = Math.abs(current - this.old[index]);
00233         if (diff < this.minDiff) {
00234             this.minDiff = diff;
00235         }
00236 
00237         
00238         index = this.width;
00239         for (int i = 1; i < (this.height - 1); i++) {
00240             current = (this.old[index - this.width] +
00241                 this.old[index + this.width] + this.westNeighborBorder[i] +
00242                 this.old[index + 1]) / 4;
00243             this.current[index] = current;
00244             diff = Math.abs(current - this.old[index]);
00245             if (diff < this.minDiff) {
00246                 this.minDiff = diff;
00247             }
00248             index += this.width;
00249         }
00250 
00251         
00252         index = (this.width * this.height) - 1;
00253         current = (this.old[index - this.width] +
00254             this.southNeighborBorder[this.width - 1] + this.old[index - 1] +
00255             this.eastNeighborBorder[this.height - 1]) / 4;
00256         this.current[index] = current;
00257         diff = Math.abs(current - this.old[index]);
00258         if (diff < this.minDiff) {
00259             this.minDiff = diff;
00260         }
00261 
00262         
00263         index = (this.width * (this.height - 1)) + 1;
00264         for (int i = 1; i < (this.width - 1); i++) {
00265             current = (this.old[index - this.width] +
00266                 this.southNeighborBorder[i] + this.old[index - 1] +
00267                 this.old[index + 1]) / 4;
00268             this.current[index] = current;
00269             diff = Math.abs(current - this.old[index]);
00270             if (diff < this.minDiff) {
00271                 this.minDiff = diff;
00272             }
00273             index++;
00274         }
00275 
00276         
00277         index = (this.width * 2) - 1;
00278         for (int i = 1; i < (this.height - 1); i++) {
00279             current = (this.old[index - this.width] +
00280                 this.old[index + this.width] + this.old[index - 1] +
00281                 this.eastNeighborBorder[i]) / 4;
00282             this.current[index] = current;
00283             diff = Math.abs(current - this.old[index]);
00284             if (diff < this.minDiff) {
00285                 this.minDiff = diff;
00286             }
00287             index += this.width;
00288         }
00289         this.totalComp += (System.currentTimeMillis() - this.startComp);
00290     }
00291 
00295     public void exchange() {
00296         double[] tmp = this.current;
00297         this.current = this.old;
00298         this.old = tmp;
00299     }
00300 
00304     public void buildNeighborhood_MethodBarrier() {
00305         this.matrix = (SubMatrix) ProSPMD.getSPMDGroup();
00306         Group allSubMatrix = ProActiveGroup.getGroup(this.matrix);
00307         Plan topology = null;
00308         try {
00309             topology = new Plan(allSubMatrix, Jacobi.WIDTH, Jacobi.HEIGHT);
00310         } catch (ConstructionOfReifiedObjectFailedException e) {
00311             System.err.println(
00312                 "** ConstructionOfReifiedObjectFailedException ** - Unable to build the plan topology");
00313             e.printStackTrace();
00314         }
00315 
00316         this.me = (SubMatrix) ProActive.getStubOnThis();
00317         this.north = (SubMatrix) topology.up(me);
00318         this.south = (SubMatrix) topology.down(me);
00319         this.west = (SubMatrix) topology.left(me);
00320         this.east = (SubMatrix) topology.right(me);
00321 
00322         int neighbors = 0;
00323         if (this.north == null) {
00324             this.northNeighborBorder = this.buildFakeBorder(this.width);
00325             this.methodsToWaitFor[0] = null;
00326         } else {
00327             this.north.setSouthBorder(this.buildNorthBorder());
00328             this.methodsToWaitFor[0] = "setNorthBorder";
00329             neighbors++;
00330         }
00331         if (this.south == null) {
00332             this.southNeighborBorder = this.buildFakeBorder(this.width);
00333             this.methodsToWaitFor[1] = null;
00334         } else {
00335             this.south.setNorthBorder(this.buildSouthBorder());
00336             this.methodsToWaitFor[1] = "setSouthBorder";
00337             neighbors++;
00338         }
00339         if (this.west == null) {
00340             this.westNeighborBorder = this.buildFakeBorder(this.height);
00341             this.methodsToWaitFor[2] = null;
00342         } else {
00343             this.west.setEastBorder(this.buildWestBorder());
00344             this.methodsToWaitFor[2] = "setWestBorder";
00345             neighbors++;
00346         }
00347         if (this.east == null) {
00348             this.eastNeighborBorder = this.buildFakeBorder(this.height);
00349             this.methodsToWaitFor[3] = null;
00350         } else {
00351             this.east.setWestBorder(this.buildEastBorder());
00352             this.methodsToWaitFor[3] = "setEastBorder";
00353             neighbors++;
00354         }
00355         if (neighbors < 4) {
00356             this.trimToSize(neighbors);
00357         }
00358     }
00359 
00363     public void buildNeighborhood_NeighborBarrier() {
00364         this.matrix = (SubMatrix) ProSPMD.getSPMDGroup();
00365         Group allSubMatrix = ProActiveGroup.getGroup(this.matrix);
00366         Plan topology = null;
00367         try {
00368             topology = new Plan(allSubMatrix, Jacobi.WIDTH, Jacobi.HEIGHT);
00369         } catch (ConstructionOfReifiedObjectFailedException e) {
00370             System.err.println(
00371                 "** ConstructionOfReifiedObjectFailedException ** - Unable to build the plan topology");
00372             e.printStackTrace();
00373         }
00374 
00375         this.me = (SubMatrix) ProActive.getStubOnThis();
00376         this.north = (SubMatrix) topology.up(me);
00377         this.south = (SubMatrix) topology.down(me);
00378         this.west = (SubMatrix) topology.left(me);
00379         this.east = (SubMatrix) topology.right(me);
00380 
00381         try {
00382             this.neighbors = (SubMatrix) ProActiveGroup.newGroup(SubMatrix.class.getName());
00383         } catch (ClassNotReifiableException e) {
00384             System.err.println(
00385                 "** ClassNotReifiableException ** - Unable to build the neighbors group");
00386             e.printStackTrace();
00387         } catch (ClassNotFoundException e) {
00388             System.err.println(
00389                 "** ClassNotFoundException ** - Unable to build the neighbors group");
00390             e.printStackTrace();
00391         }
00392         Group neighborsGroup = ProActiveGroup.getGroup(this.neighbors);
00393 
00394         if (this.north == null) {
00395             this.northNeighborBorder = this.buildFakeBorder(this.width);
00396         } else {
00397             neighborsGroup.add(this.north);
00398             this.north.setSouthBorder(this.buildNorthBorder());
00399         }
00400         if (this.south == null) {
00401             this.southNeighborBorder = this.buildFakeBorder(this.width);
00402         } else {
00403             neighborsGroup.add(this.south);
00404             this.south.setNorthBorder(this.buildSouthBorder());
00405         }
00406         if (this.west == null) {
00407             this.westNeighborBorder = this.buildFakeBorder(this.height);
00408         } else {
00409             neighborsGroup.add(this.west);
00410             this.west.setEastBorder(this.buildWestBorder());
00411         }
00412         if (this.east == null) {
00413             this.eastNeighborBorder = this.buildFakeBorder(this.height);
00414         } else {
00415             neighborsGroup.add(this.east);
00416             this.east.setWestBorder(this.buildEastBorder());
00417         }
00418         neighborsGroup.add(this.me);
00419     }
00420 
00424     public void buildNeighborhood_TotalBarrier() {
00425         this.matrix = (SubMatrix) ProSPMD.getSPMDGroup();
00426         Group allSubMatrix = ProActiveGroup.getGroup(this.matrix);
00427         Plan topology = null;
00428         try {
00429             topology = new Plan(allSubMatrix, Jacobi.WIDTH, Jacobi.HEIGHT);
00430         } catch (ConstructionOfReifiedObjectFailedException e) {
00431             System.err.println(
00432                 "** ConstructionOfReifiedObjectFailedException ** - Unable to build the plan topology");
00433             e.printStackTrace();
00434         }
00435 
00436         this.me = (SubMatrix) ProActive.getStubOnThis();
00437         this.north = (SubMatrix) topology.up(me);
00438         this.south = (SubMatrix) topology.down(me);
00439         this.west = (SubMatrix) topology.left(me);
00440         this.east = (SubMatrix) topology.right(me);
00441 
00442         if (this.north == null) {
00443             this.northNeighborBorder = this.buildFakeBorder(this.width);
00444         } else {
00445             this.north.setSouthBorder(this.buildNorthBorder());
00446         }
00447         if (this.south == null) {
00448             this.southNeighborBorder = this.buildFakeBorder(this.width);
00449         } else {
00450             this.south.setNorthBorder(this.buildSouthBorder());
00451         }
00452         if (this.west == null) {
00453             this.westNeighborBorder = this.buildFakeBorder(this.height);
00454         } else {
00455             this.west.setEastBorder(this.buildWestBorder());
00456         }
00457         if (this.east == null) {
00458             this.eastNeighborBorder = this.buildFakeBorder(this.height);
00459         } else {
00460             this.east.setWestBorder(this.buildEastBorder());
00461         }
00462     }
00463 
00469     private void trimToSize(int n) {
00470         String[] newArray = new String[n];
00471         int index = 0;
00472         for (int i = 0; i < this.methodsToWaitFor.length; i++) {
00473             if (this.methodsToWaitFor[i] != null) {
00474                 newArray[index++] = this.methodsToWaitFor[i];
00475             }
00476         }
00477         this.methodsToWaitFor = newArray;
00478     }
00479 
00486     private double[] buildFakeBorder(int size) {
00487         double[] line = new double[size];
00488         for (int i = 0; i < line.length; i++) {
00489             line[i] = Jacobi.DEFAULT_BORDER_VALUE;
00490         }
00491         return line;
00492     }
00493 
00498     private double[] buildNorthBorder() {
00499         double[] line = new double[this.width];
00500         for (int i = 0; i < this.width; i++) {
00501             line[i] = this.old[i];
00502         }
00503         return line;
00504     }
00505 
00510     private double[] buildSouthBorder() {
00511         double[] line = new double[this.width];
00512         int index = this.width * (this.height - 1);
00513         for (int i = 0; i < this.width; i++) {
00514             line[i] = this.old[index++];
00515         }
00516         return line;
00517     }
00518 
00523     private double[] buildWestBorder() {
00524         double[] line = new double[this.height];
00525         int index = 0;
00526         for (int i = 0; i < this.height; i++) {
00527             line[i] = this.old[index + this.width];
00528         }
00529         return line;
00530     }
00531 
00536     private double[] buildEastBorder() {
00537         double[] line = new double[this.height];
00538         int index = this.width;
00539         for (int i = 0; i < this.height; i++) {
00540             line[i] = this.old[index + this.width];
00541         }
00542         return line;
00543     }
00544 
00548     public void sendBordersToNeighbors() {
00549         if (this.north != null) {
00550             this.north.setSouthBorder(this.buildNorthBorder());
00551         }
00552         if (this.south != null) {
00553             this.south.setNorthBorder(this.buildSouthBorder());
00554         }
00555         if (this.west != null) {
00556             this.west.setEastBorder(this.buildWestBorder());
00557         }
00558         if (this.east != null) {
00559             this.east.setWestBorder(this.buildEastBorder());
00560         }
00561     }
00562 
00567     public void setNorthBorder(double[] border) {
00568         this.northNeighborBorder = border;
00569     }
00570 
00575     public void setSouthBorder(double[] border) {
00576         this.southNeighborBorder = border;
00577     }
00578 
00583     public void setWestBorder(double[] border) {
00584         this.westNeighborBorder = border;
00585     }
00586 
00591     public void setEastBorder(double[] border) {
00592         this.eastNeighborBorder = border;
00593     }
00594 
00598     public void compute() {
00599         this.buildNeighborhood_TotalBarrier();
00600         ProSPMD.barrier("InitDone");
00601         this.me.loop_TotalBarrier();
00602     }
00603 
00607     public void loop_MethodBarrier() {
00608         if (this.iterationsToStop == (Jacobi.ITERATIONS - 2)) {
00609             this.startTime = System.currentTimeMillis();
00610         }
00611 
00612         
00613         
00614         this.internalCompute();
00615         
00616         ProSPMD.barrier(methodsToWaitFor);
00617         
00618         this.me.borderCompute();
00619         
00620         this.sendBordersToNeighbors();
00621         
00622         this.iterationsToStop--;
00623         
00624         if ((this.iterationsToStop > 0)) { 
00625             this.me.exchange();
00626             this.me.loop_MethodBarrier();
00627         } else {
00628             this.endTime = System.currentTimeMillis() - this.startTime;
00629 
00630             System.out.println("\n\n[" + this.name +
00631                 "] Computation over (MethodBarrier) : " + "\n  WIDTH = " +
00632                 Jacobi.WIDTH + "\n  HEIGHT = " + Jacobi.HEIGHT +
00633                 "\n  ITERATIONS = " + Jacobi.ITERATIONS +
00634                 "\n  SUBMATRIX_WIDTH = " + SubMatrix.DEFAULT_WIDTH +
00635                 "\n  SUBMATRIX_HEIGHT = " + SubMatrix.DEFAULT_HEIGHT +
00636                 "\n  ELAPSED TIME = " + this.endTime + "\n  COMPUTE TIME = " +
00637                 this.totalComp + "\n  COMPUTE = " + this.nbComp + "\n\n");
00638 
00639             System.exit(0);
00640 
00641             
00642             
00643             
00644             
00645         }
00646     }
00647 
00651     public void loop_NeighborBarrier() {
00652         if (this.iterationsToStop == (Jacobi.ITERATIONS - 2)) {
00653             this.startTime = System.currentTimeMillis();
00654         }
00655 
00656         
00657         
00658         this.internalCompute();
00659         
00660         ProSPMD.barrier("SynchronizationWithNeighbors" + this.iterationsToStop,
00661             this.neighbors);
00662         
00663         this.me.borderCompute();
00664         
00665         this.iterationsToStop--;
00666         
00667         this.sendBordersToNeighbors();
00668         
00669         if ((this.iterationsToStop > 0)) { 
00670             this.me.exchange();
00671             this.me.loop_NeighborBarrier();
00672         } else {
00673             this.endTime = System.currentTimeMillis() - this.startTime;
00674 
00675             System.out.println("\n\n[" + this.name +
00676                 "] Computation over (NeighborBarrier) : " + "\n  WIDTH = " +
00677                 Jacobi.WIDTH + "\n  HEIGHT = " + Jacobi.HEIGHT +
00678                 "\n  ITERATIONS = " + Jacobi.ITERATIONS +
00679                 "\n  SUBMATRIX_WIDTH = " + SubMatrix.DEFAULT_WIDTH +
00680                 "\n  SUBMATRIX_HEIGHT = " + SubMatrix.DEFAULT_HEIGHT +
00681                 "\n  ELAPSED TIME = " + this.endTime + "\n  COMPUTE TIME = " +
00682                 this.totalComp + "\n  COMPUTE = " + this.nbComp + "\n\n");
00683 
00684             
00685             
00686             
00687             
00688             
00689         }
00690     }
00691 
00695     public void loop_TotalBarrier() {
00696         if (this.iterationsToStop == (Jacobi.ITERATIONS - 2)) {
00697             this.startTime = System.currentTimeMillis();
00698         }
00699 
00700         
00701         this.internalCompute();
00702         
00703         ProSPMD.barrier(
00704             "SynchronizationToBeSureThatAllSubmatrixHaveExchangedBorders" +
00705             this.iterationsToStop);
00706         
00707         this.me.borderCompute();
00708         
00709         this.iterationsToStop--;
00710         
00711         this.sendBordersToNeighbors();
00712         
00713         if ((this.iterationsToStop > 0)) { 
00714             this.me.exchange();
00715             this.me.loop_TotalBarrier();
00716         } else {
00717             this.endTime = System.currentTimeMillis() - this.startTime;
00718 
00719             System.out.println("\n\n[" + this.name +
00720                 "] Computation over (BigBarrier) : " + "\n  WIDTH = " +
00721                 Jacobi.WIDTH + "\n  HEIGHT = " + Jacobi.HEIGHT +
00722                 "\n  ITERATIONS = " + Jacobi.ITERATIONS +
00723                 "\n  SUBMATRIX_WIDTH = " + SubMatrix.DEFAULT_WIDTH +
00724                 "\n  SUBMATRIX_HEIGHT = " + SubMatrix.DEFAULT_HEIGHT +
00725                 "\n  ELAPSED TIME = " + this.endTime + "\n  COMPUTE TIME = " +
00726                 this.totalComp + "\n  COMPUTE = " + this.nbComp + "\n\n");
00727 
00728             
00729             
00730             
00731             
00732             
00733         }
00734     }
00735 
00739     public void stop() {
00740         this.iterationsToStop = 0;
00741     }
00742 }