00001 
00007 #ifndef __CHARM_IDXL_COMM_H
00008 #define __CHARM_IDXL_COMM_H
00009 
00010 #include "pup.h"
00011 #include "cklists.h"
00012 #include "ckhashtable.h"
00013 #include "charm.h"
00014 
00015 
00023 class IDXL_Share {
00024  public:
00025   int chk; 
00026   int idx; 
00027   IDXL_Share(int x=0) {chk=idx=-1;}
00028   IDXL_Share(int c,int i) :chk(c), idx(i) {}
00029   void pup(PUP::er &p) {p(chk); p(idx);}
00030 };
00031 PUPmarshall(IDXL_Share)
00032 
00033 
00036 class IDXL_Rec {
00037     int entity; 
00038     CkVec<IDXL_Share> shares;
00039     int oldlength;
00040 public:
00041     IDXL_Rec(int entity_=-1);
00042     ~IDXL_Rec();
00043 
00044     void pup(PUP::er &p);
00045     
00046     inline int getEntity(void) const {return entity;}
00047     inline int getShared(void) const {return shares.size();}
00048     inline int getChk(int shareNo) const {return shares[shareNo].chk;}
00049     inline int getIdx(int shareNo) const {return shares[shareNo].idx;}
00050     bool hasChk(int chk) const {
00051         for (int i=0;i<getShared();i++)
00052             if (getChk(i)==chk) return true;
00053         return false;
00054     }
00055     void add(int chk,int idx);
00056 };
00057 
00063 class IDXL_Map {
00064     CkHashtableT<CkHashtableAdaptorT<int>,IDXL_Rec *> map;
00065 public:
00066     IDXL_Map();
00067     ~IDXL_Map();
00068 
00069     
00070     void add(int entity,int chk,int idx);
00071     
00072     
00073     const IDXL_Rec *get(int entity) const;
00074 };
00075 
00082 class IDXL_List {
00083     int chunk; 
00084     CkVec<int> shared; 
00085     bool lock;
00086 public:
00087     IDXL_List();
00088     IDXL_List(int otherchunk);
00089     ~IDXL_List();
00090     int getDest(void) const {return chunk;}
00091     int size(void) const {return shared.size();}
00092     int &operator[](int idx) {return shared[idx]; }
00093     int operator[](int idx) const {return shared[idx]; }
00094     const int *getVec(void) const {return &shared[0];}
00095     bool lockIdxl();
00096     void unlockIdxl();
00097     bool isLocked();
00099     int push_back(int localIdx);
00100     bool set(int localIdx, int sharedIdx);
00101     bool unset(int sharedIdx);
00102     int exists(int localIdx);
00103     int get(int sharedIdx);
00104     void pup(PUP::er &p);
00105     void sort2d(double *coord);
00106     void sort3d(double *coord);
00107 };
00108 PUPmarshall(IDXL_List)
00109 
00110 
00111 
00112 
00113 class IDXL_Print_Map {
00114 public:
00115     virtual void map(int srcIdx) const =0;
00116 };
00117 
00124 class IDXL_Side : public CkNoncopyable {
00126     CkPupPtrVec<IDXL_List, CkPupAlwaysAllocatePtr<IDXL_List> > comm; 
00127 
00131     IDXL_Map *cached_map;
00132     IDXL_Map &getMap(void);
00133     
00134     
00135     IDXL_List *getListN(int chunk) { 
00136         for (int i=0;i<comm.size();i++)
00137             if (comm[i]->getDest()==chunk)
00138                 return comm[i];
00139         return NULL; 
00140     }
00141 public:
00142     IDXL_Side(void);
00143     void pup(PUP::er &p);
00144     ~IDXL_Side();
00146     int total() const;
00147     
00149     int size(void) const {return comm.size();}
00151     const IDXL_List &getLocalList(int idx) const { return *comm[idx]; }
00152     IDXL_List &setLocalList(int idx) { return *comm[idx]; }
00153     
00155     int findLocalList(int chunk) const {
00156         for (int i=0;i<comm.size();i++) 
00157             if (comm[i]->getDest()==chunk)
00158                 return i;
00159         return -1;
00160     }
00161     
00163     const IDXL_List &getList(int chunk) const { 
00164         const IDXL_List *ret=((IDXL_Side *)this)->getListN(chunk);
00165         if (ret==NULL) CkAbort("FEM> Communication lists corrupted (unexpected message)");
00166         return *ret; 
00167     }
00169     IDXL_List &addList(int chunk) {
00170         IDXL_List *ret=getListN(chunk);
00171         if (ret==NULL) { 
00172             ret=new IDXL_List(chunk);
00173             comm.push_back(ret);
00174         }
00175         return *ret;
00176     }
00177 
00178     IDXL_List *getIdxlListN(int chunk) {
00179       return getListN(chunk);
00180     }
00181     
00183     const IDXL_Rec *getRec(int entity) const;
00184     
00185 
00187     void flushMap(void);
00188     
00194     void add(int myChunk,int myLocalNo,
00195          int hisChunk,int hisLocalNo,IDXL_Side &hisList);
00196     
00197     
00202     void clear();
00203     
00204     
00205 
00206 
00207     bool lockIdxl(int sharedWithChk);
00208     void unlockIdxl(int sharedWithChk);
00209     bool isLocked(int sharedWithChk);
00210     int addNode(int localNo, int sharedWithChk);
00211     int removeNode(int localNo, int sharedWithChk);
00212     bool setNode(int localNo, int sharedWithChk, int sharedIdx);
00213     bool unsetNode(int sharedWithChk, int sharedIdx);
00214     int existsNode(int localNo, int sharedWithChk);
00215     int getNode(int sharedWithChk, int sharedIdx);
00216 
00217     void print(const IDXL_Print_Map *idxmap=NULL) const;
00218 
00219     void sort2d(double *coord);
00220 
00221     void sort3d(double *coord);
00222 };
00223 
00227 class IDXL : public CkNoncopyable {
00228     IDXL_Side *send,*recv;
00229     IDXL_Side *alloc_send, *alloc_recv;
00230 public:
00232     IDXL(IDXL_Side *sendrecv) {
00233         send=sendrecv; recv=sendrecv;
00234         alloc_send=alloc_recv=NULL;
00235     }
00236     
00238     IDXL(IDXL_Side *send_, IDXL_Side *recv_) {
00239         send=send_; recv=recv_;
00240         alloc_send=alloc_recv=NULL;
00241     }
00242     
00244     IDXL(void) {
00245         send=alloc_send=NULL;
00246         recv=alloc_recv=NULL;
00247     }
00248     
00250     void allocateSingle(void) {
00251         send=alloc_send=new IDXL_Side;
00252         recv=send; alloc_recv=NULL;
00253     }
00255     void allocateDual(void) {
00256         send=alloc_send=new IDXL_Side;
00257         recv=alloc_recv=new IDXL_Side;
00258     }
00259     
00260     void pup(PUP::er &p) {
00261         int isSendRecv= (send==recv);
00262         p|isSendRecv;
00263         if (!send) send=alloc_send=new IDXL_Side;
00264         send->pup(p);
00265         if (isSendRecv) {
00266             recv=send;
00267         }
00268         else {
00269             if (!recv) recv=alloc_recv=new IDXL_Side;
00270             recv->pup(p);
00271         }
00272     }
00273     ~IDXL(void) {
00274         delete alloc_send; delete alloc_recv;
00275     }
00276     
00278     bool isSingle(void) const {return send==recv;}
00279     
00280     IDXL_Side &getSend(void) {return *send;}
00281     const IDXL_Side &getSend(void) const {return *send;}
00282     IDXL_Side &getRecv(void) {return *recv;}
00283     const IDXL_Side &getRecv(void) const {return *recv;}
00284 
00285     void sort2d(double *coord);
00286 
00287     void sort3d(double *coord);
00288 };
00289 
00290 #endif