QMCPACK
hdf_multi.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) 2016 Jeongnim Kim and QMCPACK developers.
6 ////
7 //// File developed by: Miguel Morales, moralessilva2@llnl.gov, Lawrence Livermore National Laboratory
8 ////
9 //// File created by: Miguel Morales, moralessilva2@llnl.gov, Lawrence Livermore National Laboratory
10 ////////////////////////////////////////////////////////////////////////////////////////
11 
12 #ifndef QMCPLUSPLUS_HDF_MULTI_INTERFACE_H
13 #define QMCPLUSPLUS_HDF_MULTI_INTERFACE_H
14 
15 #include <multi/array.hpp>
16 #include <multi/array_ref.hpp>
17 #include "hdf_dataproxy.h"
18 #include "hdf_hyperslab.h"
19 
20 #ifdef BUILD_AFQMC
21 #if defined(ENABLE_CUDA) || defined(ENABLE_HIP)
22 #include "AFQMC/Memory/device_pointers.hpp"
23 #endif
24 #endif
25 
26 namespace qmcplusplus
27 {
28 /** specialization for vector<T>
29  *
30  * Used with any T with a proper h5_space_type, e.g., intrinsic, TinyVector<T,D>, Tensor<T,D>
31  */
32 template<typename T, class Alloc>
33 struct h5data_proxy<boost::multi::array<T, 1, Alloc>> : public h5_space_type<T, 1>
34 {
36  using FileSpace::dims;
38  using data_type = boost::multi::array<T, 1, Alloc>;
39 
40  inline h5data_proxy(const data_type& a) { dims[0] = a.num_elements(); }
41 
42  inline bool read(data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT)
43  {
44  using iextensions = typename boost::multi::iextensions<1u>;
45  if (!checkShapeConsistency<T>(grp, aname, FileSpace::rank, dims))
46  ref.reextent(iextensions{static_cast<boost::multi::size_t>(dims[0])});
47  return h5d_read(grp, aname, get_address(std::addressof(*ref.origin())), xfer_plist);
48  }
49 
50  inline bool write(const data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT) const
51  {
52  return h5d_write(grp, aname.c_str(), FileSpace::rank, dims, get_address(std::addressof(*ref.origin())), xfer_plist);
53  }
54 };
55 
56 template<typename T, class Alloc>
57 struct h5data_proxy<boost::multi::array<T, 2, Alloc>> : public h5_space_type<T, 2>
58 {
60  using FileSpace::dims;
62  using data_type = boost::multi::array<T, 2, Alloc>;
63 
64  inline h5data_proxy(const data_type& a)
65  {
66  dims[0] = std::get<0>(a.sizes());
67  dims[1] = std::get<1>(a.sizes());
68  }
69 
70  inline bool read(data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT)
71  {
72  if (!checkShapeConsistency<T>(grp, aname, FileSpace::rank, dims))
73  ref.reextent({static_cast<boost::multi::size_t>(dims[0]), static_cast<boost::multi::size_t>(dims[1])});
74  return h5d_read(grp, aname, get_address(std::addressof(*ref.origin())), xfer_plist);
75  }
76 
77  inline bool write(const data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT) const
78  {
79  return h5d_write(grp, aname.c_str(), FileSpace::rank, dims, get_address(std::addressof(*ref.origin())), xfer_plist);
80  }
81 };
82 
83 template<typename T, class Ptr>
84 struct h5data_proxy<boost::multi::array_ref<T, 1, Ptr>> : public h5_space_type<T, 1>
85 {
87  using FileSpace::dims;
89  using data_type = boost::multi::array_ref<T, 1, Ptr>;
90 
91  inline h5data_proxy(const data_type& a) { dims[0] = a.num_elements(); }
92 
93  inline bool read(data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT)
94  {
95  if (!checkShapeConsistency<T>(grp, aname, FileSpace::rank, dims))
96  {
97  if (dims[0] > 0)
98  {
99  std::cerr << " Error: multi::array_ref can't be resized in h5data_proxy<>::read." << std::endl;
100  std::cerr << dims[0] << " " << std::get<0>(ref.sizes()) << std::endl;
101  }
102  return false;
103  }
104  return h5d_read(grp, aname, get_address(std::addressof(*ref.origin())), xfer_plist);
105  }
106 
107  inline bool write(const data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT) const
108  {
109  return h5d_write(grp, aname.c_str(), FileSpace::rank, dims, get_address(std::addressof(*ref.origin())), xfer_plist);
110  }
111 };
112 
113 template<typename T, class Ptr>
114 struct h5data_proxy<boost::multi::array_ref<T, 2, Ptr>> : public h5_space_type<T, 2>
115 {
117  using FileSpace::dims;
119  using data_type = boost::multi::array_ref<T, 2, Ptr>;
120 
121  inline h5data_proxy(const data_type& a)
122  {
123  dims[0] = std::get<0>(a.sizes());
124  dims[1] = std::get<1>(a.sizes());
125  }
126 
127  inline bool read(data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT)
128  {
129  if (!checkShapeConsistency<T>(grp, aname, FileSpace::rank, dims))
130  {
131  if (dims[0] * dims[1] > 0)
132  {
133  std::cerr << " Error: multi::array_ref can't be resized in h5data_proxy<>::read." << std::endl;
134  std::cerr << dims[0] << " " << dims[1] << " " << std::get<0>(ref.sizes()) << " " << std::get<1>(ref.sizes()) << std::endl;
135  }
136  return false;
137  }
138  return h5d_read(grp, aname, get_address(std::addressof(*ref.origin())), xfer_plist);
139  }
140 
141  inline bool write(const data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT) const
142  {
143  return h5d_write(grp, aname.c_str(), FileSpace::rank, dims, get_address(std::addressof(*ref.origin())), xfer_plist);
144  }
145 };
146 
147 
148 #ifdef BUILD_AFQMC
149 #if defined(ENABLE_CUDA) || defined(ENABLE_HIP)
150 // Specializations for cuda_gpu_allocator
151 // Need buffered I/O and copies to gpu
152 template<typename T>
153 struct h5data_proxy<boost::multi::array<T, 1, device::device_allocator<T>>> : public h5_space_type<T, 1>
154 {
155  using FileSpace = h5_space_type<T, 1>;
156  using FileSpace::dims;
158  using data_type = boost::multi::array<T, 1, device::device_allocator<T>>;
159 
160  inline h5data_proxy(const data_type& a) { dims[0] = a.num_elements(); }
161 
162  inline bool read(data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT)
163  {
164  if (!checkShapeConsistency<T>(grp, aname, FileSpace::rank, dims))
165  ref.reextent({dims[0]});
166  auto sz = ref.num_elements();
167  using iextensions = typename boost::multi::iextensions<1u>;
168  boost::multi::array<T, 1> buf(iextensions{sz});
169  auto ret = h5d_read(grp, aname, get_address(buf.data()), xfer_plist);
170  device::copy_n(buf.data(), sz, ref.origin());
171  return ret;
172  }
173 
174  inline bool write(const data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT) const
175  {
176  throw std::runtime_error(" write from gpu not implemented yet.");
177  return h5d_write(grp, aname.c_str(), FileSpace::rank, dims, get_address(to_address(ref.origin())), xfer_plist);
178  }
179 };
180 
181 template<typename T>
182 struct h5data_proxy<boost::multi::array<T, 2, device::device_allocator<T>>> : public h5_space_type<T, 2>
183 {
184  using FileSpace = h5_space_type<T, 2>;
185  using FileSpace::dims;
187  using data_type = boost::multi::array<T, 2, device::device_allocator<T>>;
188 
189  inline h5data_proxy(const data_type& a)
190  {
191  dims[0] = a.size(0);
192  dims[1] = a.size(1);
193  }
194 
195  inline bool read(data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT)
196  {
197  if (!checkShapeConsistency<T>(grp, aname, FileSpace::rank, dims))
198  ref.reextent({dims[0], dims[1]});
199  auto sz = ref.num_elements();
200  using iextensions = typename boost::multi::iextensions<1u>;
201  boost::multi::array<T, 1> buf(iextensions{sz});
202  auto ret = h5d_read(grp, aname, get_address(buf.data()), xfer_plist);
203  device::copy_n(buf.data(), sz, ref.origin());
204  return ret;
205  }
206 
207  inline bool write(const data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT) const
208  {
209  throw std::runtime_error(" write from gpu not implemented yet.");
210  return h5d_write(grp, aname.c_str(), FileSpace::rank, dims, get_address(to_address(ref.origin())), xfer_plist);
211  }
212 };
213 
214 template<typename T>
215 struct h5data_proxy<boost::multi::array_ref<T, 1, device::device_pointer<T>>> : public h5_space_type<T, 1>
216 {
217  using FileSpace = h5_space_type<T, 1>;
218  using FileSpace::dims;
220  using data_type = boost::multi::array_ref<T, 1, device::device_pointer<T>>;
221 
222  inline h5data_proxy(const data_type& a) { dims[0] = a.num_elements(); }
223 
224  inline bool read(data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT)
225  {
226  if (!checkShapeConsistency<T>(grp, aname, FileSpace::rank, dims))
227  {
228  if (dims[0] > 0)
229  {
230  std::cerr << " Error: multi::array_ref can't be resized in h5data_proxy<>::read." << std::endl;
231  std::cerr << dims[0] << " " << ref.size(0) << std::endl;
232  }
233  return false;
234  }
235  auto sz = ref.num_elements();
236  using iextensions = typename boost::multi::iextensions<1u>;
237  boost::multi::array<T, 1> buf(iextensions{sz});
238  auto ret = h5d_read(grp, aname, get_address(buf.data()), xfer_plist);
239  device::copy_n(buf.data(), sz, ref.origin());
240  return ret;
241  }
242 
243  inline bool write(const data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT) const
244  {
245  throw std::runtime_error(" write from gpu not implemented yet.");
246  return h5d_write(grp, aname.c_str(), FileSpace::rank, dims, get_address(to_address(ref.origin())), xfer_plist);
247  }
248 };
249 
250 template<typename T>
251 struct h5data_proxy<boost::multi::array_ref<T, 2, device::device_pointer<T>>> : public h5_space_type<T, 2>
252 {
253  using FileSpace = h5_space_type<T, 2>;
254  using FileSpace::dims;
256  using data_type = boost::multi::array_ref<T, 2, device::device_pointer<T>>;
257 
258  inline h5data_proxy(const data_type& a)
259  {
260  dims[0] = std::get<0>(a.sizes());
261  dims[1] = std::get<1>(a.sizes());
262  }
263 
264  inline bool read(data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT)
265  {
266  if (!checkShapeConsistency<T>(grp, aname, FileSpace::rank, dims))
267  {
268  if (dims[0] * dims[1] > 0)
269  {
270  std::cerr << " Error: multi::array_ref can't be resized in h5data_proxy<>::read." << std::endl;
271  std::cerr << dims[0] << " " << dims[1] << " " << std::get<0>(ref.sizes()) << " " << std::get<1>(ref.sizes()) << std::endl;
272  }
273  return false;
274  }
275  auto sz = ref.num_elements();
276  using iextensions = typename boost::multi::iextensions<1u>;
277  boost::multi::array<T, 1> buf(iextensions{sz});
278  auto ret = h5d_read(grp, aname, get_address(buf.data()), xfer_plist);
279  device::copy_n(buf.data(), sz, ref.origin());
280  return ret;
281  }
282 
283  inline bool write(const data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT) const
284  {
285  throw std::runtime_error(" write from gpu not implemented yet.");
286  return h5d_write(grp, aname.c_str(), FileSpace::rank, dims, get_address(to_address(ref.origin())), xfer_plist);
287  }
288 };
289 
290 template<typename T, unsigned RANK>
291 struct h5data_proxy<hyperslab_proxy<boost::multi::array<T, 2, device::device_allocator<T>>, RANK>>
292 {
293  using CT = boost::multi::array<T, 2, device::device_allocator<T>>;
294  using data_type = hyperslab_proxy<CT, RANK>;
295 
296  h5data_proxy(const data_type& a) {}
297 
298  inline bool read(data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT)
299  {
300  if (ref.use_slab)
301  {
302  // later on specialize h5d_read for fancy pointers
303  auto sz = ref.ref.num_elements();
304  boost::multi::array<T, 1> buf(typename boost::multi::layout_t<1u>::extensions_type{sz});
305  auto ret = h5d_read(grp, aname.c_str(), ref.slab_rank, ref.slab_dims.data(), ref.slab_dims_local.data(),
306  ref.slab_offset.data(), buf.origin(), xfer_plist);
307  device::copy_n(buf.data(), sz, ref.ref.origin());
308  return ret;
309  }
310  else
311  {
312  int rank = ref.slab_rank;
313  if (!checkShapeConsistency<T>(grp, aname, rank, ref.slab_dims.data(), true))
314  {
315  std::cerr << " Disabled hyperslab resize with boost::multi::array<gpu_allocator>.\n";
316  return false;
317  }
318  return h5d_read(grp, aname, ref.data(), xfer_plist);
319  }
320  }
321 
322  inline bool write(const data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT) const
323  {
324  std::cerr << " Disabled hyperslab write with boost::multi::array<gpu_allocator>.\n";
325  return false;
326  }
327 };
328 
329 template<typename T, unsigned RANK>
330 struct h5data_proxy<hyperslab_proxy<boost::multi::array_ref<T, 2, device::device_pointer<T>>, RANK>>
331 {
332  using CT = boost::multi::array_ref<T, 2, device::device_pointer<T>>;
333  using data_type = hyperslab_proxy<CT, RANK>;
334 
335  h5data_proxy(const data_type& a) {}
336 
337  inline bool read(data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT)
338  {
339  if (ref.use_slab)
340  {
341  // later on specialize h5d_read for fancy pointers
342  auto sz = ref.ref.num_elements();
343  boost::multi::array<T, 1> buf(typename boost::multi::layout_t<1u>::extensions_type{sz});
344  auto ret = h5d_read(grp, aname.c_str(), ref.slab_rank, ref.slab_dims.data(), ref.slab_dims_local.data(),
345  ref.slab_offset.data(), buf.origin(), xfer_plist);
346  device::copy_n(buf.data(), sz, ref.ref.origin());
347  return ret;
348  }
349  else
350  {
351  int rank = ref.slab_rank;
352  if (!checkShapeConsistency<T>(grp, aname, rank, ref.slab_dims.data(), true))
353  {
354  std::cerr << " Disabled hyperslab resize with boost::multi::array_ref<gpu_ptr>.\n";
355  return false;
356  }
357  return h5d_read(grp, aname, ref.data(), xfer_plist);
358  }
359  }
360 
361  inline bool write(const data_type& ref, hid_t grp, const std::string& aname, hid_t xfer_plist = H5P_DEFAULT) const
362  {
363  std::cerr << " Disabled hyperslab write with boost::multi::array_ref<gpu_ptr>.\n";
364  return false;
365  }
366 };
367 
368 #endif
369 #endif
370 
371 } // namespace qmcplusplus
372 #endif
default struct to define a h5 dataspace, any intrinsic type T
Definition: hdf_dataspace.h:44
bool write(const data_type &ref, hid_t grp, const std::string &aname, hid_t xfer_plist=H5P_DEFAULT) const
Definition: hdf_multi.h:50
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
bool write(const data_type &ref, hid_t grp, const std::string &aname, hid_t xfer_plist=H5P_DEFAULT) const
Definition: hdf_multi.h:77
bool read(data_type &ref, hid_t grp, const std::string &aname, hid_t xfer_plist=H5P_DEFAULT)
Definition: hdf_multi.h:42
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 write(const data_type &ref, hid_t grp, const std::string &aname, hid_t xfer_plist=H5P_DEFAULT) const
Definition: hdf_multi.h:107
bool read(data_type &ref, hid_t grp, const std::string &aname, hid_t xfer_plist=H5P_DEFAULT)
Definition: hdf_multi.h:93
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 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_multi.h:127
bool write(const data_type &ref, hid_t grp, const std::string &aname, hid_t xfer_plist=H5P_DEFAULT) const
Definition: hdf_multi.h:141
static auto get_address(T *a)
return the address
Definition: hdf_dataspace.h:53
sycl::event copy_n(sycl::queue &aq, const T1 *restrict VA, size_t array_size, T2 *restrict VC, const std::vector< sycl::event > &events)
Definition: syclBLAS.cpp:548
static constexpr hsize_t rank
rank of the multidimensional dataspace
Definition: hdf_dataspace.h:49
h5data_proxy(const data_type &a)
Definition: hdf_dataproxy.h:36
bool h5d_read(hid_t grp, const std::string &aname, T *first, hid_t xfer_plist)
return true, if successful
h5_space_type< T, 0 > FileSpace
Definition: hdf_dataproxy.h:32
bool read(data_type &ref, hid_t grp, const std::string &aname, hid_t xfer_plist=H5P_DEFAULT)
Definition: hdf_multi.h:70
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