Rheolef  7.2
an efficient C++ finite element environment
diststream.h
Go to the documentation of this file.
1 # ifndef _RHEOLEF_DISTSTREAM_H
2 # define _RHEOLEF_DISTSTREAM_H
3 //
4 // This file is part of Rheolef.
5 //
6 // Copyright (C) 2000-2009 Pierre Saramito <Pierre.Saramito@imag.fr>
7 //
8 // Rheolef is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // Rheolef is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with Rheolef; if not, write to the Free Software
20 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 //
22 // =========================================================================
23 // AUTHORS: Pierre.Saramito@imag.fr
24 // DATE: 31 october 1997 ; 13 nov 1998
25 
26 namespace rheolef {
116 } // namespace rheolef
117 
118 #include "rheolef/communicator.h"
119 #include "rheolef/dis_macros.h"
120 #include "rheolef/catchmark.h"
121 
122 // to propagate operator<< from ostream& to odiststream&
123 // TODO: do better ? --> yes: dot it in this order in "linalg.h" & "rheolef.h"
124 #include <iomanip> // dout << std::setprecision()
125 #ifdef TO_CLEAN
126 #include "rheolef/iorheo.h" // dout << setbasename()
127 #include "rheolef/point.h" // dout << point()
128 #include "rheolef/tensor.h"
129 #include "rheolef/tensor3.h"
130 #include "rheolef/tensor4.h"
131 #endif // TO_CLEAN
132 
133 namespace rheolef {
134 
136 // [verbatim_odiststream]
137 class odiststream {
138 public:
139  typedef std::size_t size_type;
140 
141 // allocators/deallocators:
142 
143  odiststream();
144  odiststream (std::string filename, std::string suffix = "",
145  io::mode_type mode = io::out, const communicator& comm = communicator());
146  odiststream (std::string filename,
147  io::mode_type mode, const communicator& comm = communicator());
148  odiststream (std::string filename, std::string suffix, const communicator& comm);
149  odiststream (std::string filename, const communicator& comm);
150  odiststream(std::ostream& os, const communicator& comm = communicator());
151  ~odiststream();
152 
153 // modifiers:
154 
155  void open (std::string filename, std::string suffix = "",
156  io::mode_type mode = io::out, const communicator& comm = communicator());
157  void open (std::string filename,
158  io::mode_type mode, const communicator& comm = communicator());
159  void open (std::string filename, std::string suffix,
160  const communicator& comm);
161  void open (std::string filename, const communicator& comm);
162  void flush();
163  void close();
164 
165 // accessors:
166 
167  const communicator& comm() const { return _comm; }
168  bool good() const;
169  operator bool() const { return good(); }
170  static size_type io_proc();
171 // [verbatim_odiststream]
172 
173 // internals:
174 
175  std::ostream& os();
176  bool nop();
177 
178 protected:
179 // data:
180  std::ostream* _ptr_os;
182  communicator _comm;
183 private:
184  odiststream(const odiststream&);
185  odiststream& operator= (const odiststream&);
186 // [verbatim_odiststream_cont]
187 };
188 // [verbatim_odiststream_cont]
189 
190 // ------------------------------------------------------------------
191 // inlined
192 // ------------------------------------------------------------------
193 inline
195  : _ptr_os(0), _use_alloc(false), _comm()
196 {
197 }
198 inline
199 odiststream::odiststream (std::string filename, std::string suffix, io::mode_type mode, const communicator& comm)
200  : _ptr_os(0), _use_alloc(false), _comm()
201 {
202  open (filename, suffix, mode, comm);
203 }
204 inline
205 odiststream::odiststream (std::string filename, io::mode_type mode, const communicator& comm)
206  : _ptr_os(0), _use_alloc(false), _comm()
207 {
208  open (filename, mode, comm);
209 }
210 inline
211 odiststream::odiststream (std::string filename, std::string suffix, const communicator& comm)
212  : _ptr_os(0), _use_alloc(false), _comm()
213 {
214  open (filename, suffix, comm);
215 }
216 inline
217 odiststream::odiststream (std::string filename, const communicator& comm)
218  : _ptr_os(0), _use_alloc(false), _comm()
219 {
220  open (filename, comm);
221 }
222 inline
223 odiststream::odiststream(std::ostream& os, const communicator& comm)
224  : _ptr_os(&os), _use_alloc(false), _comm(comm)
225 {
226 }
227 inline
228 void
229 odiststream::open (std::string filename, io::mode_type mode, const communicator& comm)
230 {
231  open (filename, std::string(""), mode, comm);
232 }
233 inline
234 void
235 odiststream::open (std::string filename, std::string suffix, const communicator& comm)
236 {
237  open (filename, suffix, io::out, comm);
238 }
239 inline
240 void
241 odiststream::open (std::string filename, const communicator& comm)
242 {
243  open (filename, std::string(""), io::out, comm);
244 }
245 inline
246 std::ostream&
248  check_macro (_ptr_os != 0, "try to use an uninitialized odiststream");
249  return *_ptr_os;
250 }
251 #ifndef _RHEOLEF_HAVE_MPI
252 inline bool odiststream::nop() { return false; }
253 #else
254 inline bool odiststream::nop() { return size_type(_comm.rank()) != io_proc(); }
255 #endif //_RHEOLEF_HAVE_MPI
256 
257 // ------------------------------------------------------------------
258 // standard i/o:
259 // ------------------------------------------------------------------
260 # define _RHEOLEF_define_sequential_odiststream_raw_macro(arg) \
261  inline \
262  odiststream& \
263  operator << (odiststream& s, arg) { \
264  if (s.nop()) return s; \
265  s.os() << x; \
266  return s; \
267  }
268 # define _RHEOLEF_define_sequential_odiststream_macro(T) \
269  _RHEOLEF_define_sequential_odiststream_raw_macro(const T& x)
270 
281 #ifdef _RHEOLEF_HAVE_FLOAT128
282 _RHEOLEF_define_sequential_odiststream_macro(boost::multiprecision::float128)
283 #endif // _RHEOLEF_HAVE_FLOAT128
285 _RHEOLEF_define_sequential_odiststream_raw_macro(std::ostream& (*x)(std::ostream&))
286 #undef _RHEOLEF_define_sequential_odiststream_macro
287 
288 // output all small objects that have an
289 // ostream& operator<<
290 // IMPLEMENTATION NOTE:
291 // the ostream& operator<< should have been already known here
292 // thus, have to #include "point.h" at the top of this file
293 // otherwise it fails: any other solution
294 namespace details {
295 template<class T, class Sfinae = void>
296 struct is_omanip : std::false_type {};
297 // const T& version : for rheolef::setbasename & such
298 template<class T>
299 struct is_omanip <T,typename std::enable_if<
300  std::is_pointer<decltype(static_cast<std::ostream& (*)(std::ostream&, const T&)>
301  (operator<<))>::value>::type>
302  : std::true_type {};
303 // T version : for std::setprecision & such, but fails (see below)
304 // note: could not be merged with the previous enable_if
305 // otherwise it fails
306 template<class T>
307 struct is_omanip <T,typename std::enable_if<
308  std::is_pointer<decltype(static_cast<std::ostream& (*)(std::ostream&, T)>
309  (operator<<))>::value>::type>
310  : std::true_type {};
311 
312 // explicit version for std::setprecision (otherwise it fails)
313 // TODO: how to have a more implicit way ? for all std::iomanips ?
314 template<>
315 struct is_omanip <typename std::function<decltype(std::setprecision)>::result_type>
316  : std::true_type {};
317 
318 }// namespace details
319 
320 template <class T>
321 typename std::enable_if<
322  details::is_omanip<T>::value
323  ,odiststream&
324 >::type
325 operator<< (odiststream& s, const T& x)
326 {
327  if (s.nop()) return s;
328  s.os() << x;
329  return s;
330 }
331 
332 // =============================================================================
333 
335 // [verbatim_idiststream]
336 class idiststream {
337 public:
338  typedef std::size_t size_type;
339 
340 // allocators/deallocators:
341 
342  idiststream();
343  idiststream (std::istream& is, const communicator& comm = communicator());
344  idiststream (std::string filename, std::string suffix = "",
345  const communicator& comm = communicator());
346  ~idiststream();
347 
348 // modifiers:
349 
350  void open (std::string filename, std::string suffix = "",
351  const communicator& comm = communicator());
352  void close();
353 
354 // accessors:
355 
356  const communicator& comm() const { return _comm; }
357  bool good() const;
358  operator bool() const { return good(); }
359  static size_type io_proc();
360 // [verbatim_idiststream]
361 
362 // internals:
363 
364  std::istream& is();
365  bool nop();
366  bool do_load();
367 
368 protected:
369 // data:
370  std::istream* _ptr_is;
371  bool _use_alloc;
372  communicator _comm;
373 private:
374  idiststream(const idiststream&);
375  idiststream& operator= (const idiststream&);
376 // [verbatim_idiststream_cont]
377 };
378 // [verbatim_idiststream_cont]
379 // ------------------------------------------------------------------
380 // inlined
381 // ------------------------------------------------------------------
382 inline
383 idiststream::idiststream()
384  : _ptr_is(0), _use_alloc(false), _comm()
385 {
386 }
387 inline
388 idiststream::idiststream (std::istream& is, const communicator& comm)
389  : _ptr_is(&is), _use_alloc(false), _comm(comm)
390 {
391 }
392 inline
393 idiststream::idiststream (std::string filename, std::string suffix, const communicator& comm)
394  : _ptr_is(0), _use_alloc(false), _comm()
395 {
396  open (filename, suffix, comm);
397 }
398 inline
399 std::istream&
400 idiststream::is()
401 {
402  check_macro (_ptr_is != 0, "try to use an uninitialized idiststream");
403  return *_ptr_is;
404 }
405 #ifndef _RHEOLEF_HAVE_MPI
406 inline bool idiststream::nop() { return false; }
407 inline bool idiststream::do_load() { return true; }
408 #else
409 inline bool idiststream::nop() { return size_type(_comm.rank()) != io_proc(); }
410 inline bool idiststream::do_load() { return size_type(_comm.rank()) == io_proc(); }
411 #endif //_RHEOLEF_HAVE_MPI
412 
413 // ------------------------------------------------------------------
414 // standard i/o:
415 // ------------------------------------------------------------------
416 #ifdef _RHEOLEF_HAVE_MPI
417 # define _RHEOLEF_define_sequential_idiststream_macro(T) \
418 inline \
419 idiststream& \
420 operator>> (idiststream& s, T& x) \
421 { \
422  if (s.do_load()) { (s.is()) >> x; } \
423  mpi::broadcast (mpi::communicator(), x, s.io_proc()); \
424  return s; \
425 }
426 #else // _RHEOLEF_HAVE_MPI
427 # define _RHEOLEF_define_sequential_idiststream_macro(T) \
428 inline \
429 idiststream& \
430 operator>> (idiststream& s, T& x) \
431 { \
432  (s.is()) >> x; \
433  return s; \
434 }
435 #endif // _RHEOLEF_HAVE_MPI
436 
446 #ifdef _RHEOLEF_HAVE_FLOAT128
447 _RHEOLEF_define_sequential_idiststream_macro(boost::multiprecision::float128)
448 #endif // _RHEOLEF_HAVE_FLOAT128
449 
450 #undef _RHEOLEF_define_sequential_idiststream_macro
451 
452 // iomanips such as: ids << noverbose
453 inline
454 idiststream&
455 operator>> (idiststream& s, std::istream& (*x)(std::istream&))
456 {
457  s.is() >> x;
458  return s;
459 }
460 
461 // predefined distributed streams
474 
475 bool dis_scatch (idiststream& ips, const communicator& comm, std::string ch);
476 
477 inline
478 bool dis_scatch (idiststream& ips, std::string ch)
479 {
480  return dis_scatch (ips, ips.comm(), ch);
481 }
482 inline
483 idiststream&
485 {
486  if (ids.nop()) return ids;
487  ids.is() >> setmark(m.mark());
488  std::string label = "#" + m.mark();
489  if (!scatch(ids.is(),label)) {
490  bool verbose = iorheo::getverbose(ids.is());
491  if (verbose) warning_macro ("catchmark: label `"<< label <<"' not found on input");
492  }
493  return ids;
494 }
495 inline
497 operator<< (odiststream& ods, const catchmark& m)
498 {
499  if (ods.nop()) return ods;
500  ods.os() << setmark(m.mark())
501  << "#" << m.mark() << std::endl;
502  return ods;
503 }
504 // system utilities:
505 int dis_system (const std::string& command, const communicator& comm = communicator());
506 bool dis_file_exists (const std::string& filename, const communicator& comm = communicator());
507 
508 
509 } // namespace rheolef
510 # endif // _RHEOLEF_DISTSTREAM_H
field::size_type size_type
Definition: branch.cc:430
see the communicator page for the full documentation
see the catchmark page for the full documentation
Definition: catchmark.h:67
idiststream: see the diststream page for the full documentation
Definition: diststream.h:336
std::istream & is()
Definition: diststream.h:400
const communicator & comm() const
Definition: diststream.h:356
odiststream: see the diststream page for the full documentation
Definition: diststream.h:137
std::ostream * _ptr_os
Definition: diststream.h:180
std::ostream & os()
Definition: diststream.h:247
void open(std::string filename, std::string suffix="", io::mode_type mode=io::out, const communicator &comm=communicator())
This routine opens a physical output file.
Definition: diststream.cc:144
communicator _comm
Definition: diststream.h:182
std::size_t size_type
Definition: diststream.h:139
bool good() const
Definition: diststream.cc:195
const communicator & comm() const
Definition: diststream.h:167
static size_type io_proc()
Definition: diststream.cc:79
idiststream din(cin)
see the diststream page for the full documentation
Definition: diststream.h:464
odiststream dlog(clog)
see the diststream page for the full documentation
Definition: diststream.h:470
odiststream dout(cout)
see the diststream page for the full documentation
Definition: diststream.h:467
odiststream derr(cerr)
see the diststream page for the full documentation
Definition: diststream.h:473
#define warning_macro(message)
Definition: dis_macros.h:53
#define _RHEOLEF_define_sequential_odiststream_raw_macro(arg)
Definition: diststream.h:260
Expr1::float_type T
Definition: field_expr.h:230
check_macro(expr1.have_homogeneous_space(Xh1), "dual(expr1,expr2); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),expr2)")
string command
Definition: mkgeo_ball.sh:136
This file is part of Rheolef.
std::istream & operator>>(std::istream &is, const catchmark &m)
Definition: catchmark.h:88
bool scatch(std::istream &in, const std::string &ch, bool full_match=true)
scatch: see the rheostream page for the full documentation
Definition: scatch.icc:44
int dis_system(const std::string &command, const communicator &comm)
Definition: diststream.cc:214
bool dis_scatch(idiststream &ips, const communicator &comm, std::string ch)
distributed version of scatch(istream&,string)
Definition: diststream.cc:44
bool dis_file_exists(const std::string &filename, const communicator &comm)
Definition: diststream.cc:233
std::ostream & operator<<(std::ostream &os, const catchmark &m)
Definition: catchmark.h:99
_RHEOLEF_define_sequential_odiststream_macro(char) _RHEOLEF_define_sequential_odiststream_macro(int) _RHEOLEF_define_sequential_odiststream_macro(unsigned int) _RHEOLEF_define_sequential_odiststream_macro(long int) _RHEOLEF_define_sequential_odiststream_macro(long unsigned int) _RHEOLEF_define_sequential_odiststream_macro(float) _RHEOLEF_define_sequential_odiststream_macro(double) _RHEOLEF_define_sequential_odiststream_macro(long double) _RHEOLEF_define_sequential_odiststream_macro(char *const) _RHEOLEF_define_sequential_odiststream_macro(std
Definition: diststream.h:271
_RHEOLEF_define_sequential_idiststream_macro(char) _RHEOLEF_define_sequential_idiststream_macro(int) _RHEOLEF_define_sequential_idiststream_macro(long int) _RHEOLEF_define_sequential_idiststream_macro(unsigned int) _RHEOLEF_define_sequential_idiststream_macro(long unsigned int) _RHEOLEF_define_sequential_idiststream_macro(float) _RHEOLEF_define_sequential_idiststream_macro(double) _RHEOLEF_define_sequential_idiststream_macro(long double) _RHEOLEF_define_sequential_idiststream_macro(std
Definition: diststream.h:437