#include #include "MPIutils.hh" #include "MPIO.hh" void MPIO::sendSlice(int z,float *data,MPI_Request *req){ int iz = z - localorigin[2]; if(iz<0 || iz>=localdims[2]) return; //printf("PE(%u) send slice z=%u. iz=%u\n",myid,z,iz); // z == the tag //printf("localdims[0]*localdims[1]=%u iz=%u\n",localdims[0]*localdims[1],iz); // if(isRoot()) //comm.iSend(root,z,localdims[0]*localdims[1], // data+localdims[0]*localdims[1]*iz,req[iz]); //else comm.isSend(root,z,localdims[0]*localdims[1], data+localdims[0]*localdims[1]*iz,req[iz]); //for(int i=0;i<4;i++) //printf("\tslicedata[%u]@z(%u) = %f\n",i,iz,(data+localdims[0]*localdims[1]*iz)[i]); //printf("PE(%u) send %u complete\n",myid,iz); } void MPIO::requestSlice(int z,float *slicebuffer,MPI_Request *req){ // skip to z //loop (foreach p of pe's) if(!isRoot()) return; //printf("PE(%u) request slice %u\n",myid,z); for(int offset=0,p=0,reqindex=0;p=idims[2]) continue; comm.iRecv(p,z,idims[0]*idims[1],slicebuffer+offset,req[reqindex++]); //printf("reqslice(%u):MPI_Request=%u\n",iz,req[reqindex-1]); offset+=idims[0]*idims[1]; } // break if outside of z-range (dangerous if non-canonical proc layout) } void MPIO::waitForSlice(int z,float *slicebuffer,float *destbuffer,MPI_Request *req){ if(!isRoot()) return; // could do this 8k at a time // loop for each p of pe's // if within z-range, compute nelem based on dims at p // wait for current request. // re-copy based on offset & origin sliceallwait.start(); for(int p=0,reqindex=0;p=idims[2]) continue; MPI_Status stat; //printf("waitfor(%u):MPI_Request=%u\n",iz,req[reqindex]); slicewait.start(); comm.wait(req[reqindex++],stat); // frees request object too slicewait.stop(); // get information out of the status object!!!! slicecollect.start(); int offset = iorigin[1]*globaldims[0] + iorigin[0]; for(int idx=0,pos=offset,j=0;j1){ fprintf(stderr,"MPIO only accepts a single IO node right now.\n"); fprintf(stderr,"You chose %u io nodes\n",count); fprintf(stderr,"I will select only the first one\n"); } for(root=-1,p=0;preserveChunk operation if(isRoot()) file->reserveStream(IObase::Float32,3,globaldims); int writecount=0; for(int i=1;iwriteStream(slicebuffer[2],globaldims[0]*globaldims[1]); slicewrite.stop(); } } if(isRoot()){ waitForSlice(i-1,slicebuffer[(i-1)%2],slicebuffer[2],recvreq[(i-1)%2]); file->writeStream(slicebuffer[2],globaldims[0]*globaldims[1]); writecount+=globaldims[0]*globaldims[1]; // do requestfree (double-buffered request free-s) for(i=0;i<3;i++) delete slicebuffer[i]; // free everything up for(i=0;i<2;i++) delete recvreq[i]; } MPI_Status stat; for(i=0;i