rheolef  6.5
diststream.h
Go to the documentation of this file.
1 # ifndef _RHEOLEF_DISTSTREAM_H
2 # define _RHEOLEF_DISTSTREAM_H
3 // distributed i/o
4 #include "rheolef/distributed.h"
5 #include "rheolef/dis_macros.h"
6 #include "rheolef/catchmark.h"
7 namespace rheolef {
8 
9 class odiststream {
10 public:
11  typedef std::size_t size_type;
12 
13 // allocators/deallocators:
14 
16  : _ptr_os(0), _use_alloc(false), _comm() {}
17 
18  odiststream(std::ostream& os, const communicator& comm = communicator())
19  : _ptr_os(&os), _use_alloc(false), _comm(comm) {}
20 
21  odiststream (std::string filename, std::string suffix = "",
22  bool use_gzip = true,
23  const communicator& comm = communicator())
24  : _ptr_os(0), _use_alloc(false), _comm()
25  {
26  open (filename, suffix, use_gzip, comm);
27  }
28  ~odiststream();
29 
30 
31  void open (std::string filename, std::string suffix = "",
32  bool use_gzip = true,
33  const communicator& comm = communicator());
34  void flush();
35  void close();
36 
37 
38  const communicator& comm() const { return _comm; }
39  bool good() const;
40  operator bool() const { return good(); }
41  static size_type io_proc();
42 
43 public:
44  std::ostream& os() {
45  check_macro (_ptr_os != 0, "try to use an uninitialized odiststream");
46  return *_ptr_os;
47  }
48 #ifndef _RHEOLEF_HAVE_MPI
49  bool nop() { return false; }
50 #else
51  bool nop() { return size_type(_comm.rank()) != io_proc(); }
52 #endif //_RHEOLEF_HAVE_MPI
53 
54 protected:
55  std::ostream* _ptr_os;
56  bool _use_alloc;
57  communicator _comm;
58 };
59 // standard i/o:
60 # define define_sequential_odiststream_raw_macro(arg) \
61  inline \
62  odiststream& \
63  operator << (odiststream& s, arg) { \
64  if (s.nop()) return s; s.os() << x; return s; \
65  }
66 # define define_sequential_odiststream_macro(T) \
67  define_sequential_odiststream_raw_macro(const T& x)
68 
69 # define define_distributed_odiststream_macro(T) \
70  inline \
71  odiststream& \
72  operator << (odiststream& s, const T& x) { \
73  s.os() << x; return s; \
74  }
75 
76 template <class T>
77 inline
78 odiststream&
80  if (s.nop()) return s; s.os() << x; return s;
81 }
86 define_sequential_odiststream_macro(long unsigned int)
92 #ifdef _RHEOLEF_HAVE_DOUBLEDOUBLE
94 #endif // _RHEOLEF_HAVE_DOUBLEDOUBLE
96 define_sequential_odiststream_raw_macro(std::ostream& (*x)(std::ostream&))
97 
98 class idiststream {
99 public:
100  typedef std::size_t size_type;
101 
102 // allocators/deallocators:
103 
105  : _ptr_is(0), _use_alloc(false), _comm() {}
106 
107  idiststream (std::istream& is, const communicator& comm = communicator())
108  : _ptr_is(&is), _use_alloc(false), _comm(comm) {}
109 
110  idiststream (std::string filename, std::string suffix = "",
111  const communicator& comm = communicator())
112  : _ptr_is(0), _use_alloc(false), _comm()
113  {
114  open (filename, suffix, comm);
115  }
116 
117  ~idiststream();
118 
119 
120  void open (std::string filename, std::string suffix = "",
121  const communicator& comm = communicator());
122 
123  void close();
124 
125 
126  const communicator& comm() const { return _comm; }
127  bool good() const;
128  operator bool() const { return good(); }
129  static size_type io_proc();
130 
131 public:
132 #ifndef _RHEOLEF_HAVE_MPI
133  bool nop() { return false; }
134 #else
135  bool nop() { return size_type(_comm.rank()) != io_proc(); }
136 #endif //_RHEOLEF_HAVE_MPI
137 
138  std::istream& is() {
139  check_macro (_ptr_is != 0, "try to use an uninitialized idiststream");
140  return *_ptr_is;
141  }
142 #ifndef _RHEOLEF_HAVE_MPI
143  bool do_load() { return true; }
144 #else
145  bool do_load() { return size_type(_comm.rank()) == io_proc(); }
146 #endif // _RHEOLEF_HAVE_MPI
147 
148 protected:
149  std::istream* _ptr_is;
151  communicator _comm;
152 };
153 
154 #ifdef _RHEOLEF_HAVE_MPI
155 # define define_sequential_idiststream_macro(T) \
156 inline \
157 idiststream& \
158 operator >> (idiststream& s, T& x) \
159 { \
160  if (s.do_load()) { (s.is()) >> x; } \
161  mpi::broadcast (mpi::communicator(), x, s.io_proc()); \
162  return s; \
163 }
164 #else // _RHEOLEF_HAVE_MPI
165 # define define_sequential_idiststream_macro(T) \
166 inline \
167 idiststream& \
168 operator >> (idiststream& s, T& x) \
169 { \
170  (s.is()) >> x; \
171  return s; \
172 }
173 #endif // _RHEOLEF_HAVE_MPI
174 # define define_distributed_idiststream_macro(T) \
175 inline \
176 idiststream& \
177 operator >> (idiststream& s, T& x) \
178 { \
179  s.is() >> x; \
180  return s; \
181 }
182 
187 define_sequential_idiststream_macro(long unsigned int)
192 #ifdef _RHEOLEF_HAVE_DOUBLEDOUBLE
194 #endif // _RHEOLEF_HAVE_DOUBLEDOUBLE
195 
196 extern idiststream din;
197 extern odiststream dout;
200 
201 bool dis_scatch (idiststream& ips, const communicator& comm, std::string ch);
202 
203 inline
204 bool dis_scatch (idiststream& ips, std::string ch)
205 {
206  return dis_scatch (ips, ips.comm(), ch);
207 }
208 inline
209 idiststream&
210 operator>> (idiststream& ids, const catchmark& m)
211 {
212  if (ids.nop()) return ids;
213  ids.is() >> setmark(m.mark());
214  std::string label = "#" + m.mark();
215  if (!scatch(ids.is(),label)) {
216  bool verbose = iorheo::getverbose(ids.is());
217  if (verbose) warning_macro ("catchmark: label `"<< label <<"' not found on input");
218  }
219  return ids;
220 }
221 inline
222 odiststream&
224 {
225  if (ods.nop()) return ods;
226  ods.os() << setmark(m.mark())
227  << "#" << m.mark() << std::endl;
228  return ods;
229 }
230 int dis_system (const std::string& command, const communicator& comm = communicator());
231 bool dis_file_exists (const std::string& filename, const communicator& comm = communicator());
232 
233 
234 } // namespace rheolef
235 # endif // _RHEOLEF_DISTSTREAM_H
236