Branch data Line data Source code
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 <stdlib.h> // 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 : : */
38 : : class ReadHDF5Dataset
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 : 0 : 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, hid_t data_set_handle, bool parallel, const Comm* communicator = 0,
73 : : bool close_data_set_on_destruct = true );
74 : :
75 : : ReadHDF5Dataset( const char* debug_desc, bool parallel, const Comm* communicator = 0 );
76 : : void init( hid_t data_set_handle, bool close_data_set_on_destruct = true );
77 : :
78 : : bool will_close_data_set() const
79 : : {
80 : : return closeDataSet;
81 : : }
82 : : void close_data_set_on_destruct( bool val )
83 : : {
84 : : closeDataSet = val;
85 : : }
86 : :
87 : : ~ReadHDF5Dataset();
88 : :
89 : : /**\brief Change file ids to read from.
90 : : *
91 : : *\param file_ids List of rows to read from dataset
92 : : *\param start_id Rows of dataset are enumerating beginning with
93 : : * this value. Thus the offset row to be read from
94 : : * dataset will be \c file_ids.begin() - \c start_id .
95 : : *\param row_count Read buffer size in number of table rows.
96 : : *\param data_type The data type of the buffer into which table values
97 : : * are to be read.
98 : : */
99 : : void set_file_ids( const Range& file_ids, EntityHandle start_id, hsize_t row_cout, hid_t data_type );
100 : :
101 : : /**\brief Read all values in dataset (undo set_file_ids)
102 : : *
103 : : *\param row_count Read buffer size in number of table rows.
104 : : *\param data_type The data type of the buffer into which table values
105 : : * are to be read.
106 : : */
107 : : void set_all_file_ids( hsize_t row_count, hid_t data_type );
108 : :
109 : : /**\brief Return false if more data to read, true otherwise
110 : : *
111 : : * Test if the iterative read has reached the end.
112 : : */
113 : 2075 : bool done() const
114 : : {
115 [ + + ][ + - ]: 2075 : return ( currOffset == rangeEnd ) && ( readCount == 0 );
116 : : }
117 : :
118 : : /**\brief Read rows of table
119 : : *
120 : : * Read up to max_num_rows from data set.
121 : : *\param buffer Memory in which to store values read from data set
122 : : *\param rows_read The actual number of rows read from the table. Will
123 : : * never exceed \c max_rows .
124 : : */
125 : : void read( void* buffer, size_t& rows_read );
126 : :
127 : : /**\brief Return position in \c Range of file IDs at which next read will start
128 : : */
129 : : Range::const_iterator next_file_id() const
130 : : {
131 : : return currOffset;
132 : : }
133 : :
134 : : /**\brief Do null read operation
135 : : *
136 : : * Do a read call requesting no data. This functionality is provided
137 : : * so as to allow collective IO when not all processes need to make the
138 : : * same number of read calls. To prevent deadlock in this case, processes
139 : : * that have finished their necessary read calls can call this function
140 : : * so that all processes are calling the read method collectively.
141 : : */
142 : : void null_read();
143 : :
144 : : unsigned columns() const;
145 : : void set_column( unsigned c );
146 : :
147 : 891 : unsigned long get_read_count() const
148 : : {
149 : 891 : return readCount;
150 : : }
151 : 438 : const char* get_debug_desc() const
152 : : {
153 : 438 : return mpeDesc.c_str();
154 : : }
155 : :
156 : 0 : static void set_hyperslab_selection_limit( size_t val )
157 : : {
158 : 0 : hyperslabSelectionLimit = val;
159 : 0 : }
160 : : static void default_hyperslab_selection_limit();
161 : :
162 : : /** Use non-standard 'APPEND' operation for hyperslab selection */
163 : 0 : static void append_hyperslabs()
164 : : {
165 : 0 : hyperslabSelectOp = H5S_SELECT_APPEND;
166 : 0 : }
167 : : /** Revert to default select behavior for standard HDF5 library */
168 : : static void or_hyperslabs()
169 : : {
170 : : hyperslabSelectOp = H5S_SELECT_OR;
171 : : }
172 : :
173 : : private:
174 : : Range::const_iterator next_end( Range::const_iterator iter );
175 : :
176 : : Range internalRange; //!< used when reading entire dataset
177 : :
178 : : bool closeDataSet; //!< close dataset in destructor
179 : : hsize_t dataSetOffset[64], dataSetCount[64];
180 : : hid_t dataSet; //!< Handle for HDF5 data set
181 : : hid_t dataSpace; //!< Data space for data set
182 : : hid_t dataType; //!< Data type client code wants for data
183 : : hid_t fileType; //!< Data type as stored in data set
184 : : hid_t ioProp; //!< Used to specify collective IO
185 : : int dataSpaceRank; //!< Rank of data set
186 : : hsize_t rowsInTable; //!< Total number of rows in dataset
187 : : bool doConversion; //!< True if dataType != fileType
188 : : bool nativeParallel; //!< If true then reading different data on different procs
189 : :
190 : : hsize_t readCount; //!< Number of actual reads to do
191 : : hsize_t bufferSize; //!< size of buffer passed to \c read, in number of rows
192 : : const Comm* mpiComm;
193 : :
194 : : Range::const_iterator currOffset, rangeEnd;
195 : : EntityHandle startID;
196 : :
197 : : static bool haveMPEEvents;
198 : : static std::pair< int, int > mpeReadEvent;
199 : : static std::pair< int, int > mpeReduceEvent;
200 : : std::string mpeDesc;
201 : :
202 : : static size_t hyperslabSelectionLimit;
203 : : static H5S_seloper_t hyperslabSelectOp;
204 : : };
205 : :
206 : : } // namespace moab
207 : :
208 : : #endif // moab_READ_HDF5DATASET_HPP
|