Dune-Fufem 2.11-git
Loading...
Searching...
No Matches
file.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright © DUNE-FUFEM Project contributors, see file AUTHORS.md
2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception OR LGPL-3.0-or-later
3
4#ifndef DUNE_FUFEM_HDF5_FILE_HH
5#define DUNE_FUFEM_HDF5_FILE_HH
6
7#include <iostream>
8#include <sys/stat.h>
9#include <string>
10
11#if __has_include(<hdf5.h>)
12
13#include <hdf5.h>
14
16
17namespace HDF5 {
18class Grouplike {
19public:
20 bool hasDataset(std::string name) {
21 return H5Lexists(c_obj(), name.c_str(), H5P_DEFAULT);
22 }
23
24 hid_t openDataset(std::string name) {
25 return H5Dopen(c_obj(), name.c_str(), H5P_DEFAULT);
26 }
27
28 hid_t createDataset(std::string name, hid_t file_space, hid_t plist,
29 hid_t datatype) {
30 return H5Dcreate(c_obj(), name.c_str(), datatype, file_space, H5P_DEFAULT,
31 plist, H5P_DEFAULT);
32 }
33
34 virtual hid_t c_obj() = 0;
35 virtual bool isReadOnly() const = 0;
36};
37
38enum class Access { READONLY, READWRITE };
39
40class File : public Grouplike {
41public:
42 File(std::string filename, Access access = Access::READWRITE)
43 : readOnly_(access == Access::READONLY) {
44 struct stat buffer;
45
46 /* Use the latest HDF5 format (as opposed to: the latest format that supports
47 the set of features we use: H5F_LIBVER_EARLIEST)
48 Upside : Improvements in speed, file size
49 Downside: Output cannot be read by old tools/libraries
50 Remedy: h5repack and h5format_convert can restore compatibility. */
51 H5F_libver_t const minimumVersion = H5F_LIBVER_LATEST;
52 hid_t fapl = H5Pcreate(H5P_FILE_ACCESS);
53 H5Pset_libver_bounds(fapl, minimumVersion, H5F_LIBVER_LATEST);
54
55 bool const fileExists = stat(filename.c_str(), &buffer) == 0;
56 bool const createFile = !fileExists;
57 if (createFile && readOnly_)
60 "Tried to open non-existing file in read-only mode: " << filename);
61
62 // If createFile is true: We already know the file does not exist,
63 // so H5F_ACC_EXCL and H5F_ACC_TRUNC are essentially equivalent
64 unsigned int flags =
65 createFile ? H5F_ACC_EXCL : (readOnly_ ? H5F_ACC_RDONLY : H5F_ACC_RDWR);
66#if H5_VERSION_GE(1, 10, 0)
67 // Enabling SWMR reading by default on HDF-1.10 does not hurt
68 // (except maybe performance). In contrast, enabling SWMR writing
69 // produces a file that is not readable by HDF5-1.8. The user can
70 // still enable SWMR writing later through swmrEnable().
71 if (readOnly_)
72 flags |= H5F_ACC_SWMR_READ;
73#endif
74
75 file_ = createFile ? H5Fcreate(filename.c_str(), flags, H5P_DEFAULT, fapl)
76 : H5Fopen(filename.c_str(), flags, fapl);
77 if (file_ < 0)
78 DUNE_THROW(Dune::Exception, "Unable to open file: " << filename);
79 }
80
81 void flush() { H5Fflush(file_, H5F_SCOPE_LOCAL); }
82
83 ~File() { H5Fclose(file_); }
84
85 hid_t c_obj() override { return file_; }
86 bool isReadOnly() const override { return readOnly_; }
87 bool swmrEnabled() { return swmrEnabled_; }
88 void swmrEnable() {
89 if (swmrEnabled_)
90 return;
91
92#if H5_VERSION_GE(1, 10, 0)
93 if (!readOnly_) {
94 swmrEnabled_ = true;
95 H5Fstart_swmr_write(file_);
96 } else {
97 std::cerr << "WARNING: SWMR writing requested for a read-only file"
98 << std::endl;
99 }
100#else
102 << "WARNING: SWMR requested but not supported by this version of HDF5"
103 << std::endl;
104#endif
105 }
106
107private:
108 hid_t file_;
109 bool const readOnly_;
110 bool swmrEnabled_ = false;
111};
112
113class Group : public Grouplike {
114public:
115 Group(Grouplike &parent, std::string groupname) : parent_(parent) {
116 group_ = H5Lexists(parent_.c_obj(), groupname.c_str(), H5P_DEFAULT)
117 ? H5Gopen(parent_.c_obj(), groupname.c_str(), H5P_DEFAULT)
118 : H5Gcreate(parent_.c_obj(), groupname.c_str(), H5P_DEFAULT,
119 H5P_DEFAULT, H5P_DEFAULT);
120 }
121
122 ~Group() { H5Gclose(group_); }
123
124 hid_t c_obj() override { return group_; }
125 bool isReadOnly() const override { return parent_.isReadOnly(); }
126
127private:
128 Grouplike &parent_;
129 hid_t group_;
130};
131}
132
133#else
134 #warning Including the hdf5/file.hh but hdf5.h is missing.
135#endif // __has_include(<hdf5.h>)
136
137#endif
const char * name()
DebugStream & flush()
#define DUNE_THROW(E,...)
T c_str(T... args)
T endl(T... args)