dune-fem  2.4.1-rc
sionlibstreams.hh
Go to the documentation of this file.
1 #ifndef DUNE_FEM_SIONLIBSTREAMS_HH
2 #define DUNE_FEM_SIONLIBSTREAMS_HH
3 
6 
8 
9 #include <dune/common/parallel/collectivecommunication.hh>
10 #include <dune/common/parallel/mpicollectivecommunication.hh>
11 
12 #if HAVE_SIONLIB
13 
14 #if HAVE_MPI
15 #define SION_MPI
16 #endif
17 
18 #include <sion.h>
19 #endif
20 
21 namespace Dune
22 {
23 
24  namespace Fem
25  {
26 
39  //template <class Communicator>
41  {
42  //typedef SIONlibOutStream< Communicator > ThisType;
43  typedef SIONlibOutStream ThisType;
45 
46  typedef MPIHelper :: MPICommunicator MPICommunicatorType;
47 
48  // don't allow copying because of interal pointers
50  public:
59  SIONlibOutStream ( const std::string &filename, const int rank,
60  MPICommunicatorType mpiComm, ParameterReader parameter = Parameter::container() )
61  : BaseType( dataStream() ),
62  filename_( filename ),
63  mpiComm_( mpiComm ),
64  rank_( rank ),
65  numFiles_( std::min( MPIManager::size(), parameter.getValue< int >( "fem.io.sionlib.numfiles", 1 ) ) ),
66  blockSize_( parameter.getValue< int >( "fem.io.sionlib.blocksize", -1 ) )
67  {}
68 
69  SIONlibOutStream ( const std::string &filename, ParameterReader parameter = Parameter::container() )
70  : SIONlibOutStream( filename, MPIManager::rank(), MPIHelper :: getCommunicator(), parameter )
71  {}
72 
73  SIONlibOutStream ( const std::string &filename, const int rank, ParameterReader parameter = Parameter::container() )
74  : SIONlibOutStream( filename, rank, MPIHelper :: getCommunicator(), parameter )
75  {}
76 
79  {
80  writeFile();
81  delete data_; data_ = 0;
82  }
83 
84  protected:
85  std::ostream& dataStream()
86  {
87  // init data stream
88  data_ = new std::stringstream();
89  assert( data_ );
90  return *data_;
91  }
92 
93  void writeFile()
94  {
95 #if HAVE_SIONLIB && HAVE_MPI
96  if( data_ )
97  {
98  // get data buffer
99  std::string data ( data_->str() );
100 
101  // get chunk size for this process
102  // use sionlib int64
103  sion_int64 chunkSize = data.size();
104 
105  // file mode is: write byte
106  const char* fileMode = "wb";
107 
108  // number of physical files to be created
109  int numFiles = numFiles_;
110 
111  // block size of filesystem, -1 use system default
112  int blockSize = blockSize_;
113 
114  // my rank
115  int rank = rank_;
116  // file pointer
117  FILE* file = 0;
118 
119  // open sion file
120  int sid =
121  sion_paropen_mpi( (char *) filename_.c_str(),
122  (char *) fileMode,
123  &numFiles, // number of physical files
124  mpiComm_, // global comm
125  &mpiComm_, // local comm
126  &chunkSize, // maximal size of data to be written
127  &blockSize, // filesystem block size
128  &rank, // my rank
129  &file, // file pointer that is set by sion lib
130  NULL
131  );
132  if( sid == -1 )
133  DUNE_THROW( IOError, "opening sion_paropen_mpi for writing failed!" << filename_ );
134 
135  assert( file );
136 
137  // get pointer to buffer
138  const char* buffer = data.c_str();
139  // write data
140  assert( sizeof(char) == 1 );
141  sion_fwrite( buffer, 1, chunkSize, sid);
142 
143  // close file
144  sion_parclose_mpi( sid );
145  }
146 #else
147  std::cerr << "WARNING: SIONlib or MPI not available" << std::endl;
148 #endif
149  }
150 
152  std::stringstream* data_;
153 
154  const std::string filename_;
155  MPICommunicatorType mpiComm_;
156 
157  const int rank_;
158  const int numFiles_;
159  const int blockSize_;
160  };
161 
172  //template <class Communicator>
174  {
175  typedef SIONlibInStream ThisType;
176  typedef StandardInStream BaseType;
177 
178  typedef MPIHelper :: MPICommunicator MPICommunicatorType;
179 
180  // don't allow copying because of interal pointers
181  SIONlibInStream( const SIONlibInStream& ) ;
182  public:
191  SIONlibInStream ( const std::string &filename,
192  const int rank = MPIManager :: rank(),
193  MPICommunicatorType mpiComm = MPIHelper :: getCommunicator() )
194  : BaseType( readFile( filename , rank, mpiComm ) )
195  {
196  }
197 
200  {
201  delete data_; data_ = 0;
202  }
203 
204  protected:
205  std::istream& readFile( const std::string& filename,
206  int rank,
207  MPICommunicatorType mpiComm )
208  {
209  data_ = new std::stringstream();
210  assert( data_ );
211 #if HAVE_SIONLIB
212  // chunkSize is set by sion_paropen_mpi
213  sion_int64 chunkSize = 0;
214  // file mode is: read byte
215  const char* fileMode = "rb";
216 
217  // blockSize, is recovered from stored files
218  int blockSize = -1;
219 
220  // file handle
221  FILE* file = 0;
222 
223  // sion file handle
224  int sid = 0;
225 
226 #if HAVE_MPI
227  // number of files, is overwritten by sion_open
228  int numFiles = 1;
229 
230  // if MPI is avaialbe use sion_paropen_mpi
231  const int mpiSize = MPIManager :: size () ;
232 
233  if( mpiSize > 1 )
234  {
235  // open sion file
236  sid = sion_paropen_mpi( (char *) filename.c_str(),
237  (char *) fileMode,
238  &numFiles, // numFiles
239  mpiComm, // global comm
240  &mpiComm, // local comm
241  &chunkSize, // is set by library
242  &blockSize, // block size
243  &rank, // my rank
244  &file, // file pointer that is set by sion lib
245  NULL
246  );
247 
248  if( sid == -1 )
249  DUNE_THROW( IOError, "opening sion_paropen_mpi for reading failed!" << filename );
250  }
251  else
252 #endif
253  // serial open of file
254  {
255  // open sion file for reading only rank information
256  sid = sion_open_rank( (char *) filename.c_str(),
257  (char *) fileMode,
258  &chunkSize, // is set by library
259  &blockSize, // block size
260  &rank, // my rank
261  &file // file pointer that is set by sion lib
262  );
263 
264  if( sid == -1 )
265  DUNE_THROW( IOError, "opening sion_ropen for reading failed!" << filename );
266  }
267 
268  assert( file );
269 
270  // get bytes available for reading (might differ from total chunkSize)
271  chunkSize = sion_bytes_avail_in_block( sid );
272 
273  // create buffer
274  std::string data;
275  data.resize( chunkSize );
276 
277  // get pointer to buffer
278  char* buffer = (char *) data.c_str();
279  assert( sizeof(char) == 1 );
280  // read data
281  sion_fread( buffer, 1, chunkSize, sid );
282 
283  // write data to stream
284  data_ = new std::stringstream();
285  assert( data_ );
286  data_->write( buffer, chunkSize );
287 
288 #if HAVE_MPI
289  // close file
290  if( mpiSize > 1 )
291  {
292  sion_parclose_mpi( sid );
293  }
294  else
295 #endif
296  {
297  sion_close( sid );
298  }
299 #endif // HAVE_SIONLIB
300 
301  return *data_;
302  }
303 
305  std::stringstream* data_;
306  };
307 
311  template <>
313  {
315  typedef MPIHelper :: MPICommunicator MPICommunicatorType;
316 
323  static SIONlibInStream* create( const std::string& filename,
324  const int rank = MPIManager::rank(),
325  const MPICommunicatorType& mpiComm = MPIHelper :: getCommunicator() )
326  {
327  return new SIONlibInStream( filename, rank, mpiComm );
328  }
329  };
330 
331  } // namespace Fem
332 
333 } // namespace Dune
334 
335 #endif // #ifndef DUNE_FEM_BINARYSTREAMS_HH
~SIONlibOutStream()
destructor writing internal data buffer to the file via SIONlib
Definition: sionlibstreams.hh:78
std::stringstream * data_
standard file stream
Definition: sionlibstreams.hh:305
input stream reading from a given std::istream
Definition: standardstreams.hh:194
static int rank()
Definition: mpimanager.hh:116
void writeFile()
Definition: sionlibstreams.hh:93
SIONlibInStream(const std::string &filename, const int rank=MPIManager::rank(), MPICommunicatorType mpiComm=MPIHelper::getCommunicator())
constructor
Definition: sionlibstreams.hh:191
~SIONlibInStream()
destructor deleting interal data buffer
Definition: sionlibstreams.hh:199
MPIHelper::MPICommunicator MPICommunicatorType
type of MPI communicator
Definition: sionlibstreams.hh:315
static int size()
Definition: mpimanager.hh:121
SIONlibOutStream(const std::string &filename, const int rank, MPICommunicatorType mpiComm, ParameterReader parameter=Parameter::container())
constructor
Definition: sionlibstreams.hh:59
std::istream & readFile(const std::string &filename, int rank, MPICommunicatorType mpiComm)
Definition: sionlibstreams.hh:205
const int blockSize_
Definition: sionlibstreams.hh:159
Factory class for Fem Streams to deal with different constructor parameters.
Definition: streams.hh:358
output stream writing into a given std::ostream
Definition: standardstreams.hh:59
Definition: coordinate.hh:4
std::ostream & dataStream()
Definition: sionlibstreams.hh:85
Definition: mpimanager.hh:19
output stream writing into a single file with the SIONlib (http://www2.fz-juelich.de/jsc/sionlib/)
Definition: sionlibstreams.hh:40
const int numFiles_
Definition: sionlibstreams.hh:158
static ParameterContainer & container()
Definition: io/parameter.hh:190
STL namespace.
const int rank_
Definition: sionlibstreams.hh:157
const std::string filename_
Definition: sionlibstreams.hh:154
SIONlibOutStream(const std::string &filename, const int rank, ParameterReader parameter=Parameter::container())
Definition: sionlibstreams.hh:73
MPICommunicatorType mpiComm_
Definition: sionlibstreams.hh:155
std::stringstream * data_
standard file stream
Definition: sionlibstreams.hh:152
SIONlibOutStream(const std::string &filename, ParameterReader parameter=Parameter::container())
Definition: sionlibstreams.hh:69
static SIONlibInStream * create(const std::string &filename, const int rank=MPIManager::rank(), const MPICommunicatorType &mpiComm=MPIHelper::getCommunicator())
return pointer to stream object created by new.
Definition: sionlibstreams.hh:323
input stream reading from a file in binary form
Definition: sionlibstreams.hh:173
static double min(const Double &v, const double p)
Definition: double.hh:375