Commit aa97b21c authored by Samuel Debionne's avatar Samuel Debionne Committed by Alejandro Homs Puron
Browse files

[IO] Move error handling to the H5 wrapper

parent 23bcd743
......@@ -40,16 +40,10 @@ namespace io::h5
// Open the HDF5 file
const char* nx_class = is_nexus ? "NXroot" : nullptr;
auto f = nx::file::open(filename, nx_class);
if (!f.is_open())
LIMA_THROW_EXCEPTION(lima::hdf5_error("Error opening H5 file")
<< boost::errinfo_filesystem_path(filename));
// Get Dataset
auto&& dataset_path = params.dataset_path;
m_dset = dataset::open(f, dataset_path);
if (!m_dset.is_open())
LIMA_THROW_EXCEPTION(lima::hdf5_error("Error opening H5 dataset")
<< boost::errinfo_h5_path(dataset_path));
// Query dataspace dimensions
auto dspace = m_dset.space();
......@@ -105,8 +99,7 @@ namespace io::h5
void read_view(View const& v, hsize_t frame_idx = 0)
{
if (frame_idx >= m_frame_slice.count)
LIMA_THROW_EXCEPTION(lima::hdf5_error("Frame number out of bound")
<< boost::errinfo_h5_idx(frame_idx));
LIMA_THROW_EXCEPTION(lima::hdf5_error("Frame number out of bound") << boost::errinfo_h5_idx(frame_idx));
else if (v.dimensions() != m_frame_dims)
LIMA_THROW_EXCEPTION(lima::hdf5_error("Frame dimensions mismatch"));
......
......@@ -49,7 +49,12 @@ namespace io
static file create(std::filesystem::path const& name, unsigned flags = H5F_ACC_TRUNC,
hid_t fcpl_id = H5P_DEFAULT, hid_t fapl_id = H5P_DEFAULT)
{
return H5Fcreate(name.string().c_str(), flags, fcpl_id, fapl_id);
hid_t res = H5Fcreate(name.string().c_str(), flags, fcpl_id, fapl_id);
if (res < 0)
LIMA_THROW_EXCEPTION(lima::hdf5_error("Failed to create H5 File")
<< boost::errinfo_filesystem_path(name) << make_errinfo_stack());
return res;
}
/// Opens an existing H5 file, flags determines the access mode:
......@@ -57,7 +62,12 @@ namespace io
static file open(std::filesystem::path const& name, unsigned flags = H5F_ACC_RDONLY,
hid_t fapl_id = H5P_DEFAULT)
{
return H5Fopen(name.string().c_str(), flags, fapl_id);
hid_t res = H5Fopen(name.string().c_str(), flags, fapl_id);
if (res < 0)
LIMA_THROW_EXCEPTION(lima::hdf5_error("Failed to open H5 File")
<< boost::errinfo_filesystem_path(name) << make_errinfo_stack());
return res;
}
/// Returns true if the file is open (aka the hid is valid)
......@@ -99,14 +109,24 @@ namespace io
static group create(Location const& loc, path const& name, hid_t lcpl_id = H5P_DEFAULT,
hid_t gcpl_id = H5P_DEFAULT, hid_t gapl_id = H5P_DEFAULT)
{
return H5Gcreate2(loc, name.c_str(), lcpl_id, gcpl_id, gapl_id);
hid_t res = H5Gcreate2(loc, name.c_str(), lcpl_id, gcpl_id, gapl_id);
if (res < 0)
LIMA_THROW_EXCEPTION(lima::hdf5_error("Failed to create H5 Group")
<< boost::errinfo_h5_path(name) << make_errinfo_stack());
return res;
}
/// Opens an existing group
template <typename Location>
static group open(Location const& loc, path const& name, hid_t gapl_id = H5P_DEFAULT)
{
return H5Gopen2(loc, name.c_str(), gapl_id);
hid_t res = H5Gopen2(loc, name.c_str(), gapl_id);
if (res < 0)
LIMA_THROW_EXCEPTION(lima::hdf5_error("Failed to open H5 Group")
<< boost::errinfo_h5_path(name) << make_errinfo_stack());
return res;
}
/// Returns true if the group is open (aka the hid is valid)
......@@ -139,13 +159,23 @@ namespace io
dataspace dspace = dataspace::create(), hid_t lcpl_id = H5P_DEFAULT,
hid_t dcpl_id = H5P_DEFAULT, hid_t dapl_id = H5P_DEFAULT)
{
return dataset(H5Dcreate2(loc, name.c_str(), dtype_id, dspace, lcpl_id, dcpl_id, dapl_id));
hid_t res = H5Dcreate2(loc, name.c_str(), dtype_id, dspace, lcpl_id, dcpl_id, dapl_id);
if (res < 0)
LIMA_THROW_EXCEPTION(lima::hdf5_error("Failed to create H5 Dataset")
<< boost::errinfo_h5_path(name) << make_errinfo_stack());
return res;
}
template <typename Location>
static dataset open(Location const& loc, path const& name, hid_t dapl_id = H5P_DEFAULT)
{
return dataset(H5Dopen2(loc, name.c_str(), dapl_id));
hid_t res = H5Dopen2(loc, name.c_str(), dapl_id);
if (res < 0)
LIMA_THROW_EXCEPTION(lima::hdf5_error("Failed to open H5 Dataset")
<< boost::errinfo_h5_path(name) << make_errinfo_stack());
return res;
}
/// Returns true if the dataset is open (aka the hid is valid)
......@@ -158,24 +188,31 @@ namespace io
predef_datatype datatype() const { return H5Dget_type(member.get()); }
/// Writes data to the dataset
herr_t write(const void* buffer, predef_datatype dtype, hid_t mem_dspace = H5S_ALL,
hid_t file_dspace = H5S_ALL, hid_t dtpl_id = H5P_DEFAULT)
void write(const void* buffer, predef_datatype dtype, hid_t mem_dspace = H5S_ALL,
hid_t file_dspace = H5S_ALL, hid_t dtpl_id = H5P_DEFAULT)
{
return H5Dwrite(member.get(), dtype, mem_dspace, file_dspace, dtpl_id, buffer);
herr_t res = H5Dwrite(member.get(), dtype, mem_dspace, file_dspace, dtpl_id, buffer);
if (res < 0)
LIMA_THROW_EXCEPTION(lima::hdf5_error("Failed to write to H5 Dataset") << make_errinfo_stack());
}
/// Writes chunk to the dataset
herr_t write_chunk(const void* buffer, uint32_t filter_mask, hsize_t offset[], size_t data_size,
hid_t dtpl_id = H5P_DEFAULT)
void write_chunk(const void* buffer, uint32_t filter_mask, hsize_t offset[], size_t data_size,
hid_t dtpl_id = H5P_DEFAULT)
{
return H5Dwrite_chunk(member.get(), dtpl_id, filter_mask, offset, data_size, buffer);
herr_t res = H5Dwrite_chunk(member.get(), dtpl_id, filter_mask, offset, data_size, buffer);
if (res < 0)
LIMA_THROW_EXCEPTION(lima::hdf5_error("Failed to write chunk to H5 Dataset")
<< make_errinfo_stack());
}
/// Reads from the dataset
herr_t read(void* buffer, predef_datatype dtype, hid_t mem_dspace = H5S_ALL, hid_t file_dspace = H5S_ALL,
hid_t dtpl_id = H5P_DEFAULT)
void read(void* buffer, predef_datatype dtype, hid_t mem_dspace = H5S_ALL, hid_t file_dspace = H5S_ALL,
hid_t dtpl_id = H5P_DEFAULT)
{
return H5Dread(member.get(), dtype, mem_dspace, file_dspace, dtpl_id, buffer);
herr_t res = H5Dread(member.get(), dtype, mem_dspace, file_dspace, dtpl_id, buffer);
if (res < 0)
LIMA_THROW_EXCEPTION(lima::hdf5_error("Failed to read from H5 Dataset") << make_errinfo_stack());
}
/// Changes the sizes of a dataset's dimensions.
......
......@@ -8,10 +8,10 @@
#include <string>
#include <boost/exception/errinfo_errno.hpp>
#include <lima/exceptions.hpp>
#include <lima/io/h5/wrapper/errinfo.hpp>
#include <lima/io/h5/wrapper/errstack.hpp>
#include <lima/io/h5/wrapper/handle.hpp>
#include <lima/io/h5/wrapper/dataspace.hpp>
#include <lima/io/h5/wrapper/datatype.hpp>
......@@ -57,6 +57,9 @@ namespace io
// Write the attribute data
herr_t res = H5Awrite(m_hid.get(), dtype, &attr_data);
if (res < 0)
LIMA_THROW_EXCEPTION(lima::hdf5_error("Failed to get H5 Attribute info")
<< make_errinfo_stack());
return *this;
}
......@@ -67,6 +70,9 @@ namespace io
// Write the attribute data
herr_t res = H5Awrite(m_hid.get(), dtype, attr_data.c_str());
if (res < 0)
LIMA_THROW_EXCEPTION(lima::hdf5_error("Failed to get H5 Attribute info")
<< make_errinfo_stack());
return *this;
}
......@@ -77,14 +83,16 @@ namespace io
// Get the attribute info
if (H5Aget_info(m_hid.get(), &attr_info) < 0)
LIMA_THROW_EXCEPTION(lima::io_error("Error getting H5 Attribute info"));
LIMA_THROW_EXCEPTION(lima::hdf5_error("Failed to get H5 Attribute info")
<< make_errinfo_stack());
std::string attr_data(attr_info.data_size, 0);
string_datatype dtype(attr_data);
// Read the attribute data
if (H5Aread(m_hid.get(), dtype, attr_data.data()) < 0)
LIMA_THROW_EXCEPTION(lima::io_error("Error reading H5 Attribute string data"));
LIMA_THROW_EXCEPTION(lima::hdf5_error("Failed to read H5 Attribute string data")
<< make_errinfo_stack());
// Remove trailing null terminator
if (attr_data.back() == '\0')
......@@ -111,11 +119,18 @@ namespace io
// Create an attribute
unique_attribute_hid_t attribute_id(
H5Acreate2(m_hid.get(), attr_name, dtype, dspace, H5P_DEFAULT, H5P_DEFAULT));
if (!attribute_id)
LIMA_THROW_EXCEPTION(lima::hdf5_error("Failed to create H5 Attribute")
<< make_errinfo_stack());
// Write the attribute data
herr_t res = H5Awrite(attribute_id.get(), dtype, &attr_data);
if (res < 0)
LIMA_THROW_EXCEPTION(lima::hdf5_error("Failed to write H5 Attribute")
<< make_errinfo_stack());
} else
LIMA_THROW_EXCEPTION(lima::io_error("H5 Attribute already exists"));
LIMA_THROW_EXCEPTION(lima::hdf5_error("H5 Attribute already exists")
<< make_errinfo_stack());
}
inline void create(const char* attr_name, const char* const attr_data)
......@@ -126,11 +141,18 @@ namespace io
// Create an attribute
unique_attribute_hid_t attribute_id(
H5Acreate2(m_hid.get(), attr_name, dtype, dspace, H5P_DEFAULT, H5P_DEFAULT));
if (!attribute_id)
LIMA_THROW_EXCEPTION(lima::hdf5_error("Failed to create H5 Attribute")
<< make_errinfo_stack());
// Write the attribute data
herr_t res = H5Awrite(attribute_id.get(), dtype, attr_data);
if (res < 0)
LIMA_THROW_EXCEPTION(lima::hdf5_error("Failed to write H5 Attribute")
<< make_errinfo_stack());
} else
LIMA_THROW_EXCEPTION(lima::io_error("H5 Attribute already exists"));
LIMA_THROW_EXCEPTION(lima::hdf5_error("H5 Attribute already exists")
<< make_errinfo_stack());
}
inline void create(const char* attr_name, std::string const& attr_data)
......@@ -172,11 +194,17 @@ namespace io
auto dspace = dataspace::create();
unique_dataset_hid_t dataset_id(
H5Dcreate2(impl(), ds_name.c_str(), dtype, dspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT));
if (!dataset_id)
LIMA_THROW_EXCEPTION(lima::hdf5_error("Failed to create H5 Dataset")
<< make_errinfo_stack());
// Write the scalar dataset data
herr_t res = H5Dwrite(dataset_id.get(), dtype, dspace, dspace, H5P_DEFAULT, &ds_data);
if (res < 0)
LIMA_THROW_EXCEPTION(lima::hdf5_error("Failed to write H5 Dataset")
<< make_errinfo_stack());
} else
LIMA_THROW_EXCEPTION(lima::io_error("H5 Dataset already exists"));
LIMA_THROW_EXCEPTION(lima::hdf5_error("H5 Dataset already exists") << make_errinfo_stack());
}
void create_dataset(path ds_name, std::string const& ds_data)
......@@ -187,11 +215,17 @@ namespace io
auto dspace = dataspace::create();
unique_dataset_hid_t dataset_id(
H5Dcreate2(impl(), ds_name.c_str(), dtype, dspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT));
if (!dataset_id)
LIMA_THROW_EXCEPTION(lima::hdf5_error("Failed to create H5 Dataset")
<< make_errinfo_stack());
// Write the scalar dataset data
herr_t res = H5Dwrite(dataset_id.get(), dtype, dspace, dspace, H5P_DEFAULT, ds_data.c_str());
if (res < 0)
LIMA_THROW_EXCEPTION(lima::hdf5_error("Failed to write H5 Dataset")
<< make_errinfo_stack());
} else
LIMA_THROW_EXCEPTION(lima::io_error("H5 Dataset already exists"));
LIMA_THROW_EXCEPTION(lima::hdf5_error("H5 Dataset already exists") << make_errinfo_stack());
}
struct dset_proxy
......
......@@ -13,6 +13,8 @@
#include <lima/exceptions.hpp>
#include <lima/io/h5/wrapper/errinfo.hpp>
#include <lima/io/h5/wrapper/errstack.hpp>
#include <lima/io/h5/wrapper/handle.hpp>
namespace lima
......@@ -26,12 +28,21 @@ namespace io
dataspace(hid_t hid) : m_hid(hid) {}
/// Create a dataspace from a given class (H5S_xxxx)
static dataspace create(H5S_class_t type = H5S_SCALAR) { return H5Screate(type); }
static dataspace create(H5S_class_t type = H5S_SCALAR)
{
hid_t res = H5Screate(type);
if (res < 0)
LIMA_THROW_EXCEPTION(lima::hdf5_error("Failed to create H5 Dataspace") << make_errinfo_stack());
return res;
}
/// Create a simple dataspace and opens it for access
static dataspace create_simple(int rank, const hsize_t dims[], const hsize_t maxdims[] = NULL)
{
return H5Screate_simple(rank, dims, maxdims);
hid_t res = H5Screate_simple(rank, dims, maxdims);
if (res < 0)
LIMA_THROW_EXCEPTION(lima::hdf5_error("Failed to create H5 Dataspace") << make_errinfo_stack());
return res;
}
/// Determines the dimensionality of a dataspace.
......
......@@ -165,9 +165,6 @@ namespace io
// Open the HDF5 file
auto f = nx::file::create(filename);
if (!f.is_open())
LIMA_THROW_EXCEPTION(lima::hdf5_error("H5Fcreate error")
<< boost::errinfo_filesystem_path(filename));
auto nb_frames = params.nb_frames_per_file;
auto nb_frames_per_chunk = params.nb_frames_per_chunk;
......@@ -250,8 +247,6 @@ namespace io
// Create dataset
m_dset = dataset::create(entry, data_path, m_dtype, file_space, H5P_DEFAULT, dcpl, H5P_DEFAULT);
if (!m_dset.is_open())
LIMA_THROW_EXCEPTION(lima::hdf5_error("H5Dcreate2 error"));
// Add interpretation attributes
m_dset.attrs.create("interpretation", "image"s);
......@@ -297,9 +292,7 @@ namespace io
switch (m_compression) {
case compression_enum::none: {
herr_t res = m_dset.write_chunk(data_ptr, filter_mask, offset, data_size);
if (res < 0)
LIMA_THROW_EXCEPTION(lima::hdf5_error("H5Dwrite_chunk error") << boost::errinfo_errno(res));
m_dset.write_chunk(data_ptr, filter_mask, offset, data_size);
break;
}
case compression_enum::zip: {
......@@ -322,9 +315,8 @@ namespace io
<< " (ratio=" << ((double) data_size / (double) comp_size) << ")";
// Write chunk
herr_t res = m_dset.write_chunk(comp_data, filter_mask, offset, comp_size);
if (res < 0)
LIMA_THROW_EXCEPTION(lima::hdf5_error("H5Dwrite_chunk error") << boost::errinfo_errno(res));
m_dset.write_chunk(comp_data, filter_mask, offset, comp_size);
#endif //defined(LIMA_ENABLE_ZLIB)
break;
}
......@@ -349,9 +341,8 @@ namespace io
<< " (ratio=" << ((double) data_size / (double) comp_size) << ")";
// Write chunk
herr_t res = m_dset.write_chunk(comp_data, filter_mask, offset, comp_size + 12);
if (res < 0)
LIMA_THROW_EXCEPTION(lima::hdf5_error("H5Dwrite_chunk error") << boost::errinfo_errno(res));
m_dset.write_chunk(comp_data, filter_mask, offset, comp_size + 12);
#endif //defined(LIMA_ENABLE_BSHUF_LZ4)
break;
}
......@@ -371,9 +362,7 @@ namespace io
uint32_t filter_mask = 0;
// Write chunk
herr_t res = m_dset.write_chunk(comp_data, filter_mask, offset, comp_size);
if (res < 0)
LIMA_THROW_EXCEPTION(lima::hdf5_error("H5Dwrite_chunk error") << boost::errinfo_errno(res));
m_dset.write_chunk(comp_data, filter_mask, offset, comp_size);
}
protected:
......@@ -425,9 +414,6 @@ namespace io
// Open the HDF5 file
auto f = nx::file::create(filename);
if (!f.is_open())
LIMA_THROW_EXCEPTION(lima::hdf5_error("H5Fcreate error")
<< boost::errinfo_filesystem_path(filename));
auto nb_frames = params.nb_frames_per_file;
auto nb_frames_per_chunk = params.nb_frames_per_chunk;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment