Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
ReadHDF5Dataset.hpp
Go to the documentation of this file.
1 /** \file ReadHDF5Dataset.hpp
2  * \author Jason Kraftcheck
3  * \date 2010-07-09
4  */
5 
6 #ifndef moab_READ_HDF5DATASET_HPP
7 #define moab_READ_HDF5DATASET_HPP
8 
9 #include "moab/MOABConfig.h"
10 #ifdef MOAB_HAVE_MPI
11 #include <moab_mpi.h>
12 #endif
13 
14 #include <cstdlib> // for size_t
15 #include <H5Ipublic.h>
16 #include <H5Spublic.h>
17 
18 #include "moab/Range.hpp"
19 #include <vector>
20 
21 namespace moab
22 {
23 
24 /**\brief Utility used for reading portions of an HDF5 dataset
25  *
26  * Implement iterative read of table where:
27  * - subset of rows to be read can be specified usign an Range of offsets
28  * - each read fills as much as possible of a passed buffer
29  * - each read call reads a subsequent set of rows of the data set in an
30  * iterator-like fashion.
31  *
32  * NOTE: This class also implements an RAII pattern for the data set handle:
33  * It will close the data set in its destructor unless it is specified
34  * to the constructor that only a single column should be read.
35  *
36  * NOTE: This class will always do collective IO for parallel reads.
37  */
39 {
40  public:
41 #ifdef MOAB_HAVE_MPI
42  typedef MPI_Comm Comm;
43 #else
44  typedef int Comm;
45 #endif
46 
47  class Exception
48  {
49  public:
50  int line_no;
51  Exception( int l ) : line_no( l ) {}
52  };
53 
54  /**\brief Setup to read entire table
55  *\param data_set_handle The HDF5 DataSet to read.
56  *\param parallel Doing true partial-read parallel read (as opposed
57  * to read and delete where collective IO is done for
58  * everything because all procs read the same stuff.)
59  *\param communictor If \c parallel is \c true and \c io_prop is
60  * \c H5FD_MPIO_COLLECTIVE, then this
61  * must be a pointer to the MPI_Communicator value.
62  *\param close_data_set_on_destruct Call \c H5Dclose on passed
63  * \c data_set_handle in desturctor.
64  *
65  *\NOTE If \c parallel is \c true and \c io_prop is \c H5FD_MPIO_COLLECTIVE,
66  * then not only must \c communicator be non-null, but this call must
67  * be made collectively!
68 
69  *\NOTE Class instance will not be usable until one of either
70  * \c set_file_ids or \c set_all_file_ids is called.
71  */
72  ReadHDF5Dataset( const char* debug_desc,
73  hid_t data_set_handle,
74  bool parallel,
75  const Comm* communicator = 0,
76  bool close_data_set_on_destruct = true );
77 
78  ReadHDF5Dataset( const char* debug_desc, bool parallel, const Comm* communicator = 0 );
79  void init( hid_t data_set_handle, bool close_data_set_on_destruct = true );
80 
81  bool will_close_data_set() const
82  {
83  return closeDataSet;
84  }
85  void close_data_set_on_destruct( bool val )
86  {
87  closeDataSet = val;
88  }
89 
91 
92  /**\brief Change file ids to read from.
93  *
94  *\param file_ids List of rows to read from dataset
95  *\param start_id Rows of dataset are enumerating beginning with
96  * this value. Thus the offset row to be read from
97  * dataset will be \c file_ids.begin() - \c start_id .
98  *\param row_count Read buffer size in number of table rows.
99  *\param data_type The data type of the buffer into which table values
100  * are to be read.
101  */
102  void set_file_ids( const Range& file_ids, EntityHandle start_id, hsize_t row_cout, hid_t data_type );
103 
104  /**\brief Read all values in dataset (undo set_file_ids)
105  *
106  *\param row_count Read buffer size in number of table rows.
107  *\param data_type The data type of the buffer into which table values
108  * are to be read.
109  */
110  void set_all_file_ids( hsize_t row_count, hid_t data_type );
111 
112  /**\brief Return false if more data to read, true otherwise
113  *
114  * Test if the iterative read has reached the end.
115  */
116  bool done() const
117  {
118  return ( currOffset == rangeEnd ) && ( readCount == 0 );
119  }
120 
121  /**\brief Read rows of table
122  *
123  * Read up to max_num_rows from data set.
124  *\param buffer Memory in which to store values read from data set
125  *\param rows_read The actual number of rows read from the table. Will
126  * never exceed \c max_rows .
127  */
128  void read( void* buffer, size_t& rows_read );
129 
130  /**\brief Return position in \c Range of file IDs at which next read will start
131  */
133  {
134  return currOffset;
135  }
136 
137  /**\brief Do null read operation
138  *
139  * Do a read call requesting no data. This functionality is provided
140  * so as to allow collective IO when not all processes need to make the
141  * same number of read calls. To prevent deadlock in this case, processes
142  * that have finished their necessary read calls can call this function
143  * so that all processes are calling the read method collectively.
144  */
145  void null_read();
146 
147  unsigned columns() const;
148  void set_column( unsigned c );
149 
150  unsigned long get_read_count() const
151  {
152  return readCount;
153  }
154  const char* get_debug_desc() const
155  {
156  return mpeDesc.c_str();
157  }
158 
159  static void set_hyperslab_selection_limit( size_t val )
160  {
162  }
163  static void default_hyperslab_selection_limit();
164 
165  /** Use non-standard 'APPEND' operation for hyperslab selection */
166  static void append_hyperslabs()
167  {
168  hyperslabSelectOp = H5S_SELECT_APPEND;
169  }
170  /** Revert to default select behavior for standard HDF5 library */
171  static void or_hyperslabs()
172  {
173  hyperslabSelectOp = H5S_SELECT_OR;
174  }
175 
176  private:
178 
179  Range internalRange; //!< used when reading entire dataset
180 
181  bool closeDataSet; //!< close dataset in destructor
182  hsize_t dataSetOffset[64], dataSetCount[64];
183  hid_t dataSet; //!< Handle for HDF5 data set
184  hid_t dataSpace; //!< Data space for data set
185  hid_t dataType; //!< Data type client code wants for data
186  hid_t fileType; //!< Data type as stored in data set
187  hid_t ioProp; //!< Used to specify collective IO
188  int dataSpaceRank; //!< Rank of data set
189  hsize_t rowsInTable; //!< Total number of rows in dataset
190  bool doConversion; //!< True if dataType != fileType
191  bool nativeParallel; //!< If true then reading different data on different procs
192 
193  hsize_t readCount; //!< Number of actual reads to do
194  hsize_t bufferSize; //!< size of buffer passed to \c read, in number of rows
195  const Comm* mpiComm;
196 
199 
200  static bool haveMPEEvents;
201  static std::pair< int, int > mpeReadEvent;
202  static std::pair< int, int > mpeReduceEvent;
203  std::string mpeDesc;
204 
205  static size_t hyperslabSelectionLimit;
206  static H5S_seloper_t hyperslabSelectOp;
207 };
208 
209 } // namespace moab
210 
211 #endif // moab_READ_HDF5DATASET_HPP