org/objectweb/proactive/loadbalancing/util/JacobiWorker.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.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         // ORIENTATION
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         // ID
00050         private int id;
00051 
00052         //synchro
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         // neigbohroud
00061         private JacobiWorker up;
00062         private JacobiWorker down;
00063         private JacobiWorker left;
00064         private JacobiWorker right;     
00065         private int nbNeighbours;
00066         
00067         // current virtual boudaries
00068         private double[] vbUp;
00069         private double[] vbDown;
00070         private double[] vbLeft;
00071         private double[] vbRight;
00072         
00073         // upper left x y
00074         private int upperLeftX;
00075         private int upperLeftY; 
00076         
00077         // square size
00078         private int subMatrixSize;
00079         // global matrix size
00080         private int globalMatrixSize;
00081         // boundaries value
00082         private double boundaryValue;
00083         
00084         //sub matrix
00085         private double[][] subMatrix;
00086         private double[][] subTemp;
00087         
00088         // Profiling
00089         private long startTime;
00090         private long elapsedTime;
00091         
00093         // CONSTRUCTORS
00095         
00096         public JacobiWorker(){
00097                 //void
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         // INITIALIZATION
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                 //this.displayMatrix(true);
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         // COMPUTATION
00162         
00166         public void computeNewSubMatrix(){
00167         
00168             //TIMER
00169             if (this.startTime==0)
00170                 this.startTime = System.currentTimeMillis();
00171                 
00172             // send border values to neighbors 
00173             this.sendBoundaries();
00174 
00175                 // compute INSIDE the submatrix
00176             for (int line=this.upperLeftY+1 ; line < this.upperLeftY+this.subMatrixSize-1 ; line++){
00177                         this.computeInsideLine(line);
00178                 }
00179             
00180             // the first iteration
00181             if (!this.hasStarted){
00182                 this.hasStarted = true;
00183                 if (this.alreadyRcvBound){
00184                     // finish computation
00185                     this.computeBorderLine();                   
00186                     this.updateMatrix();
00187                     this.iteration++;
00188                     this.nbGetBoundRcvd=0;                      
00189                     //send ack to neighbors
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                 //      compute first and last line
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                  // compute fisrt and last column
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                 // swap matrix to avoid usless creation
00249                 double[][] tmp = this.subMatrix;
00250                 this.subMatrix = this.subTemp;  
00251                 this.subTemp = tmp;     
00252         }
00253         
00254         
00255         
00256         //virtual accessor for neighbour values
00257         // x an y in the global matrix
00258         
00259         private double getUpperValue(int x, int y){
00260                 if (y==0){ 
00261                         // must return boudarie value
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                                 // must return boudarie value
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                                 // must return boudarie value
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                                 // must return boudarie value
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         // SYNCHRONIZATION
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 //        System.out.println("[JACOBI] Worker " + this.id +  " receives endIter " + iter);
00345             this.nbEndIterRcvd++;
00346             if (this.nbEndIterRcvd==this.nbNeighbours){
00347                 if (this.iteration==this.maxIter){
00348                                 // end of the computation
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                                 // iter again
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 //        System.out.println("[JACOBI] Worker " + this.id +  " receives boundary " + iter + " from " + fromWho);
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         //System.out.println(idpa + " Worker " + id + " has received " + this.nbGetBoundRcvd);
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                         // TODO Auto-generated catch block
00395                         e.printStackTrace();
00396                     }
00397                 }
00398                 
00399                     // finish computation
00400                     this.computeBorderLine();                   
00401                     //System.out.print(""+iter+"-");
00402                     //this.displayMatrix(true);
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                     //send ack to neighbors
00410                     this.sendEndIter();
00411                 }
00412                 
00413                 
00414             }
00415             
00416         }
00417         
00418         
00419         
00420         
00421         private void sendEndIter(){
00422         UniqueID idpa = ProActive.getBodyOnThis().getID();
00423         //System.out.println(idpa + " Worker " + id + " send enIter " + this.iteration);
00424             //send ack to neighbors
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         

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