Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug fix: Use Series::writeIterations() without explicit flushing #1030

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/openPMD/Series.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ class SeriesImpl : public AttributableImpl
friend class SeriesIterator;
friend class internal::SeriesInternal;
friend class Series;
friend class WriteIterations;

protected:
// Should not be called publicly, only by implementing classes
Expand Down
1 change: 1 addition & 0 deletions include/openPMD/backend/Attributable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ class AttributableImpl
friend class Series;
friend class SeriesImpl;
friend class Writable;
friend class WriteIterations;

protected:
internal::AttributableData * m_attri = nullptr;
Expand Down
9 changes: 6 additions & 3 deletions src/Series.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1426,10 +1426,13 @@ SeriesInternal::~SeriesInternal()
// we must not throw in a destructor
try
{
auto & series = get();
// WriteIterations gets the first shot at flushing
series.m_writeIterations = auxiliary::Option< WriteIterations >();
/*
* Scenario: A user calls `Series::flush()` but does not check for thrown
* exceptions. The exception will propagate further up, usually thereby
* popping the stack frame that holds the `Series` object.
* Scenario: A user calls `Series::flush()` but does not check for
* thrown exceptions. The exception will propagate further up, usually
* thereby popping the stack frame that holds the `Series` object.
* `Series::~Series()` will run. This check avoids that the `Series` is
* needlessly flushed a second time. Otherwise, error messages can get
* very confusing.
Expand Down
3 changes: 2 additions & 1 deletion src/WriteIterations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ WriteIterations::SharedResources::SharedResources( iterations_t _iterations )

WriteIterations::SharedResources::~SharedResources()
{
if( currentlyOpen.has_value() )
if( currentlyOpen.has_value() &&
iterations.retrieveSeries().get().m_lastFlushSuccessful )
{
auto lastIterationIndex = currentlyOpen.get();
auto & lastIteration = iterations.at( lastIterationIndex );
Expand Down
51 changes: 51 additions & 0 deletions test/SerialIOTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4297,3 +4297,54 @@ TEST_CASE( "deferred_parsing", "[serial]" )
deferred_parsing( t );
}
}

// @todo merge this back with the chaotic_stream test of PR #949
// (bug noticed while working on that branch)
void no_explicit_flush( std::string filename )
{
std::vector< uint64_t > sampleData{ 5, 9, 1, 3, 4, 6, 7, 8, 2, 0 };
std::string jsonConfig = R"(
{
"adios2": {
"schema": 20210209,
"engine": {
"type": "bp4",
"usesteps": true
}
}
})";

{
Series series( filename, Access::CREATE, jsonConfig );
for( uint64_t currentIteration = 0; currentIteration < 10;
++currentIteration )
{
auto dataset =
series.writeIterations()[ currentIteration ]
.meshes[ "iterationOrder" ][ MeshRecordComponent::SCALAR ];
dataset.resetDataset( { determineDatatype< uint64_t >(), { 10 } } );
dataset.storeChunk( sampleData, { 0 }, { 10 } );
// series.writeIterations()[ currentIteration ].close();
}
}

{
Series series( filename, Access::READ_ONLY );
size_t index = 0;
for( auto iteration : series.readIterations() )
{
REQUIRE( iteration.iterationIndex == index );
++index;
}
REQUIRE( index == 10 );
}
}

TEST_CASE( "no_explicit_flush", "[serial]" )
{
for( auto const & t : testedFileExtensions() )
{
no_explicit_flush( "../samples/chaotic_stream_filebased_%T." + t );
no_explicit_flush( "../samples/chaotic_stream." + t );
ax3l marked this conversation as resolved.
Show resolved Hide resolved
}
}