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: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
8 //                    Ken Esler, kpesler@gmail.com, University of Illinois at Urbana-Champaign
9 //                    Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
10 //
11 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
12 //////////////////////////////////////////////////////////////////////////////////////
13 
14 
15 #ifndef OHMMS_HDF_STL_NUMERICATTRIBIO_H
16 #define OHMMS_HDF_STL_NUMERICATTRIBIO_H
17 #include "OhmmsData/HDFAttribIO.h"
18 #include "Numerics/HDFNumericAttrib.h"
19 #include <complex>
20 #include <bitset>
21 
22 namespace qmcplusplus
23 {
24 /** Specialization for std::vector<double> */
25 template<>
26 struct HDFAttribIO<std::vector<int>> : public HDFAttribIOBase
27 {
28   typedef std::vector<int> ArrayType_t;
29   ArrayType_t& ref;
30   bool replace;
31 
32   HDFAttribIO<ArrayType_t>(ArrayType_t& a, bool reuse = false) : ref(a), replace(reuse) {}
33 
34   inline void write(hid_t grp, const char* name)
35   {
36     if (replace)
37     {
38       hid_t dataset = H5Dopen(grp, name);
39       hid_t ret     = H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &(ref[0]));
40       H5Dclose(dataset);
41     }
42     else
43     {
44       hsize_t dim     = ref.size();
45       hid_t dataspace = H5Screate_simple(1, &dim, NULL);
46       hid_t dataset   = H5Dcreate(grp, name, H5T_NATIVE_INT, dataspace, H5P_DEFAULT);
47       hid_t ret       = H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &ref[0]);
48       H5Sclose(dataspace);
49       H5Dclose(dataset);
50     }
51   }
52 
53   inline void read(hid_t grp, const char* name)
54   {
55     hid_t h1        = H5Dopen(grp, name);
56     hid_t dataspace = H5Dget_space(h1);
57     hsize_t dims_out[1];
58     int rank     = H5Sget_simple_extent_ndims(dataspace);
59     int status_n = H5Sget_simple_extent_dims(dataspace, dims_out, NULL);
60     if (ref.size() != int(dims_out[0]))
61     {
62       ref.resize(int(dims_out[0]));
63     }
64     hid_t ret = H5Dread(h1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &ref[0]);
65     H5Sclose(dataspace);
66     H5Dclose(h1);
67   }
68 };
69 
70 template<>
71 struct HDFAttribIO<std::vector<double>> : public HDFAttribIOBase
72 {
73   typedef std::vector<double> ArrayType_t;
74   std::vector<hsize_t> Dim;
75   ArrayType_t& ref;
76   bool replace;
77   int offset_;
78 
79   HDFAttribIO<ArrayType_t>(ArrayType_t& a, bool over = false) : ref(a), replace(over), offset_(0)
80   {
81     Dim.resize(1, a.size());
82   }
83 
84   HDFAttribIO<ArrayType_t>(ArrayType_t& a, std::vector<int>& dim, int offset = 0)
85       : ref(a), replace(false), offset_(offset)
86   {
87     Dim.resize(dim.size());
88     for (int i = 0; i < dim.size(); i++)
89       Dim[i] = static_cast<hsize_t>(dim[i]);
90   }
91 
92   HDFAttribIO<ArrayType_t>(ArrayType_t& a, hsize_t ndim, hsize_t* dim, int offset = 0)
93       : ref(a), replace(false), offset_(offset)
94   {
95     Dim.resize(ndim);
96     for (int i = 0; i < ndim; i++)
97       Dim[i] = dim[0];
98   }
99 
100   inline void write(hid_t grp, const char* name)
101   {
102     //hsize_t dim = ref.size();
103     //hid_t dataspace  = H5Screate_simple(1, &dim, NULL);
104     if (replace)
105     {
106       hid_t dataset = H5Dopen(grp, name);
107       hid_t ret     = H5Dwrite(dataset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, &(ref[offset_]));
108       H5Dclose(dataset);
109     }
110     else
111     {
112       hid_t dataspace = H5Screate_simple(Dim.size(), &Dim[0], NULL);
113       hid_t dataset   = H5Dcreate(grp, name, H5T_NATIVE_DOUBLE, dataspace, H5P_DEFAULT);
114       hid_t ret       = H5Dwrite(dataset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, &ref[offset_]);
115       H5Sclose(dataspace);
116       H5Dclose(dataset);
117     }
118   }
119 
120   inline void read(hid_t grp, const char* name)
121   {
122     hid_t h1        = H5Dopen(grp, name);
123     hid_t dataspace = H5Dget_space(h1);
124     //hsize_t dims_out[1];
125     std::vector<hsize_t> dims_out(Dim);
126     int rank     = H5Sget_simple_extent_ndims(dataspace);
127     int status_n = H5Sget_simple_extent_dims(dataspace, &dims_out[0], NULL);
128     Dim          = dims_out;
129     hsize_t ntot = Dim[0];
130     for (int i = 1; i < Dim.size(); i++)
131       ntot *= Dim[i];
132     if (ref.size() != int(ntot))
133     {
134       ref.resize(int(ntot));
135     }
136     hid_t ret = H5Dread(h1, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, &ref[0]);
137     H5Sclose(dataspace);
138     H5Dclose(h1);
139   }
140 };
141 
142 template<>
143 struct HDFAttribIO<std::vector<std::complex<double>>> : public HDFAttribIOBase
144 {
145   //NOTE: This specialization assumes each complex number was/will be saved
146   // as a pair of doubles. This is checked.
147 
148   typedef std::vector<std::complex<double>> ArrayType_t;
149   std::vector<hsize_t> Dim;
150   ArrayType_t& ref;
151 
152   //Assumes complex stored as a pair of floats/doubles.
153   HDFAttribIO<ArrayType_t>(ArrayType_t& a) : ref(a)
154   {
155     Dim.resize(2);
156     Dim[0] = a.size();
157     Dim[1] = 2;
158   }
159 
160   inline void write(hid_t grp, const char* name)
161   {
162     //hsize_t dim = ref.size();
163     //hid_t dataspace  = H5Screate_simple(1, &dim, NULL);
164     hid_t dataspace = H5Screate_simple(Dim.size(), &Dim[0], NULL);
165     hid_t dataset   = H5Dcreate(grp, name, H5T_NATIVE_DOUBLE, dataspace, H5P_DEFAULT);
166     hid_t ret       = H5Dwrite(dataset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, &ref[0]);
167     H5Sclose(dataspace);
168     H5Dclose(dataset);
169   }
170 
171   inline void read(hid_t grp, const char* name)
172   {
173     // Turn off error printing
174     H5E_auto2_t func;
175     void* client_data;
176     H5Eget_auto2(H5E_DEFAULT, &func, &client_data);
177     H5Eset_auto2(H5E_DEFAULT, NULL, NULL);
178     hid_t h1        = H5Dopen(grp, name);
179     hid_t dataspace = H5Dget_space(h1);
180     //hsize_t dims_out[1];
181     std::vector<hsize_t> dims_out(Dim);
182     int rank = H5Sget_simple_extent_ndims(dataspace);
183     if (rank != 2)
184     {
185       //LOGMSG("Error: HDF rank does not match for complex vector")
186       return;
187     }
188     int status_n = H5Sget_simple_extent_dims(dataspace, &dims_out[0], NULL);
189     if (dims_out[1] != 2)
190     {
191       //LOGMSG("Error: HDF rank does not match for complex vector")
192       return;
193     }
194     Dim          = dims_out;
195     hsize_t ntot = Dim[0];
196     if (ref.size() != int(ntot))
197     {
198       ref.resize(int(ntot));
199     }
200     hid_t ret = H5Dread(h1, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, &ref[0]);
201     H5Sclose(dataspace);
202     H5Dclose(h1);
203     H5Eset_auto2(H5E_DEFAULT, func, client_data);
204   }
205 };
206 
207 template<std::size_t N>
208 struct HDFAttribIO<std::bitset<N>> : public HDFAttribIOBase
209 {
210   //NOTE: This specialization assumes each complex number was/will be saved
211   // as a pair of doubles. This is checked.
212 
213   typedef std::bitset<N> ArrayType_t;
214   ArrayType_t& ref;
215   bool replace;
216 
217   //Assumes complex stored as a pair of floats/doubles.
218   HDFAttribIO<ArrayType_t>(ArrayType_t& a, bool reuse = false) : ref(a), replace(reuse) {}
219 
220   inline void write(hid_t grp, const char* name)
221   {
222     unsigned long c = ref.to_ulong();
223     HDFAttribIO<unsigned long> hc(c, replace);
224     hc.write(grp, name);
225   }
226 
227   inline void read(hid_t grp, const char* name)
228   {
229     unsigned long c = ref.to_ulong();
230     HDFAttribIO<unsigned long> hc(c);
231     hc.read(grp, name);
232     ref = c;
233   }
234 };
235 } // namespace qmcplusplus
236 #endif
237