Start writing more HDF5 interface functions in C++

This commit is contained in:
Paul Romano 2018-04-16 15:58:03 -05:00
parent 05e40a142f
commit b0c7f07d02

View file

@ -1,44 +1,153 @@
#ifndef HDF5_INTERFACE_H
#define HDF5_INTERFACE_H
#include <array>
#include <string.h>
#include "error.h"
#include "hdf5.h"
#include "hdf5_hl.h"
#include "error.h"
#include <array>
#include <string>
#include <sstream>
namespace openmc {
bool
using_mpio_device(hid_t obj_id) {
// Determine file that this object is part of
hid_t file_id = H5Iget_file_id(obj_id);
// Get file access property list
hid_t fapl_id = H5Fget_access_plist(file_id);
// Get low-level driver identifier
hid_t driver = H5Pget_driver(fapl_id);
// Free resources
H5Pclose(fapl_id);
H5Fclose(file_id);
return driver == H5FD_MPIO;
}
hid_t
create_group(hid_t parent_id, char const *name)
{
hid_t out = H5Gcreate(parent_id, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
if (out < 0) {
std::string err_msg{"Failed to create HDF5 group \""};
err_msg += name;
err_msg += "\"";
std::stringstream err_msg;
err_msg << "Failed to create HDF5 group \"" << name << "\"";
fatal_error(err_msg);
}
return out;
}
hid_t
create_group(hid_t parent_id, const std::string &name)
{
return create_group(parent_id, name.c_str());
}
void
close_dataset(hid_t dataset_id)
{
if (H5Dclose(dataset_id) < 0) fatal_error("Failed to close dataset");
}
void
close_group(hid_t group_id)
{
herr_t err = H5Gclose(group_id);
if (err < 0) {
fatal_error("Failed to close HDF5 group");
if (H5Gclose(group_id) < 0) fatal_error("Failed to close group");
}
hid_t
file_open(const char* filename, char mode, bool parallel=false)
{
bool create;
unsigned int flags;
switch (mode) {
case 'r':
case 'a':
create = false;
flags = (mode == 'r' ? H5F_ACC_RDONLY : H5F_ACC_RDWR);
break;
case 'w':
case 'x':
create = true;
flags = (mode == 'x' ? H5F_ACC_EXCL : H5F_ACC_TRUNC);
break;
}
hid_t plist;
if (parallel) {
// Setup file access property list with parallel I/O access
plist = H5Pcreate(H5P_FILE_ACCESS);
#ifdef PHDF5
H5Pset_fapl_mpio(plist, mpi_intracomm, MPI_INFO_NULL);
#endif
} else {
plist = H5P_DEFAULT;
}
// Open the file collectively
hid_t file_id;
if (create) {
file_id = H5Fopen(filename, flags, plist);
} else {
file_id = H5Fcreate(filename, flags, H5P_DEFAULT, plist);
}
// Close the property list
if (parallel) H5Pclose(plist);
return file_id;
}
hid_t
file_open(const std::string& filename, char mode, bool parallel=false) {
file_open(filename.c_str(), mode, parallel);
}
void file_close(hid_t file_id) {
H5Fclose(file_id);
}
bool
object_exists(hid_t object_id, const char* name) {
htri_t out = H5LTpath_valid(object_id, name, true);
if (out < 0) {
std::stringstream err_msg;
err_msg << "Failed to check if object \"" << name << "\" exists.";
fatal_error(err_msg);
}
return (out > 0);
}
hid_t
open_dataset(hid_t group_id, const char* name){
if (object_exists(group_id, name)) {
return H5Dopen(group_id, name, H5P_DEFAULT);
} else {
std::stringstream err_msg;
err_msg << "Group \"" << name << "\" does not exist";
fatal_error(err_msg);
}
}
hid_t
open_group(hid_t group_id, const char* name){
if (object_exists(group_id, name)) {
return H5Gopen(group_id, name, H5P_DEFAULT);
} else {
std::stringstream err_msg;
err_msg << "Group \"" << name << "\" does not exist";
fatal_error(err_msg);
}
}
@ -60,6 +169,35 @@ write_double_1D(hid_t group_id, char const *name,
H5Dclose(dataset);
}
void
write_double(hid_t group_id, int ndim, const hsize_t* dims, const char* name,
double* buffer, bool indep) {
hid_t dspace = H5Screate_simple(ndim, dims, nullptr);
hid_t dset = H5Dcreate(group_id, name, H5T_NATIVE_DOUBLE, dspace,
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
if (using_mpio_device(group_id)) {
#ifdef PHDF5
// Set up collective vs independent I/O
auto data_xfer_mode {indep ? H5FD_MPIO_INDEPENDENT : H5FD_MPIO_COLLECTIVE};
// Create dataset transfer property list
hid_t plist = H5Pcreate(H5P_DATASET_XFER);
H5Pset_dxpl_mpio(plist, data_xfer_mode);
// Write data
H5Dwrite(dset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, plist, buffer);
H5Pclose(plist);
#endif
} else {
H5Dwrite(dset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, buffer);
}
// Free resources
H5Dclose(dset);
H5Sclose(dspace);
}
void
write_string(hid_t group_id, char const *name, char const *buffer)