00001 #ifndef _AMPIIMPL_H
00002 #define _AMPIIMPL_H
00003
00004 #include <string.h>
00005
00006 #include "ampi.h"
00007 #include "charm++.h"
00008 #include "ckliststring.h"
00009
00010 #if AMPI_COMLIB
00011
00012 #include "StreamingStrategy.h"
00013 #include "EachToManyMulticastStrategy.h"
00014 #include "BroadcastStrategy.h"
00015 #else
00016 #define ComlibInstanceHandle int
00017 #endif
00018
00019 #if 0
00020 #define AMPI_DEBUG CkPrintf
00021 #else
00022 #define AMPI_DEBUG
00023 #endif
00024
00025 #if AMPIMSGLOG
00026
00027
00028 static CkListString msgLogRanks;
00029 static int msgLogWrite;
00030 static int msgLogRead;
00031 static char *msgLogFilename;
00032
00033 #if CMK_PROJECTIONS_USE_ZLIB && 0
00034 #include <zlib.h>
00035 namespace PUP{
00036 class zdisk : public er {
00037 protected:
00038 gzFile F;
00039 zdisk(unsigned int type,gzFile f):er(type),F(f) {}
00040 zdisk(const zdisk &p);
00041 void operator=(const zdisk &p);
00042
00043
00044 virtual void impl_startSeek(seekBlock &s);
00045 virtual int impl_tell(seekBlock &s);
00046 virtual void impl_seek(seekBlock &s,int off);
00047 };
00048
00049
00050 class tozDisk : public zdisk {
00051 protected:
00052
00053 virtual void bytes(void *p,int n,size_t itemSize,dataType t);
00054 public:
00055
00056
00057
00058 tozDisk(gzFile f):zdisk(IS_PACKING,f) {}
00059 };
00060
00061
00062 class fromzDisk : public zdisk {
00063 protected:
00064
00065 virtual void bytes(void *p,int n,size_t itemSize,dataType t);
00066 public:
00067
00068
00069
00070 fromzDisk(gzFile f):zdisk(IS_UNPACKING,f) {}
00071 };
00072 };
00073 #endif
00074 #endif // AMPIMSGLOG
00075
00076 #define AMPI_COUNTER 0
00077
00078 #define AMPI_ALLTOALL_SHORT_MSG 32
00079 #if CMK_CONVERSE_LAPI || CMK_BIGSIM_CHARM
00080 #define AMPI_ALLTOALL_MEDIUM_MSG 4194304
00081 #else
00082 #define AMPI_ALLTOALL_MEDIUM_MSG 32768
00083 #endif
00084
00085 #if AMPI_COUNTER
00086 class AmpiCounters{
00087 public:
00088 int send,recv,isend,irecv,barrier,bcast,gather,scatter,allgather,alltoall,reduce,allreduce,scan;
00089 AmpiCounters(){
00090 send=0;recv=0;isend=0;irecv=0;barrier=0;bcast=0;gather=0;scatter=0;allgather=0;alltoall=0;reduce=0;allreduce=0;scan=0;
00091 }
00092 void output(int idx){
00093 printf("[%d]send=%d;recv=%d;isend=%d;irecv=%d;barrier=%d;bcast=%d;gather=%d;scatter=%d;allgather=%d;alltoall=%d;reduce=%d;allreduce=%d;scan=%d\n",idx,send,recv,isend,irecv,barrier,bcast,gather,scatter,allgather,alltoall,reduce,allreduce,scan);
00094 }
00095 };
00096 #endif
00097
00098
00099
00100 void applyOp(MPI_Datatype datatype, MPI_Op op, int count, void* invec, void* inoutvec);
00101 PUPfunctionpointer(MPI_Op)
00102 class AmpiOpHeader {
00103 public:
00104 MPI_User_function* func;
00105 MPI_Datatype dtype;
00106 int len;
00107 int szdata;
00108 AmpiOpHeader(MPI_User_function* f,MPI_Datatype d,int l,int szd):
00109 func(f),dtype(d),len(l),szdata(szd) { }
00110 };
00111
00112
00113
00114 class WinStruct{
00115 public:
00116 MPI_Comm comm;
00117 int index;
00118 WinStruct(void):comm(MPI_COMM_NULL),index(-1){ }
00119 WinStruct(MPI_Comm comm_, int index_):comm(comm_),index(index_){ }
00120 void pup(PUP::er &p){ p|comm; p|index; }
00121 };
00122
00123 class ampi;
00124 class lockQueueEntry {
00125 public:
00126 int requestRank;
00127 int pe_src;
00128 int ftHandle;
00129 int lock_type;
00130 lockQueueEntry (int _requestRank, int _pe_src, int _ftHandle, int _lock_type)
00131 : requestRank(_requestRank), pe_src(_pe_src), ftHandle(_ftHandle), lock_type(_lock_type) {}
00132 lockQueueEntry () {}
00133 };
00134
00135 typedef CkQ<lockQueueEntry *> LockQueue;
00136
00137 class win_obj {
00138 public:
00139 char* winName;
00140 int winNameLeng;
00141 int initflag;
00142
00143 void *baseAddr;
00144 MPI_Aint winSize;
00145 int disp_unit;
00146 MPI_Comm comm;
00147
00148 int owner;
00149 LockQueue lockQueue;
00150
00151
00152
00153 void setName(const char *src,int len);
00154 void getName(char *src,int *len);
00155
00156 public:
00157 void pup(PUP::er &p);
00158
00159 win_obj();
00160 win_obj(char *name, void *base, MPI_Aint size, int disp_unit, MPI_Comm comm);
00161 ~win_obj();
00162
00163 int create(char *name, void *base, MPI_Aint size, int disp_unit,
00164 MPI_Comm comm);
00165 int free();
00166
00167 int put(void *orgaddr, int orgcnt, int orgunit,
00168 MPI_Aint targdisp, int targcnt, int targunit);
00169
00170 int get(void *orgaddr, int orgcnt, int orgunit,
00171 MPI_Aint targdisp, int targcnt, int targunit);
00172 int accumulate(void *orgaddr, int orgcnt, MPI_Datatype orgtype, MPI_Aint targdisp, int targcnt,
00173 MPI_Datatype targtype, MPI_Op op);
00174
00175 int iget(int orgcnt, MPI_Datatype orgtype,
00176 MPI_Aint targdisp, int targcnt, MPI_Datatype targtype);
00177 int igetWait(MPI_Request *req, MPI_Status *status);
00178 int igetFree(MPI_Request *req, MPI_Status *status);
00179
00180 int fence();
00181
00182 int lock(int requestRank, int pe_src, int ftHandle, int lock_type);
00183 int unlock(int requestRank, int pe_src, int ftHandle);
00184
00185 int wait();
00186 int post();
00187 int start();
00188 int complete();
00189
00190 void lockTopQueue();
00191 void enqueue(int requestRank, int pe_src, int ftHandle, int lock_type);
00192 void dequeue();
00193 bool emptyQueue();
00194 };
00195
00196
00197 class KeyvalPair{
00198 protected:
00199 int klen, vlen;
00200 char* key;
00201 char* val;
00202 public:
00203 KeyvalPair(void){ }
00204 KeyvalPair(char* k, char* v);
00205 ~KeyvalPair(void);
00206 void pup(PUP::er& p){
00207 p|klen; p|vlen;
00208 if(p.isUnpacking()){
00209 key=new char[klen];
00210 val=new char[vlen];
00211 }
00212 p(key,klen);
00213 p(val,vlen);
00214 }
00215 friend class InfoStruct;
00216 };
00217
00218 class InfoStruct{
00219 CkPupPtrVec<KeyvalPair> nodes;
00220 bool valid;
00221 public:
00222 InfoStruct(void):valid(true) { }
00223 void setvalid(bool valid_){ valid = valid_; }
00224 bool getvalid(void){ return valid; }
00225 void set(char* k, char* v);
00226 void dup(InfoStruct& src);
00227 int get(char* k, int vl, char*& v);
00228 int deletek(char* k);
00229 int get_valuelen(char* k, int* vl);
00230 int get_nkeys(void) { return nodes.size(); }
00231 int get_nthkey(int n,char* k);
00232 void myfree(void);
00233 void pup(PUP::er& p);
00234 };
00235
00236 class CProxy_ampi;
00237 class CProxyElement_ampi;
00238
00239
00240 class ampiCommStruct {
00241 MPI_Comm comm;
00242 CkArrayID ampiID;
00243 int size;
00244 int isWorld;
00245 int isInter;
00246 CkVec<int> indices;
00247 CkVec<int> remoteIndices;
00248
00249 int ndims;
00250 CkVec<int> dims;
00251 CkVec<int> periods;
00252
00253
00254 CkVec<void *> keyvals;
00255
00256
00257 int nvertices;
00258 CkVec<int> index;
00259 CkVec<int> edges;
00260
00261
00262 void makeWorldIndices(void) const {
00263
00264 CkVec<int> *ind=(CkVec<int> *)&indices;
00265 for (int i=0;i<size;i++) ind->push_back(i);
00266 }
00267 public:
00268 ampiCommStruct(int ignored=0) {size=-1;isWorld=-1;isInter=0;}
00269 ampiCommStruct(MPI_Comm comm_,const CkArrayID &id_,int size_)
00270 :comm(comm_), ampiID(id_),size(size_), isWorld(1), isInter(0) {}
00271 ampiCommStruct(MPI_Comm comm_,const CkArrayID &id_,
00272 int size_,const CkVec<int> &indices_)
00273 :comm(comm_), ampiID(id_),size(size_),isInter(0),
00274 isWorld(0), indices(indices_) {}
00275 ampiCommStruct(MPI_Comm comm_,const CkArrayID &id_,
00276 int size_,const CkVec<int> &indices_,
00277 const CkVec<int> &remoteIndices_)
00278 :comm(comm_),ampiID(id_),size(size_),isWorld(0),isInter(1),
00279 indices(indices_),remoteIndices(remoteIndices_) {}
00280 void setArrayID(const CkArrayID &nID) {ampiID=nID;}
00281
00282 MPI_Comm getComm(void) const {return comm;}
00283 const CkVec<int> &getIndices(void) const {
00284 if (isWorld && indices.size()!=size) makeWorldIndices();
00285 return indices;
00286 }
00287 const CkVec<int> &getRemoteIndices(void) const {return remoteIndices;}
00288 CkVec<void *> &getKeyvals(void) {return keyvals;}
00289
00290
00291 CProxy_ampi getProxy(void) const;
00292
00293
00294 int getIndexForRank(int r) const {
00295 #ifndef CMK_OPTIMIZE
00296 if (r>=size) CkAbort("AMPI> You passed in an out-of-bounds process rank!");
00297 #endif
00298 if (isWorld) return r;
00299 else return indices[r];
00300 }
00301 int getIndexForRemoteRank(int r) const {
00302 #ifndef CMK_OPTIMIZE
00303 if (r>=remoteIndices.size()) CkAbort("AMPI> You passed in an out-of-bounds process rank!");
00304 #endif
00305 if (isWorld) return r;
00306 else return remoteIndices[r];
00307 }
00308
00309 int getRankForIndex(int i) const {
00310 if (isWorld) return i;
00311 else {
00312 for (int r=0;r<indices.size();r++)
00313 if (indices[r]==i) return r;
00314 return -1;
00315 }
00316 }
00317
00318 int getSize(void) const {return size;}
00319
00320 inline int isinter(void) const { return isInter; }
00321 inline const CkVec<int> &getindices() const {
00322 if (isWorld && indices.size()!=size) makeWorldIndices();
00323 return indices;
00324 }
00325 inline const CkVec<int> &getdims() const {return dims;}
00326 inline const CkVec<int> &getperiods() const {return periods;}
00327
00328 inline int getndims() {return ndims;}
00329 inline void setndims(int ndims_) {ndims = ndims_; }
00330 inline void setdims(const CkVec<int> &dims_) { dims = dims_; }
00331 inline void setperiods(const CkVec<int> &periods_) { periods = periods_; }
00332
00333
00334 inline int getnvertices() {return nvertices;}
00335 inline const CkVec<int> &getindex() const {return index;}
00336 inline const CkVec<int> &getedges() const {return edges;}
00337
00338 inline void setnvertices(int nvertices_) {nvertices = nvertices_; }
00339 inline void setindex(const CkVec<int> &index_) { index = index_; }
00340 inline void setedges(const CkVec<int> &edges_) { edges = edges_; }
00341
00342 void pup(PUP::er &p) {
00343 p|comm;
00344 p|ampiID;
00345 p|size;
00346 p|isWorld;
00347 p|isInter;
00348 p|indices;
00349 p|remoteIndices;
00350 p|ndims;
00351 p|dims;
00352 p|periods;
00353 p|nvertices;
00354 p|index;
00355 p|edges;
00356 }
00357 };
00358 PUPmarshall(ampiCommStruct)
00359
00360 struct mpi_comm_world
00361 {
00362 mpi_comm_world(const mpi_comm_world &m);
00363 void operator=(const mpi_comm_world &m);
00364 char *name;
00365 public:
00366 ampiCommStruct comm;
00367 mpi_comm_world() {
00368 name=NULL;
00369 }
00370 ~mpi_comm_world() {
00371 if (name) { delete[] name; name=0; }
00372 }
00373 void setName(const char *src) {
00374 setName(src,strlen(src));
00375 }
00376 void setName(const char *src,int len) {
00377 name=new char[len+1];
00378 memcpy(name,src,len);
00379 name[len] = '\0';
00380 }
00381 const char *getName(void) const { return name; }
00382 void pup(PUP::er &p) {
00383 p|comm;
00384 int len=0;
00385 if (name!=NULL) len=strlen(name)+1;
00386 p|len;
00387 if (p.isUnpacking()) name=new char[len];
00388 p(name,len);
00389 }
00390 };
00391 class mpi_comm_worlds {
00392 mpi_comm_world s[MPI_MAX_COMM_WORLDS];
00393 public:
00394 mpi_comm_world &operator[](int i) {return s[i];}
00395 void pup(PUP::er &p) {
00396 for (int i=0;i<MPI_MAX_COMM_WORLDS;i++)
00397 s[i].pup(p);
00398 }
00399 };
00400
00401 typedef CkVec<int> groupStruct;
00402
00403 inline void outputOp(groupStruct vec){
00404 if(vec.size()>50){
00405 CkPrintf("vector too large to output!\n");
00406 return;
00407 }
00408 CkPrintf("output vector: size=%d {",vec.size());
00409 for(int i=0;i<vec.size();i++)
00410 CkPrintf(" %d ",vec[i]);
00411 CkPrintf("}\n");
00412 }
00413 inline int getPosOp(int idx, groupStruct vec){
00414 for (int r=0;r<vec.size();r++)
00415 if (vec[r]==idx) return r;
00416 return MPI_UNDEFINED;
00417 }
00418 inline groupStruct unionOp(groupStruct vec1, groupStruct vec2){
00419 groupStruct newvec(vec1);
00420 for(int i=0;i<vec2.size();i++){
00421 if(getPosOp(vec2[i],vec1)==MPI_UNDEFINED)
00422 newvec.push_back(vec2[i]);
00423 }
00424 return newvec;
00425 }
00426 inline groupStruct intersectOp(groupStruct vec1, groupStruct vec2){
00427 groupStruct newvec;
00428 for(int i=0;i<vec1.size();i++){
00429 if(getPosOp(vec1[i],vec2)!=MPI_UNDEFINED)
00430 newvec.push_back(vec1[i]);
00431 }
00432 return newvec;
00433 }
00434 inline groupStruct diffOp(groupStruct vec1, groupStruct vec2){
00435 groupStruct newvec;
00436 for(int i=0;i<vec1.size();i++){
00437 if(getPosOp(vec1[i],vec2)==MPI_UNDEFINED)
00438 newvec.push_back(vec1[i]);
00439 }
00440 return newvec;
00441 }
00442 inline int* translateRanksOp(int n,groupStruct vec1,int* ranks1,groupStruct
00443 vec2, int *ret){
00444 for(int i=0;i<n;i++){
00445 ret[i] = getPosOp(vec1[ranks1[i]],vec2);
00446 }
00447 return ret;
00448 }
00449 inline int compareVecOp(groupStruct vec1,groupStruct vec2){
00450 int i,pos,ret = MPI_IDENT;
00451 if(vec1.size() != vec2.size()) return MPI_UNEQUAL;
00452 for(i=0;i<vec1.size();i++){
00453 pos = getPosOp(vec1[i],vec2);
00454 if(pos == MPI_UNDEFINED) return MPI_UNEQUAL;
00455 if(pos != i) ret = MPI_SIMILAR;
00456 }
00457 return ret;
00458 }
00459 inline groupStruct inclOp(int n,int* ranks,groupStruct vec){
00460 groupStruct retvec;
00461 for(int i=0;i<n;i++){
00462 retvec.push_back(vec[ranks[i]]);
00463 }
00464 return retvec;
00465 }
00466 inline groupStruct exclOp(int n,int* ranks,groupStruct vec){
00467 groupStruct retvec;
00468 int add=1;
00469 for(int j=0;j<vec.size();j++){
00470 for(int i=0;i<n;i++)
00471 if(j==ranks[i]){ add=0; break; }
00472 if(add==1) retvec.push_back(vec[j]);
00473 else add=1;
00474 }
00475 return retvec;
00476 }
00477 inline groupStruct rangeInclOp(int n, int ranges[][3], groupStruct vec){
00478 groupStruct retvec;
00479 int first,last,stride;
00480 for(int i=0;i<n;i++){
00481 first = ranges[i][0];
00482 last = ranges[i][1];
00483 stride = ranges[i][2];
00484 for(int j=0;j<=(last-first)/stride;j++)
00485 retvec.push_back(vec[first+stride*j]);
00486 }
00487 return retvec;
00488 }
00489 inline groupStruct rangeExclOp(int n, int ranges[][3], groupStruct vec){
00490 groupStruct retvec;
00491 CkVec<int> ranksvec;
00492 int first,last,stride;
00493 int *ranks,cnt;
00494 int i,j;
00495 for(i=0;i<n;i++){
00496 first = ranges[i][0];
00497 last = ranges[i][1];
00498 stride = ranges[i][2];
00499 for(j=0;j<=(last-first)/stride;j++)
00500 ranksvec.push_back(first+stride*j);
00501 }
00502 cnt=ranksvec.size();
00503 ranks=new int[cnt];
00504 for(i=0;i<cnt;i++)
00505 ranks[i]=ranksvec[i];
00506 return exclOp(cnt,ranks,vec);
00507 }
00508
00509 #include "tcharm.h"
00510 #include "tcharmc.h"
00511
00512 #include "ampi.decl.h"
00513 #include "ddt.h"
00514 #include "charm-api.h"
00515 #include <sys/stat.h>
00516
00517 extern int _mpi_nworlds;
00518
00519 #define MPI_ATA_SEQ_TAG MPI_TAG_UB_VALUE+1
00520 #define MPI_BCAST_TAG MPI_TAG_UB_VALUE+10
00521 #define MPI_BARR_TAG MPI_TAG_UB_VALUE+11
00522 #define MPI_REDUCE_TAG MPI_TAG_UB_VALUE+12
00523 #define MPI_GATHER_TAG MPI_TAG_UB_VALUE+13
00524 #define MPI_SCATTER_TAG MPI_TAG_UB_VALUE+14
00525 #define MPI_SCAN_TAG MPI_TAG_UB_VALUE+15
00526 #define MPI_ATA_TAG MPI_TAG_UB_VALUE+16
00527
00528 #define MyAlign8(x) (((x)+7)&(~7))
00529
00534 class AmpiRequest {
00535 public:
00536 void *buf;
00537 int count;
00538 int type;
00539 int tag;
00540 int src;
00541 int comm;
00542
00543 #if CMK_BIGSIM_CHARM
00544 public:
00545 void *event;
00546 #endif
00547 protected:
00548 bool isvalid;
00549 public:
00550 AmpiRequest(){ }
00552 virtual ~AmpiRequest(){ }
00553
00557 virtual int start(void){ return -1; }
00558
00560 virtual CmiBool test(MPI_Status *sts) =0;
00561
00563 virtual void complete(MPI_Status *sts) =0;
00564
00567 virtual int wait(MPI_Status *sts) =0;
00568
00569 virtual void receive(ampi *ptr, AmpiMsg *msg) = 0;
00570
00572 virtual void free(void){ isvalid=false; }
00573 inline bool isValid(void){ return isvalid; }
00574
00577 virtual int getType(void) =0;
00578
00579 virtual void pup(PUP::er &p) {
00580 p((char *)&buf,sizeof(void *));
00581 p(count);
00582 p(type);
00583 p(src);
00584 p(tag);
00585 p(comm);
00586 p(isvalid);
00587 #if CMK_BIGSIM_CHARM
00588
00589
00590
00591 p((char *)&event, sizeof(void *));
00592 #endif
00593 }
00594
00595
00596 virtual void print();
00597 };
00598
00599 class PersReq : public AmpiRequest {
00600 int sndrcv;
00601 public:
00602 PersReq(void *buf_, int count_, int type_, int src_, int tag_,
00603 MPI_Comm comm_, int sndrcv_)
00604 {
00605 buf=buf_; count=count_; type=type_; src=src_; tag=tag_;
00606 comm=comm_; sndrcv=sndrcv_; isvalid=true;
00607 }
00608 PersReq(){};
00609 ~PersReq(){ }
00610 int start();
00611 CmiBool test(MPI_Status *sts);
00612 void complete(MPI_Status *sts);
00613 int wait(MPI_Status *sts);
00614 void receive(ampi *ptr, AmpiMsg *msg) {}
00615 inline int getType(void){ return 1; }
00616 virtual void pup(PUP::er &p){
00617 AmpiRequest::pup(p);
00618 p(sndrcv);
00619 }
00620
00621 virtual void print();
00622 };
00623
00624 class IReq : public AmpiRequest {
00625 public:
00626 bool statusIreq;
00627 int length;
00628 IReq(void *buf_, int count_, int type_, int src_, int tag_, MPI_Comm comm_)
00629 {
00630 buf=buf_; count=count_; type=type_; src=src_; tag=tag_;
00631 comm=comm_; isvalid=true; statusIreq=false; length=0;
00632 }
00633 IReq(): statusIreq(false){};
00634 ~IReq(){ }
00635 CmiBool test(MPI_Status *sts);
00636 void complete(MPI_Status *sts);
00637 int wait(MPI_Status *sts);
00638 inline int getType(void){ return 2; }
00639 void receive(ampi *ptr, AmpiMsg *msg);
00640 virtual void pup(PUP::er &p){
00641 AmpiRequest::pup(p);
00642 p|statusIreq; p|length;
00643 }
00644
00645 virtual void print();
00646 };
00647
00648 class ATAReq : public AmpiRequest {
00649 class Request {
00650 protected:
00651 void *buf;
00652 int count;
00653 int type;
00654 int src;
00655 int tag;
00656 int comm;
00657 #if CMK_BIGSIM_CHARM
00658 void *event;
00659 #endif
00660 virtual void pup(PUP::er &p){
00661 p((char *)&buf,sizeof(void *));
00662 p(count);
00663 p(type);
00664 p(src);p(tag);p(comm);
00665 #if CMK_BIGSIM_CHARM
00666
00667
00668
00669 p((char *)&event, sizeof(void *));
00670 #endif
00671 }
00672 friend class ATAReq;
00673 };
00674 Request *myreqs;
00675 int elmcount;
00676 int idx;
00677 public:
00678 ATAReq(int c_):elmcount(c_),idx(0) { myreqs = new Request [c_]; isvalid=true; }
00679 ATAReq(){};
00680 ~ATAReq(void) { if(myreqs) delete [] myreqs; }
00681 int addReq(void *buf_, int count_, int type_, int src_, int tag_, MPI_Comm comm_){
00682 myreqs[idx].buf=buf_; myreqs[idx].count=count_;
00683 myreqs[idx].type=type_; myreqs[idx].src=src_;
00684 myreqs[idx].tag=tag_; myreqs[idx].comm=comm_;
00685 return (++idx);
00686 }
00687 CmiBool test(MPI_Status *sts);
00688 void complete(MPI_Status *sts);
00689 int wait(MPI_Status *sts);
00690 void receive(ampi *ptr, AmpiMsg *msg) {}
00691 inline int getCount(void){ return elmcount; }
00692 inline int getType(void){ return 3; }
00693
00694 virtual void pup(PUP::er &p){
00695 AmpiRequest::pup(p);
00696 p(elmcount);
00697 p(idx);
00698 if(p.isUnpacking()){
00699 myreqs = new Request[elmcount];
00700 }
00701 for(int i=0;i<idx;i++){
00702 myreqs[i].pup(p);
00703 }
00704 if(p.isDeleting()){
00705 delete []myreqs;
00706 }
00707 }
00708
00709 virtual void print();
00710 };
00711
00712 class SReq : public AmpiRequest {
00713 public:
00714 bool statusIreq;
00715 SReq(MPI_Comm comm_): statusIreq(false) {
00716 comm = comm_; isvalid=true;
00717 }
00718 SReq(): statusIreq(false) {}
00719 ~SReq(){ }
00720 CmiBool test(MPI_Status *sts);
00721 void complete(MPI_Status *sts);
00722 int wait(MPI_Status *sts);
00723 void receive(ampi *ptr, AmpiMsg *msg) {}
00724 inline int getType(void){ return 4; }
00725 virtual void pup(PUP::er &p){
00726 AmpiRequest::pup(p);
00727 p|statusIreq;
00728 }
00729
00730 virtual void print();
00731 };
00732
00733 class GPUReq : public AmpiRequest {
00734 bool isComplete;
00735
00736 public:
00737 GPUReq();
00738 int getType() { return 5; }
00739 CmiBool test(MPI_Status *sts);
00740 void complete(MPI_Status *sts);
00741 int wait(MPI_Status *sts);
00742 void receive(ampi *ptr, AmpiMsg *msg);
00743 void setComplete();
00744 };
00745
00747 class AmpiRequestList : private CkSTLHelper<AmpiRequest *> {
00748 AmpiRequest** block;
00749 int blklen;
00750 int len;
00751 void makeBlock(int blklen_,int len_) {
00752 block=new AmpiRequest* [blklen_];
00753 blklen=blklen_; len=len_;
00754 }
00755 void freeBlock(void) {
00756 len=0; blklen=0;
00757 delete[] block; block=NULL;
00758 }
00759 void copyFrom(const AmpiRequestList &src) {
00760 makeBlock(src.blklen, src.len);
00761 elementCopy(block,src.block,blklen);
00762 }
00763 public:
00764 AmpiRequestList() {block=NULL;blklen=len=0;}
00765 ~AmpiRequestList() { freeBlock(); }
00766 AmpiRequestList(const AmpiRequestList &src) {copyFrom(src);}
00767 AmpiRequestList(int size) { makeBlock(size,size); }
00768 AmpiRequestList &operator=(const AmpiRequestList &src) {
00769 freeBlock();
00770 copyFrom(src);
00771 return *this;
00772 }
00773
00774 AmpiRequest* operator[](size_t n) { return block[n]; }
00775
00776 int size(void) const {return len;}
00777 void setSize(int blklen_) {
00778 AmpiRequest **oldBlock=block;
00779 makeBlock(blklen_,len);
00780 elementCopy(block,oldBlock,len);
00781 delete[] oldBlock;
00782 }
00783
00784 void growAtLeast(int pos) {
00785 if (pos>=blklen) setSize(pos*2+16);
00786 }
00787 void insertAt(int pos, AmpiRequest* elt) {
00788 if (pos>=len) {
00789 growAtLeast(pos);
00790 len=pos+1;
00791 }
00792 block[pos] = elt;
00793 }
00794 void free(int pos) {
00795 if (pos<0 || pos>=len) return;
00796 block[pos]->free();
00797 delete block[pos];
00798 block[pos]=NULL;
00799 }
00800 void push_back(AmpiRequest* elt) {insertAt(len,elt);}
00801 int insert(AmpiRequest* elt){
00802
00803
00804
00805 for(int i=0;i<len;i++){
00806 if(block[i]==NULL){
00807 block[i] = elt;
00808 return i;
00809 }
00810 }
00811 push_back(elt);
00812 return len-1;
00813 }
00814
00815 inline void checkRequest(MPI_Request idx){
00816 if(!(idx==-1 || (idx < this->len && (block[idx])->isValid())))
00817 CkAbort("Invalid MPI_Request\n");
00818 }
00819
00820
00821
00822 int findRequestIndex(AmpiRequest *req){
00823 for(int i=0; i<len; i++){
00824 if(block[i]==req) return i;
00825 }
00826 return -1;
00827 }
00828
00829 void pup(PUP::er &p);
00830
00831
00832 void print(){
00833 for(int i=0; i<len; i++){
00834 if(block[i]==NULL) continue;
00835 CmiPrintf("AmpiRequestList Element %d [%p]: \n", i+1, block[i]);
00836 block[i]->print();
00837 }
00838 }
00839 };
00840
00841
00842 class memBuf {
00843 CkVec<char> buf;
00844 public:
00845 memBuf() { }
00846 memBuf(int size) :buf(size) {}
00847 void setSize(int s) {buf.resize(s);}
00848 int getSize(void) const {return buf.size();}
00849 const void *getData(void) const {return (const void *)&buf[0];}
00850 void *getData(void) {return (void *)&buf[0];}
00851 };
00852
00853 template <class T>
00854 inline void pupIntoBuf(memBuf &b,T &t) {
00855 PUP::sizer ps;ps|t;
00856 b.setSize(ps.size());
00857 PUP::toMem pm(b.getData()); pm|t;
00858 }
00859
00860 template <class T>
00861 inline void pupFromBuf(const void *data,T &t) {
00862 PUP::fromMem p(data); p|t;
00863 }
00864
00865 class AmpiMsg : public CMessage_AmpiMsg {
00866 public:
00867 int seq;
00868 int tag;
00869 int srcIdx;
00870 int srcRank;
00871 MPI_Comm comm;
00872 int length;
00873 #if CMK_BIGSIM_CHARM
00874 void *event;
00875 int eventPe;
00876 #endif
00877 char *data;
00878
00879 AmpiMsg(void) { data = NULL; }
00880 AmpiMsg(int _s, int t, int sIdx,int sRank, int l, int c) :
00881 seq(_s), tag(t),srcIdx(sIdx), srcRank(sRank), comm(c), length(l) {
00882 }
00883 static AmpiMsg* pup(PUP::er &p, AmpiMsg *m)
00884 {
00885 int seq, length, tag, srcIdx, srcRank, comm;
00886 if(p.isPacking() || p.isSizing()) {
00887 seq = m->seq;
00888 tag = m->tag;
00889 srcIdx = m->srcIdx;
00890 srcRank = m->srcRank;
00891 comm = m->comm;
00892 length = m->length;
00893 }
00894 p(seq); p(tag); p(srcIdx); p(srcRank); p(comm); p(length);
00895 if(p.isUnpacking()) {
00896 m = new (length, 0) AmpiMsg(seq, tag, srcIdx, srcRank, length, comm);
00897 }
00898 p(m->data, length);
00899 if(p.isDeleting()) {
00900 delete m;
00901 m = 0;
00902 }
00903 return m;
00904 }
00905 };
00906
00913 class AmpiOtherElement {
00914 public:
00916 int seqIncoming, seqOutgoing;
00917
00919 int nOut;
00920
00921 AmpiOtherElement(void) {
00922 seqIncoming=0; seqOutgoing=0;
00923 nOut=0;
00924 }
00925
00926 void pup(PUP::er &p) {
00927 p|seqIncoming; p|seqOutgoing;
00928 p|nOut;
00929 }
00930 };
00931
00932 class AmpiSeqQ : private CkNoncopyable {
00933 CkMsgQ<AmpiMsg> out;
00934 CkPagedVector<AmpiOtherElement> elements;
00935
00936 void putOutOfOrder(int srcIdx, AmpiMsg *msg);
00937
00938 public:
00939 AmpiSeqQ() {}
00940 void init(int numP);
00941 ~AmpiSeqQ ();
00942 void pup(PUP::er &p);
00943
00950 inline int put(int srcIdx, AmpiMsg *msg) {
00951 AmpiOtherElement &el=elements[srcIdx];
00952 if (msg->seq==el.seqIncoming) {
00953 el.seqIncoming++;
00954 return 1+el.nOut;
00955 }
00956 else {
00957 putOutOfOrder(srcIdx, msg);
00958 return 0;
00959 }
00960 }
00961
00964 AmpiMsg *getOutOfOrder(int p);
00965
00967 int nextOutgoing(int p) {
00968 return elements[p].seqOutgoing++;
00969 }
00970 };
00971 PUPmarshall(AmpiSeqQ)
00972
00973
00974 inline CProxy_ampi ampiCommStruct::getProxy(void) const {return ampiID;}
00975 const ampiCommStruct &universeComm2CommStruct(MPI_Comm universeNo);
00976
00977
00978 class KeyvalNode {
00979 public:
00980 MPI_Copy_function *copy_fn;
00981 MPI_Delete_function *delete_fn;
00982 void *extra_state;
00983
00984
00985 KeyvalNode(void): copy_fn(NULL), delete_fn(NULL), extra_state(NULL)
00986 { }
00987 KeyvalNode(MPI_Copy_function *cf, MPI_Delete_function *df, void* es):
00988 copy_fn(cf), delete_fn(df), extra_state(es)
00989 { }
00990
00991 void pup(PUP::er& p){ }
00992 };
00993
00994
00995
00996
00997
00998 class ampiParent : public CBase_ampiParent {
00999 CProxy_TCharm threads;
01000 TCharm *thread;
01001 void prepareCtv(void);
01002
01003 MPI_Comm worldNo;
01004 ampi *worldPtr;
01005 ampiCommStruct worldStruct;
01006 ampiCommStruct selfStruct;
01007
01008 CkPupPtrVec<ampiCommStruct> splitComm;
01009 CkPupPtrVec<ampiCommStruct> groupComm;
01010 CkPupPtrVec<ampiCommStruct> cartComm;
01011 CkPupPtrVec<ampiCommStruct> graphComm;
01012 CkPupPtrVec<ampiCommStruct> interComm;
01013 CkPupPtrVec<ampiCommStruct> intraComm;
01014
01015 CkPupPtrVec<groupStruct> groups;
01016 CkPupPtrVec<WinStruct> winStructList;
01017 CkPupPtrVec<InfoStruct> infos;
01018
01019 inline int isSplit(MPI_Comm comm) const {
01020 return (comm>=MPI_COMM_FIRST_SPLIT && comm<MPI_COMM_FIRST_GROUP);
01021 }
01022 const ampiCommStruct &getSplit(MPI_Comm comm) {
01023 int idx=comm-MPI_COMM_FIRST_SPLIT;
01024 if (idx>=splitComm.size()) CkAbort("Bad split communicator used");
01025 return *splitComm[idx];
01026 }
01027 void splitChildRegister(const ampiCommStruct &s);
01028
01029 inline int isGroup(MPI_Comm comm) const {
01030 return (comm>=MPI_COMM_FIRST_GROUP && comm<MPI_COMM_FIRST_CART);
01031 }
01032 const ampiCommStruct &getGroup(MPI_Comm comm) {
01033 int idx=comm-MPI_COMM_FIRST_GROUP;
01034 if (idx>=groupComm.size()) CkAbort("Bad group communicator used");
01035 return *groupComm[idx];
01036 }
01037 void groupChildRegister(const ampiCommStruct &s);
01038 inline int isInGroups(MPI_Group group) const {
01039 return (group>=0 && group<groups.size());
01040 }
01041
01042 void cartChildRegister(const ampiCommStruct &s);
01043 void graphChildRegister(const ampiCommStruct &s);
01044 void interChildRegister(const ampiCommStruct &s);
01045
01046 inline int isIntra(MPI_Comm comm) const {
01047 return (comm>=MPI_COMM_FIRST_INTRA && comm<MPI_COMM_FIRST_RESVD);
01048 }
01049 const ampiCommStruct &getIntra(MPI_Comm comm) {
01050 int idx=comm-MPI_COMM_FIRST_INTRA;
01051 if (idx>=intraComm.size()) CkAbort("Bad intra-communicator used");
01052 return *intraComm[idx];
01053 }
01054 void intraChildRegister(const ampiCommStruct &s);
01055
01056
01057
01058 int* kv_builtin_storage;
01059 int kv_is_builtin(int keyval);
01060 CkPupPtrVec<KeyvalNode> kvlist;
01061
01062 int RProxyCnt;
01063 CProxy_ampi tmpRProxy;
01064
01065 public:
01066 int ampiInitCallDone;
01067
01068 public:
01069 ampiParent(MPI_Comm worldNo_,CProxy_TCharm threads_);
01070 ampiParent(CkMigrateMessage *msg);
01071 void ckJustMigrated(void);
01072 void ckJustRestored(void);
01073 ~ampiParent();
01074
01075 ampi *lookupComm(MPI_Comm comm) {
01076 if (comm!=worldStruct.getComm())
01077 CkAbort("ampiParent::lookupComm> Bad communicator!");
01078 return worldPtr;
01079 }
01080
01081
01082 TCharm *registerAmpi(ampi *ptr,ampiCommStruct s,bool forMigration);
01083
01084
01085 void ExchangeProxy(CProxy_ampi rproxy){
01086 if(RProxyCnt==0){ tmpRProxy=rproxy; RProxyCnt=1; }
01087 else if(RProxyCnt==1) { tmpRProxy.setRemoteProxy(rproxy); rproxy.setRemoteProxy(tmpRProxy); RProxyCnt=0; }
01088 else CkAbort("ExchangeProxy: RProxyCnt>1");
01089 }
01090
01091
01092 MPI_Comm getNextSplit(void) const {return MPI_COMM_FIRST_SPLIT+splitComm.size();}
01093 MPI_Comm getNextGroup(void) const {return MPI_COMM_FIRST_GROUP+groupComm.size();}
01094 MPI_Comm getNextCart(void) const {return MPI_COMM_FIRST_CART+cartComm.size();}
01095 MPI_Comm getNextGraph(void) const {return MPI_COMM_FIRST_GRAPH+graphComm.size();}
01096 MPI_Comm getNextInter(void) const {return MPI_COMM_FIRST_INTER+interComm.size();}
01097 MPI_Comm getNextIntra(void) const {return MPI_COMM_FIRST_INTRA+intraComm.size();}
01098
01099 inline int isCart(MPI_Comm comm) const {
01100 return (comm>=MPI_COMM_FIRST_CART && comm<MPI_COMM_FIRST_GRAPH);
01101 }
01102 ampiCommStruct &getCart(MPI_Comm comm) {
01103 int idx=comm-MPI_COMM_FIRST_CART;
01104 if (idx>=cartComm.size()) CkAbort("Bad cartesian communicator used");
01105 return *cartComm[idx];
01106 }
01107 inline int isGraph(MPI_Comm comm) const {
01108 return (comm>=MPI_COMM_FIRST_GRAPH && comm<MPI_COMM_FIRST_INTER);
01109 }
01110 ampiCommStruct &getGraph(MPI_Comm comm) {
01111 int idx=comm-MPI_COMM_FIRST_GRAPH;
01112 if (idx>=graphComm.size()) CkAbort("Bad graph communicator used");
01113 return *graphComm[idx];
01114 }
01115 inline int isInter(MPI_Comm comm) const {
01116 return (comm>=MPI_COMM_FIRST_INTER && comm<MPI_COMM_FIRST_INTRA);
01117 }
01118 const ampiCommStruct &getInter(MPI_Comm comm) {
01119 int idx=comm-MPI_COMM_FIRST_INTER;
01120 if (idx>=interComm.size()) CkAbort("Bad inter-communicator used");
01121 return *interComm[idx];
01122 }
01123
01124 void pup(PUP::er &p);
01125
01126 inline void start_measure() {
01127 usesAutoMeasure = CmiFalse;
01128 }
01129 inline void stop_measure() {
01130 usesAutoMeasure = CmiTrue;
01131 }
01132 virtual void UserSetLBLoad(void) {
01133
01134 }
01135
01136 void startCheckpoint(const char* dname);
01137 void Checkpoint(int len, const char* dname);
01138 void ResumeThread(void);
01139 TCharm* getTCharmThread() {return thread;}
01140
01141 inline const ampiCommStruct &comm2CommStruct(MPI_Comm comm) {
01142 if (comm==MPI_COMM_WORLD) return worldStruct;
01143 if (comm==MPI_COMM_SELF) return selfStruct;
01144 if (comm==worldNo) return worldStruct;
01145 if (isSplit(comm)) return getSplit(comm);
01146 if (isGroup(comm)) return getGroup(comm);
01147 if (isCart(comm)) return getCart(comm);
01148 if (isGraph(comm)) return getGraph(comm);
01149 if (isInter(comm)) return getInter(comm);
01150 if (isIntra(comm)) return getIntra(comm);
01151 return universeComm2CommStruct(comm);
01152 }
01153
01154
01155 inline ampi *comm2ampi(MPI_Comm comm) {
01156 if (comm==MPI_COMM_WORLD) return worldPtr;
01157 if (comm==MPI_COMM_SELF) return worldPtr;
01158 if (comm==worldNo) return worldPtr;
01159 if (isSplit(comm)) {
01160 const ampiCommStruct &st=getSplit(comm);
01161 return st.getProxy()[thisIndex].ckLocal();
01162 }
01163 if (isGroup(comm)) {
01164 const ampiCommStruct &st=getGroup(comm);
01165 return st.getProxy()[thisIndex].ckLocal();
01166 }
01167 if (isCart(comm)) {
01168 const ampiCommStruct &st = getCart(comm);
01169 return st.getProxy()[thisIndex].ckLocal();
01170 }
01171 if (isGraph(comm)) {
01172 const ampiCommStruct &st = getGraph(comm);
01173 return st.getProxy()[thisIndex].ckLocal();
01174 }
01175 if (isInter(comm)) {
01176 const ampiCommStruct &st=getInter(comm);
01177 return st.getProxy()[thisIndex].ckLocal();
01178 }
01179 if (isIntra(comm)) {
01180 const ampiCommStruct &st=getIntra(comm);
01181 return st.getProxy()[thisIndex].ckLocal();
01182 }
01183 if (comm>MPI_COMM_WORLD) return worldPtr;
01184 CkAbort("Invalid communicator used!");
01185 return NULL;
01186 }
01187
01188 inline int hasComm(const MPI_Group group){
01189 MPI_Comm comm = (MPI_Comm)group;
01190 return ( comm==MPI_COMM_WORLD || comm==worldNo || isSplit(comm) || isGroup(comm) || isCart(comm) || isGraph(comm) || isIntra(comm) );
01191 }
01192 inline const groupStruct group2vec(MPI_Group group){
01193 if(hasComm(group))
01194 return comm2CommStruct((MPI_Comm)group).getIndices();
01195 if(isInGroups(group))
01196 return *groups[group];
01197 CkAbort("ampiParent::group2vec: Invalid group id!");
01198 return *groups[0];
01199 }
01200 inline MPI_Group saveGroupStruct(groupStruct vec){
01201 int idx = groups.size();
01202 groups.resize(idx+1);
01203 groups[idx]=new groupStruct(vec);
01204 return (MPI_Group)idx;
01205 }
01206 inline int getRank(const MPI_Group group){
01207 groupStruct vec = group2vec(group);
01208 return getPosOp(thisIndex,vec);
01209 }
01210
01211 inline int getMyPe(void){
01212 return CkMyPe();
01213 }
01214 inline int hasWorld(void) const {
01215 return worldPtr!=NULL;
01216 }
01217
01218 inline void checkComm(MPI_Comm comm){
01219 if ((comm > MPI_COMM_FIRST_RESVD && comm != MPI_COMM_SELF && comm != MPI_COMM_WORLD)
01220 || (isSplit(comm) && comm-MPI_COMM_FIRST_SPLIT >= splitComm.size())
01221 || (isGroup(comm) && comm-MPI_COMM_FIRST_GROUP >= groupComm.size())
01222 || (isCart(comm) && comm-MPI_COMM_FIRST_CART >= cartComm.size())
01223 || (isGraph(comm) && comm-MPI_COMM_FIRST_GRAPH >= graphComm.size())
01224 || (isInter(comm) && comm-MPI_COMM_FIRST_INTER >= interComm.size())
01225 || (isIntra(comm) && comm-MPI_COMM_FIRST_INTRA >= intraComm.size()) )
01226 CkAbort("Invalide MPI_Comm\n");
01227 }
01228
01230 inline MPI_Group comm2group(const MPI_Comm comm){
01231 if(isInter(comm)) return MPI_GROUP_NULL;
01232 ampiCommStruct s = comm2CommStruct(comm);
01233 if(comm!=MPI_COMM_WORLD && comm!=s.getComm()) CkAbort("Error in ampiParent::comm2group()");
01234 return (MPI_Group)(s.getComm());
01235 }
01236
01237 inline int getRemoteSize(const MPI_Comm comm){
01238 if(isInter(comm)) return getInter(comm).getRemoteIndices().size();
01239 else return -1;
01240 }
01241 inline MPI_Group getRemoteGroup(const MPI_Comm comm){
01242 if(isInter(comm)) return saveGroupStruct(getInter(comm).getRemoteIndices());
01243 else return MPI_GROUP_NULL;
01244 }
01245
01246 int createKeyval(MPI_Copy_function *copy_fn, MPI_Delete_function *delete_fn,
01247 int *keyval, void* extra_state);
01248 int freeKeyval(int *keyval);
01249 int putAttr(MPI_Comm comm, int keyval, void* attribute_val);
01250 int getAttr(MPI_Comm comm, int keyval, void *attribute_val, int *flag);
01251 int deleteAttr(MPI_Comm comm, int keyval);
01252
01253 CkDDT myDDTsto;
01254 CkDDT *myDDT;
01255 AmpiRequestList ampiReqs;
01256
01257
01258
01259
01260
01261 int addWinStruct(WinStruct* win);
01262 WinStruct getWinStruct(MPI_Win win);
01263 void removeWinStruct(WinStruct win);
01264
01265 #if AMPI_COUNTER
01266 public:
01267 AmpiCounters counters;
01268 #endif
01269
01270 public:
01271 MPI_Info createInfo(void);
01272 MPI_Info dupInfo(MPI_Info info);
01273 void setInfo(MPI_Info info, char *key, char *value);
01274 int deleteInfo(MPI_Info info, char *key);
01275 int getInfo(MPI_Info info, char *key, int valuelen, char *value);
01276 int getInfoValuelen(MPI_Info info, char *key, int *valuelen);
01277 int getInfoNkeys(MPI_Info info);
01278 int getInfoNthkey(MPI_Info info, int n, char *key);
01279 void freeInfo(MPI_Info info);
01280
01281 public:
01282 #if AMPIMSGLOG
01283
01284 int pupBytes;
01285 #if CMK_PROJECTIONS_USE_ZLIB && 0
01286 gzFile fMsgLog;
01287 PUP::tozDisk *toPUPer;
01288 PUP::fromzDisk *fromPUPer;
01289 #else
01290 FILE* fMsgLog;
01291 PUP::toDisk *toPUPer;
01292 PUP::fromDisk *fromPUPer;
01293 #endif
01294 #endif
01295 void init();
01296 void finalize();
01297 };
01298
01299
01300
01301
01302
01303 class ampi : public CBase_ampi {
01304 friend class IReq;
01305 friend class SReq;
01306 CProxy_ampiParent parentProxy;
01307 void findParent(bool forMigration);
01308 ampiParent *parent;
01309 TCharm *thread;
01310 bool resumeOnRecv;
01311
01312 ampiCommStruct myComm;
01313 int myRank;
01314 groupStruct tmpVec;
01315 CProxy_ampi remoteProxy;
01316
01317 #if AMPI_COMLIB
01319 CProxy_ampi comlibProxy;
01320
01322 ComlibInstanceHandle ciStreaming;
01323 ComlibInstanceHandle ciBcast;
01324 ComlibInstanceHandle ciAllgather;
01325 ComlibInstanceHandle ciAlltoall;
01326 #endif
01327
01328 int seqEntries;
01329 AmpiSeqQ oorder;
01330 void inorder(AmpiMsg *msg);
01331
01332 void init(void);
01333
01334 public:
01335
01336 ampi();
01337 ampi(CkArrayID parent_,const ampiCommStruct &s);
01338 ampi(CkArrayID parent_,const ampiCommStruct &s,ComlibInstanceHandle ciStreaming_,
01339 ComlibInstanceHandle ciBcast_,ComlibInstanceHandle ciAllgather_,ComlibInstanceHandle ciAlltoall_);
01340 ampi(CkMigrateMessage *msg);
01341 void ckJustMigrated(void);
01342 void ckJustRestored(void);
01343 ~ampi();
01344
01345 virtual void pup(PUP::er &p);
01346
01347 void allInitDone(CkReductionMsg *m);
01348 void setInitDoneFlag();
01349
01350 void block(void);
01351 void unblock(void);
01352 void yield(void);
01353 void generic(AmpiMsg *);
01354 void ssend_ack(int sreq);
01355 void reduceResult(CkReductionMsg *m);
01356 void splitPhase1(CkReductionMsg *msg);
01357 void commCreatePhase1(CkReductionMsg *msg);
01358 void cartCreatePhase1(CkReductionMsg *m);
01359 void graphCreatePhase1(CkReductionMsg *m);
01360 void intercommCreatePhase1(CkReductionMsg *m);
01361 void intercommMergePhase1(CkReductionMsg *msg);
01362
01363 public:
01364
01365 inline const ampiCommStruct &comm2CommStruct(MPI_Comm comm) {
01366 return parent->comm2CommStruct(comm);
01367 }
01368
01369 AmpiMsg *makeAmpiMsg(int destIdx,int t,int sRank,const void *buf,int count,
01370 int type,MPI_Comm destcomm, int sync=0);
01371
01372 #if AMPI_COMLIB
01373 inline void comlibsend(int t, int s, const void* buf, int count, int type, int rank, MPI_Comm destcomm);
01374 #endif
01375 inline void send(int t, int s, const void* buf, int count, int type, int rank, MPI_Comm destcomm, int sync=0);
01376 static void sendraw(int t, int s, void* buf, int len, CkArrayID aid,
01377 int idx);
01378 void delesend(int t, int s, const void* buf, int count, int type,
01379 int rank, MPI_Comm destcomm, CProxy_ampi arrproxy, int sync=0);
01380 inline int processMessage(AmpiMsg *msg, int t, int s, void* buf, int count, int type);
01381 inline AmpiMsg * getMessage(int t, int s, int comm, int *sts);
01382 int recv(int t,int s,void* buf,int count,int type,int comm,int *sts=0);
01383 void probe(int t,int s,int comm,int *sts);
01384 int iprobe(int t,int s,int comm,int *sts);
01385 void bcast(int root, void* buf, int count, int type,MPI_Comm comm);
01386 static void bcastraw(void* buf, int len, CkArrayID aid);
01387 void split(int color,int key,MPI_Comm *dest, int type);
01388 void commCreate(const groupStruct vec,MPI_Comm *newcomm);
01389 void cartCreate(const groupStruct vec, MPI_Comm *newcomm);
01390 void graphCreate(const groupStruct vec, MPI_Comm *newcomm);
01391 void intercommCreate(const groupStruct rvec, int root, MPI_Comm *ncomm);
01392
01393 inline int isInter(void) { return myComm.isinter(); }
01394 void intercommMerge(int first, MPI_Comm *ncomm);
01395
01396 inline int getWorldRank(void) const {return parent->thisIndex;}
01398 inline int getRank(MPI_Comm comm) const {
01399 if (comm==MPI_COMM_SELF) return 0;
01400 else return myRank;
01401 }
01402 inline int getSize(MPI_Comm comm) const {
01403 if (comm==MPI_COMM_SELF) return 1;
01404 else return myComm.getSize();
01405 }
01406 inline MPI_Comm getComm(void) const {return myComm.getComm();}
01407 inline CkVec<int> getIndices(void) const { return myComm.getindices(); }
01408 inline const CProxy_ampi &getProxy(void) const {return thisProxy;}
01409 inline const CProxy_ampi &getRemoteProxy(void) const {return remoteProxy;}
01410 inline void setRemoteProxy(CProxy_ampi rproxy) { remoteProxy = rproxy; thread->resume(); }
01411 inline int getIndexForRank(int r) const {return myComm.getIndexForRank(r);}
01412 inline int getIndexForRemoteRank(int r) const {return myComm.getIndexForRemoteRank(r);}
01413 #if AMPI_COMLIB
01414 inline const CProxy_ampi &getComlibProxy(void) const { return comlibProxy; }
01415 inline ComlibInstanceHandle getStreaming(void) { return ciStreaming; }
01416 inline ComlibInstanceHandle getBcast(void) { return ciBcast; }
01417 inline ComlibInstanceHandle getAllgather(void) { return ciAllgather; }
01418 inline ComlibInstanceHandle getAlltoall(void) { return ciAlltoall; }
01419
01420 inline Strategy* getStreamingStrategy(void) { return CkpvAccess(conv_com_object).getStrategy(ciStreaming); }
01421 inline Strategy* getBcastStrategy(void) { return CkpvAccess(conv_com_object).getStrategy(ciBcast); }
01422 inline Strategy* getAllgatherStrategy(void) { return CkpvAccess(conv_com_object).getStrategy(ciAllgather); }
01423 inline Strategy* getAlltoallStrategy(void) { return CkpvAccess(conv_com_object).getStrategy(ciAlltoall); }
01424 #endif
01425
01426 CkDDT *getDDT(void) {return parent->myDDT;}
01427 CthThread getThread() { return thread->getThread(); }
01428 #if CMK_LBDB_ON
01429 void setMigratable(int mig) {
01430 if(mig) thread->setMigratable(CmiTrue);
01431 else thread->setMigratable(CmiFalse);
01432 }
01433 #endif
01434 public:
01435
01436
01437
01438
01439
01440 CmmTable msgs;
01441 CmmTable posted_ireqs;
01442 int nbcasts;
01443
01444 private:
01445 CkPupPtrVec<win_obj> winObjects;
01446 public:
01447 MPI_Win createWinInstance(void *base, MPI_Aint size, int disp_unit, MPI_Info info);
01448 int deleteWinInstance(MPI_Win win);
01449 int winGetGroup(WinStruct win, MPI_Group *group);
01450 int winPut(void *orgaddr, int orgcnt, MPI_Datatype orgtype, int rank,
01451 MPI_Aint targdisp, int targcnt, MPI_Datatype targtype, WinStruct win);
01452 int winGet(void *orgaddr, int orgcnt, MPI_Datatype orgtype, int rank,
01453 MPI_Aint targdisp, int targcnt, MPI_Datatype targtype, WinStruct win);
01454 int winIGet(MPI_Aint orgdisp, int orgcnt, MPI_Datatype orgtype, int rank,
01455 MPI_Aint targdisp, int targcnt, MPI_Datatype targtype, WinStruct win,
01456 MPI_Request *req);
01457 int winIGetWait(MPI_Request *request, MPI_Status *status);
01458 int winIGetFree(MPI_Request *request, MPI_Status *status);
01459 void winRemotePut(int orgtotalsize, char* orgaddr, int orgcnt, MPI_Datatype orgtype,
01460 MPI_Aint targdisp, int targcnt, MPI_Datatype targtype,
01461 int winIndex, CkFutureID ftHandle, int pe_src);
01462 void winRemoteGet(int orgcnt, MPI_Datatype orgtype, MPI_Aint targdisp,
01463 int targcnt, MPI_Datatype targtype,
01464 int winIndex, CkFutureID ftHandle, int pe_src);
01465 AmpiMsg* winRemoteIGet(int orgdisp, int orgcnt, MPI_Datatype orgtype, MPI_Aint targdisp,
01466 int targcnt, MPI_Datatype targtype, int winIndex);
01467 int winLock(int lock_type, int rank, WinStruct win);
01468 int winUnlock(int rank, WinStruct win);
01469 void winRemoteLock(int lock_type, int winIndex, CkFutureID ftHandle, int pe_src, int requestRank);
01470 void winRemoteUnlock(int winIndex, CkFutureID ftHandle, int pe_src, int requestRank);
01471 int winAccumulate(void *orgaddr, int orgcnt, MPI_Datatype orgtype, int rank,
01472 MPI_Aint targdisp, int targcnt, MPI_Datatype targtype,
01473 MPI_Op op, WinStruct win);
01474 void winRemoteAccumulate(int orgtotalsize, char* orgaddr, int orgcnt, MPI_Datatype orgtype, MPI_Aint targdisp,
01475 int targcnt, MPI_Datatype targtype,
01476 MPI_Op op, int winIndex, CkFutureID ftHandle,
01477 int pe_src);
01478 void winSetName(WinStruct win, char *name);
01479 void winGetName(WinStruct win, char *name, int *length);
01480 win_obj* getWinObjInstance(WinStruct win);
01481 int getNewSemaId();
01482
01483 AmpiMsg* Alltoall_RemoteIGet(int disp, int targcnt, MPI_Datatype targtype, int tag);
01484 private:
01485 int AlltoallGetFlag;
01486 void *Alltoallbuff;
01487 public:
01488 void setA2AIGetFlag(void* ptr) {AlltoallGetFlag=1;Alltoallbuff=ptr;}
01489 void resetA2AIGetFlag() {AlltoallGetFlag=0;Alltoallbuff=NULL;}
01490
01491 };
01492
01493 ampiParent *getAmpiParent(void);
01494 ampi *getAmpiInstance(MPI_Comm comm);
01495 void checkComm(MPI_Comm comm);
01496 void checkRequest(MPI_Request req);
01497
01498
01499 #define AMPIAPI(routineName) TCHARM_API_TRACE(routineName,"ampi")
01500
01501 #endif
01502