Utopia 2
Framework for studying models of complex & adaptive systems.
Loading...
Searching...
No Matches
hdfdataspace.hh
Go to the documentation of this file.
1#ifndef UTOPIA_DATAIO_HDFDATASPACE_HH
2#define UTOPIA_DATAIO_HDFDATASPACE_HH
3
4#include <armadillo>
5#include <stdexcept>
6
7#include <hdf5.h>
8
9#include "../core/logging.hh"
10#include "../core/type_traits.hh"
11#include "../core/ostream.hh"
12
13#include "hdfobject.hh"
14#include "hdfutilities.hh"
15
16
17namespace Utopia
18{
19namespace DataIO
20{
36class HDFDataspace final : public HDFObject< HDFCategory::dataspace >
37{
38 public:
47 {
48 if (is_valid())
49 {
51 }
52 else
53 {
54 throw std::runtime_error(
55 "Error, trying to get rank of invalid dataspace");
56 return 0;
57 }
58 }
59
66 std::pair< arma::Row< hsize_t >, arma::Row< hsize_t > >
68 {
69 if (not is_valid())
70 {
71 throw std::runtime_error(
72 "Error, trying to get properties of invalid dataspace," +
73 std::to_string(get_C_id()));
74 }
75
76 arma::Row< hsize_t > size;
78
79 arma::Row< hsize_t > capacity;
80 capacity.resize(size.size());
81
82 H5Sget_simple_extent_dims(get_C_id(), size.memptr(), capacity.memptr());
83
84 return std::make_pair(size, capacity);
85 }
86
93 arma::Row< hsize_t >
95 {
96 return get_properties().first;
97 }
98
105 arma::Row< hsize_t >
107 {
108 return get_properties().second;
109 }
110
116 void
118 {
119
120 this->_log->debug("Opening dataspace, setting it to H5S_ALL");
121 // no explicit close function needed for H5S_ALL
122 _id.open(H5S_ALL, [](hid_t) -> herr_t { return 1; });
123 _path = "Dataspace_all";
124 }
125
132 template < typename Object >
133 void
134 open(Object&& object)
135 {
136
137 this->_log->debug(
138 "Opening dataspace of {}", generate_object_name(object));
139
140 // open_dataspace is defined for attribute and dataset
141 // in their respective headerfiles to provide uniform
142 // interface for both, such that we do not have to
143 // differentiate between them
144 bind_to(open_dataspace(std::forward< Object >(object)),
145 &H5Sclose,
146 object.get_path() + " dataspace");
147
148 _log = spdlog::get("data_io");
149 }
150
161 void
162 open(std::string name,
164 arma::Row< hsize_t > extent,
165 arma::Row< hsize_t > capacity)
166 {
167
168 this->_log->debug("Opening dataspace from scratch with rank {}, extent "
169 "{} and capacity {}",
170 rank,
171 Utils::str(extent),
173 if (capacity.size() == 0)
174 {
175 bind_to(
176 H5Screate_simple(rank, extent.memptr(), NULL), &H5Sclose, name);
177 }
178 else
179 {
180 bind_to(H5Screate_simple(rank, extent.memptr(), capacity.memptr()),
181 &H5Sclose,
182 name);
183 }
184
185 _log = spdlog::get("data_io");
186 }
187
194 std::pair< arma::Row< hsize_t >, arma::Row< hsize_t > >
196 {
197 arma::Row< hsize_t > start;
198 arma::Row< hsize_t > end;
199
200 if (is_valid())
201 {
202 hsize_t r = rank();
203 start.resize(r);
204 end.resize(r);
205
206 if (H5Sget_select_bounds(get_C_id(), start.memptr(), end.memptr()) <
207 0)
208 {
209 throw std::runtime_error(
210 "Error, cannot get selection bounds of invalid dataspace");
211 }
212 }
213 return std::make_pair(start, end);
214 }
215
224 void
225 select_slice(arma::Row< hsize_t > start,
226 arma::Row< hsize_t > end,
227 arma::Row< hsize_t > stride)
228 {
229
230 this->_log->debug(
231 "Selecting slice in dataspace with start={}, end={}, stride={}",
232 Utils::str(start),
233 Utils::str(end),
235
236 if (not is_valid())
237 {
238 throw std::runtime_error(
239 "Error, trying to select a slice in an invalid dataspace");
240 }
241
242 hsize_t r = rank();
243
244 if ((start.n_elem != r) or (end.n_elem != r))
245 {
246 throw std::runtime_error(
247 "Error, dimensionality of start and end has to be the same as "
248 "the dataspace's rank");
249 }
250 // stride may not be given, and hence we have to check for
251 // it in order to correctly compute the counts vector: divison
252 // can be skipped when stride.size() == 0
253
254 arma::Row< hsize_t > count;
255 hsize_t* strideptr = nullptr;
256 if (stride.size() == 0)
257 {
258 count = ((end - start)).as_row();
259 }
260 else
261 {
262 count = ((end - start) / stride).as_row();
263 strideptr = stride.memptr();
264 }
265
268 start.memptr(),
269 strideptr,
270 count.memptr(),
271 nullptr);
272 if (err < 0)
273 {
274 throw std::runtime_error(
275 "Error when trying to select slice in dataspace");
276 }
277 }
278
283 void
285 {
286 this->_log->debug("Selecting everything in dataspace");
287
288 if (not is_valid())
289 {
290 throw std::runtime_error(
291 "Error, trying to select everything of an invalid dataspace");
292 }
293
295 if (err < 0)
296 {
297 throw std::runtime_error(
298 "Error when trying to select entire dataspace");
299 }
300 }
301
310 void
311 resize(arma::Row< hsize_t > new_size)
312 {
313 this->_log->debug("Resizing dataset from {} to {}",
314 Utils::str(size()),
315 Utils::str(new_size));
316
317 if (not is_valid())
318 {
319 throw std::runtime_error(
320 "Error, trying to resize an invalid dataspace");
321 }
322
324
325 // make capacity bigger if needed
326 auto new_capacity = arma::max(current_capacity, new_size);
327
328 // resize the dataspace
330 new_size.size(),
331 new_size.memptr(),
332 current_capacity.memptr());
333
334 if (err < 0)
335 {
336 throw std::runtime_error("Error in resizing dataspace");
337 }
338 }
339
344 void
346 {
347 this->_log->debug("Releasing selection");
348
349 if (not is_valid())
350 {
351 throw std::runtime_error(
352 "Cannot reset selection, dataspace is invalid");
353 }
354
356 }
357
364 {
365 open();
366 }
367
372 HDFDataspace(const HDFDataspace&) = default;
373
379
386 operator=(const HDFDataspace&) = default;
387
395
403 HDFDataspace(std::string name,
405 std::vector< hsize_t > extent,
406 std::vector< hsize_t > capacity)
407 {
408 open(name, rank, extent, capacity);
409 }
410
418 template < typename Object >
420 std::enable_if_t<
421 not std::is_same_v< std::decay_t< Object >, HDFDataspace >,
422 int > = 0)
423 {
424 open(std::forward< Object >(object));
425 }
426
431 virtual ~HDFDataspace() = default;
432
438 void
440 {
441 using std::swap;
443 swap(static_cast< Base& >(*this), static_cast< Base& >(other));
444 }
445};
446
453void
455{
456 lhs.swap(rhs);
457}
458
459}
460
461}
462#endif
Class that wraps an HDF5 dataspace and takes care of managing its resources.
Definition hdfdataspace.hh:37
void open(hid_t id, std::function< herr_t(hid_t) > closing_func)
Open the object and bind it to another C-Level id.
Definition hdfidentifier.hh:156
Common base class for all HDF5 classes in the DATAIO Module i.e., for all classes that wrap HDF5-C-Li...
Definition hdfobject.hh:37
std::string _path
Name of the object.
Definition hdfobject.hh:50
std::string get_path() const
Get the name or path object.
Definition hdfobject.hh:88
virtual bool is_valid() const
Check if the object is still valid.
Definition hdfobject.hh:143
std::shared_ptr< spdlog::logger > _log
pointer to the logger for dataio
Definition hdfobject.hh:56
HDFIdentifier _id
Identifier object that binds an instance of this class to an HDF5 object.
Definition hdfobject.hh:44
hid_t get_C_id() const
Get the C id object.
Definition hdfobject.hh:120
void bind_to(hid_t id, std::function< herr_t(hid_t) > closing_func, std::string path={})
Open the object and bind it to a HDF5 object identified by 'id' with name 'path'. Object should be cr...
Definition hdfobject.hh:186
void swap(WriteTask< BGB, DW, DB, AWG, AWD > &lhs, WriteTask< BGB, DW, DB, AWG, AWD > &rhs)
Swaps the state of lhs and rhs.
Definition write_task.hh:240
Container select_entities(const Manager &mngr, const DataIO::Config &sel_cfg)
Select entities according to parameters specified in a configuration.
Definition select.hh:213
hid_t open_dataspace(Object &&object)
Depending on object category, opens a dataset or attribute dataspace.
Definition hdfutilities.hh:235
arma::Row< hsize_t > size()
Get the current size of the dataspace in each dimension.
Definition hdfdataspace.hh:94
void open(std::string name, hsize_t rank, arma::Row< hsize_t > extent, arma::Row< hsize_t > capacity)
Open a new dataset of type 'simple', which is equivalent to a N-dimensional array of dimension N = 'r...
Definition hdfdataspace.hh:162
void swap(HDFDataspace &other)
Swap state with argument.
Definition hdfdataspace.hh:439
HDFDataspace(HDFDataspace &&)=default
Move constructor.
void release_selection()
Release a previously defined selection.
Definition hdfdataspace.hh:345
std::string generate_object_name(const Object &object)
Use category and path variable of object to make a string that identifies the object it is applied to...
Definition hdfutilities.hh:220
virtual ~HDFDataspace()=default
Destroy the HDFDataspace object.
void select_slice(arma::Row< hsize_t > start, arma::Row< hsize_t > end, arma::Row< hsize_t > stride)
Select a slice in the dataspace defined by [start, end, stride] in the manner of numpy....
Definition hdfdataspace.hh:225
arma::Row< hsize_t > capacity()
Get the capacity of the dataspace in each dimension.
Definition hdfdataspace.hh:106
HDFDataspace(const HDFDataspace &)=default
Copy constructor.
HDFDataspace(Object &&object, std::enable_if_t< not std::is_same_v< std::decay_t< Object >, HDFDataspace >, int >=0)
Construct a new HDFDataspace object from an HDFDataset or HDFAttribute. This loads the file-dataspace...
Definition hdfdataspace.hh:419
void open(Object &&object)
Open the dataspace with an HDF5 object, i.e., dataset or attribute.
Definition hdfdataspace.hh:134
HDFDataspace(std::string name, hsize_t rank, std::vector< hsize_t > extent, std::vector< hsize_t > capacity)
Construct HDFDataspace from the given arguments.
Definition hdfdataspace.hh:403
void select_all()
Select the entire dataspace as hyperslap to be read/written to.
Definition hdfdataspace.hh:284
std::pair< arma::Row< hsize_t >, arma::Row< hsize_t > > get_selection_bounds()
Get the selection bounding box, i.e., the start and end vector of the currently selected subset of th...
Definition hdfdataspace.hh:195
HDFDataspace()
Construct HDFDataspace per default. Equivalent to using H5S_ALL when employing the pure C interface.
Definition hdfdataspace.hh:363
hsize_t rank()
Get thet dataspace's rank, i.e., number of dimensions.
Definition hdfdataspace.hh:46
void open()
Open the dataspace - set it to be equivalent to any data that later will be used to write or read.
Definition hdfdataspace.hh:117
HDFDataspace & operator=(const HDFDataspace &)=default
Copy assign dataspace.
std::pair< arma::Row< hsize_t >, arma::Row< hsize_t > > get_properties()
Get the properties object: size and capacity.
Definition hdfdataspace.hh:67
HDFDataspace & operator=(HDFDataspace &&)=default
Move assign dataspace.
void resize(arma::Row< hsize_t > new_size)
Resize the dataspace. The new size needs to fit into the dataspaces capacity.
Definition hdfdataspace.hh:311
This file provides metafunctions for automatically determining the nature of a C/C++ types at compile...
std::string str(T &&t)
Turn any object for which operator<< exists into a string. Mostly useful for logging data via spdlog ...
Definition ostream.hh:164
Definition agent.hh:11