• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

openmc-dev / openmc / 14515233533

17 Apr 2025 12:06PM UTC coverage: 83.16% (-2.3%) from 85.414%
14515233533

Pull #3087

github

web-flow
Merge 6ed397e9d into 47ca2916a
Pull Request #3087: wheel building with scikit build core

140769 of 169274 relevant lines covered (83.16%)

11830168.1 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

79.53
/src/hdf5_interface.cpp
1
#include "openmc/hdf5_interface.h"
2

3
#include <cstring>
4
#include <stdexcept>
5
#include <string>
6

7
#include "xtensor/xarray.hpp"
8
#include "xtensor/xtensor.hpp"
9
#include <fmt/core.h>
10

11
#include "hdf5.h"
12
#include "hdf5_hl.h"
13
#ifdef OPENMC_MPI
14
#include "mpi.h"
15
#include "openmc/message_passing.h"
16
#endif
17

18
#include "openmc/array.h"
19

20
namespace openmc {
21

22
bool attribute_exists(hid_t obj_id, const char* name)
847,396✔
23
{
24
  htri_t out = H5Aexists_by_name(obj_id, ".", name, H5P_DEFAULT);
847,396✔
25
  return out > 0;
847,396✔
26
}
27

28
size_t attribute_typesize(hid_t obj_id, const char* name)
9,559,653✔
29
{
30
  hid_t attr = H5Aopen(obj_id, name, H5P_DEFAULT);
9,559,653✔
31
  hid_t filetype = H5Aget_type(attr);
9,559,653✔
32
  size_t n = H5Tget_size(filetype);
9,559,653✔
33
  H5Tclose(filetype);
9,559,653✔
34
  H5Aclose(attr);
9,559,653✔
35
  return n;
9,559,653✔
36
}
37

38
void get_shape(hid_t obj_id, hsize_t* dims)
×
39
{
40
  auto type = H5Iget_type(obj_id);
×
41
  hid_t dspace;
42
  if (type == H5I_DATASET) {
×
43
    dspace = H5Dget_space(obj_id);
×
44
  } else if (type == H5I_ATTR) {
×
45
    dspace = H5Aget_space(obj_id);
×
46
  } else {
47
    throw std::runtime_error {
×
48
      "Expected dataset or attribute in call to get_shape."};
×
49
  }
50
  H5Sget_simple_extent_dims(dspace, dims, nullptr);
×
51
  H5Sclose(dspace);
×
52
}
53

54
vector<hsize_t> attribute_shape(hid_t obj_id, const char* name)
7,697,029✔
55
{
56
  hid_t attr = H5Aopen(obj_id, name, H5P_DEFAULT);
7,697,029✔
57
  vector<hsize_t> shape = object_shape(attr);
7,697,029✔
58
  H5Aclose(attr);
7,697,029✔
59
  return shape;
7,697,029✔
60
}
×
61

62
vector<hsize_t> object_shape(hid_t obj_id)
14,580,964✔
63
{
64
  // Get number of dimensions
65
  auto type = H5Iget_type(obj_id);
14,580,964✔
66
  hid_t dspace;
67
  if (type == H5I_DATASET) {
14,580,964✔
68
    dspace = H5Dget_space(obj_id);
6,883,935✔
69
  } else if (type == H5I_ATTR) {
7,697,029✔
70
    dspace = H5Aget_space(obj_id);
7,697,029✔
71
  } else {
72
    throw std::runtime_error {
×
73
      "Expected dataset or attribute in call to object_shape."};
×
74
  }
75
  int n = H5Sget_simple_extent_ndims(dspace);
14,580,964✔
76

77
  // Get shape of array
78
  vector<hsize_t> shape(n);
14,580,964✔
79
  H5Sget_simple_extent_dims(dspace, shape.data(), nullptr);
14,580,964✔
80

81
  // Free resources and return
82
  H5Sclose(dspace);
14,580,964✔
83
  return shape;
14,580,964✔
84
}
×
85

86
void get_shape_attr(hid_t obj_id, const char* name, hsize_t* dims)
×
87
{
88
  hid_t attr = H5Aopen(obj_id, name, H5P_DEFAULT);
×
89
  hid_t dspace = H5Aget_space(attr);
×
90
  H5Sget_simple_extent_dims(dspace, dims, nullptr);
×
91
  H5Sclose(dspace);
×
92
  H5Aclose(attr);
×
93
}
94

95
hid_t create_group(hid_t parent_id, char const* name)
128,325✔
96
{
97
  hid_t out = H5Gcreate(parent_id, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
128,325✔
98
  if (out < 0) {
128,325✔
99
    fatal_error(fmt::format("Failed to create HDF5 group \"{}\"", name));
×
100
  }
101
  return out;
128,325✔
102
}
103

104
hid_t create_group(hid_t parent_id, const std::string& name)
77,131✔
105
{
106
  return create_group(parent_id, name.c_str());
77,131✔
107
}
108

109
void close_dataset(hid_t dataset_id)
4,953,052✔
110
{
111
  if (H5Dclose(dataset_id) < 0)
4,953,052✔
112
    fatal_error("Failed to close dataset");
×
113
}
4,953,052✔
114

115
void close_group(hid_t group_id)
9,207,936✔
116
{
117
  if (H5Gclose(group_id) < 0)
9,207,936✔
118
    fatal_error("Failed to close group");
×
119
}
9,207,936✔
120

121
void close_object(hid_t obj_id)
1,953,140✔
122
{
123
  if (H5Oclose(obj_id) < 0)
1,953,140✔
124
    fatal_error("Failed to close object");
×
125
}
1,953,140✔
126

127
int dataset_ndims(hid_t dset)
80✔
128
{
129
  hid_t dspace = H5Dget_space(dset);
80✔
130
  int ndims = H5Sget_simple_extent_ndims(dspace);
80✔
131
  H5Sclose(dspace);
80✔
132
  return ndims;
80✔
133
}
134

135
size_t dataset_typesize(hid_t obj_id, const char* name)
119✔
136
{
137
  hid_t dset = open_dataset(obj_id, name);
119✔
138
  hid_t filetype = H5Dget_type(dset);
119✔
139
  size_t n = H5Tget_size(filetype);
119✔
140
  H5Tclose(filetype);
119✔
141
  close_dataset(dset);
119✔
142
  return n;
119✔
143
}
144

145
void ensure_exists(hid_t obj_id, const char* name, bool attribute)
16,050,879✔
146
{
147
  if (attribute) {
16,050,879✔
148
    if (!attribute_exists(obj_id, name)) {
2,188✔
149
      fatal_error(fmt::format("Attribute \"{}\" does not exist in object {}",
×
150
        name, object_name(obj_id)));
×
151
    }
152
  } else {
153
    if (!object_exists(obj_id, name)) {
16,048,691✔
154
      fatal_error(fmt::format("Object \"{}\" does not exist in object {}", name,
×
155
        object_name(obj_id)));
×
156
    }
157
  }
158
}
16,050,879✔
159

160
hid_t file_open(const char* filename, char mode, bool parallel)
33,387✔
161
{
162
  bool create;
163
  unsigned int flags;
164
  switch (mode) {
33,387✔
165
  case 'r':
23,747✔
166
  case 'a':
167
    create = false;
23,747✔
168
    flags = (mode == 'r' ? H5F_ACC_RDONLY : H5F_ACC_RDWR);
23,747✔
169
    break;
23,747✔
170
  case 'w':
9,640✔
171
  case 'x':
172
    create = true;
9,640✔
173
    flags = (mode == 'x' ? H5F_ACC_EXCL : H5F_ACC_TRUNC);
9,640✔
174
    break;
9,640✔
175
  default:
×
176
    fatal_error(fmt::format("Invalid file mode: ", mode));
×
177
  }
178

179
  hid_t plist = H5P_DEFAULT;
33,387✔
180
#ifdef PHDF5
181
  if (parallel) {
18,112✔
182
    // Setup file access property list with parallel I/O access
183
    plist = H5Pcreate(H5P_FILE_ACCESS);
2,818✔
184
    H5Pset_fapl_mpio(plist, openmc::mpi::intracomm, MPI_INFO_NULL);
2,818✔
185
  }
186
#endif
187

188
  // Open the file collectively
189
  hid_t file_id;
190
  if (create) {
33,387✔
191
    file_id = H5Fcreate(filename, flags, H5P_DEFAULT, plist);
9,640✔
192
  } else {
193
    file_id = H5Fopen(filename, flags, plist);
23,747✔
194
  }
195
  if (file_id < 0) {
33,387✔
196
    fatal_error(fmt::format(
×
197
      "Failed to open HDF5 file with mode '{}': {}", mode, filename));
198
  }
199

200
#ifdef PHDF5
201
  // Close the property list
202
  if (parallel)
18,112✔
203
    H5Pclose(plist);
2,818✔
204
#endif
205

206
  return file_id;
33,387✔
207
}
208

209
hid_t file_open(const std::string& filename, char mode, bool parallel)
32,672✔
210
{
211
  return file_open(filename.c_str(), mode, parallel);
32,672✔
212
}
213

214
hid_t open_group(hid_t group_id, const std::string& name)
×
215
{
216
  return open_group(group_id, name.c_str());
×
217
}
218

219
void file_close(hid_t file_id)
33,378✔
220
{
221
  H5Fclose(file_id);
33,378✔
222
}
33,378✔
223

224
void get_name(hid_t obj_id, std::string& name)
2,722✔
225
{
226
  size_t size = 1 + H5Iget_name(obj_id, nullptr, 0);
2,722✔
227
  name.resize(size);
2,722✔
228
  // TODO: switch to name.data() when using C++17
229
  H5Iget_name(obj_id, &name[0], size);
2,722✔
230
}
2,722✔
231

232
int get_num_datasets(hid_t group_id)
2,722✔
233
{
234
  // Determine number of links in the group
235
  H5G_info_t info;
236
  H5Gget_info(group_id, &info);
2,722✔
237

238
  // Iterate over links to get number of groups
239
  H5O_info_t oinfo;
240
  int ndatasets = 0;
2,722✔
241
  for (hsize_t i = 0; i < info.nlinks; ++i) {
6,420✔
242
    // Determine type of object (and skip non-group)
243
    H5Oget_info_by_idx(
3,698✔
244
      group_id, ".", H5_INDEX_NAME, H5_ITER_INC, i, &oinfo, H5P_DEFAULT);
245
    if (oinfo.type == H5O_TYPE_DATASET)
3,698✔
246
      ndatasets += 1;
3,698✔
247
  }
248

249
  return ndatasets;
2,722✔
250
}
251

252
int get_num_groups(hid_t group_id)
×
253
{
254
  // Determine number of links in the group
255
  H5G_info_t info;
256
  H5Gget_info(group_id, &info);
×
257

258
  // Iterate over links to get number of groups
259
  H5O_info_t oinfo;
260
  int ngroups = 0;
×
261
  for (hsize_t i = 0; i < info.nlinks; ++i) {
×
262
    // Determine type of object (and skip non-group)
263
    H5Oget_info_by_idx(
×
264
      group_id, ".", H5_INDEX_NAME, H5_ITER_INC, i, &oinfo, H5P_DEFAULT);
265
    if (oinfo.type == H5O_TYPE_GROUP)
×
266
      ngroups += 1;
×
267
  }
268

269
  return ngroups;
×
270
}
271

272
void get_datasets(hid_t group_id, char* name[])
2,722✔
273
{
274
  // Determine number of links in the group
275
  H5G_info_t info;
276
  H5Gget_info(group_id, &info);
2,722✔
277

278
  // Iterate over links to get names
279
  H5O_info_t oinfo;
280
  hsize_t count = 0;
2,722✔
281
  size_t size;
282
  for (hsize_t i = 0; i < info.nlinks; ++i) {
6,420✔
283
    // Determine type of object (and skip non-group)
284
    H5Oget_info_by_idx(
3,698✔
285
      group_id, ".", H5_INDEX_NAME, H5_ITER_INC, i, &oinfo, H5P_DEFAULT);
286
    if (oinfo.type != H5O_TYPE_DATASET)
3,698✔
287
      continue;
×
288

289
    // Get size of name
290
    size = 1 + H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, i,
3,698✔
291
                 nullptr, 0, H5P_DEFAULT);
292

293
    // Read name
294
    H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, i,
3,698✔
295
      name[count], size, H5P_DEFAULT);
3,698✔
296
    count += 1;
3,698✔
297
  }
298
}
2,722✔
299

