org/objectweb/proactive/ext/security/test/jacobi/SubMatrix.java

00001 /* 
00002  * ################################################################
00003  * 
00004  * ProActive: The Java(TM) library for Parallel, Distributed, 
00005  *            Concurrent computing with Security and Mobility
00006  * 
00007  * Copyright (C) 1997-2007 INRIA/University of Nice-Sophia Antipolis
00008  * Contact: proactive@objectweb.org
00009  * 
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Lesser General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2.1 of the License, or any later version.
00014  *  
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Lesser General Public License for more details.
00019  * 
00020  * You should have received a copy of the GNU Lesser General Public
00021  * License along with this library; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00023  * USA
00024  *  
00025  *  Initial developer(s):               The ProActive Team
00026  *                        http://www.inria.fr/oasis/ProActive/contacts.html
00027  *  Contributor(s): 
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         // north-west corner
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         // north-east corner
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         // north border
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         // south-west corner
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         // west border
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         // south-east corner
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         // south border
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         // east border
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         //System.out.println("["+this.name+"]  iterations : " + this.iterationsToStop);
00613         // compute the internal values
00614         this.internalCompute();
00615         // synchronization to be sure that all submatrix have exchanged borders
00616         ProSPMD.barrier(methodsToWaitFor);
00617         // compute the border values
00618         this.me.borderCompute();
00619         // send the borders to neighbors for the next loop
00620         this.sendBordersToNeighbors();
00621         // decrement the iteration counter
00622         this.iterationsToStop--;
00623         // continue or stop ?
00624         if ((this.iterationsToStop > 0)) { // && (this.minDiff > Jacobi.MINDIFF)) {
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             //                  if (this.minDiff < Jacobi.MINDIFF) {
00642             //                          System.out.println("[" + this.name + "] sent the \"end signal\"");
00643             //                          this.matrix.stop();
00644             //                  }
00645         }
00646     }
00647 
00651     public void loop_NeighborBarrier() {
00652         if (this.iterationsToStop == (Jacobi.ITERATIONS - 2)) {
00653             this.startTime = System.currentTimeMillis();
00654         }
00655 
00656         // System.out.println("iterations : " + this.iterationsToStop);
00657         // compute the internal values
00658         this.internalCompute();
00659         // synchronization to be sure that all submatrix have exchanged borders
00660         ProSPMD.barrier("SynchronizationWithNeighbors" + this.iterationsToStop,
00661             this.neighbors);
00662         // compute the border values
00663         this.me.borderCompute();
00664         // decrement the iteration counter
00665         this.iterationsToStop--;
00666         // send the borders to neighbors
00667         this.sendBordersToNeighbors();
00668         // continue or stop ?
00669         if ((this.iterationsToStop > 0)) { // && (this.minDiff > Jacobi.MINDIFF)) {
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             //System.exit(0);
00685             //                  if (this.minDiff < Jacobi.MINDIFF) {
00686             //                          System.out.println("[" + this.name + "] sent the \"end signal\"");
00687             //                          this.matrix.stop();
00688             //                  }
00689         }
00690     }
00691 
00695     public void loop_TotalBarrier() {
00696         if (this.iterationsToStop == (Jacobi.ITERATIONS - 2)) {
00697             this.startTime = System.currentTimeMillis();
00698         }
00699 
00700         // compute the internal values
00701         this.internalCompute();
00702         // synchronization to be sure that all submatrix have exchanged borders
00703         ProSPMD.barrier(
00704             "SynchronizationToBeSureThatAllSubmatrixHaveExchangedBorders" +
00705             this.iterationsToStop);
00706         // compute the border values
00707         this.me.borderCompute();
00708         // decrement the iteration counter
00709         this.iterationsToStop--;
00710         // send the borders to neighbors
00711         this.sendBordersToNeighbors();
00712         // continue or stop ?
00713         if ((this.iterationsToStop > 0)) { // && (this.minDiff > Jacobi.MINDIFF)) {
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             //  System.exit(0);
00729             //                  if (this.minDiff < Jacobi.MINDIFF) {
00730             //                          System.out.println("[" + this.name + "] sent the \"end signal\"");
00731             //                          this.matrix.stop();
00732             //                  }
00733         }
00734     }
00735 
00739     public void stop() {
00740         this.iterationsToStop = 0;
00741     }
00742 }

Generated on Mon Jan 22 15:16:11 2007 for ProActive by  doxygen 1.5.1