High Performance Plasticity  0.5.0
hdfUtilsCpp.h
Go to the documentation of this file.
1 
6 #ifndef HPP_HDFUTILSCPP_H
7 #define HPP_HDFUTILSCPP_H
8 
9 #include <stdexcept>
10 #include <cstddef>
11 #include <string>
12 #include <stdio.h>
13 #include <map>
14 #include <vector>
15 #include <iostream>
16 #include <sstream>
17 #include "mpi.h"
18 #include <hpp/config.h>
19 #include <hdf5/serial/H5Cpp.h>
20 #include <hpp/hdfUtils.h>
21 
22 namespace hpp
23 {
24 
30 template <typename T>
31 H5::DataType getHDF5Type() {
32  H5::DataType dataType;
33  if (std::is_same<T, float>::value) {
34  dataType = H5::PredType::NATIVE_FLOAT;
35  }
36  else if (std::is_same<T, double>::value) {
37  dataType = H5::PredType::NATIVE_DOUBLE;
38  }
39  else if (std::is_same<T, int>::value) {
40  dataType = H5::PredType::NATIVE_INT32;
41  }
42  else if (std::is_same<T, long int>::value) {
43  dataType = H5::PredType::NATIVE_LONG;
44  }
45  else if (std::is_same<T, long long int>::value) {
46  dataType = H5::PredType::NATIVE_LLONG;
47  }
48  else if (std::is_same<T, unsigned int>::value) {
49  dataType = H5::PredType::NATIVE_UINT32;
50  }
51  else if (std::is_same<T, unsigned long int>::value) {
52  dataType = H5::PredType::NATIVE_ULONG;
53  }
54  else if (std::is_same<T, unsigned long long int>::value) {
55  dataType = H5::PredType::NATIVE_ULLONG;
56  }
57  else {
58  throw HDFUtilsError("Datatype lookup not implemented for this type.");
59  }
60  return dataType;
61 }
62 
64  std::vector<hsize_t> dataOffset;
65  std::vector<hsize_t> dataCount;
66  H5::DataType datatype;
67 };
68 
69 template <typename T>
70 H5::DataSet createHDF5Dataset(H5::H5File& file, const H5std_string& datasetName, std::vector<hsize_t> dataDims) {
71  // Create the dataset
72  hsize_t dataRank = dataDims.size();
73  H5::DataSpace dataspace;
74  if (dataRank == 0) {
75  dataspace = H5::DataSpace();
76  }
77  else {
78  dataspace = H5::DataSpace(dataRank, dataDims.data());
79  }
80  H5::DataType dataType = getHDF5Type<T>();
81  H5::DataSet dataset = file.createDataSet(datasetName.c_str(), dataType, dataspace);
82 
83  // Return
84  return dataset;
85 }
86 
87 template <typename T>
88 H5::DataSet createHDF5GridOfArrays(H5::H5File& file, const H5std_string& datasetName, std::vector<hsize_t> gridDims, std::vector<hsize_t> arrayDims) {
89  // Get full data dims
90  std::vector<hsize_t> dataDims = gridDims;
91  dataDims.insert(dataDims.end(), arrayDims.begin(), arrayDims.end());
92 
93  // Create
94  return createHDF5Dataset<T>(file, datasetName, dataDims);
95 }
96 
97 template <typename T>
98 HDFReadWriteParams getReadWriteParametersForSingleHDF5Array(H5::DataSet& dataset, std::vector<hsize_t> gridOffset,
99  std::vector<hsize_t> arrayDims)
100 {
101  // Grid: the grid of arrays, dimensions (m_1, m_2, ... )
102  // Array: the array, dimensions (n_1, n_2, ... )
103  // Data: The combination, dimensions (m1, m2, ..., n1, n_2, ...)
104  // Offset: The offset of the array within the grid
105 
106  // Check that datatypes match
107  H5::DataType datatype = dataset.getDataType();
108  H5::DataType datatypeExpected = getHDF5Type<T>();
109  if (!(datatype == datatypeExpected)) { //no "!=" in API
110  throw HDFUtilsError("Datatype mismatch.");
111  }
112 
113  // Get data dimensions
114  H5::DataSpace dataspace = dataset.getSpace();
115  hsize_t dataRank = dataspace.getSimpleExtentNdims();
116  std::vector<hsize_t> dataDims(dataRank);
117  dataspace.getSimpleExtentDims(dataDims.data());
118 
119  // Check rank matches
120  hsize_t gridRank = gridOffset.size();
121  hsize_t arrayRank = arrayDims.size();
122  hsize_t dataRankExpected = gridRank + arrayRank;
123  if (dataRank != dataRankExpected) {
124  throw HDFUtilsError("Data rank mismatch.");
125  }
126 
127  // Check array dimensions match
128  std::vector<hsize_t> arrayDimsRead(dataDims.end()-arrayDims.size(), dataDims.end());
129  if (arrayDims != arrayDimsRead) {
130  throw HDFUtilsError("Array dimension mismatch.");
131  }
132 
133  // Get the grid dimensions
134  std::vector<hsize_t> gridDims(dataDims.begin(), dataDims.begin()+gridRank);
135 
136  // Check that offset is within the grid bounds
137  for (unsigned int i=0; i<gridRank; i++) {
138  if (gridOffset[i] > gridDims[i]-1) {
139  throw HDFUtilsError("Offset out of grid bounds.");
140  }
141  }
142 
143  // The offset and count in the overall data
144  std::vector<hsize_t> dataOffset(dataRank);
145  std::vector<hsize_t> dataCount(dataRank);
146  for (unsigned int i=0; i<gridRank; i++) {
147  dataOffset[i] = gridOffset[i];
148  dataCount[i] = 1;
149  }
150  for (unsigned int i=0; i<arrayRank; i++) {
151  dataOffset[gridRank + i] = 0;
152  dataCount[gridRank + i] = arrayDims[i];
153  }
154 
155  // Prepare parameters
156  HDFReadWriteParams parms;
157  parms.dataOffset = dataOffset;
158  parms.dataCount = dataCount;
159  parms.datatype = datatype;
160 
161  // Return
162  return parms;
163 }
164 
165 template <typename T>
166 void readWriteHDF5SimpleArray(H5::DataSet& dataset, HDFReadWriteParams parms, T* output, HDFReadWrite mode)
167 {
168  // Dataspace
169  H5::DataSpace dataspace = dataset.getSpace();
170 
171  // Create the memspace for the read/write
172  H5::DataSpace memspace(parms.dataCount.size(), parms.dataCount.data());
173 
174  // Select the hyperslab
175  dataspace.selectHyperslab(H5S_SELECT_SET, parms.dataCount.data(), parms.dataOffset.data());
176 
177  // Read/write
178  if (mode == HDFReadWrite::Read) {
179  dataset.read(output, parms.datatype, memspace, dataspace);
180  }
181  else if (mode == HDFReadWrite::Write) {
182  dataset.write(output, parms.datatype, memspace, dataspace);
183  }
184  else {
185  throw HDFUtilsError("Unrecognized mode.");
186  }
187 }
188 
189 template <typename T>
190 void readHDF5SimpleArray(H5::DataSet& dataset, HDFReadWriteParams parms, T* output) {
191  readWriteHDF5SimpleArray<T>(dataset, parms, output, HDFReadWrite::Read);
192 }
193 
194 template <typename T>
195 void writeHDF5SimpleArray(H5::DataSet& dataset, HDFReadWriteParams parms, T* output) {
196  readWriteHDF5SimpleArray<T>(dataset, parms, output, HDFReadWrite::Write);
197 }
198 
199 template <typename T>
200 void readSingleHDF5Array(H5::DataSet& dataset, std::vector<hsize_t> gridOffset, std::vector<hsize_t> arrayDims, T* output) {
201  HDFReadWriteParams parms = getReadWriteParametersForSingleHDF5Array<T>(dataset, gridOffset, arrayDims);
202  readHDF5SimpleArray<T>(dataset, parms, output);
203 }
204 
205 template <typename T>
206 void writeSingleHDF5Array(H5::DataSet& dataset, std::vector<hsize_t> gridOffset, std::vector<hsize_t> arrayDims, T* output) {
207  HDFReadWriteParams parms = getReadWriteParametersForSingleHDF5Array<T>(dataset, gridOffset, arrayDims);
208  writeHDF5SimpleArray<T>(dataset, parms, output);
209 }
210 
211 template <typename T>
212 void writeVectorToHDF5Array(H5::H5File& file, const std::string& dsetName, std::vector<T>& vec) {
213  std::vector<hsize_t> dataOffset;
214  std::vector<hsize_t> dataDims = {vec.size()};
215  H5::DataSet dset = createHDF5Dataset<T>(file, dsetName, dataDims);
216  writeSingleHDF5Array<T>(dset, dataOffset, dataDims, vec.data());
217 }
218 
219 template <typename T>
220 void addAttribute(H5::H5File& file, const std::string& attrName, T attrVal) {
221  H5::DataSpace scalarSpace(H5S_SCALAR);
222  auto attr = file.createAttribute(attrName, getHDF5Type<T>(), scalarSpace);
223  attr.write(getHDF5Type<T>(), &attrVal);
224 }
225 
226 } //END NAMESPACE HPP
227 
228 #endif /* HPP_HDFUTILS_CPP */
std::vector< hsize_t > dataOffset
Definition: hdfUtilsCpp.h:64
HDFReadWriteParamsC getReadWriteParametersForSingleHDF5Array(hid_t dset_id, std::vector< hsize_t > gridOffset, std::vector< hsize_t > arrayDims)
Gets the parameters and ensures that they&#39;re compatible with the actual dataset.
Definition: hdfUtils.h:228
hid_t createHDF5Dataset(hid_t file_id, std::string datasetName, std::vector< hsize_t > dataDims)
Definition: hdfUtils.h:104
Definition: casesUtils.cpp:4
void writeSingleHDF5Array(hid_t dset_id, hid_t plist_id, std::vector< hsize_t > gridOffset, std::vector< hsize_t > arrayDims, T *output)
Definition: hdfUtils.h:287
void readWriteHDF5SimpleArray(hid_t dset_id, hid_t plist_id, HDFReadWriteParamsC parms, T *output, HDFReadWrite mode)
Definition: hdfUtils.h:237
hid_t createHDF5GridOfArrays(hid_t file_id, std::string datasetName, std::vector< hsize_t > gridDims, std::vector< hsize_t > arrayDims)
Definition: hdfUtils.h:127
void writeHDF5SimpleArray(hid_t dset_id, hid_t plist_id, HDFReadWriteParamsC parms, T *output)
Definition: hdfUtils.h:269
Header file for helper functions with HDF.
HDFReadWrite
Definition: hdfUtils.h:51
Definition: hdfUtils.h:26
H5::DataType getHDF5Type()
Get HDF5 equivalent type.
Definition: hdfUtilsCpp.h:31
void addAttribute(H5::H5File &file, const std::string &attrName, T attrVal)
Definition: hdfUtilsCpp.h:220
H5::DataType datatype
Definition: hdfUtilsCpp.h:66
void readHDF5SimpleArray(hid_t dset_id, hid_t plist_id, HDFReadWriteParamsC parms, T *output)
Definition: hdfUtils.h:264
Definition: hdfUtilsCpp.h:63
void writeVectorToHDF5Array(H5::H5File &file, const std::string &dsetName, std::vector< T > &vec)
Definition: hdfUtilsCpp.h:212
std::vector< hsize_t > dataCount
Definition: hdfUtilsCpp.h:65
void readSingleHDF5Array(hid_t dset_id, hid_t plist_id, std::vector< hsize_t > gridOffset, std::vector< hsize_t > arrayDims, T *output)
Definition: hdfUtils.h:274