300
void get_groups(hid_t group_id, char* name[])
×
301
{
302
  // Determine number of links in the group
303
  H5G_info_t info;
304
  H5Gget_info(group_id, &info);
×
305

306
  // Iterate over links to get names
307
  H5O_info_t oinfo;
308
  hsize_t count = 0;
×
309
  size_t size;
310
  for (hsize_t i = 0; i < info.nlinks; ++i) {
×
311
    // Determine type of object (and skip non-group)
312
    H5Oget_info_by_idx(
×
313
      group_id, ".", H5_INDEX_NAME, H5_ITER_INC, i, &oinfo, H5P_DEFAULT);
314
    if (oinfo.type != H5O_TYPE_GROUP)
×
315
      continue;
×
316

317
    // Get size of name
318
    size = 1 + H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, i,
×
319
                 nullptr, 0, H5P_DEFAULT);
320

321
    // Read name
322
    H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, i,
×
323
      name[count], size, H5P_DEFAULT);
×
324
    count += 1;
×
325
  }
326
}
327

328
vector<std::string> member_names(hid_t group_id, H5O_type_t type)
794,108✔
329
{
330
  // Determine number of links in the group
331
  H5G_info_t info;
332
  H5Gget_info(group_id, &info);
794,108✔
333

334
  // Iterate over links to get names
335
  H5O_info_t oinfo;
336
  size_t size;
337
  vector<std::string> names;
794,108✔
338
  for (hsize_t i = 0; i < info.nlinks; ++i) {
4,281,758✔
339
    // Determine type of object (and skip non-group)
340
    H5Oget_info_by_idx(
3,487,650✔
341
      group_id, ".", H5_INDEX_NAME, H5_ITER_INC, i, &oinfo, H5P_DEFAULT);
342
    if (oinfo.type != type)
3,487,650✔
343
      continue;
×
344

345
    // Get size of name
346
    size = 1 + H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, i,
3,487,650✔
347
                 nullptr, 0, H5P_DEFAULT);
348

349
    // Read name
350
    char* buffer = new char[size];
3,487,650✔
351
    H5Lget_name_by_idx(
3,487,650✔
352
      group_id, ".", H5_INDEX_NAME, H5_ITER_INC, i, buffer, size, H5P_DEFAULT);
353
    names.emplace_back(&buffer[0]);
3,487,650✔
354
    delete[] buffer;
3,487,650✔
355
  }
