Rheolef  7.2
an efficient C++ finite element environment
 
Loading...
Searching...
No Matches
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
26namespace 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
133namespace rheolef {
134
136// [verbatim_odiststream]
138public:
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
178protected:
179// data:
180 std::ostream* _ptr_os;
182 communicator _comm;
183private:
184 odiststream(const odiststream&);
185 odiststream& operator= (const odiststream&);
186// [verbatim_odiststream_cont]
187};
188// [verbatim_odiststream_cont]
189
190// ------------------------------------------------------------------
191// inlined
192// ------------------------------------------------------------------
193inline
195 : _ptr_os(0), _use_alloc(false), _comm()
196{
197}
198inline
199odiststream::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}
204inline
205odiststream::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}
210inline
211odiststream::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}
216inline
217odiststream::odiststream (std::string filename, const communicator& comm)
218 : _ptr_os(0), _use_alloc(false), _comm()
219{
220 open (filename, comm);
221}
222inline
223odiststream::odiststream(std::ostream& os, const communicator& comm)
224 : _ptr_os(&os), _use_alloc(false), _comm(comm)
225{
226}
227inline
228void
229odiststream::open (std::string filename, io::mode_type mode, const communicator& comm)
230{
231 open (filename, std::string(""), mode, comm);
232}
233inline
234void
235odiststream::open (std::string filename, std::string suffix, const communicator& comm)
236{
237 open (filename, suffix, io::out, comm);
238}
239inline
240void
241odiststream::open (std::string filename, const communicator& comm)
242{
243 open (filename, std::string(""), io::out, comm);
244}
245inline
246std::ostream&
248 check_macro (_ptr_os != 0, "try to use an uninitialized odiststream");
249 return *_ptr_os;
250}
251#ifndef _RHEOLEF_HAVE_MPI
252inline bool odiststream::nop() { return false; }
253#else
254inline 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
294namespace details {
295template<class T, class Sfinae = void>
296struct is_omanip : std::false_type {};
297// const T& version : for rheolef::setbasename & such
298template<class T>
299struct 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
306template<class T>
307struct 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 ?
314template<>
315struct is_omanip <typename std::function<decltype(std::setprecision)>::result_type>
316 : std::true_type {};
317
318}// namespace details
319
320template <class T>
321typename std::enable_if<
322 details::is_omanip<T>::value
323 ,odiststream&
324>::type
325operator<< (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]
336class idiststream {
337public:
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
368protected:
369// data:
370 std::istream* _ptr_is;
371 bool _use_alloc;
372 communicator _comm;
373private:
374 idiststream(const idiststream&);
375 idiststream& operator= (const idiststream&);
376// [verbatim_idiststream_cont]
377};
378// [verbatim_idiststream_cont]
379// ------------------------------------------------------------------
380// inlined
381// ------------------------------------------------------------------
382inline
383idiststream::idiststream()
384 : _ptr_is(0), _use_alloc(false), _comm()
385{
386}
387inline
388idiststream::idiststream (std::istream& is, const communicator& comm)
389 : _ptr_is(&is), _use_alloc(false), _comm(comm)
390{
391}
392inline
393idiststream::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}
398inline
399std::istream&
400idiststream::is()
401{
402 check_macro (_ptr_is != 0, "try to use an uninitialized idiststream");
403 return *_ptr_is;
404}
405#ifndef _RHEOLEF_HAVE_MPI
406inline bool idiststream::nop() { return false; }
407inline bool idiststream::do_load() { return true; }
408#else
409inline bool idiststream::nop() { return size_type(_comm.rank()) != io_proc(); }
410inline 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) \
418inline \
419idiststream& \
420operator>> (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) \
428inline \
429idiststream& \
430operator>> (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
453inline
455operator>> (idiststream& s, std::istream& (*x)(std::istream&))
456{
457 s.is() >> x;
458 return s;
459}
460
461// predefined distributed streams
464extern idiststream din;
467extern odiststream dout;
470extern odiststream dlog;
473extern odiststream derr;
474
475bool dis_scatch (idiststream& ips, const communicator& comm, std::string ch);
476
477inline
478bool dis_scatch (idiststream& ips, std::string ch)
479{
480 return dis_scatch (ips, ips.comm(), ch);
481}
482inline
483idiststream&
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}
495inline
497operator<< (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:
505int dis_system (const std::string& command, const communicator& comm = communicator());
506bool 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.
communicator _comm
Definition diststream.h:182
std::size_t size_type
Definition diststream.h:139
static size_type io_proc()
Definition diststream.cc:79
const communicator & comm() const
Definition diststream.h:167
#define warning_macro(message)
Definition dis_macros.h:53
#define _RHEOLEF_define_sequential_odiststream_raw_macro(arg)
Definition diststream.h:260
#define _RHEOLEF_define_sequential_idiststream_macro(T)
Definition diststream.h:417
#define _RHEOLEF_define_sequential_odiststream_macro(T)
Definition diststream.h:268
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)")
This file is part of Rheolef.
std::ostream & operator<<(std::ostream &os, const catchmark &m)
Definition catchmark.h:99
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
bool dis_scatch(idiststream &ips, const communicator &comm, std::string ch)
distributed version of scatch(istream&,string)
Definition diststream.cc:44
int dis_system(const std::string &command, const communicator &comm)
bool dis_file_exists(const std::string &filename, const communicator &comm)
std::istream & operator>>(std::istream &is, const catchmark &m)
Definition catchmark.h:88
STL namespace.