TRIQS/h5
2.0.0
C++ interface to HDF5
Toggle main menu visibility
Loading...
Searching...
No Matches
file.cpp
Go to the documentation of this file.
1
// Copyright (c) 2019-2024 Simons Foundation
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0.txt
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
// Authors: Thomas Hahn, Olivier Parcollet, Nils Wentzell
16
21
22
#include "
./file.hpp
"
23
24
#include <hdf5.h>
25
#include <hdf5_hl.h>
26
27
#include <stdexcept>
28
29
using namespace
std::string_literals;
30
31
// throw an exception with a given message if a condition is not met
32
#define CHECK_OR_THROW(Cond, Mess) \
33
if (!(Cond)) throw std::runtime_error("Error in h5::file: "s + (Mess));
34
35
namespace
h5 {
36
37
file::file
(
const
char
*
name
,
char
mode) {
38
switch
(mode) {
39
// open existing file in read only mode
40
case
'r'
:
id
= H5Fopen(
name
, H5F_ACC_RDONLY, H5P_DEFAULT);
break
;
41
// create new or overwrite existing file in read-write mode
42
case
'w'
:
id
= H5Fcreate(
name
, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
break
;
43
// create new or append to existing file in read-write mode
44
case
'a'
: {
45
// turn off error handling
46
herr_t (*old_func)(
void
*) =
nullptr
;
47
void
*old_client_data =
nullptr
;
48
H5Eget_auto1(&old_func, &old_client_data);
49
H5Eset_auto1(
nullptr
,
nullptr
);
50
51
// this may fail
52
id
= H5Fcreate(
name
, H5F_ACC_EXCL, H5P_DEFAULT, H5P_DEFAULT);
53
54
// turn on error handling
55
H5Eset_auto1(old_func, old_client_data);
56
57
// open in read-write mode if creation failed
58
if
(
id
< 0)
id
= H5Fopen(
name
, H5F_ACC_RDWR, H5P_DEFAULT);
59
break
;
60
}
61
// create new file in read-write mode if the file does not exist yet
62
case
'e'
:
id
= H5Fcreate(
name
, H5F_ACC_EXCL, H5P_DEFAULT, H5P_DEFAULT);
break
;
63
default
:
throw
std::runtime_error(
"File mode is not one of r, w, a, e"
);
64
}
65
66
// throw an exception if opening/creating the file failed
67
if
(
id
< 0)
throw
std::runtime_error(
"Opening/Creating the file "
s +
name
+
" failed"
);
68
}
69
70
// same function is used in h5::group
71
std::string
file::name
()
const
{
72
// get length of the name
73
ssize_t size = H5Fget_name(
id
,
nullptr
, 1);
74
75
// reserve a buffer and get name
76
std::vector<char> buf(size + 1, 0x00);
77
H5Fget_name(
id
, buf.data(), size + 1);
78
79
// return string
80
std::string res =
""
;
81
res.append(&(buf.front()));
82
return
res;
83
}
84
85
void
file::flush
() {
86
if
(not
is_valid
())
return
;
87
auto
err = H5Fflush(
id
, H5F_SCOPE_GLOBAL);
88
CHECK_OR_THROW((err >= 0),
"Flushing the file failed"
);
89
}
90
91
file::file
() {
92
// create a file access property list
93
proplist
fapl = H5Pcreate(H5P_FILE_ACCESS);
94
CHECK_OR_THROW((fapl >= 0),
"Creating the fapl failed"
);
95
96
// set the file driver to use the `H5FD_CORE` driver
97
auto
err = H5Pset_fapl_core(fapl, (
size_t
)(64 * 1024),
false
);
98
CHECK_OR_THROW((err >= 0),
"Setting the core file driver in fapl failed"
);
99
100
// create a buffered memory file
101
this->
id
= H5Fcreate(
"MemoryBuffer"
, 0, H5P_DEFAULT, fapl);
102
CHECK_OR_THROW((this->
is_valid
()),
"Creating a buffered memory file failed"
);
103
}
104
105
file::file
(
const
std::byte *buf,
size_t
size) {
106
// create a file access property list
107
proplist
fapl = H5Pcreate(H5P_FILE_ACCESS);
108
CHECK_OR_THROW((fapl >= 0),
"Creating the fapl failed"
);
109
110
// set the file driver to use the `H5FD_CORE` driver
111
auto
err = H5Pset_fapl_core(fapl, (
size_t
)(64 * 1024),
false
);
112
CHECK_OR_THROW((err >= 0),
"Setting the core file driver in fapl failed"
);
113
114
// set the initial file image to the given memory buffer
115
err = H5Pset_file_image(fapl, (
void
*)buf, size);
116
CHECK_OR_THROW((err >= 0),
"Setting the file image to a given memory buffer failed"
);
117
118
// create a buffered memory file
119
this->
id
= H5Fopen(
"MemoryBuffer"
, H5F_ACC_RDWR, fapl);
120
CHECK_OR_THROW((this->
is_valid
()),
"Creating a buffered memory file failed"
);
121
}
122
123
std::vector<std::byte>
file::as_buffer
()
const
{
124
// flush the file
125
auto
f =
hid_t
(*
this
);
126
auto
err = H5Fflush(f, H5F_SCOPE_GLOBAL);
127
CHECK_OR_THROW((err >= 0),
"Flushing the buffered memory file failed"
);
128
129
// retrieve size of the file image
130
ssize_t image_len = H5Fget_file_image(f,
nullptr
, (
size_t
)0);
131
CHECK_OR_THROW((image_len > 0),
"Getting the file image size failed"
);
132
133
// create buffer and copy file image to it
134
std::vector<std::byte> buf(image_len, std::byte{0});
135
ssize_t bytes_read = H5Fget_file_image(f, (
void
*)buf.data(), (
size_t
)image_len);
136
CHECK_OR_THROW(bytes_read == image_len,
"Writing file image to buffer failed"
);
137
138
return
buf;
139
}
140
141
}
// namespace h5
h5::file::name
std::string name() const
Get the name of the file.
Definition
file.cpp:71
h5::file::as_buffer
std::vector< std::byte > as_buffer() const
Get a copy of the associated byte buffer.
Definition
file.cpp:123
h5::file::flush
void flush()
Flush the file by calling H5Fflush.
Definition
file.cpp:85
h5::file::file
file()
Default constructor creates a buffered memory file.
Definition
file.cpp:91
h5::object::is_valid
bool is_valid() const
Ensure that the wrapped HDF5 ID is valid (by calling H5Iis_valid).
Definition
object.cpp:116
file.hpp
Provides a handle to an HDF5 file.
h5::proplist
object proplist
Type alias for an HDF5 property list.
Definition
object.hpp:129
h5::hid_t
int64_t hid_t
ID type used in HDF5.
Definition
utils.hpp:45
h5
file.cpp
Generated by
1.17.0