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.loadbalancing.util;
00032 import org.objectweb.proactive.ProActive;
00033 import org.objectweb.proactive.core.UniqueID;
00034
00035
00040 public class JacobiWorker implements java.io.Serializable{
00041
00042
00043 static final int UP = 1;
00044 static final int DOWN = 2;
00045 static final int LEFT = 3;
00046 static final int RIGHT = 4;
00047
00048
00049
00050 private int id;
00051
00052
00053 private int iteration;
00054 private int maxIter;
00055 private int nbGetBoundRcvd;
00056 private int nbEndIterRcvd;
00057 private boolean hasStarted;
00058 private boolean alreadyRcvBound;
00059
00060
00061 private JacobiWorker up;
00062 private JacobiWorker down;
00063 private JacobiWorker left;
00064 private JacobiWorker right;
00065 private int nbNeighbours;
00066
00067
00068 private double[] vbUp;
00069 private double[] vbDown;
00070 private double[] vbLeft;
00071 private double[] vbRight;
00072
00073
00074 private int upperLeftX;
00075 private int upperLeftY;
00076
00077
00078 private int subMatrixSize;
00079
00080 private int globalMatrixSize;
00081
00082 private double boundaryValue;
00083
00084
00085 private double[][] subMatrix;
00086 private double[][] subTemp;
00087
00088
00089 private long startTime;
00090 private long elapsedTime;
00091
00093
00095
00096 public JacobiWorker(){
00097
00098 }
00099
00100 public JacobiWorker(Integer id){
00101 this.id = id.intValue();
00102 this.boundaryValue = 0;
00103 this.iteration=0;
00104 this.nbGetBoundRcvd=0;
00105 this.maxIter = 100;
00106 this.startTime = 0;
00107 this.elapsedTime = 0;
00108 this.nbEndIterRcvd = 0;
00109 this.alreadyRcvBound = false;
00110 this.hasStarted = false;
00111 }
00112
00113 public JacobiWorker(Integer id, Double boundaryValue, Integer maxIter){
00114 this.id = id.intValue();
00115 this.boundaryValue = boundaryValue.doubleValue();
00116 this.iteration=0;
00117 this.nbGetBoundRcvd=0;
00118 this.maxIter = maxIter.intValue();
00119 this.startTime = 0;
00120 this.elapsedTime = 0;
00121 this.nbEndIterRcvd = 0;
00122 this.alreadyRcvBound = false;
00123 this.hasStarted = false;
00124 }
00125
00126
00128
00130
00131 public int setSubMatrix(int globalMatrixSize, int subMatrixSize, int upperLeftX, int upperLeftY, double[][] subMatrix){
00132 this.globalMatrixSize = globalMatrixSize;
00133 this.subMatrixSize = subMatrixSize;
00134 this.upperLeftX = upperLeftX;
00135 this.upperLeftY = upperLeftY;
00136 this.subMatrix = subMatrix;
00137 this.subTemp = new double[subMatrixSize][subMatrixSize];
00138 System.out.println("[JACOBI] worker " + id + " : submatrix intialized");
00139
00140 return 0;
00141 }
00142
00143 public int setNeighbours(JacobiWorker up, JacobiWorker down, JacobiWorker left, JacobiWorker right){
00144 this.up = up;
00145 this.down = down;
00146 this.left = left;
00147 this.right = right;
00148 this.nbNeighbours=0;
00149 this.nbNeighbours += up==null ? 0 : 1;
00150 this.nbNeighbours += down==null ? 0 : 1;
00151 this.nbNeighbours += left==null ? 0 : 1;
00152 this.nbNeighbours += right==null ? 0 : 1;
00153 System.out.println("[JACOBI] worker " + id + " : neighboroud initialized (" + this.nbNeighbours + " neighbours)");
00154 return 0;
00155 }
00156
00157
00158
00160
00162
00166 public void computeNewSubMatrix(){
00167
00168
00169 if (this.startTime==0)
00170 this.startTime = System.currentTimeMillis();
00171
00172
00173 this.sendBoundaries();
00174
00175
00176 for (int line=this.upperLeftY+1 ; line < this.upperLeftY+this.subMatrixSize-1 ; line++){
00177 this.computeInsideLine(line);
00178 }
00179
00180
00181 if (!this.hasStarted){
00182 this.hasStarted = true;
00183 if (this.alreadyRcvBound){
00184
00185 this.computeBorderLine();
00186 this.updateMatrix();
00187 this.iteration++;
00188 this.nbGetBoundRcvd=0;
00189
00190 this.sendEndIter();
00191 }
00192 }
00193
00194 }
00195
00196
00197
00203 public void computeInsideLine(int line){
00204 int i;
00205 for (i=this.upperLeftX+1 ; i<this.upperLeftX+this.subMatrixSize-1 ; i++){
00206 this.subTemp[i-this.upperLeftX][line-this.upperLeftY] = (this.getLeftValue(i,line)+this.getRightValue(i,line)+
00207 this.getUpperValue(i,line)+this.getDownerValue(i,line))*0.25;
00208 }
00209 }
00210
00211
00212
00216 public void computeBorderLine(){
00217
00218 for (int i=this.upperLeftX ; i<this.subMatrixSize+this.upperLeftX-1;i++){
00219 this.computeOnePoint(i,this.upperLeftY);
00220 this.computeOnePoint(i,this.subMatrixSize+this.upperLeftY-1);
00221 }
00222
00223 for (int j=this.upperLeftY;j<this.upperLeftY+this.subMatrixSize;j++){
00224 this.computeOnePoint(this.upperLeftX, j);
00225 this.computeOnePoint(this.upperLeftX+this.subMatrixSize-1, j);
00226 }
00227 }
00228
00229
00236 private void computeOnePoint(int i, int j){
00237 this.subTemp[i-this.upperLeftX][j-this.upperLeftY] = (this.getLeftValue(i,j)+this.getRightValue(i,j)+
00238 this.getUpperValue(i,j)+this.getDownerValue(i,j))*0.25;
00239 }
00240
00241
00242
00243
00247 private void updateMatrix(){
00248
00249 double[][] tmp = this.subMatrix;
00250 this.subMatrix = this.subTemp;
00251 this.subTemp = tmp;
00252 }
00253
00254
00255
00256
00257
00258
00259 private double getUpperValue(int x, int y){
00260 if (y==0){
00261
00262 return this.boundaryValue;
00263 } else if (y==this.upperLeftY){
00264 return this.vbUp[x-this.upperLeftX];
00265 } else {
00266 return subMatrix[x-this.upperLeftX][y-1-this.upperLeftY];
00267 }
00268
00269 }
00270
00271 private double getDownerValue(int x, int y){
00272 if (y==this.globalMatrixSize-1){
00273
00274 return this.boundaryValue;
00275 } else if (y==this.upperLeftY+this.subMatrixSize-1){
00276 return this.vbDown[x-this.upperLeftX];
00277 } else {
00278 return subMatrix[x-this.upperLeftX][y+1-this.upperLeftY];
00279 }
00280
00281 }
00282
00283 private double getLeftValue(int x, int y){
00284 if (x==0){
00285
00286 return this.boundaryValue;
00287 } else if (x==this.upperLeftX){
00288 return this.vbLeft[y-this.upperLeftY];
00289 } else {
00290 return subMatrix[x-1-this.upperLeftX][y-this.upperLeftY];
00291 }
00292
00293 }
00294 private double getRightValue(int x, int y){
00295 if (x==this.globalMatrixSize-1){
00296
00297 return this.boundaryValue;
00298 } else if (x==this.upperLeftX+this.subMatrixSize-1){
00299 return this.vbRight[y-this.upperLeftY];
00300 } else {
00301 return subMatrix[x+1-this.upperLeftX][y-this.upperLeftY];
00302 }
00303 }
00304
00305
00306
00308
00310
00316 public void sendBoundaries(){
00317 if (this.up!=null){
00318 double [] upline = new double[this.subMatrixSize];
00319 for (int i=0;i<this.subMatrixSize;i++){
00320 upline[i] = this.subMatrix[i][0];
00321 }
00322 this.up.receiveBoundary(JacobiWorker.DOWN,upline, this.iteration);
00323 }
00324 if (this.down!=null){
00325 double [] downline = new double[this.subMatrixSize];
00326 for (int i=0;i<this.subMatrixSize;i++){
00327 downline[i] = this.subMatrix[i][this.subMatrixSize-1];
00328 }
00329 this.down.receiveBoundary(JacobiWorker.UP,downline, this.iteration);
00330 }
00331 if (this.left!=null){
00332 this.left.receiveBoundary(JacobiWorker.RIGHT,this.subMatrix[0], this.iteration);
00333 }
00334 if (this.right!=null){
00335 this.right.receiveBoundary(JacobiWorker.LEFT,this.subMatrix[this.subMatrixSize-1], this.iteration);
00336 }
00337
00338
00339 }
00340
00341
00342
00343 public void endIter(int iter){
00344
00345 this.nbEndIterRcvd++;
00346 if (this.nbEndIterRcvd==this.nbNeighbours){
00347 if (this.iteration==this.maxIter){
00348
00349 this.elapsedTime = System.currentTimeMillis() - this.startTime;
00350 System.out.println("[JACOBI] Worker " + this.id + " : computation ended after " + this.iteration + "(" + this.subMatrix[10][10] + ").");
00351 System.out.println("[JACOBI] Time elapsed for Worker " + this.id + " : " + this.elapsedTime);
00352 return;
00353 }else{
00354
00355 this.nbEndIterRcvd=0;
00356 this.computeNewSubMatrix();
00357 }
00358 }
00359 }
00360
00361
00362
00363 public void receiveBoundary(int fromWho, double[] boundary, int iter){
00364
00365
00366
00367 this.nbGetBoundRcvd++;
00368 switch (fromWho) {
00369 case JacobiWorker.UP :
00370 this.vbUp = boundary;
00371 break;
00372 case JacobiWorker.DOWN :
00373 this.vbDown = boundary;
00374 break;
00375 case JacobiWorker.LEFT :
00376 this.vbLeft = boundary;
00377 break;
00378 case JacobiWorker.RIGHT :
00379 this.vbRight = boundary;
00380 break;
00381 }
00382 UniqueID idpa = ProActive.getBodyOnThis().getID();
00383
00384 if (this.nbGetBoundRcvd==this.nbNeighbours){
00385
00386 if (!this.hasStarted){
00387 this.alreadyRcvBound=true;
00388 }else{
00389 if (iter!=this.iteration){
00390 System.err.println(ProActive.getBodyOnThis().getID() + " ITER ERROR : local = "+ this.iteration + " ; remote = " + iter + "\n\n\n\n\n\n" );
00391 try {
00392 Thread.sleep(100000);
00393 } catch (InterruptedException e) {
00394
00395 e.printStackTrace();
00396 }
00397 }
00398
00399
00400 this.computeBorderLine();
00401
00402
00403 this.updateMatrix();
00404 this.iteration++;
00405 if (iteration%50==0){
00406 System.out.println("Worker " + id + " : " + iteration + " (" + this.subMatrix[10][10] + ") in " + (System.currentTimeMillis() - this.startTime) + " ms");
00407 }
00408 this.nbGetBoundRcvd=0;
00409
00410 this.sendEndIter();
00411 }
00412
00413
00414 }
00415
00416 }
00417
00418
00419
00420
00421 private void sendEndIter(){
00422 UniqueID idpa = ProActive.getBodyOnThis().getID();
00423
00424
00425 if (this.up!=null){
00426 this.up.endIter(this.iteration);
00427 }
00428 if (this.down!=null){
00429 this.down.endIter(this.iteration);
00430 }
00431 if (this.left!=null){
00432 this.left.endIter(this.iteration);
00433 }
00434 if (this.right!=null){
00435 this.right.endIter(this.iteration);
00436 }
00437 }
00438
00439
00440
00441
00442
00447 private void displayMatrix(boolean inDouble){
00448 System.out.println("[JACOBI] Submatrix for worker " + this.id);
00449 if (inDouble){
00450 for (int i=0;i<this.subMatrixSize;i++){
00451 for (int j=0;j<this.subMatrixSize;j++){
00452 System.out.print(" "+this.subMatrix[i][j]);
00453 }
00454 System.out.println("");
00455 }
00456 }else{
00457 for (int i=0;i<this.subMatrixSize;i++){
00458 for (int j=0;j<this.subMatrixSize;j++){
00459 System.out.print(" "+(int)(this.subMatrix[i][j]));
00460 }
00461 System.out.println("");
00462 }
00463 }
00464 }
00465
00466
00470 private void displayLine(int line){
00471 System.out.println("[JACOBI] Line " + line + " for worker " + this.id);
00472 for (int j=0;j<this.subMatrixSize;j++){
00473 System.out.print(" "+this.subMatrix[line][j]);
00474 }
00475 System.out.println("");
00476 }
00477
00482 private void printDebug(){
00483 System.out.println("[JACOBI] Worker " + id + " : ");
00484 System.out.println(" * upperLeftX = " + this.upperLeftX);
00485 System.out.println(" * upperLeftY = " + this.upperLeftY);
00486 System.out.println(" * nbNeighbours = " + this.nbNeighbours);
00487 }
00488
00489
00490 public String toString(){
00491 return " Worker " + id + " at iter " + this.iteration;
00492 }
00493
00494 }
00495
00496