@@ -1294,15 +1294,24 @@ void HDF5IOHandlerImpl::openDataset(
12941294 *dtype = d;
12951295
12961296 int ndims = H5Sget_simple_extent_ndims (dataset_space);
1297- std::vector<hsize_t > dims (ndims, 0 );
1298- std::vector<hsize_t > maxdims (ndims, 0 );
1297+ if (ndims == 0 )
1298+ {
1299+ // Is a scalar. Since the openPMD-api frontend supports no scalar
1300+ // datasets, return the extent as {1}
1301+ *parameters.extent = {1 };
1302+ }
1303+ else
1304+ {
1305+ std::vector<hsize_t > dims (ndims, 0 );
1306+ std::vector<hsize_t > maxdims (ndims, 0 );
12991307
1300- H5Sget_simple_extent_dims (dataset_space, dims.data (), maxdims.data ());
1301- Extent e;
1302- for (auto const &val : dims)
1303- e.push_back (val);
1304- auto extent = parameters.extent ;
1305- *extent = e;
1308+ H5Sget_simple_extent_dims (dataset_space, dims.data (), maxdims.data ());
1309+ Extent e;
1310+ for (auto const &val : dims)
1311+ e.push_back (val);
1312+ auto &extent = parameters.extent ;
1313+ *extent = e;
1314+ }
13061315
13071316 herr_t status;
13081317 status = H5Sclose (dataset_space);
@@ -1555,28 +1564,54 @@ void HDF5IOHandlerImpl::writeDataset(
15551564 " [HDF5] Internal error: Failed to open HDF5 dataset during dataset "
15561565 " write" );
15571566
1558- std::vector<hsize_t > start;
1559- for (auto const &val : parameters.offset )
1560- start.push_back (static_cast <hsize_t >(val));
1561- std::vector<hsize_t > stride (start.size (), 1 ); /* contiguous region */
1562- std::vector<hsize_t > count (start.size (), 1 ); /* single region */
1563- std::vector<hsize_t > block;
1564- for (auto const &val : parameters.extent )
1565- block.push_back (static_cast <hsize_t >(val));
1566- memspace =
1567- H5Screate_simple (static_cast <int >(block.size ()), block.data (), nullptr );
15681567 filespace = H5Dget_space (dataset_id);
1569- status = H5Sselect_hyperslab (
1570- filespace,
1571- H5S_SELECT_SET,
1572- start.data (),
1573- stride.data (),
1574- count.data (),
1575- block.data ());
1576- VERIFY (
1577- status == 0 ,
1578- " [HDF5] Internal error: Failed to select hyperslab during dataset "
1579- " write" );
1568+ int ndims = H5Sget_simple_extent_ndims (filespace);
1569+
1570+ if (ndims == 0 )
1571+ {
1572+ if (parameters.offset != Offset{0 } || parameters.extent != Extent{1 })
1573+ {
1574+ std::stringstream errorMessage;
1575+ errorMessage
1576+ << " HDF5 dataset '" << concrete_h5_file_position (writable)
1577+ << " ' is scalar (dimensionality 0) and must be accessed with "
1578+ " offset [0] and extent [1]. Was accessed with offset " ;
1579+ auxiliary::write_vec_to_stream (errorMessage, parameters.offset )
1580+ << " and extent " ;
1581+ auxiliary::write_vec_to_stream (errorMessage, parameters.extent )
1582+ << " ." ;
1583+ throw error::WrongAPIUsage (errorMessage.str ());
1584+ }
1585+ memspace = H5Screate_simple (0 , nullptr , nullptr );
1586+ VERIFY (
1587+ memspace > 0 ,
1588+ " [HDF5] Internal error: Failed to create memspace during dataset "
1589+ " write" );
1590+ }
1591+ else
1592+ {
1593+ std::vector<hsize_t > start;
1594+ for (auto const &val : parameters.offset )
1595+ start.push_back (static_cast <hsize_t >(val));
1596+ std::vector<hsize_t > stride (start.size (), 1 ); /* contiguous region */
1597+ std::vector<hsize_t > count (start.size (), 1 ); /* single region */
1598+ std::vector<hsize_t > block;
1599+ for (auto const &val : parameters.extent )
1600+ block.push_back (static_cast <hsize_t >(val));
1601+ memspace = H5Screate_simple (
1602+ static_cast <int >(block.size ()), block.data (), nullptr );
1603+ status = H5Sselect_hyperslab (
1604+ filespace,
1605+ H5S_SELECT_SET,
1606+ start.data (),
1607+ stride.data (),
1608+ count.data (),
1609+ block.data ());
1610+ VERIFY (
1611+ status == 0 ,
1612+ " [HDF5] Internal error: Failed to select hyperslab during dataset "
1613+ " write" );
1614+ }
15801615
15811616 void const *data = parameters.data .get ();
15821617
@@ -2013,28 +2048,54 @@ void HDF5IOHandlerImpl::readDataset(
20132048 " [HDF5] Internal error: Failed to open HDF5 dataset during dataset "
20142049 " read" );
20152050
2016- std::vector<hsize_t > start;
2017- for (auto const &val : parameters.offset )
2018- start.push_back (static_cast <hsize_t >(val));
2019- std::vector<hsize_t > stride (start.size (), 1 ); /* contiguous region */
2020- std::vector<hsize_t > count (start.size (), 1 ); /* single region */
2021- std::vector<hsize_t > block;
2022- for (auto const &val : parameters.extent )
2023- block.push_back (static_cast <hsize_t >(val));
2024- memspace =
2025- H5Screate_simple (static_cast <int >(block.size ()), block.data (), nullptr );
20262051 filespace = H5Dget_space (dataset_id);
2027- status = H5Sselect_hyperslab (
2028- filespace,
2029- H5S_SELECT_SET,
2030- start.data (),
2031- stride.data (),
2032- count.data (),
2033- block.data ());
2034- VERIFY (
2035- status == 0 ,
2036- " [HDF5] Internal error: Failed to select hyperslab during dataset "
2037- " read" );
2052+ int ndims = H5Sget_simple_extent_ndims (filespace);
2053+
2054+ if (ndims == 0 )
2055+ {
2056+ if (parameters.offset != Offset{0 } || parameters.extent != Extent{1 })
2057+ {
2058+ std::stringstream errorMessage;
2059+ errorMessage
2060+ << " HDF5 dataset '" << concrete_h5_file_position (writable)
2061+ << " ' is scalar (dimensionality 0) and must be accessed with "
2062+ " offset [0] and extent [1]. Was accessed with offset " ;
2063+ auxiliary::write_vec_to_stream (errorMessage, parameters.offset )
2064+ << " and extent " ;
2065+ auxiliary::write_vec_to_stream (errorMessage, parameters.extent )
2066+ << " ." ;
2067+ throw error::WrongAPIUsage (errorMessage.str ());
2068+ }
2069+ memspace = H5Screate_simple (0 , nullptr , nullptr );
2070+ VERIFY (
2071+ memspace > 0 ,
2072+ " [HDF5] Internal error: Failed to create memspace during dataset "
2073+ " read" );
2074+ }
2075+ else
2076+ {
2077+ std::vector<hsize_t > start;
2078+ for (auto const &val : parameters.offset )
2079+ start.push_back (static_cast <hsize_t >(val));
2080+ std::vector<hsize_t > stride (start.size (), 1 ); /* contiguous region */
2081+ std::vector<hsize_t > count (start.size (), 1 ); /* single region */
2082+ std::vector<hsize_t > block;
2083+ for (auto const &val : parameters.extent )
2084+ block.push_back (static_cast <hsize_t >(val));
2085+ memspace = H5Screate_simple (
2086+ static_cast <int >(block.size ()), block.data (), nullptr );
2087+ status = H5Sselect_hyperslab (
2088+ filespace,
2089+ H5S_SELECT_SET,
2090+ start.data (),
2091+ stride.data (),
2092+ count.data (),
2093+ block.data ());
2094+ VERIFY (
2095+ status == 0 ,
2096+ " [HDF5] Internal error: Failed to select hyperslab during dataset "
2097+ " read" );
2098+ }
20382099
20392100 void *data = parameters.data .get ();
20402101
0 commit comments