00001 #ifndef __AMR_H
00002 #define __AMR_H
00003 
00004 
00005 #include <stdio.h>
00006 #include <stdlib.h>
00007 #include <string.h>
00008 #include "charm++.h"
00009 #include "bitvec.h"
00010 #include "amr.decl.h"
00011 #include "statcoll.h"
00012 #include "fifo.h"
00013 #include <math.h>
00014 
00015 #define NEG_X 0
00016 #define POS_X 1
00017 #define NEG_Y 2
00018 #define POS_Y 3
00019 #define NEG_Z 4
00020 #define POS_Z 5
00021 #define DEBUGA(x) 
00022 #define DEBUGR(x) 
00023 #define DEBUGT(x) 
00024 #define DEBUGS(x) 
00025 #define DEBUGRC(x) 
00026 #define DEBUGJ(x) 
00027 #define DEBUG(x) 
00028 #define DEBUGN(x) 
00029 
00030 class NeighborMsg;
00031 class ChildInitMsg;
00032 
00033 class AmrUserData:public PUP::able {
00034   int dimension;
00035  public:
00036   BitVec myIndex;
00037   AmrUserData(){}
00038   AmrUserData(CkMigrateMessage *m): PUP::able(m){}
00039   virtual void init()
00040     {}
00041   static AmrUserData *createDataWrapper(BitVec idx, int dim) {
00042     
00043     AmrUserData* ptr = createData();
00044     ptr->myIndex = idx;
00045     ptr->dimension = dim;
00046     ptr->init();
00047     return ptr;
00048   }
00049   static AmrUserData *createDataWrapper(BitVec idx, int dim, void *data, int dataSize)
00050     {
00051       
00052       AmrUserData* ptr = createData(data, dataSize);
00053       ptr->myIndex = idx;
00054       ptr->dimension = dim;
00055       ptr->init();
00056       return ptr;
00057     }
00058 
00059   static AmrUserData *createData();
00060   static AmrUserData *createData(void *data, int dataSize);
00061   
00062   static void deleteNborData(void * data);
00063   static void deleteChildData(void * data);
00064   
00065   NeighborMsg **fragment(NeighborMsg* msg,int nMsg);
00066   void combineAndStore(NeighborMsg *msg1,NeighborMsg *msg2);
00067 
00068   void combineAndStore(NeighborMsg* msg1, NeighborMsg *msg2,NeighborMsg *msg3, NeighborMsg *msg4);
00069   void store(NeighborMsg *msg);
00070  
00071   bool isOnNegXBoundary() {
00072     return (myIndex.vec[0] == 0)? true:false;
00073   }
00074   bool isOnPosXBoundary() {
00075     int i = myIndex.numbits/dimension;
00076     int mask=0, mult = 1;
00077     for(int k=i; k>0; k--) {
00078       mask += mult;
00079       mult = mult << 1;
00080     }
00081     return ((myIndex.vec[0] & mask) ==mask)? true:false;
00082   }
00083 
00084   bool isOnNegYBoundary() {
00085     return (myIndex.vec[1] == 0)? true:false;
00086   }
00087 
00088   bool isOnPosYBoundary() {
00089     int i = myIndex.numbits/dimension;
00090     int mask=0, mult = 1;
00091     for(int k=i; k>0; k--) {
00092       mask += mult;
00093       mult = mult << 1;
00094     }
00095     return ((myIndex.vec[1] & mask) ==mask)? true:false;
00096   }
00097 
00098   bool isOnNegZBoundary() {
00099     return (myIndex.vec[2] == 0)? true:false;
00100   }
00101 
00102   bool isOnPosZBoundary() {
00103     int i = myIndex.numbits/dimension;
00104     int mask=0, mult = 1;
00105     for(int k=i; k>0; k--) {
00106       mask += mult;
00107       mult = mult << 1;
00108     }
00109     return ((myIndex.vec[2] & mask) ==mask)? true:false;
00110   }
00111 
00112   virtual void ** fragmentNborData(void* data, int *sizePtr){ return NULL;}
00113   virtual void ** getNborMsgArray(int* sizePtr){return NULL;}
00114   
00115   virtual void store(void* data , int dataSize, int neighborSide){}
00116   virtual void combineAndStore(void **dataArray, int dataSize,int neighborSide){}
00117   virtual bool refineCriterion(void){return false;}
00118   
00119   
00120   virtual void **fragmentForRefine(int *sizePtr){ return NULL;}
00121   virtual void doComputation(void){}
00122   virtual void pup(PUP::er &p) {
00123     PUP::able::pup(p);
00124     myIndex.pup(p);
00125     p(dimension);
00126   }
00127   PUPable_decl(AmrUserData);
00128   virtual ~AmrUserData(){}  
00129 };
00130 
00131 class NeighborMsg : public CMessage_NeighborMsg 
00132 {
00133  public:
00134   int which_neighbor;
00135   int run_until;
00136   int numbits;
00137   int dataSize;
00138   BitVec nborIdx;
00139   void *data;
00140   NeighborMsg() {
00141     data = NULL;
00142   }
00143   static void* pack(NeighborMsg *msg);
00144   static NeighborMsg* unpack(void *inbuf);
00145   void pup(PUP::er &p);
00146 
00147 
00148   ~NeighborMsg(){ 
00149     AmrUserData::deleteNborData(data);
00150   }
00151 };
00152 
00153 class ChildInitMsg : public CMessage_ChildInitMsg 
00154 {
00155  public:
00156   int run_until;
00157   int num_neighbors;
00158   int synchstep;
00159   int dataSize;
00160   void *data;
00161   static void* pack(ChildInitMsg *msg);
00162   static ChildInitMsg* unpack(void *inbuf);
00163  
00164   ~ChildInitMsg() { 
00165     AmrUserData::deleteChildData(data);
00166   }
00167 };
00168 
00169 class _DMsg : public CMessage__DMsg {
00170  public:
00171   BitVec sender;
00172   int from;
00173   _DMsg(){}
00174   _DMsg(BitVec sendVec, int pos){
00175     sender = sendVec;
00176     from = pos;
00177   }
00178 };
00179 
00180 class _RefineChkMsg : public CMessage__RefineChkMsg {
00181  public:
00182   BitVec index;
00183   int run_until;
00184   _RefineChkMsg() {}
00185   _RefineChkMsg(BitVec idx,int run) {
00186     index = idx;
00187     run_until = run;
00188   }
00189 };
00190 
00191 class _RefineMsg : public CMessage__RefineMsg {
00192  public:
00193   
00194   
00195   int autorefine; 
00196   
00197   
00198   BitVec index;
00199 
00200   _RefineMsg() { autorefine = 0;}
00201   _RefineMsg(int reftype) {
00202     autorefine = reftype;
00203     if(autorefine == 1) {
00204       CkError("Automatic refinement message without a return address\n");
00205     }
00206   }
00207   _RefineMsg(int reftype,BitVec idx) {
00208     index = idx;
00209     autorefine = reftype;
00210   }
00211 };
00212 
00213 
00214 class _RedMsg : public CMessage__RedMsg {
00215  public:
00216   _RedMsg() { type  = 0;}
00217   _RedMsg(int x) {type = x;}
00218   int type;
00219   
00220 
00221 
00222 
00223 };
00224 
00225 class _ArrInitMsg : public CMessage__ArrInitMsg 
00226 {
00227  public:
00228   BitVec parent; 
00229   char type; 
00230              
00231   int interval;
00232   int depth; 
00233   int totalIterations; 
00234   CkChareID coordHandle;
00235   bool statCollection;
00236   
00237   CkGroupID gid;
00238   
00239 };
00240 
00241 class StartUpMsg :public CMessage_StartUpMsg
00242 {
00243  public:
00244   int depth;
00245   int synchInterval;
00246   int dimension;
00247   int totalIterations;
00248   int statCollection;
00249   StartUpMsg () {
00250     depth = 2;
00251     synchInterval = 30;
00252     dimension = 2;
00253     statCollection = 1;
00254   }
00255   StartUpMsg(int dep,int synchInt, int dim,int totIter) {
00256     depth = dep;
00257     synchInterval = synchInt;
00258     dimension = dim;
00259     totalIterations = totIter;
00260     statCollection = 0;
00261   }
00262 
00263   StartUpMsg(int dep,int synchInt, int dim,int totIter, bool statcoll) {
00264     depth = dep;
00265     synchInterval = synchInt;
00266     dimension = dim;
00267     totalIterations = totIter;
00268     statCollection = statcoll;
00269   }
00270   
00271 };
00272 
00273 class AmrCoordinator: public Chare {
00274   private:
00275   CProxy_Cell arrayProxy;
00276   int synchInterval;
00277   int depth;
00278   int dimension;
00279   int totalIterations;
00280   CkChareID myHandle;
00281 
00282   int statCollection;
00283   CkGroupID gid;
00284 
00285   int leaves;
00286   int refine;
00287   int arefine;
00288   int migrations;
00289   int statMsgs;
00290 
00291   double startTime;
00292   int phase; 
00293   
00294   int phaseStep;
00295  public:
00296   
00297   AmrCoordinator(){}
00298   AmrCoordinator(_DMsg* msg);
00299   AmrCoordinator(StartUpMsg *msg);
00300   AmrCoordinator(CkMigrateMessage *msg){}
00301 
00302   void synchronise(_RedMsg *msg);
00303   void create_tree();
00304   void reportStats(_StatCollMsg *m);
00305   void resetClock();
00306 };
00307 
00308 
00309 
00310 
00311 class Cell : public ArrayElementT <BitVec> {
00312  protected:
00313   int dimension;
00314   AmrUserData *userData;
00315   CProxy_Cell arrayProxy; 
00316   char type;     
00317   
00318   BitVec parent; 
00319   
00320   
00321   
00322   BitVec **children;
00323 
00324   BitVec myIndex; 
00325   
00326   
00327   
00328   int num_neighbors, neighbors_reported;
00329   
00330   int run_until; 
00331   int run_done;  
00332   
00333   int *neighbors;
00334   
00335   
00336   
00337   int *nborRecvMsgCount;
00338   NeighborMsg ***nborRecvMsgBuff;
00339   
00340   FIFO_QUEUE *msg_queue;
00341   FIFO_QUEUE *temp_queue;
00342   char* start_ptr;
00343   int msg_count;
00344   
00345   
00346   int refined;
00347   int autorefine;
00348   BitVec retidx;
00349 
00350   
00351   int synchleavrep;
00352   int synchinterval,synchstep;
00353   int justRefined;
00354   
00355   
00356   CkChareID coordHandle;
00357   
00358   int statCollection;
00359   
00360   CkGroupID gid;
00361   
00362   void init_cell(_ArrInitMsg *msg);
00363   void treeSetup(_ArrInitMsg *msg);
00364   
00365 
00366 
00367 
00368 
00369 
00370   virtual void reg_nbor_msg(int neighbor_side, NeighborMsg *msg){}
00371   void check_queue(void);
00372   
00373   friend void FIFO_EnQueue(FIFO_QUEUE *queue, void *elt);
00374   friend int FIFO_Empty(FIFO_QUEUE *);
00375   friend void FIFO_DeQueue(FIFO_QUEUE *queue, void **element);
00376   friend void FIFO_Destroy(FIFO_QUEUE *queue);
00377   friend int FIFO_Fill(FIFO_QUEUE *queue);
00378   
00379   int sendInDimension(int dim,int side,NeighborMsg* msg);
00380   int sendInDimension(int dim,int side);
00381   int powerOfTwo(int);
00382   
00383  public:
00384   Cell(){}
00385   
00386   Cell(CkMigrateMessage *msg) {}
00387   
00388   void refine(_RefineMsg* msg);
00389   void change_to_leaf(ChildInitMsg* msg);
00390   void neighbor_data(NeighborMsg *msg);
00391 
00392   void cpyNborMsg(NeighborMsg* dest,NeighborMsg * src);  
00393   void refine_confirmed(_DMsg *msg);
00394   void resume(_DMsg *msg);
00395   void synchronise(_RedMsg *msg);
00396   void refineExec(_DMsg *msg);
00397   void checkRefine(_RefineChkMsg* msg);
00398   void refineReady(BitVec retidx,int pos);
00399   virtual void create_children(_ArrInitMsg** cmsg){}
00400   virtual void doIterations(void);
00401   virtual void forwardSplitMsg(NeighborMsg *msg ,int neighbor_side) {}
00402   virtual void pup(PUP::er &p);
00403   virtual void ResumeFromSync() {
00404     
00405     
00406     synchstep += synchinterval;
00407     if (type == 'l') {
00408       CkArrayIndexBitVec index(parent);
00409       arrayProxy[index].synchronise(new _RedMsg(1));
00410       DEBUGN(("Synchronising: x %d y %d z %d bits %d\n", myIndex.vec[0],
00411           myIndex.vec[1],myIndex.vec[2], myIndex.numbits));
00412     }
00413   }
00414   
00415   void goToAtSync(_DMsg* msg) {
00416     delete msg;
00417     ArrayElement::AtSync();
00418   }
00419 
00420   virtual ~Cell(){
00421     if(type == 'l') {
00422       if(userData)
00423     delete userData;
00424     }
00425     
00426     for(int i=0;i<dimension;i++)
00427       delete[] children[i];
00428     delete[] children;
00429     
00430     delete[] neighbors;
00431     
00432     delete[] nborRecvMsgCount;
00433     int size = powerOfTwo(dimension-1);
00434     
00435     if(nborRecvMsgBuff) {
00436       for(int i=0; i<2*dimension; i++) {
00437     for(int j=0; j<size; j++) {
00438       
00439 
00440     }
00441     delete[] nborRecvMsgBuff[i];
00442       }
00443       delete[] nborRecvMsgBuff;
00444     }
00445     
00446     if(msg_queue) {
00447       while(!FIFO_Empty(msg_queue)) {
00448     NeighborMsg* tempMsg;
00449     FIFO_DeQueue(msg_queue,(void**) &tempMsg);
00450     delete tempMsg;
00451       }
00452       FIFO_Destroy(msg_queue);
00453     }
00454   } 
00455 };
00456 
00457 class Cell2D: public Cell {
00458  private:
00459   void frag_msg(NeighborMsg *,int,int,int,int);
00460 
00461  public:
00462   Cell2D() {}
00463   Cell2D(_ArrInitMsg *);
00464   Cell2D(CkMigrateMessage *msg) {}
00465   void reg_nbor_msg(int neighbor_side, NeighborMsg *msg);
00466   virtual void create_children(_ArrInitMsg** cmsg);
00467   virtual void forwardSplitMsg(NeighborMsg *msg ,int neighbor_side);
00468   
00469   virtual void pup(PUP::er &p){
00470     Cell::pup(p);
00471     if (p.isUnpacking()){
00472       CProxy_Cell2D aProxy(thisArrayID);
00473       arrayProxy = *(CProxy_Cell*)&aProxy;
00474     } 
00475   }
00476 };
00477 
00478 class Cell1D: public Cell {
00479  private:
00480   
00481  public:
00482   Cell1D() {}
00483   Cell1D(_ArrInitMsg *);
00484   Cell1D(CkMigrateMessage *msg) {}
00485   
00486   void reg_nbor_msg(int neighbor_side, NeighborMsg *msg);
00487   virtual void create_children(_ArrInitMsg** cmsg);
00488   virtual void forwardSplitMsg(NeighborMsg *msg ,int neighbor_side);
00489   virtual void pup(PUP::er &p){
00490     Cell::pup(p);
00491     if (p.isUnpacking()){
00492       CProxy_Cell1D aProxy(thisArrayID);
00493       arrayProxy = *(CProxy_Cell*)&aProxy;
00494     } 
00495   }
00496 };
00497 
00498 
00499 class Cell3D: public Cell {
00500  private:
00501   void frag_msg(NeighborMsg *,int,int,int,int,int,int,int,int);
00502  public:
00503   Cell3D() {}
00504   Cell3D(_ArrInitMsg *);
00505   Cell3D(CkMigrateMessage *msg) {}
00506   void reg_nbor_msg(int neighbor_side, NeighborMsg *msg);
00507   virtual void create_children(_ArrInitMsg** cmsg);
00508   virtual void forwardSplitMsg(NeighborMsg *msg ,int neighbor_side);
00509   virtual void pup(PUP::er &p){
00510     Cell::pup(p);
00511     if (p.isUnpacking()){
00512       CProxy_Cell3D aProxy(thisArrayID);
00513       arrayProxy = *(CProxy_Cell*)&aProxy;
00514     }
00515   }
00516 };
00517 
00518 
00519 #endif
00520 
00521 
00522 
00523 
00524