356
  return names;
1,588,216✔
357
}
×
358

359
vector<std::string> group_names(hid_t group_id)
777,148✔
360
{
361
  return member_names(group_id, H5O_TYPE_GROUP);
777,148✔
362
}
363

364
vector<std::string> dataset_names(hid_t group_id)
16,960✔
365
{
366
  return member_names(group_id, H5O_TYPE_DATASET);
16,960✔
367
}
368

369
bool object_exists(hid_t object_id, const char* name)
19,874,615✔
370
{
371
  htri_t out = H5LTpath_valid(object_id, name, true);
19,874,615✔
372
  if (out < 0) {
19,874,615✔
373
    fatal_error(fmt::format("Failed to check if object \"{}\" exists.", name));
×
374
  }
375
  return (out > 0);
19,874,615✔
376
}
377

378
std::string object_name(hid_t obj_id)
18,381✔
379
{
380
  // Determine size and create buffer
381
  size_t size = 1 + H5Iget_name(obj_id, nullptr, 0);
18,381✔
382
  char* buffer = new char[size];
18,381✔
383

384
  // Read and return name
385
  H5Iget_name(obj_id, buffer, size);
18,381✔
386
  std::string str = buffer;
18,381✔
387
  delete[] buffer;
18,381✔
388
  return str;
18,381✔
389
}
390

