Sierra Toolkit Version of the Day
mpi_filebuf.hpp
00001 /* ------------------------------------------------------------------ */
00002 /* Copyright 2000 Sandia Corporation, Albuquerque, NM.                */
00003 /* ------------------------------------------------------------------ */
00004 
00005 #ifndef STK_UTIL_PARALLEL_mpi_filebuf_hpp
00006 #define STK_UTIL_PARALLEL_mpi_filebuf_hpp
00007 
00008 #include <ios>
00009 #include <iostream>
00010 #include <cstdio>
00011 #include <mpi.h>
00012 
00013 //: Specialize the ANSI Standard C++ streambuf class
00014 //: for a parallel file buffer.  The actual file is
00015 //: only touched by the root processor.
00016 //
00017 //  READ MODE: The file is read on the root processor and
00018 //  broadcast one buffer at a time to the remaining processors.
00019 //
00020 //  WRITE MODE: Each processor has a buffer that is locally
00021 //  filled.  When the buffer is full on the root processor the
00022 //  buffer is written to the output file.  When the buffer is
00023 //  full on any other processor the size of the buffer is doubled.
00024 //  The 'mpi_filebuf::flush' method gathers all buffers on the
00025 //  root processor and writes the buffers to the output file.
00026 //
00027 //  GLOBAL: Calls to the 'open', 'flush', 'close', destructor,
00028 //  and 'underflow' methods are global; these calls must be
00029 //  made on all processors.  The 'underflow' method is called
00030 //  by the 'istream' that uses the 'mpi_filebuf' object when
00031 //  ever the input buffer is empty.  Thus reading from an 'istream'
00032 //  that uses an 'mpi_filebuf' must be globally consistent.
00033 
00034 class mpi_filebuf : public std::streambuf {
00035 public:
00036 
00037   //: Construct an MPI-parallel input/output file buffer
00038   mpi_filebuf();
00039 
00040   //: GLOBAL: Open a file.
00041   // The file name is only significant on the root processsor.
00042   // May only be opened as ios::in, ios::out, ios:app.
00043   mpi_filebuf * open(
00044     MPI_Comm       communicator ,       /* All processors */
00045     const int            root_processor ,     /* All processors */
00046     const std::ios_base::openmode file_mode , /* All processors */
00047     const char * const   file_name = NULL );  /* Root processor */
00048 
00049   //: GLOBAL: Close the file.
00050   // If output mode then flush the output.
00051   mpi_filebuf * close();
00052 
00053   //: GLOBAL: Flush the buffered output to the file.
00054   // Sends all buffers to the root processor,
00055   // write to the file, and flushes the file.
00056   mpi_filebuf * flush();
00057 
00058   //: GLOBAL: Destructor
00059   //  Close and then reclaim memory.
00060   virtual ~mpi_filebuf();
00061 
00062   //: Query if open, a local operations
00063   int is_open() const ;
00064 
00065   //: When the file buffer is in the 'closed' state set the buffer length,
00066   //  The input argument must be consistent on all processors; however,
00067   //  this condition is not checked until the next 'open' operation.
00068   mpi_filebuf * set_buffer_length( const size_t buffer_length );
00069 
00070   //: Query the current buffer
00071   void get_buffer( const char * & , size_t & ) const ;
00072 
00073   //: Query wall-clock time spent communicating.
00074   double wtime() const ;
00075 
00076 protected:
00077 
00078   //: Called to refill the input buffer
00079   virtual int underflow();
00080 
00081   //: Called when output buffer is filled
00082   virtual int overflow( int c = EOF );
00083 
00084   //: Sync is a no-op
00085   virtual int sync();
00086 
00087   //: Setbuf is a no-op
00088   virtual std::streambuf * setbuf( char * s , std::streamsize n );
00089 
00090 private:
00091 
00092   mpi_filebuf( const mpi_filebuf & ); // Not allowed
00093   mpi_filebuf & operator = ( const mpi_filebuf & ); // Not allowed
00094 
00095   MPI_Comm  comm ;            // Communicator
00096   int comm_root ;       // Rank of root processor
00097   std::FILE *   comm_root_fp ;    // Root processor's file
00098   int comm_output ;     // Output file
00099   char *  comm_buffer ;     // local buffer
00100   size_t  comm_buffer_len ; // length of buffer
00101   double  comm_time ;       // wall-time spent communicating
00102 };
00103 
00104 /*--------------------------------------------------------------------*/
00105 
00106 inline int  mpi_filebuf::is_open() const { return NULL != comm_buffer ; }
00107 
00108 /* The SUN has the 'streambuf::pptr()' as a non-const method,
00109    which violates the ISO/ANSI standard specification.
00110    Therefore, must cast away the const. */
00111 
00112 inline void mpi_filebuf::get_buffer( const char * & b , size_t & n ) const
00113   { b = comm_buffer ; n = ((mpi_filebuf*)this)->pptr() - comm_buffer ; }
00114 
00115 inline double mpi_filebuf::wtime() const { return comm_time ; }
00116 
00117 #endif // STK_UTIL_PARALLEL_mpi_filebuf_hpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines