QMCPACK
hdf_stl.h
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2024 QMCPACK developers.
6 //
7 // File developed by: Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
8 // Peter W. Doak, doakpw@ornl.gov, Oak Ridge National Laboratory
9 //
10 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
11 //////////////////////////////////////////////////////////////////////////////////////
12 
13 
14 #ifndef QMCPLUSPLUS_HDF_STL_INTERFACE_H
15 #define QMCPLUSPLUS_HDF_STL_INTERFACE_H
16 
17 #include <vector>
18 #include <sstream>
19 #include <bitset>
20 
21 namespace qmcplusplus
22 {
23 /** specialization for std::vector<T>
24  *
25  * Used with any T with a proper h5_space_type, e.g., intrinsic, TinyVector<T,D>, Tensor<T,D>
26  */
27 template<typename T>
28 struct h5data_proxy<std::vector<T>> : public h5_space_type<T, 1>
29 {
31  using FileSpace::dims;
33  using data_type = std::vector<T>;
34 
35  inline h5data_proxy(const data_type& a) { dims[0] = a.size(); }
36 
37  inline bool read(data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT)
38  {
39  if (!checkShapeConsistency<T>(grp, aname, FileSpace::rank, dims))
40  ref.resize(dims[0]);
41  return h5d_read(grp, aname, get_address(&ref[0]), xfer_plist);
42  }
43 
44  inline bool write(const data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT) const
45  {
46  return h5d_write(grp, aname.c_str(), FileSpace::rank, dims, get_address(&ref[0]), xfer_plist);
47  }
48 
49  inline bool write(const data_type& ref,
50  hid_t grp,
51  const std::string& aname,
52  const std::vector<hsize_t>& dvec,
53  hid_t xfer_plist) const
54  {
55  return h5d_write(grp, aname.c_str(), dvec.size(), dvec.data(), get_address(&ref[0]), xfer_plist);
56  }
57 };
58 
59 /** specialization for std::vector<bool>
60  *
61  * Used with bool which doesn't have a h5 datatype we can use.
62  */
63 template<>
64 struct h5data_proxy<std::vector<bool>> : public h5_space_type<char, 1>
65 {
67  using FileSpace::dims;
69  using data_type = std::vector<bool>;
70 
71  inline h5data_proxy(const data_type& a) { dims[0] = a.size(); }
72 
73  inline bool read(data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT)
74  {
75  std::vector<char> temp_char_vec;
76  if (!checkShapeConsistency<char>(grp, aname, FileSpace::rank, dims))
77  temp_char_vec.resize(dims[0]);
78  h5d_read(grp, aname, get_address(temp_char_vec.data()), xfer_plist);
79  ref.resize(dims[0]);
80  std::transform(temp_char_vec.begin(), temp_char_vec.end(), ref.begin(), [](auto& cval) { return cval > 0; });
81  return true;
82  }
83 
84  inline bool write(const data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT) const
85  {
86  std::vector<char> temp_char_vec(ref.size());
87  std::transform(ref.begin(), ref.end(), temp_char_vec.begin(), [](bool bval) { return bval ? 1 : 0; });
88  return h5d_write(grp, aname.c_str(), FileSpace::rank, dims, get_address(temp_char_vec.data()), xfer_plist);
89  }
90 
91  inline bool write(const data_type& ref,
92  hid_t grp,
93  const std::string& aname,
94  const std::vector<hsize_t>& dvec,
95  hid_t xfer_plist) const
96  {
97  std::vector<char> temp_char_vec(ref.size());
98  std::transform(ref.begin(), ref.end(), temp_char_vec.begin(), [](bool bval) { return bval ? 1 : 0; });
99  return h5d_write(grp, aname.c_str(), dvec.size(), dvec.data(), get_address(temp_char_vec.data()), xfer_plist);
100  }
101 };
102 
103 /** specialization for std::bitset<N>
104  */
105 template<std::size_t N>
106 struct h5data_proxy<std::bitset<N>>
107 {
108  using data_type = std::bitset<N>;
109 
110  h5data_proxy(const data_type& a) {}
111 
112  inline bool read(data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT)
113  {
114  unsigned long c = ref.to_ulong();
116  if (hc.read(ref, grp, aname, xfer_plist))
117  {
118  ref = c;
119  return true;
120  }
121  else
122  return false;
123  }
124 
125  inline bool write(const data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT) const
126  {
127  unsigned long c = ref.to_ulong();
129  return hc.write(ref, grp, aname, xfer_plist);
130  }
131 };
132 
133 
134 /** Specialization for std::string */
135 template<>
136 struct h5data_proxy<std::string>
137 {
138  using data_type = std::string;
139 
140  h5data_proxy(const data_type& a) {}
141 
142  inline bool read(data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT)
143  {
144  hid_t dataset = H5Dopen(grp, aname.c_str(), H5P_DEFAULT);
145  if (dataset > -1)
146  {
147  hid_t datatype = H5Dget_type(dataset);
148  hsize_t dim_out;
149  if (datatype == H5T_NATIVE_CHAR)
150  {
151  hid_t dataspace = H5Dget_space(dataset);
152  hid_t status = H5Sget_simple_extent_dims(dataspace, &dim_out, NULL);
153  H5Sclose(dataspace);
154  }
155  else
156  {
157  dim_out = H5Tget_size(datatype);
158  }
159  ref.resize(dim_out);
160  herr_t ret = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, xfer_plist, &(ref[0]));
161  H5Tclose(datatype);
162  H5Dclose(dataset);
163  return ret != -1;
164  }
165  return false;
166  }
167 
168  inline bool write(const data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT) const
169  {
170  hid_t str80 = H5Tcopy(H5T_C_S1);
171  H5Tset_size(str80, ref.size());
172  hsize_t dim = 1;
173 
174  herr_t ret = -1;
175  hid_t h1 = H5Dopen(grp, aname.c_str(), H5P_DEFAULT);
176  if (h1 < 0) // missing create one
177  {
178  hid_t dataspace = H5Screate_simple(1, &dim, NULL);
179  hid_t dataset = H5Dcreate(grp, aname.c_str(), str80, dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
180  ret = H5Dwrite(dataset, str80, H5S_ALL, H5S_ALL, xfer_plist, ref.data());
181  H5Sclose(dataspace);
182  H5Dclose(dataset);
183  }
184  else
185  {
186  ret = H5Dwrite(h1, str80, H5S_ALL, H5S_ALL, xfer_plist, ref.data());
187  }
188  H5Dclose(h1);
189  return ret != -1;
190  }
191 };
192 
193 /// Specialization for vector of strings
194 template<>
195 struct h5data_proxy<std::vector<std::string>>
196 {
197  using data_type = std::vector<std::string>;
198 
199  h5data_proxy(const data_type& a) {}
200 
201  inline bool read(data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT)
202  {
203  hid_t datatype = H5Tcopy(H5T_C_S1);
204  H5Tset_size(datatype, H5T_VARIABLE);
205  hid_t dataset = H5Dopen(grp, aname.c_str(), H5P_DEFAULT);
206  std::vector<char*> char_list;
207  herr_t ret = -1;
208  if (dataset > -1)
209  {
210  hsize_t dim_out;
211  hid_t dataspace = H5Dget_space(dataset);
212  hid_t status = H5Sget_simple_extent_dims(dataspace, &dim_out, NULL);
213 
214  char_list.resize(dim_out);
215  ret = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, xfer_plist, char_list.data());
216 
217  for (int i = 0; i < dim_out; i++)
218  ref.push_back(char_list[i]);
219 
220  H5Dvlen_reclaim(datatype, dataspace, xfer_plist, char_list.data());
221 
222  H5Sclose(dataspace);
223  H5Dclose(dataset);
224  }
225  H5Tclose(datatype);
226 
227  return ret >= 0;
228  }
229 
230  inline bool write(const data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT) const
231  {
232  // See the section in the HDF user's manual on datatypes,
233  // particularly the subsection on strings.
234  // (e.g. http://davis.lbl.gov/Manuals/HDF5-1.8.7/UG/11_Datatypes.html)
235  // and stackoverflow
236  // https://stackoverflow.com/questions/6184817/hdf5-inserting-a-set-of-strings-in-a-dataset
237  hid_t datatype = H5Tcopy(H5T_C_S1);
238  H5Tset_size(datatype, H5T_VARIABLE);
239  hsize_t dim = ref.size();
240 
241  // Create vector of pointers to the actual string data
242  std::vector<const char*> char_list;
243  for (int i = 0; i < ref.size(); i++)
244  char_list.push_back(ref[i].data());
245 
246  hid_t h1 = H5Dopen(grp, aname.c_str(), H5P_DEFAULT);
247  herr_t ret = -1;
248  if (h1 < 0) // missing create one
249  {
250  hid_t dataspace = H5Screate_simple(1, &dim, NULL);
251  hid_t dataset = H5Dcreate(grp, aname.c_str(), datatype, dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
252  ret = H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL, xfer_plist, char_list.data());
253  H5Sclose(dataspace);
254  H5Dclose(dataset);
255  }
256  else
257  ret = H5Dwrite(h1, datatype, H5S_ALL, H5S_ALL, xfer_plist, char_list.data());
258 
259  H5Dclose(h1);
260  return ret >= 0;
261  }
262 };
263 
264 template<>
265 struct h5data_proxy<std::ostringstream>
266 {
267  using data_type = std::ostringstream;
268 
269  h5data_proxy(const data_type& a) {}
270 
271  inline bool read(data_type& ref, hid_t grp, char* name, hid_t xfer_plist = H5P_DEFAULT) { return false; }
272 
273  inline bool write(const data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT) const
274  {
275  std::string clone(ref.str());
277  return proxy.write(clone, grp, aname);
278  }
279 };
280 
281 } // namespace qmcplusplus
282 #endif
default struct to define a h5 dataspace, any intrinsic type T
Definition: hdf_dataspace.h:44
bool read(data_type &ref, hid_t grp, const std::string &aname, hid_t xfer_plist=H5P_DEFAULT)
Definition: hdf_stl.h:112
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
bool write(const data_type &ref, hid_t grp, const std::string &aname, const std::vector< hsize_t > &dvec, hid_t xfer_plist) const
Definition: hdf_stl.h:91
bool write(const data_type &ref, hid_t grp, const std::string &aname, const std::vector< hsize_t > &dvec, hid_t xfer_plist) const
Definition: hdf_stl.h:49
bool write(const data_type &ref, hid_t grp, const std::string &aname, hid_t xfer_plist=H5P_DEFAULT) const
Definition: hdf_dataproxy.h:47
bool read(data_type &ref, hid_t grp, const std::string &aname, hid_t xfer_plist=H5P_DEFAULT)
Definition: hdf_stl.h:201
Specialization for std::string.
Definition: hdf_stl.h:136
bool write(const data_type &ref, hid_t grp, const std::string &aname, hid_t xfer_plist=H5P_DEFAULT) const
Definition: hdf_stl.h:273
hsize_t dims[RANK > 0 ? RANK :1]
shape of the dataspace, protected for zero size array, hdf5 support scalar as rank = 0 ...
Definition: hdf_dataspace.h:47
bool write(const data_type &ref, hid_t grp, const std::string &aname, hid_t xfer_plist=H5P_DEFAULT) const
Definition: hdf_stl.h:84
bool write(const data_type &ref, hid_t grp, const std::string &aname, hid_t xfer_plist=H5P_DEFAULT) const
Definition: hdf_stl.h:44
bool read(data_type &ref, hid_t grp, const std::string &aname, hid_t xfer_plist=H5P_DEFAULT)
Definition: hdf_dataproxy.h:38
bool read(data_type &ref, hid_t grp, const std::string &aname, hid_t xfer_plist=H5P_DEFAULT)
Definition: hdf_stl.h:73
bool read(data_type &ref, hid_t grp, const std::string &aname, hid_t xfer_plist=H5P_DEFAULT)
Definition: hdf_stl.h:142
bool write(const data_type &ref, hid_t grp, const std::string &aname, hid_t xfer_plist=H5P_DEFAULT) const
Definition: hdf_stl.h:125
bool write(const data_type &ref, hid_t grp, const std::string &aname, hid_t xfer_plist=H5P_DEFAULT) const
Definition: hdf_stl.h:168
static auto get_address(T *a)
return the address
Definition: hdf_dataspace.h:53
bool read(data_type &ref, hid_t grp, const std::string &aname, hid_t xfer_plist=H5P_DEFAULT)
Definition: hdf_stl.h:37
static constexpr hsize_t rank
rank of the multidimensional dataspace
Definition: hdf_dataspace.h:49
bool h5d_read(hid_t grp, const std::string &aname, T *first, hid_t xfer_plist)
return true, if successful
bool write(const data_type &ref, hid_t grp, const std::string &aname, hid_t xfer_plist=H5P_DEFAULT) const
Definition: hdf_stl.h:230
bool read(data_type &ref, hid_t grp, char *name, hid_t xfer_plist=H5P_DEFAULT)
Definition: hdf_stl.h:271
bool h5d_write(hid_t grp, const std::string &aname, hsize_t ndims, const hsize_t *dims, const T *first, hid_t xfer_plist)
generic h5data_proxy<T> for scalar basic datatypes defined in hdf_dataspace.h Note if the dataset to ...
Definition: hdf_dataproxy.h:29