391
hid_t open_dataset(hid_t group_id, const char* name)
4,997,538✔
392
{
393
  ensure_exists(group_id, name);
4,997,538✔
394
  return H5Dopen(group_id, name, H5P_DEFAULT);
4,997,538✔
395
}
396

397
hid_t open_group(hid_t group_id, const char* name)
9,098,013✔
398
{
399
  ensure_exists(group_id, name);
9,098,013✔
400
  return H5Gopen(group_id, name, H5P_DEFAULT);
9,098,013✔
401
}
402

403
hid_t open_object(hid_t group_id, const std::string& name)
1,953,140✔
404
{
405
  ensure_exists(group_id, name.c_str());
1,953,140✔
406
  return H5Oopen(group_id, name.c_str(), H5P_DEFAULT);
1,953,140✔
407
}
408

409
void read_attr(hid_t obj_id, const char* name, hid_t mem_type_id, void* buffer)
27,767,860✔
410
{
411
  hid_t attr = H5Aopen(obj_id, name, H5P_DEFAULT);
27,767,860✔
412
  H5Aread(attr, mem_type_id, buffer);
27,767,860✔
413
  H5Aclose(attr);
27,767,860✔
414
}
27,767,860✔
415

416
void read_attr_double(hid_t obj_id, const char* name, double* buffer)
128✔
417
{
418
  read_attr(obj_id, name, H5T_NATIVE_DOUBLE, buffer);
128✔
419
}
128✔
420

