Skip to content

Commit 77a55a3

Browse files
HDF5: Delete and re-create attribute when overwriting with diff. type (#1697)
* HDF5: Delete and re-create attribute when overwriting with diff. type * WIP: Change datatype in test Somehow truncation test is broken by this * Add forgotten H5Aclose() call
1 parent 1bd63c7 commit 77a55a3

File tree

2 files changed

+47
-5
lines changed

2 files changed

+47
-5
lines changed

src/IO/HDF5/HDF5IOHandler.cpp

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1694,8 +1694,7 @@ void HDF5IOHandlerImpl::writeAttribute(
16941694
"[HDF5] Internal error: Failed to get HDF5 datatype during attribute "
16951695
"write");
16961696
std::string name = parameters.name;
1697-
if (H5Aexists(node_id, name.c_str()) == 0)
1698-
{
1697+
auto create_attribute_anew = [&]() {
16991698
hid_t dataspace = getH5DataSpace(att);
17001699
VERIFY(
17011700
dataspace >= 0,
@@ -1717,14 +1716,47 @@ void HDF5IOHandlerImpl::writeAttribute(
17171716
status == 0,
17181717
"[HDF5] Internal error: Failed to close HDF5 dataspace during "
17191718
"attribute write");
1720-
}
1721-
else
1719+
};
1720+
if (H5Aexists(node_id, name.c_str()) != 0)
17221721
{
17231722
attribute_id = H5Aopen(node_id, name.c_str(), H5P_DEFAULT);
17241723
VERIFY(
1725-
node_id >= 0,
1724+
attribute_id >= 0,
17261725
"[HDF5] Internal error: Failed to open HDF5 attribute during "
17271726
"attribute write");
1727+
/*
1728+
* Only reuse the old attribute if it had the same type.
1729+
*/
1730+
hid_t type_id = H5Aget_type(attribute_id);
1731+
VERIFY(
1732+
type_id >= 0,
1733+
"[HDF5] Internal error: Failed to inquire HDF5 attribute type "
1734+
"during attribute write");
1735+
auto equal = H5Tequal(type_id, dataType);
1736+
VERIFY(
1737+
equal >= 0,
1738+
"[HDF5] Internal error: Failed to compare HDF5 attribute types "
1739+
"during attribute write");
1740+
if (equal == 0) // unequal
1741+
{
1742+
status = H5Aclose(attribute_id);
1743+
VERIFY(
1744+
status == 0,
1745+
"[HDF5] Internal error: Failed to close previous HDF5 "
1746+
"attribute "
1747+
"during attribute write");
1748+
status = H5Adelete(node_id, name.c_str());
1749+
VERIFY(
1750+
status == 0,
1751+
"[HDF5] Internal error: Failed to delete previous HDF5 "
1752+
"attribute "
1753+
"during attribute write");
1754+
create_attribute_anew();
1755+
}
1756+
}
1757+
else
1758+
{
1759+
create_attribute_anew();
17281760
}
17291761

17301762
using DT = Datatype;

test/SerialIOTest.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7522,6 +7522,8 @@ void groupbased_read_write(std::string const &ext)
75227522

75237523
E_x.setAttribute("updated_in_run", 0);
75247524
E_y.setAttribute("updated_in_run", 0);
7525+
E_y.setAttribute("changed_datatype_in_run", 0);
7526+
write.close();
75257527
}
75267528

75277529
{
@@ -7540,6 +7542,8 @@ void groupbased_read_write(std::string const &ext)
75407542

75417543
E_x.setAttribute("updated_in_run", 1);
75427544
E_y.setAttribute("updated_in_run", 1);
7545+
E_y.setAttribute("changed_datatype_in_run", "one");
7546+
write.close();
75437547
}
75447548

75457549
{
@@ -7551,6 +7555,9 @@ void groupbased_read_write(std::string const &ext)
75517555
REQUIRE(E_x_0_fromRun0.getAttribute("updated_in_run").get<int>() == 0);
75527556
REQUIRE(E_x_1_fromRun1.getAttribute("updated_in_run").get<int>() == 1);
75537557
REQUIRE(E_y_0_fromRun1.getAttribute("updated_in_run").get<int>() == 1);
7558+
REQUIRE(
7559+
E_y_0_fromRun1.getAttribute("changed_datatype_in_run")
7560+
.get<std::string>() == "one");
75547561

75557562
auto chunk_E_x_0_fromRun0 = E_x_0_fromRun0.loadChunk<int>({0}, {1});
75567563
auto chunk_E_x_1_fromRun1 = E_x_1_fromRun1.loadChunk<int>({0}, {1});
@@ -7561,6 +7568,7 @@ void groupbased_read_write(std::string const &ext)
75617568
REQUIRE(*chunk_E_x_0_fromRun0 == 0);
75627569
REQUIRE(*chunk_E_x_1_fromRun1 == 1);
75637570
REQUIRE(*chunk_E_y_0_fromRun1 == 1);
7571+
read.close();
75647572
}
75657573

75667574
// check that truncation works correctly
@@ -7574,12 +7582,14 @@ void groupbased_read_write(std::string const &ext)
75747582

75757583
E_x.storeChunkRaw(&data, {0}, {1});
75767584
E_x.setAttribute("updated_in_run", 2);
7585+
write.close();
75777586
}
75787587

75797588
{
75807589
Series read(filename, Access::READ_ONLY);
75817590
REQUIRE(read.iterations.size() == 1);
75827591
REQUIRE(read.iterations.count(2) == 1);
7592+
read.close();
75837593
}
75847594
}
75857595

0 commit comments

Comments
 (0)