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