421
void read_attr_int(hid_t obj_id, const char* name, int* buffer)
5,508✔
422
{
423
  read_attr(obj_id, name, H5T_NATIVE_INT, buffer);
5,508✔
424
}
5,508✔
425

426
void read_attr_string(hid_t obj_id, const char* name, size_t slen, char* buffer)
9,559,653✔
427
{
428
  // Create datatype for a string
429
  hid_t datatype = H5Tcopy(H5T_C_S1);
9,559,653✔
430
  H5Tset_size(datatype, slen);
9,559,653✔
431
  // numpy uses null-padding when writing fixed-length strings
432
  H5Tset_strpad(datatype, H5T_STR_NULLPAD);
9,559,653✔
433

434
  // Read data into buffer
435
  read_attr(obj_id, name, datatype, buffer);
9,559,653✔
436

437
  // Free resources
438
  H5Tclose(datatype);
9,559,653✔
439
}
9,559,653✔
440

441
void read_dataset_lowlevel(hid_t obj_id, const char* name, hid_t mem_type_id,
6,916,344✔
442
  hid_t mem_space_id, bool indep, void* buffer)
443
{
444
  hid_t dset = obj_id;
6,916,344✔
445
  if (name)
6,916,344✔
446
    dset = open_dataset(obj_id, name);
44,486✔
447

448
  if (using_mpio_device(dset)) {
6,916,344✔
449
#ifdef PHDF5
450
    // Set up collective vs independent I/O
451
    auto data_xfer_mode = indep ? H5FD_MPIO_INDEPENDENT : H5FD_MPIO_COLLECTIVE;
455✔
452

453
    // Create dataset transfer property list
454
    hid_t plist = H5Pcreate(H5P_DATASET_XFER);
455✔
455
    H5Pset_dxpl_mpio(plist, data_xfer_mode);
455✔
456

457
    // Read data
458
    H5Dread(dset, mem_type_id, mem_space_id, H5S_ALL, plist, buffer);
455✔
459
    H5Pclose(plist);
455✔
460
#endif
461
  } else {
462
    H5Dread(dset, mem_type_id, mem_space_id, H5S_ALL, H5P_DEFAULT, buffer);
6,915,889✔
463
  }
464

465
  if (name)
6,916,344✔
466
    H5Dclose(dset);
44,486✔
467
}
6,916,344✔
468

469
template<>
470
void read_dataset(hid_t dset, xt::xarray<std::complex<double>>& arr, bool indep)
416✔
471
{
472
  // Get shape of dataset
473
  vector<hsize_t> shape = object_shape(dset);
416✔
474

475
  // Allocate new array to read data into
476
  std::size_t size = 1;
416✔
477
  for (const auto x : shape)
1,248✔
478
    size *= x;
832✔
479
  vector<std::complex<double>> buffer(size);
416✔
480

481
  // Read data from attribute
482
  read_complex(dset, nullptr, buffer.data(), indep);
416✔
483

484
  // Adapt into xarray
485
  arr = xt::adapt(buffer, shape);
416✔
486
}
416✔
487

