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