1 #ifndef LIBGEODECOMP_IO_PARALLELWRITER_H 2 #define LIBGEODECOMP_IO_PARALLELWRITER_H 3 4 #include <libgeodecomp/config.h> 5 #include <libgeodecomp/io/writer.h> 6 #include <libgeodecomp/geometry/coord.h> 7 #include <libgeodecomp/geometry/region.h> 8 #include <libgeodecomp/parallelization/distributedsimulator.h> 9 10 #include <string> 11 #include <stdexcept> 12 13 namespace LibGeoDecomp { 14 15 template<typename CELL_TYPE> 16 class DistributedSimulator; 17 18 /** 19 * ParallelWriter is the parent class for all parallel IO. Its being 20 * used with ParallelSimulator, which contrasts it from Writer. Just 21 * like writer, it defines a number of callbacks which are invoked by 22 * the simulator. Also, ParallelWriter registers at the 23 * DistributedSimulator, which will delete it upon its destruction. 24 * Never allocate a ParallelWriter on the stack! 25 * 26 * A conceptual difference from Writer should be noted: multiple 27 * ParallelWriter objects of the same type will exists, typically one 28 * per MPI process. Thus one either needs to use MPI IO or individual 29 * files per instance. For other differences see below. 30 */ 31 template<typename CELL_TYPE> 32 class ParallelWriter 33 { 34 public: 35 friend class Serialization; 36 typedef typename APITraits::SelectTopology<CELL_TYPE>::Value Topology; 37 typedef typename DistributedSimulator<CELL_TYPE>::GridType GridType; 38 typedef Region<Topology::DIM> RegionType; 39 typedef Coord<Topology::DIM> CoordType; 40 41 /** 42 * is the equivalent to Writer(). 43 */ ParallelWriter(const std::string & prefix,const unsigned & period)44 ParallelWriter( 45 const std::string& prefix, 46 const unsigned& period) : 47 prefix(prefix), 48 period(period) 49 { 50 if (period == 0) { 51 throw std::invalid_argument("period must be positive"); 52 } 53 } 54 ~ParallelWriter()55 virtual ~ParallelWriter() 56 {} 57 58 /** 59 * "virtual copy constructor". This function may be called 60 * whenever a deep copy of a writer is needed instead of a plain 61 * pointer copy. 62 * 63 * Advice to implementers: use CRTP ( 64 * http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern 65 * ) to implemenent this automagically -- see other Writer 66 * implemenent for advice on this subject. 67 */ 68 virtual ParallelWriter *clone() const = 0; 69 70 /** 71 * notifies the ParallelWriter that the supplied region is the 72 * domain of the current process. This fuction will be called once 73 * the domain decomposition has been done. Writers can use this 74 * information to decide on the size of buffers to allocate or 75 * determine file offsets. validRegion in stepFinished() will 76 * always be a subset of newRegion. 77 */ setRegion(const Region<Topology::DIM> & newRegion)78 virtual void setRegion(const Region<Topology::DIM>& newRegion) 79 { 80 region = newRegion; 81 } 82 83 /** 84 * is called back from sim after each simulation step. event 85 * specifies the phase in which the simulation is currently in. 86 * This may be used for instance to open/close files at the 87 * beginning/end of the simulation. lastCall is set to true if 88 * this is the final invocation for this step -- handy if the 89 * simulator needs to call the writer multiple times for different 90 * parts of the grid (e.g. for the ghost zones and then again for 91 * the interior of the domain). 92 */ 93 virtual void stepFinished( 94 const GridType& grid, 95 const RegionType& validRegion, 96 const CoordType& globalDimensions, 97 unsigned step, 98 WriterEvent event, 99 std::size_t rank, 100 bool lastCall) = 0; 101 getPeriod()102 const unsigned& getPeriod() const 103 { 104 return period; 105 } 106 getPrefix()107 const std::string& getPrefix() const 108 { 109 return prefix; 110 } 111 112 protected: 113 Region<Topology::DIM> region; 114 std::string prefix; 115 unsigned period; 116 }; 117 118 } 119 120 #endif 121