488
void read_double(hid_t obj_id, const char* name, double* buffer, bool indep)
6,564✔
489
{
490
  read_dataset_lowlevel(
6,564✔
491
    obj_id, name, H5T_NATIVE_DOUBLE, H5S_ALL, indep, buffer);
6,564✔
492
}
6,564✔
493

494
void read_int(hid_t obj_id, const char* name, int* buffer, bool indep)
×
495
{
496
  read_dataset_lowlevel(obj_id, name, H5T_NATIVE_INT, H5S_ALL, indep, buffer);
×
497
}
498

499
void read_llong(hid_t obj_id, const char* name, long long* buffer, bool indep)
×
500
{
501
  read_dataset_lowlevel(obj_id, name, H5T_NATIVE_LLONG, H5S_ALL, indep, buffer);
×
502
}
503

504
void read_string(
119✔
505
  hid_t obj_id, const char* name, size_t slen, char* buffer, bool indep)
506
{
507
  // Create datatype for a string
508
  hid_t datatype = H5Tcopy(H5T_C_S1);
119✔
509
  H5Tset_size(datatype, slen);
119✔
510
  // numpy uses null-padding when writing fixed-length strings
511
  H5Tset_strpad(datatype, H5T_STR_NULLPAD);
119✔
512

513
  // Read data into buffer
514
  read_dataset_lowlevel(obj_id, name, datatype, H5S_ALL, indep, buffer);
119✔
515

516
  // Free resources
517
  H5Tclose(datatype);
119✔
518
}
119✔
519

520
void read_complex(
416✔
521
  hid_t obj_id, const char* name, std::complex<double>* buffer, bool indep)
522
{
523
  // Create compound datatype for complex numbers
524
  struct complex_t {
525
    double re;
526
    double im;
527
  };
528
  complex_t tmp;
529
  hid_t complex_id = H5Tcreate(H5T_COMPOUND, sizeof tmp);
416✔
530
  H5Tinsert(complex_id, "r", HOFFSET(complex_t, re), H5T_NATIVE_DOUBLE);
416✔
531
  H5Tinsert(complex_id, "i", HOFFSET(complex_t, im), H5T_NATIVE_DOUBLE);
416✔
532

533
  // Read data
534
  read_dataset_lowlevel(obj_id, name, complex_id, H5S_ALL, indep, buffer);
416✔
535

536
  // Free resources
537
  H5Tclose(complex_id);
416✔
538
}
416✔
539

540
void read_tally_results(
70✔
541
  hid_t group_id, hsize_t n_filter, hsize_t n_score, double* results)
542
{
543
  // Create dataspace for hyperslab in memory
544
  constexpr int ndim = 3;
70✔
545
  hsize_t dims[ndim] {n_filter, n_score, 3};
70✔
546
  hsize_t start[ndim] {0, 0, 1};
70✔
547
  hsize_t count[ndim] {n_filter, n_score, 2};
70✔
548
  hid_t memspace = H5Screate_simple(ndim, dims, nullptr);
70✔
549
  H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, nullptr, count, nullptr);
70✔
550

551
  // Read the dataset
552
  read_dataset_lowlevel(
70✔
553
    group_id, "results", H5T_NATIVE_DOUBLE, memspace, false, results);
70✔
554

555
  // Free resources
556
  H5Sclose(memspace);
70✔
557
}
70✔
558

559
void write_attr(hid_t obj_id, int ndim, const hsize_t* dims, const char* name,
139,981✔
560
  hid_t mem_type_id, const void* buffer)
