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