votca 2024.1-dev
Loading...
Searching...
No Matches
checkpointwriter.h
Go to the documentation of this file.
1/*
2 * Copyright 2009-2020 The VOTCA Development Team (http://www.votca.org)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 *
15 */
16
17#pragma once
18#ifndef VOTCA_XTP_CHECKPOINTWRITER_H
19#define VOTCA_XTP_CHECKPOINTWRITER_H
20
21// Standard includes
22#include <map>
23#include <string>
24#include <type_traits>
25#include <typeinfo>
26#include <vector>
27
28#if defined(__clang__)
29#elif defined(__GNUC__)
30#pragma GCC diagnostic push
31#pragma GCC diagnostic ignored "-Wdeprecated-copy"
32#endif
33
34// Third party includes
35#include <H5Cpp.h>
36
37// VOTCA includes
38#include <votca/tools/linalg.h>
39
40// Local VOTCA includes
41#include "checkpoint_utils.h"
42#include "checkpointtable.h"
43#include "eigen.h"
44
45namespace votca {
46namespace xtp {
47
48using namespace checkpoint_utils;
49
51 public:
52 CheckpointWriter(const CptLoc& loc) : CheckpointWriter(loc, "/") {};
53
54 CheckpointWriter(const CptLoc& loc, const std::string& path)
55 : loc_(loc), path_(path) {};
56
57 // see the following links for details
58 // https://stackoverflow.com/a/8671617/1186564
59 template <typename T>
60 typename std::enable_if<!std::is_fundamental<T>::value>::type operator()(
61 const T& data, const std::string& name) const {
62 try {
63 WriteData(loc_, data, name);
64 } catch (H5::Exception&) {
65 std::stringstream message;
66 message << "Could not write " << name << " to " << loc_.getFileName()
67 << ":" << path_;
68
69 throw std::runtime_error(message.str());
70 }
71 }
72
73 // Use this overload if T is a fundamental type
74 // int, double, unsigned, etc, but not bool
75 template <typename T>
76 typename std::enable_if<std::is_fundamental<T>::value &&
77 !std::is_same<T, bool>::value>::type
78 operator()(const T& v, const std::string& name) const {
79 try {
80 WriteScalar(loc_, v, name);
81 } catch (H5::Exception&) {
82 std::stringstream message;
83 message << "Could not write " << name << " to " << loc_.getFileName()
84 << ":" << path_ << std::endl;
85
86 throw std::runtime_error(message.str());
87 }
88 }
89
90 void operator()(const bool& v, const std::string& name) const {
91 Index temp = static_cast<Index>(v);
92 try {
93 WriteScalar(loc_, temp, name);
94 } catch (H5::Exception&) {
95 std::stringstream message;
96 message << "Could not write " << name << " to " << loc_.getFileName()
97 << ":" << path_ << std::endl;
98
99 throw std::runtime_error(message.str());
100 }
101 }
102
103 void operator()(const std::string& v, const std::string& name) const {
104 try {
105 WriteScalar(loc_, v, name);
106 } catch (H5::Exception&) {
107 std::stringstream message;
108 message << "Could not write " << name << " to " << loc_.getFileName()
109 << ":" << path_ << std::endl;
110
111 throw std::runtime_error(message.str());
112 }
113 }
114
115 CheckpointWriter openChild(const std::string& childName) const {
116 try {
117 return CheckpointWriter(loc_.openGroup(childName),
118 path_ + "/" + childName);
119 } catch (H5::Exception&) {
120 try {
121 return CheckpointWriter(loc_.createGroup(childName),
122 path_ + "/" + childName);
123 } catch (H5::Exception&) {
124 std::stringstream message;
125 message << "Could not open or create" << loc_.getFileName() << ":/"
126 << path_ << "/" << childName << std::endl;
127
128 throw std::runtime_error(message.str());
129 }
130 }
131 }
132
133 template <typename T>
134 CptTable openTable(const std::string& name, std::size_t nRows,
135 bool compact = false) {
136 CptTable table;
137 try {
138 table = CptTable(name, sizeof(typename T::data), loc_);
139 T::SetupCptTable(table);
140 } catch (H5::Exception&) {
141 try {
142 table = CptTable(name, sizeof(typename T::data), nRows);
143 T::SetupCptTable(table);
144 table.initialize(loc_, compact);
145 } catch (H5::Exception&) {
146 std::stringstream message;
147 message << "Could not open table " << name << " in "
148 << loc_.getFileName() << ":" << path_ << std::endl;
149 throw std::runtime_error(message.str());
150 }
151 }
152
153 return table;
154 }
155
156 private:
158 const std::string path_;
159 template <typename T>
160 void WriteScalar(const CptLoc& loc, const T& value,
161 const std::string& name) const {
162
163 hsize_t dims[1] = {1};
164 H5::DataSpace dp(1, dims);
165 const H5::DataType* dataType = InferDataType<T>::get();
166 H5::Attribute attr;
167 try {
168 attr = loc.createAttribute(name, *dataType, dp);
169 } catch (H5::AttributeIException&) {
170 attr = loc.openAttribute(name);
171 }
172 attr.write(*dataType, &value);
173 }
174
175 void WriteScalar(const CptLoc& loc, const std::string& value,
176 const std::string& name) const {
177 hsize_t dims[1] = {1};
178 H5::DataSpace dp(1, dims);
179 const H5::DataType* strType = InferDataType<std::string>::get();
180
181 H5::Attribute attr;
182
183 try {
184 attr = loc.createAttribute(name, *strType, dp);
185 } catch (H5::AttributeIException&) {
186 attr = loc.openAttribute(name);
187 }
188
189 const char* c_str_copy = value.c_str();
190 attr.write(*strType, &c_str_copy);
191 }
192
193 template <typename T>
194 void WriteData(const CptLoc& loc, const Eigen::MatrixBase<T>& matrix,
195 const std::string& name) const {
196
197 hsize_t matRows = hsize_t(matrix.rows());
198 hsize_t matCols = hsize_t(matrix.cols());
199
200 hsize_t dims[2] = {matRows, matCols}; // eigen vectors are n,1 matrices
201
202 if (dims[1] == 0) {
203 dims[1] = 1;
204 }
205
206 H5::DataSpace dp(2, dims);
207 const H5::DataType* dataType = InferDataType<typename T::Scalar>::get();
208 H5::DataSet dataset;
209 try {
210 dataset = loc.createDataSet(name.c_str(), *dataType, dp);
211 } catch (H5::GroupIException&) {
212 dataset = loc.openDataSet(name.c_str());
213 }
214
215 hsize_t matColSize = matrix.derived().outerStride();
216
217 hsize_t fileRows = matCols;
218
219 hsize_t fStride[2] = {1, fileRows};
220 hsize_t fCount[2] = {1, 1};
221 hsize_t fBlock[2] = {1, fileRows};
222
223 hsize_t mStride[2] = {matColSize, 1};
224 hsize_t mCount[2] = {1, 1};
225 hsize_t mBlock[2] = {matCols, 1};
226
227 hsize_t mDim[2] = {matCols, matColSize};
228 H5::DataSpace mspace(2, mDim);
229
230 for (hsize_t i = 0; i < matRows; i++) {
231 hsize_t fStart[2] = {i, 0};
232 hsize_t mStart[2] = {0, i};
233 dp.selectHyperslab(H5S_SELECT_SET, fCount, fStart, fStride, fBlock);
234 mspace.selectHyperslab(H5S_SELECT_SET, mCount, mStart, mStride, mBlock);
235 dataset.write(matrix.derived().data(), *dataType, mspace, dp);
236 }
237 }
238
239 template <typename T>
240 typename std::enable_if<std::is_fundamental<T>::value>::type WriteData(
241 const CptLoc& loc, const std::vector<T> v,
242 const std::string& name) const {
243 hsize_t dims[2] = {(hsize_t)v.size(), 1};
244
245 const H5::DataType* dataType = InferDataType<T>::get();
246 H5::DataSet dataset;
247 H5::DataSpace dp(2, dims);
248 try {
249 dataset = loc.createDataSet(name.c_str(), *dataType, dp);
250 } catch (H5::GroupIException&) {
251 dataset = loc.openDataSet(name.c_str());
252 }
253 dataset.write(v.data(), *dataType);
254 }
255
256 void WriteData(const CptLoc& loc, const std::vector<std::string>& v,
257 const std::string& name) const {
258
259 hsize_t dims[1] = {(hsize_t)v.size()};
260
261 std::vector<const char*> c_str_copy;
262 c_str_copy.reserve(v.size());
263 for (const std::string& s : v) {
264 c_str_copy.push_back(s.c_str());
265 }
266 const H5::DataType* dataType = InferDataType<std::string>::get();
267 H5::DataSet dataset;
268 H5::DataSpace dp(1, dims);
269 try {
270 dataset = loc.createDataSet(name.c_str(), *dataType, dp);
271 } catch (H5::GroupIException&) {
272 dataset = loc.openDataSet(name.c_str());
273 }
274 dataset.write(c_str_copy.data(), *dataType);
275 }
276
277 void WriteData(const CptLoc& loc, const std::vector<Eigen::Vector3d>& v,
278 const std::string& name) const {
279
280 size_t c = 0;
281 std::string r;
282 CptLoc parent;
283 try {
284 parent = loc.createGroup(name);
285 } catch (H5::GroupIException&) {
286 parent = loc.openGroup(name);
287 }
288 for (auto const& x : v) {
289 r = std::to_string(c);
290 WriteData(parent, x, "ind" + r);
291 ++c;
292 }
293 }
294
295 void WriteData(const CptLoc& loc, const tools::EigenSystem& sys,
296 const std::string& name) const {
297
298 CptLoc parent;
299 try {
300 parent = loc.createGroup(name);
301 } catch (H5::GroupIException&) {
302 parent = loc.openGroup(name);
303 }
304
305 WriteData(parent, sys.eigenvalues(), "eigenvalues");
306 WriteData(parent, sys.eigenvectors(), "eigenvectors");
307 WriteData(parent, sys.eigenvectors2(), "eigenvectors2");
308 WriteScalar(parent, Index(sys.info()), "info");
309 }
310
311 template <typename T1, typename T2>
312 void WriteData(const CptLoc& loc, const std::map<T1, std::vector<T2>> map,
313 const std::string& name) const {
314
315 size_t c = 0;
316 std::string r;
317 // Iterate over the map and write map as a number of vectors with T1 as
318 // index
319 for (auto const& x : map) {
320 r = std::to_string(c);
321 CptLoc tempGr;
322 try {
323 tempGr = loc.createGroup(name);
324 } catch (H5::GroupIException&) {
325 tempGr = loc.openGroup(name);
326 }
327 WriteData(tempGr, x.second, "index" + r);
328 ++c;
329 }
330 }
331};
332} // namespace xtp
333} // namespace votca
334
335#if defined(__clang__)
336#elif defined(__GNUC__)
337#pragma GCC diagnostic pop
338#endif
339
340#endif // VOTCA_XTP_CHECKPOINTWRITER_H
const Eigen::MatrixXd & eigenvectors2() const
Definition eigensystem.h:36
Eigen::ComputationInfo info() const
Definition eigensystem.h:39
const Eigen::VectorXd & eigenvalues() const
Definition eigensystem.h:30
const Eigen::MatrixXd & eigenvectors() const
Definition eigensystem.h:33
CheckpointWriter(const CptLoc &loc, const std::string &path)
std::enable_if< std::is_fundamental< T >::value &&!std::is_same< T, bool >::value >::type operator()(const T &v, const std::string &name) const
CheckpointWriter(const CptLoc &loc)
void WriteScalar(const CptLoc &loc, const std::string &value, const std::string &name) const
void WriteData(const CptLoc &loc, const Eigen::MatrixBase< T > &matrix, const std::string &name) const
CheckpointWriter openChild(const std::string &childName) const
void operator()(const std::string &v, const std::string &name) const
void WriteScalar(const CptLoc &loc, const T &value, const std::string &name) const
void operator()(const bool &v, const std::string &name) const
std::enable_if<!std::is_fundamental< T >::value >::type operator()(const T &data, const std::string &name) const
void WriteData(const CptLoc &loc, const std::vector< Eigen::Vector3d > &v, const std::string &name) const
void WriteData(const CptLoc &loc, const std::map< T1, std::vector< T2 > > map, const std::string &name) const
void WriteData(const CptLoc &loc, const tools::EigenSystem &sys, const std::string &name) const
std::enable_if< std::is_fundamental< T >::value >::type WriteData(const CptLoc &loc, const std::vector< T > v, const std::string &name) const
CptTable openTable(const std::string &name, std::size_t nRows, bool compact=false)
void WriteData(const CptLoc &loc, const std::vector< std::string > &v, const std::string &name) const
void initialize(const CptLoc &loc, bool compact)
H5::Group CptLoc
base class for all analysis tools
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26