![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 /** \file ReadHDF5Dataset.hpp
00002 * \author Jason Kraftcheck
00003 * \date 2010-07-09
00004 */
00005
00006 #ifndef moab_READ_HDF5DATASET_HPP
00007 #define moab_READ_HDF5DATASET_HPP
00008
00009 #include "moab/MOABConfig.h"
00010 #ifdef MOAB_HAVE_MPI
00011 #include
00012 #endif
00013
00014 #include // for size_t
00015 #include
00016 #include
00017
00018 #include "moab/Range.hpp"
00019 #include
00020
00021 namespace moab
00022 {
00023
00024 /**\brief Utility used for reading portions of an HDF5 dataset
00025 *
00026 * Implement iterative read of table where:
00027 * - subset of rows to be read can be specified usign an Range of offsets
00028 * - each read fills as much as possible of a passed buffer
00029 * - each read call reads a subsequent set of rows of the data set in an
00030 * iterator-like fashion.
00031 *
00032 * NOTE: This class also implements an RAII pattern for the data set handle:
00033 * It will close the data set in its destructor unless it is specified
00034 * to the constructor that only a single column should be read.
00035 *
00036 * NOTE: This class will always do collective IO for parallel reads.
00037 */
00038 class ReadHDF5Dataset
00039 {
00040 public:
00041 #ifdef MOAB_HAVE_MPI
00042 typedef MPI_Comm Comm;
00043 #else
00044 typedef int Comm;
00045 #endif
00046
00047 class Exception
00048 {
00049 public:
00050 int line_no;
00051 Exception( int l ) : line_no( l ) {}
00052 };
00053
00054 /**\brief Setup to read entire table
00055 *\param data_set_handle The HDF5 DataSet to read.
00056 *\param parallel Doing true partial-read parallel read (as opposed
00057 * to read and delete where collective IO is done for
00058 * everything because all procs read the same stuff.)
00059 *\param communictor If \c parallel is \c true and \c io_prop is
00060 * \c H5FD_MPIO_COLLECTIVE, then this
00061 * must be a pointer to the MPI_Communicator value.
00062 *\param close_data_set_on_destruct Call \c H5Dclose on passed
00063 * \c data_set_handle in desturctor.
00064 *
00065 *\NOTE If \c parallel is \c true and \c io_prop is \c H5FD_MPIO_COLLECTIVE,
00066 * then not only must \c communicator be non-null, but this call must
00067 * be made collectively!
00068
00069 *\NOTE Class instance will not be usable until one of either
00070 * \c set_file_ids or \c set_all_file_ids is called.
00071 */
00072 ReadHDF5Dataset( const char* debug_desc,
00073 hid_t data_set_handle,
00074 bool parallel,
00075 const Comm* communicator = 0,
00076 bool close_data_set_on_destruct = true );
00077
00078 ReadHDF5Dataset( const char* debug_desc, bool parallel, const Comm* communicator = 0 );
00079 void init( hid_t data_set_handle, bool close_data_set_on_destruct = true );
00080
00081 bool will_close_data_set() const
00082 {
00083 return closeDataSet;
00084 }
00085 void close_data_set_on_destruct( bool val )
00086 {
00087 closeDataSet = val;
00088 }
00089
00090 ~ReadHDF5Dataset();
00091
00092 /**\brief Change file ids to read from.
00093 *
00094 *\param file_ids List of rows to read from dataset
00095 *\param start_id Rows of dataset are enumerating beginning with
00096 * this value. Thus the offset row to be read from
00097 * dataset will be \c file_ids.begin() - \c start_id .
00098 *\param row_count Read buffer size in number of table rows.
00099 *\param data_type The data type of the buffer into which table values
00100 * are to be read.
00101 */
00102 void set_file_ids( const Range& file_ids, EntityHandle start_id, hsize_t row_cout, hid_t data_type );
00103
00104 /**\brief Read all values in dataset (undo set_file_ids)
00105 *
00106 *\param row_count Read buffer size in number of table rows.
00107 *\param data_type The data type of the buffer into which table values
00108 * are to be read.
00109 */
00110 void set_all_file_ids( hsize_t row_count, hid_t data_type );
00111
00112 /**\brief Return false if more data to read, true otherwise
00113 *
00114 * Test if the iterative read has reached the end.
00115 */
00116 bool done() const
00117 {
00118 return ( currOffset == rangeEnd ) && ( readCount == 0 );
00119 }
00120
00121 /**\brief Read rows of table
00122 *
00123 * Read up to max_num_rows from data set.
00124 *\param buffer Memory in which to store values read from data set
00125 *\param rows_read The actual number of rows read from the table. Will
00126 * never exceed \c max_rows .
00127 */
00128 void read( void* buffer, size_t& rows_read );
00129
00130 /**\brief Return position in \c Range of file IDs at which next read will start
00131 */
00132 Range::const_iterator next_file_id() const
00133 {
00134 return currOffset;
00135 }
00136
00137 /**\brief Do null read operation
00138 *
00139 * Do a read call requesting no data. This functionality is provided
00140 * so as to allow collective IO when not all processes need to make the
00141 * same number of read calls. To prevent deadlock in this case, processes
00142 * that have finished their necessary read calls can call this function
00143 * so that all processes are calling the read method collectively.
00144 */
00145 void null_read();
00146
00147 unsigned columns() const;
00148 void set_column( unsigned c );
00149
00150 unsigned long get_read_count() const
00151 {
00152 return readCount;
00153 }
00154 const char* get_debug_desc() const
00155 {
00156 return mpeDesc.c_str();
00157 }
00158
00159 static void set_hyperslab_selection_limit( size_t val )
00160 {
00161 hyperslabSelectionLimit = val;
00162 }
00163 static void default_hyperslab_selection_limit();
00164
00165 /** Use non-standard 'APPEND' operation for hyperslab selection */
00166 static void append_hyperslabs()
00167 {
00168 hyperslabSelectOp = H5S_SELECT_APPEND;
00169 }
00170 /** Revert to default select behavior for standard HDF5 library */
00171 static void or_hyperslabs()
00172 {
00173 hyperslabSelectOp = H5S_SELECT_OR;
00174 }
00175
00176 private:
00177 Range::const_iterator next_end( Range::const_iterator iter );
00178
00179 Range internalRange; //!< used when reading entire dataset
00180
00181 bool closeDataSet; //!< close dataset in destructor
00182 hsize_t dataSetOffset[64], dataSetCount[64];
00183 hid_t dataSet; //!< Handle for HDF5 data set
00184 hid_t dataSpace; //!< Data space for data set
00185 hid_t dataType; //!< Data type client code wants for data
00186 hid_t fileType; //!< Data type as stored in data set
00187 hid_t ioProp; //!< Used to specify collective IO
00188 int dataSpaceRank; //!< Rank of data set
00189 hsize_t rowsInTable; //!< Total number of rows in dataset
00190 bool doConversion; //!< True if dataType != fileType
00191 bool nativeParallel; //!< If true then reading different data on different procs
00192
00193 hsize_t readCount; //!< Number of actual reads to do
00194 hsize_t bufferSize; //!< size of buffer passed to \c read, in number of rows
00195 const Comm* mpiComm;
00196
00197 Range::const_iterator currOffset, rangeEnd;
00198 EntityHandle startID;
00199
00200 static bool haveMPEEvents;
00201 static std::pair< int, int > mpeReadEvent;
00202 static std::pair< int, int > mpeReduceEvent;
00203 std::string mpeDesc;
00204
00205 static size_t hyperslabSelectionLimit;
00206 static H5S_seloper_t hyperslabSelectOp;
00207 };
00208
00209 } // namespace moab
00210
00211 #endif // moab_READ_HDF5DATASET_HPP