aboutsummaryrefslogtreecommitdiff
path: root/src/MPIO.fast.hh
blob: 51d5b03c54d03d33a8d52231131f2b2940f54787 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#ifndef __MPIO_HH_
#define __MPIO_HH_
#include "IO.hh"
#include "MPIutils.hh"
#include "Timer.H"

/* Simplifies assumptions about domain decomposition */ 
/*
  Module: MPIO

  Description:
  Implements slice-based Parallel IO for IEEEIO libraries.
  Uses iSend/iRecv of XY slices to hide message passing latency.
  This is a simplified version of PIO which makes fewer assumptions
  about the layout of the data.
  
  Will eventually be subclassed from IObase so that you can
  drop-in replace a single-threaded IO system with this
  multithreaded one.  writeChunk() will be used to announce
  the local chunks and perform the write in parallel rather
  than collecting serially.
  
  Needs to have extensions to automatically remove ghost zones
  setLocalDims(origin,dims,minindex,maxindex)

  Limitations:
  * currently only works for 3D grids
  * only understands Float32 and Float64 datatypes
  * Assumes HPF layout (eg, canonical processor layout where
    all PE's are aligned to grid... no partial overlaps)
  * Uses XY slices (assumes fortran ordering for dimensions)
  * Collects only to a single file (cannot do a multi-gather).
 */
class MPIO /* : public IObase */ {
  int *gdims,*gorigins,grank;
  MPIcomm &comm;
  int globaldims[3]; // for master
  int localorigin[3],localdims[3];
  int root,myid;
  IObase *file;
  Timer slicewait,slicewrite,slicecollect,sliceselect;
  Timer sliceallwait;
  int *chunkindex,*chunkindexcount,*slicemap,*procmap;
  inline int isRoot(){ return ((myid == root)?1:0);}
  // MPI_Request *slice_send_requests;
protected:
  inline void sendSlice(int z,float *data,MPI_Request *req);
  void requestSlice(int z,float *slicebuffer,MPI_Request *req);
  void waitForSlice(int z,float *slicebuffer,float *destbuffer,MPI_Request *req);
public:
  MPIO(IObase *io,MPIcomm &c);
  ~MPIO();
  void setLocalDims(int rank,int *origin, int *dims);
  virtual int write(IObase::DataType type,int rank,int *dims,void *data);
  void write(float *data);
};

void MPIO::sendSlice(int z,float *data,MPI_Request *req){
  int iz = z - localorigin[2];
  if(iz<0 || iz>=localdims[2]) return;
  //printf("sendslice %u\n",z);
  comm.isSend(root,z,localdims[0]*localdims[1],
	      data+localdims[0]*localdims[1]*iz,req[iz]);
}

#endif // __MPIO_HH_