561
{
562
  // If array is given, create a simple dataspace. Otherwise, create a scalar
563
  // datascape.
564
  hid_t dspace;
565
  if (ndim > 0) {
139,981✔
566
    dspace = H5Screate_simple(ndim, dims, nullptr);
27,077✔
567
  } else {
568
    dspace = H5Screate(H5S_SCALAR);
112,904✔
569
  }
570

571
  // Create attribute and Write data
572
  hid_t attr =
573
    H5Acreate(obj_id, name, mem_type_id, dspace, H5P_DEFAULT, H5P_DEFAULT);
139,981✔
574
  H5Awrite(attr, mem_type_id, buffer);
139,981✔
575

576
  // Free resources
577
  H5Aclose(attr);
139,981✔
578
  H5Sclose(dspace);
139,981✔
579
}
139,981✔
580

581
void write_attr_double(hid_t obj_id, int ndim, const hsize_t* dims,
×
582
  const char* name, const double* buffer)
583
{
584
  write_attr(obj_id, ndim, dims, name, H5T_NATIVE_DOUBLE, buffer);
×
585
}
586

587
void write_attr_int(hid_t obj_id, int ndim, const hsize_t* dims,
×
588
  const char* name, const int* buffer)
589
{
590
  write_attr(obj_id, ndim, dims, name, H5T_NATIVE_INT, buffer);
×
591
}
592

593
void write_attr_string(hid_t obj_id, const char* name, const char* buffer)
22,723✔
594
{
595
  size_t n = strlen(buffer);
22,723✔
596
  if (n > 0) {
22,723✔
597
    // Set up appropriate datatype for a fixed-length string
598
    hid_t datatype = H5Tcopy(H5T_C_S1);
18,513✔
599
    H5Tset_size(datatype, n);
18,513✔
600

601
    write_attr(obj_id, 0, nullptr, name, datatype, buffer);
18,513✔
602

603
    // Free resources
604
    H5Tclose(datatype);
18,513✔
605
  }
606
}
22,723✔
607

608
void write_dataset_lowlevel(hid_t group_id, int ndim, const hsize_t* dims,
514,919✔
609
  const char* name, hid_t mem_type_id, hid_t mem_space_id, bool indep,
610
  const void* buffer)
