Immediate flush mode - #1846
Immediate flush mode#1846franzpoeschel wants to merge 82 commits into
Conversation
53bdf60 to
9c02a26
Compare
| auto init_directly = [this, &comm..., &filepath]( | ||
| std::unique_ptr<ParsedInput> parsed_input, | ||
| json::TracingJSON tracing_json) { | ||
| json::TracingJSON tracing_json, |
Check notice
Code scanning / CodeQL
Large object passed by value Note
| else | ||
| { | ||
| auto read_again = E_x_read.loadChunk<int>({0, 0}, {mpi_size, 4}); | ||
| // REQUIRE_THROWS(read.flush()); |
Check notice
Code scanning / CodeQL
Commented-out code Note test
3b5c07f to
c725c7b
Compare
84d0f30 to
6e9c239
Compare
| std::move(ls_cfg), | ||
| /*flush_immediately=*/false); | ||
| } | ||
| // storeChunk(std::move(data), std::move(o), std::move(e)); |
Check notice
Code scanning / CodeQL
Commented-out code Note
af38436 to
822c03f
Compare
33b4186 to
7b99854
Compare
| template <typename T> | ||
| void RecordComponent::loadChunk(std::shared_ptr<T> data, Offset o, Extent e) | ||
| void RecordComponent::loadChunk_impl( | ||
| std::shared_ptr<T> const &data, internal::LoadStoreConfigWithBuffer cfg) |
Check notice
Code scanning / CodeQL
Large object passed by value Note
7b99854 to
48a7af8
Compare
2f456f4 to
c0475c4
Compare
d11d683 to
588b813
Compare
| std::static_pointer_cast<T>(std::move(ptr)), | ||
| std::move(offset), | ||
| std::move(extent)); | ||
| // static_assert(!std::is_same_v<T_with_extent, std::string>, "EVIL"); |
Check notice
Code scanning / CodeQL
Commented-out code Note
| #endif | ||
| } | ||
|
|
||
| TEST_CASE("future_test", "[auxiliary]") |
Check notice
Code scanning / CodeQL
Unused static function Note test
| inline DynamicMemoryView<T> RecordComponent::storeChunkSpanCreateBuffer_impl( | ||
| internal::LoadStoreConfig cfg, F &&createBuffer) | ||
| { | ||
| [[maybe_unused]] auto [o, e, api] = std::move(cfg); |
Check notice
Code scanning / CodeQL
Unused local variable Note
| #endif | ||
| } | ||
|
|
||
| TEST_CASE("unsafe_no_automatic_flush_immediate_flush_test", "[core]") |
Check notice
Code scanning / CodeQL
Unused static function Note test
2bca70c to
f29b628
Compare
for more information, see https://pre-commit.ci
for more information, see https://pre-commit.ci
…tics The chaining API's push_chunk() ignores OPENPMD_FLUSH_IMMEDIATELY for safety. When unsafeNoAutomaticFlush() is used, that guarantee no longer applies, so run legacy flushing semantics instead: unsafeNoAutomaticFlush_impl() now sets the internal api to LS_API::legacy, making push_chunk() honor the immediate-flush setting again. Adds a Core test (unsafe_no_automatic_flush_immediate_flush_test) verifying that chunks are flushed immediately when m_flush_immediately is set and buffered otherwise.
Explain how the synchronous flush option (flush_immediately/ OPENPMD_FLUSH_IMMEDIATELY) interacts with the two load/store APIs: - Legacy API (storeChunk()/loadChunk() and friends) only enqueues operations performed at flush points, so the sync-flush option makes each such call its own flush point. - Chaining API (prepareLoadStore()) flushes automatically upon evaluation of its DeferredComputation object and is unaffected by the sync-flush option, unless unsafeNoAutomaticFlush() is used, which falls back to legacy flushing semantics. - The span-based API always defers; Python defaults to immediate flushing. Documented in Doxygen/comments in the source code, in the .rst docs (workflow.rst and backendconfig.rst) and in the Python bindings docstring.
8dd3f15 to
ea5fa08
Compare
Support immediate (synchronous) flushing via
flush_immediatelyBase branch:
adios2-memory-selection· Feature branch:synchronous-flush. Use this for the Diff: Diff until then: https://github.com/franzpoeschel/openPMD-api/compare/adios2-memory-selection...franzpoeschel:openPMD-api:synchronous-flush?expand=1Motivation
The openPMD-api is a deferred data API: load/store operations are enqueued and only executed at explicit flush points. This is efficient but easy to get wrong (missed flushes, ordering surprises). This PR adds an opt-in immediate flush mode where every load/store call acts as an implicit flush point.
What changes
flush_immediately(JSON/TOML key orOPENPMD_FLUSH_IMMEDIATELY=1). Default:falsein C++,truein Python (merged in viajson::merge()).FlushLevel::ImmediateFlushwith updatedflush_level::*helpers, so an immediate flush can write datasets/attributes/hierarchy like aUserFlushwithout being a user-visible global flush point;determineUnsetDirty()treats it as a no-op.push_chunk(): performs a frontend hierarchy flush atImmediateFlush, enqueues the chunk directly, and flushes the backend queueall within the store/load call.
RecordComponent::flush()fixed so the read path only drainsm_chunksat a true global flush point.LS_API { legacy, chaining }: only the legacy API (andPatchRecordComponent) respects immediate flushing; the chaining API manages its own deferred flush and stays deferred;storeChunkSpanforcesflush_immediately=falseto keep span buffers valid.internal::GlobalParameters(from whichAbstractIOHandlerderives), plusinternal::AbstractIOHandlerInitFromreplacing the(path, access, initialize_from)packs in all handler constructors /createIOHandler(). Deferred init now carries options into the real handler viaGlobalParameters. AddsSeries::flushImmediately().adios2_bp5_flushsize, immediate throw on closed-iteration, skips for tests needing non-collective deferred store).backendconfig.rstandworkflow.rstdocument the option and that immediate flushing introduces implicit flush points.Compatibility
Deferred default for C++ is fully preserved; purely additive.
Testing
OPENPMD_FLUSH_IMMEDIATELY=0and=1(36/36 each).adios2_streaming(SST) abort that also reproduces on the base branch (environment-related, not introduced here).TODO:
Diff until then: https://github.com/franzpoeschel/openPMD-api/compare/adios2-memory-selection...franzpoeschel:openPMD-api:synchronous-flush?expand=1