openPMD-api
 
Loading...
Searching...
No Matches
AbstractIOHandler.hpp
1/* Copyright 2017-2025 Fabian Koller, Axel Huebl, Franz Poeschel
2 *
3 * This file is part of openPMD-api.
4 *
5 * openPMD-api is free software: you can redistribute it and/or modify
6 * it under the terms of of either the GNU General Public License or
7 * the GNU Lesser General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * openPMD-api is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License and the GNU Lesser General Public License
15 * for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * and the GNU Lesser General Public License along with openPMD-api.
19 * If not, see <http://www.gnu.org/licenses/>.
20 */
21#pragma once
22
23#include "openPMD/IO/Access.hpp"
24#include "openPMD/IO/Format.hpp"
25#include "openPMD/IO/IOTask.hpp"
26#include "openPMD/IterationEncoding.hpp"
27#include "openPMD/config.hpp"
28#include "openPMD/version.hpp"
29
30#if openPMD_HAVE_MPI
31#include <mpi.h>
32#endif
33
34#include <future>
35#include <memory>
36#include <queue>
37#include <stdexcept>
38#include <string>
39#include <type_traits>
40
41namespace openPMD
42{
43namespace json
44{
45 class JsonMatcher;
46}
47
52// do not write `enum class FlushLevel : unsigned char` here since NVHPC
53// does not compile it correctly
83
84enum class OpenpmdStandard
85{
86 v_1_0_0,
87 v_1_0_1,
88 v_1_1_0,
89 v_2_0_0
90};
91
92namespace auxiliary
93{
94 auto parseStandard(std::string const &) -> OpenpmdStandard;
95 auto formatStandard(OpenpmdStandard) -> char const *;
96} // namespace auxiliary
97
98namespace internal
99{
105 struct FlushParams
106 {
108 std::string backendConfig = "{}";
109
110 explicit FlushParams()
111 {}
112 FlushParams(FlushLevel flushLevel_in) : flushLevel(flushLevel_in)
113 {}
114 FlushParams(FlushLevel flushLevel_in, std::string backendConfig_in)
115 : flushLevel(flushLevel_in)
116 , backendConfig{std::move(backendConfig_in)}
117 {}
118 };
119
120 /*
121 * To be used for reading
122 */
123 FlushParams const defaultFlushParams{};
124
125 struct ParsedFlushParams;
126
138 enum class SeriesStatus : unsigned char
139 {
140 Default,
143 Parsing
147 };
148
149 // @todo put this somewhere else
150 template <typename Functor, typename... Args>
151 auto withRWAccess(SeriesStatus &status, Functor &&functor, Args &&...args)
152 -> decltype(std::forward<Functor>(functor)(std::forward<Args>(args)...))
153 {
154 using Res = decltype(std::forward<Functor>(functor)(
155 std::forward<Args>(args)...));
156 if constexpr (std::is_void_v<Res>)
157 {
158 auto oldStatus = status;
159 status = internal::SeriesStatus::Parsing;
160 try
161 {
162 std::forward<decltype(functor)>(functor)();
163 }
164 catch (...)
165 {
166 status = oldStatus;
167 throw;
168 }
169 status = oldStatus;
170 return;
171 }
172 else
173 {
174 auto oldStatus = status;
175 status = internal::SeriesStatus::Parsing;
176 Res res;
177 try
178 {
179 res = std::forward<decltype(functor)>(functor)();
180 }
181 catch (...)
182 {
183 status = oldStatus;
184 throw;
185 }
186 status = oldStatus;
187 return res;
188 }
189 }
190} // namespace internal
191
192namespace detail
193{
194 class ADIOS2File;
195}
196
205class AbstractIOHandler
206{
207 friend class Series;
208 friend class ADIOS2IOHandlerImpl;
209 friend class JSONIOHandlerImpl;
210 friend class HDF5IOHandlerImpl;
211 friend class detail::ADIOS2File;
212
213private:
214 void setIterationEncoding(IterationEncoding encoding);
215
216protected:
217 // Needs to be a pointer due to include structure, this header is
218 // transitively included in user code, but we don't reexport the JSON
219 // library
220 std::unique_ptr<json::JsonMatcher> jsonMatcher;
221
222public:
223#if openPMD_HAVE_MPI
224 template <typename TracingJSON>
225 AbstractIOHandler(
226 std::optional<std::unique_ptr<AbstractIOHandler>> initialize_from,
227 std::string path,
228 Access at,
229 TracingJSON &&jsonConfig,
230 MPI_Comm);
231#endif
232
233 template <typename TracingJSON>
234 AbstractIOHandler(
235 std::optional<std::unique_ptr<AbstractIOHandler>> initialize_from,
236 std::string path,
237 Access at,
238 TracingJSON &&jsonConfig);
239
240 AbstractIOHandler(std::optional<std::unique_ptr<AbstractIOHandler>>);
241
242 virtual ~AbstractIOHandler();
243
244 AbstractIOHandler(AbstractIOHandler const &) = delete;
245 // std::queue::queue(queue&&) is not noexcept
246 // NOLINTNEXTLINE(performance-noexcept-move-constructor)
247 AbstractIOHandler(AbstractIOHandler &&) noexcept(false);
248
249 AbstractIOHandler &operator=(AbstractIOHandler const &) = delete;
250 AbstractIOHandler &operator=(AbstractIOHandler &&) noexcept;
251
257 virtual void enqueue(IOTask const &iotask)
258 {
259 m_work.push(iotask);
260 }
261
267 std::future<void> flush(internal::FlushParams const &);
268
274 virtual std::future<void> flush(internal::ParsedFlushParams &) = 0;
275
277 virtual std::string backendName() const = 0;
278 virtual bool fullSupportForVariableBasedEncoding() const;
279
280 std::string directory;
281 /*
282 * Originally, the reason for distinguishing these two was that during
283 * parsing in reading access modes, the access type would be temporarily
284 * const_cast'ed to an access type that would support modifying
285 * the openPMD object model. Then, it would be const_cast'ed back to
286 * READ_ONLY, to disable further modifications.
287 * Due to this approach's tendency to cause subtle bugs, and due to its
288 * difficult debugging properties, this was replaced by the SeriesStatus
289 * enum, defined in this file.
290 * The distinction of backendAccess and frontendAccess stays relevant, since
291 * the frontend can use it in order to pretend to the backend that another
292 * access type is being used. This is used by the file-based append mode,
293 * which is entirely implemented by the frontend, which internally uses
294 * the backend in CREATE mode.
295 */
296 Access m_backendAccess;
297 Access m_frontendAccess;
298 std::queue<IOTask> m_work;
299
300 /**************************************************************************
301 * Since the AbstractIOHandler is linked to every object of the frontend, *
302 * it stores a number of members that are needed by methods traversing *
303 * the object hierarchy. Those members are found below. *
304 **************************************************************************/
305
314 internal::SeriesStatus m_seriesStatus = internal::SeriesStatus::Default;
315 IterationEncoding m_encoding = IterationEncoding::groupBased;
316 OpenpmdStandard m_standard = auxiliary::parseStandard(getStandardDefault());
317 bool m_verify_homogeneous_extents = true;
318}; // AbstractIOHandler
319
320} // namespace openPMD
virtual std::future< void > flush(internal::ParsedFlushParams &)=0
Process operations in queue according to FIFO.
std::future< void > flush(internal::FlushParams const &)
Process operations in queue according to FIFO.
Definition AbstractIOHandler.cpp:106
bool m_lastFlushSuccessful
This is to avoid that the destructor tries flushing again if an error happened.
Definition AbstractIOHandler.hpp:313
virtual std::string backendName() const =0
The currently used backend.
virtual void enqueue(IOTask const &iotask)
Add provided task to queue according to FIFO.
Definition AbstractIOHandler.hpp:257
Self-contained description of a single IO operation.
Definition IOTask.hpp:836
Definition ADIOS2File.hpp:143
Class to handle default and dataset-specific JSON configurations.
Definition JSONMatcher.hpp:89
Public definitions of openPMD-api.
Definition Date.cpp:29
Access
File access mode to use during IO.
Definition Access.hpp:58
FlushLevel
Determine what items should be flushed upon Series::flush()
Definition AbstractIOHandler.hpp:55
@ SkeletonOnly
Restricted mode, ensures to set up the openPMD hierarchy (as far as defined so far) in the backend.
Definition AbstractIOHandler.hpp:77
@ CreateOrOpenFiles
Only creates/opens files, nothing more.
Definition AbstractIOHandler.hpp:81
@ InternalFlush
Default mode, used when flushes are triggered internally, e.g.
Definition AbstractIOHandler.hpp:69
@ UserFlush
Flush operation that was triggered by user code.
Definition AbstractIOHandler.hpp:61
IterationEncoding
Encoding scheme of an Iterations Series'.
Definition IterationEncoding.hpp:33
std::string getStandardDefault()
Return the default used version of the openPMD standard (read & write, run-time)
Definition version.cpp:41
Parameters recursively passed through the openPMD hierarchy when flushing.
Definition AbstractIOHandler.hpp:106
Definition FlushParametersInternal.hpp:32