611
{
612
  // If array is given, create a simple dataspace. Otherwise, create a scalar
613
  // datascape.
614
  hid_t dspace;
615
  if (ndim > 0) {
514,919✔
616
    dspace = H5Screate_simple(ndim, dims, nullptr);
156,868✔
617
  } else {
618
    dspace = H5Screate(H5S_SCALAR);
358,051✔
619
  }
620

621
  hid_t dset = H5Dcreate(
514,919✔
622
    group_id, name, mem_type_id, dspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
623

624
  if (using_mpio_device(group_id)) {
514,919✔
625
#ifdef PHDF5
626
    // Set up collective vs independent I/O
627
    auto data_xfer_mode = indep ? H5FD_MPIO_INDEPENDENT : H5FD_MPIO_COLLECTIVE;
628

629
    // Create dataset transfer property list
630
    hid_t plist = H5Pcreate(H5P_DATASET_XFER);
631
    H5Pset_dxpl_mpio(plist, data_xfer_mode);
632

633
    // Write data
634
    H5Dwrite(dset, mem_type_id, mem_space_id, H5S_ALL, plist, buffer);
635
    H5Pclose(plist);
636
#endif
637
  } else {
638
    H5Dwrite(dset, mem_type_id, mem_space_id, H5S_ALL, H5P_DEFAULT, buffer);
514,919✔
639
  }
640

641
  // Free resources
642
  H5Dclose(dset);
514,919✔
643
  H5Sclose(dspace);
514,919✔
644
}
514,919✔
645

646
void write_double(hid_t group_id, int ndim, const hsize_t* dims,
×
647
  const char* name, const double* buffer, bool indep)
648
{
649
  write_dataset_lowlevel(
×
650
    group_id, ndim, dims, name, H5T_NATIVE_DOUBLE, H5S_ALL, indep, buffer);
×
651
}
652

653
void write_int(hid_t group_id, int ndim, const hsize_t* dims, const char* name,
1,078✔
654
  const int* buffer, bool indep)
655
{
656
  write_dataset_lowlevel(
1,078✔
657
    group_id, ndim, dims, name, H5T_NATIVE_INT, H5S_ALL, indep, buffer);
1,078✔
658
}
1,078✔
659

660
void write_llong(hid_t group_id, int ndim, const hsize_t* dims,
×
661
  const char* name, const long long* buffer, bool indep)
662
{
663
  write_dataset_lowlevel(
×
664
    group_id, ndim, dims, name, H5T_NATIVE_LLONG, H5S_ALL, indep, buffer);
×
665
}
666

667
void write_string(hid_t group_id, int ndim, const hsize_t* dims, size_t slen,
237,200✔
668
  const char* name, const char* buffer, bool indep)
669
{
670
  if (slen > 0) {
237,200✔
671
    // Set up appropriate datatype for a fixed-length string
672
    hid_t datatype = H5Tcopy(H5T_C_S1);
215,164✔
673
    H5Tset_size(datatype, slen);
215,164✔
674

675
    write_dataset_lowlevel(
215,164✔
676
      group_id, ndim, dims, name, datatype, H5S_ALL, indep, buffer);
677

678
    // Free resources
679
    H5Tclose(datatype);
215,164✔
680
  }
681
}
237,200✔
682

683
void write_string(
191,501✔
684
  hid_t group_id, const char* name, const std::string& buffer, bool indep)
685
{
686
  write_string(
191,501✔
687
    group_id, 0, nullptr, buffer.length(), name, buffer.c_str(), indep);
688
}
191,501✔
689

690
void write_tally_results(
17,082✔
691
  hid_t group_id, hsize_t n_filter, hsize_t n_score, const double* results)
692
{
693
  // Set dimensions of sum/sum_sq hyperslab to store
694
  constexpr int ndim = 3;
17,082✔
695
  hsize_t count[ndim] {n_filter, n_score, 2};
17,082✔
696

697
  // Set dimensions of results array
698
  hsize_t dims[ndim] {n_filter, n_score, 3};
17,082✔
699
  hsize_t start[ndim] {0, 0, 1};
17,082✔
700
  hid_t memspace = H5Screate_simple(ndim, dims, nullptr);
17,082✔
701
  H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, nullptr, count, nullptr);
17,082✔
702

703
  // Create and write dataset
704
  write_dataset_lowlevel(group_id, ndim, count, "results", H5T_NATIVE_DOUBLE,
17,082✔
705
    memspace, false, results);
706

707
  // Free resources
708
  H5Sclose(memspace);
17,082✔
709
}
17,082✔
710

711
bool using_mpio_device(hid_t obj_id)
7,431,263✔
712
{
713
  // Determine file that this object is part of
714
  hid_t file_id = H5Iget_file_id(obj_id);
7,431,263✔
715

716
  // Get file access property list
717
  hid_t fapl_id = H5Fget_access_plist(file_id);
7,431,263✔
718

719
  // Get low-level driver identifier
720
  hid_t driver = H5Pget_driver(fapl_id);
7,431,263✔
721

722
  // Free resources
723
  H5Pclose(fapl_id);
7,431,263✔
724
  H5Fclose(file_id);
7,431,263✔
725

726
  return driver == H5FD_MPIO;
7,431,263✔
727
}
728

729
// Specializations of the H5TypeMap template struct
730
template<>
731
const hid_t H5TypeMap<bool>::type_id = H5T_NATIVE_INT8;
732
template<>
733
const hid_t H5TypeMap<int>::type_id = H5T_NATIVE_INT;
734
template<>
735
const hid_t H5TypeMap<unsigned long>::type_id = H5T_NATIVE_ULONG;
736
template<>
737
const hid_t H5TypeMap<unsigned long long>::type_id = H5T_NATIVE_ULLONG;
738
template<>
739
const hid_t H5TypeMap<unsigned int>::type_id = H5T_NATIVE_UINT;
740
template<>
741
const hid_t H5TypeMap<int64_t>::type_id = H5T_NATIVE_INT64;
742
template<>
743
const hid_t H5TypeMap<double>::type_id = H5T_NATIVE_DOUBLE;
744
template<>
745
const hid_t H5TypeMap<char>::type_id = H5T_NATIVE_CHAR;
746

747
} // namespace openmc
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc