openPMD-api
 
Loading...
Searching...
No Matches
ADIOS2Auxiliary.hpp
1/* Copyright 2017-2025 Franz Poeschel., Axel Huebl
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
22#pragma once
23
24#include "openPMD/Error.hpp"
25#include "openPMD/IO/ADIOS/macros.hpp"
26#include "openPMD/config.hpp"
27
28#if openPMD_HAVE_ADIOS2
29#include "openPMD/Dataset.hpp"
30#include "openPMD/Datatype.hpp"
31#include "openPMD/DatatypeHelpers.hpp"
32
33#include <adios2.h>
34
35#include <complex>
36#include <stdexcept>
37#include <utility>
38#include <vector>
39#endif
40
41namespace openPMD
42{
43enum class GroupOrDataset
44{
45 GROUP,
46 DATASET
47};
48
49namespace adios_defs
50{
51 enum class FlushTarget : unsigned char
52 {
53 Buffer,
54 Buffer_Override,
55 Disk,
56 Disk_Override,
57 NewStep,
58 NewStep_Override
59 };
60
61 using FlushTarget = adios_defs::FlushTarget;
62 FlushTarget flushTargetFromString(std::string const &str);
63
64 enum class UseGroupTable
65 {
66 Yes,
67 No
68 };
69
70 /*
71 * Necessary to implement the `reopen` flag of
72 * `Parameter<Operation::OPEN_FILE>`. The distinction between Open and
73 * Reopen is necessary for Write workflows in file-based encoding. In order
74 * to write new data to an Iteration that was created and closed previously,
75 * the only applicable access mode is Append mode, ideally in conjunction
76 * with `SetParameter("FlattenSteps", "ON")`.
77 */
78 enum class OpenFileAs
79 {
80 Create,
81 Open,
82 ReopenFileThatWeCreated
83 };
84} // namespace adios_defs
85
86/*
87 * The following strings are used during parsing of the JSON configuration
88 * string for the ADIOS2 backend.
89 */
90namespace adios_defaults
91{
92 using const_str = char const *const;
93 constexpr const_str str_engine = "engine";
94 constexpr const_str str_type = "type";
95 constexpr const_str str_treat_unsupported_engine_like = "pretend_engine";
96 constexpr const_str str_params = "parameters";
97 constexpr const_str str_usesteps = "usesteps";
98 constexpr const_str str_flushtarget = "preferred_flush_target";
99 constexpr const_str str_usesstepsAttribute = "__openPMD_internal/useSteps";
100 constexpr const_str str_useModifiableAttributes =
101 "__openPMD_internal/useModifiableAttributes";
102 constexpr const_str str_adios2Schema =
103 "__openPMD_internal/openPMD2_adios2_schema";
104 constexpr const_str str_isBoolean = "__is_boolean__";
105 constexpr const_str str_activeTablePrefix = "__openPMD_groups";
106 constexpr const_str str_groupBasedWarning =
107 "__openPMD_internal/warning_bugprone_groupbased_encoding";
108} // namespace adios_defaults
109
110#if openPMD_HAVE_ADIOS2
111namespace detail
112{
113 // ADIOS2 does not natively support boolean values
114 // Since we need them for attributes,
115 // we represent booleans as unsigned chars
116 using bool_representation = unsigned char;
117
118 template <typename T>
120 {
121 static std::string type();
122 };
123
124 template <typename T>
125 struct ToDatatypeHelper<std::vector<T>>
126 {
127 static std::string type();
128 };
129
130 template <typename T, size_t n>
131 struct ToDatatypeHelper<std::array<T, n>>
132 {
133 static std::string type();
134 };
135
136 template <>
137 struct ToDatatypeHelper<bool>
138 {
139 static std::string type();
140 };
141
143 {
144 template <typename T>
145 std::string operator()();
146
147 template <int n>
148 std::string operator()();
149 };
150
157 Datatype fromADIOS2Type(std::string const &dt, bool verbose = true);
158
159 enum class VariableOrAttribute : unsigned char
160 {
161 Variable,
162 Attribute
163 };
164
166 {
167 template <typename T>
168 static Extent call(
169 adios2::IO &,
170 std::string const &attributeName,
171 VariableOrAttribute);
172
173 template <int n, typename... Params>
174 static Extent call(Params &&...);
175 };
176
189 Datatype attributeInfo(
190 adios2::IO &IO,
191 std::string const &attributeName,
192 bool verbose,
193 VariableOrAttribute voa = VariableOrAttribute::Attribute);
194
195 inline bool readOnly(adios2::Mode mode)
196 {
197 switch (mode)
198 {
199 case adios2::Mode::Append:
200 case adios2::Mode::Write:
201 return false;
202 case adios2::Mode::Read:
203 case adios2::Mode::ReadRandomAccess:
204 return true;
205 case adios2::Mode::Undefined:
206 case adios2::Mode::Sync:
207 case adios2::Mode::Deferred:
208 break;
209 }
210 throw error::Internal("Control flow error: No ADIOS2 open mode.");
211 }
212 inline bool writeOnly(adios2::Mode mode)
213 {
214 switch (mode)
215 {
216 case adios2::Mode::Append:
217 case adios2::Mode::Write:
218 return true;
219 case adios2::Mode::Read:
220 case adios2::Mode::ReadRandomAccess:
221 return false;
222 case adios2::Mode::Undefined:
223 case adios2::Mode::Sync:
224 case adios2::Mode::Deferred:
225 break;
226 }
227 throw error::Internal("Control flow error: No ADIOS2 open mode.");
228 }
229} // namespace detail
230
246template <typename Action, typename... Args>
247auto switchAdios2AttributeType(Datatype dt, Args &&...args)
248 -> decltype(Action::template call<char>(std::forward<Args>(args)...))
249{
250 using ReturnType =
251 decltype(Action::template call<char>(std::forward<Args>(args)...));
252 switch (dt)
253 {
254 case Datatype::CHAR:
255 return Action::template call<char>(std::forward<Args>(args)...);
256 case Datatype::UCHAR:
257 return Action::template call<unsigned char>(
258 std::forward<Args>(args)...);
259 case Datatype::SCHAR:
260 return Action::template call<signed char>(std::forward<Args>(args)...);
261 case Datatype::SHORT:
262 return Action::template call<short>(std::forward<Args>(args)...);
263 case Datatype::INT:
264 return Action::template call<int>(std::forward<Args>(args)...);
265 case Datatype::LONG:
266 return Action::template call<long>(std::forward<Args>(args)...);
267 case Datatype::LONGLONG:
268 return Action::template call<long long>(std::forward<Args>(args)...);
269 case Datatype::USHORT:
270 return Action::template call<unsigned short>(
271 std::forward<Args>(args)...);
272 case Datatype::UINT:
273 return Action::template call<unsigned int>(std::forward<Args>(args)...);
274 case Datatype::ULONG:
275 return Action::template call<unsigned long>(
276 std::forward<Args>(args)...);
277 case Datatype::ULONGLONG:
278 return Action::template call<unsigned long long>(
279 std::forward<Args>(args)...);
280 case Datatype::FLOAT:
281 return Action::template call<float>(std::forward<Args>(args)...);
282 case Datatype::DOUBLE:
283 return Action::template call<double>(std::forward<Args>(args)...);
284 case Datatype::LONG_DOUBLE:
285 return Action::template call<long double>(std::forward<Args>(args)...);
286 case Datatype::CFLOAT:
287 return Action::template call<std::complex<float>>(
288 std::forward<Args>(args)...);
289 case Datatype::CDOUBLE:
290 return Action::template call<std::complex<double>>(
291 std::forward<Args>(args)...);
292 // missing std::complex< long double > type in ADIOS2 v2.6.0
293 // case Datatype::CLONG_DOUBLE:
294 // return action
295 // .OPENPMD_TEMPLATE_OPERATOR()< std::complex< long double > >(
296 // std::forward< Args >( args )... );
297 case Datatype::STRING:
298 return Action::template call<std::string>(std::forward<Args>(args)...);
299 case Datatype::UNDEFINED:
300 return detail::
301 CallUndefinedDatatype<0, ReturnType, Action, Args &&...>::call(
302 std::forward<Args>(args)...);
303 default:
304 throw std::runtime_error(
305 "Internal error: Encountered unknown datatype (switchType) ->" +
306 std::to_string(static_cast<int>(dt)));
307 }
308}
309
326template <typename Action, typename... Args>
327auto switchAdios2VariableType(Datatype dt, Args &&...args)
328 -> decltype(Action::template call<char>(std::forward<Args>(args)...))
329{
330 using ReturnType =
331 decltype(Action::template call<char>(std::forward<Args>(args)...));
332 switch (dt)
333 {
334 case Datatype::CHAR:
335 return Action::template call<char>(std::forward<Args>(args)...);
336 case Datatype::UCHAR:
337 return Action::template call<unsigned char>(
338 std::forward<Args>(args)...);
339 case Datatype::SCHAR:
340 return Action::template call<signed char>(std::forward<Args>(args)...);
341 case Datatype::SHORT:
342 return Action::template call<short>(std::forward<Args>(args)...);
343 case Datatype::INT:
344 return Action::template call<int>(std::forward<Args>(args)...);
345 case Datatype::LONG:
346 return Action::template call<long>(std::forward<Args>(args)...);
347 case Datatype::LONGLONG:
348 return Action::template call<long long>(std::forward<Args>(args)...);
349 case Datatype::USHORT:
350 return Action::template call<unsigned short>(
351 std::forward<Args>(args)...);
352 case Datatype::UINT:
353 return Action::template call<unsigned int>(std::forward<Args>(args)...);
354 case Datatype::ULONG:
355 return Action::template call<unsigned long>(
356 std::forward<Args>(args)...);
357 case Datatype::ULONGLONG:
358 return Action::template call<unsigned long long>(
359 std::forward<Args>(args)...);
360 case Datatype::FLOAT:
361 return Action::template call<float>(std::forward<Args>(args)...);
362 case Datatype::DOUBLE:
363 return Action::template call<double>(std::forward<Args>(args)...);
364 case Datatype::LONG_DOUBLE:
365 return Action::template call<long double>(std::forward<Args>(args)...);
366 case Datatype::CFLOAT:
367 return Action::template call<std::complex<float>>(
368 std::forward<Args>(args)...);
369 case Datatype::CDOUBLE:
370 return Action::template call<std::complex<double>>(
371 std::forward<Args>(args)...);
372 // missing std::complex< long double > type in ADIOS2 v2.6.0
373 // case Datatype::CLONG_DOUBLE:
374 // return action
375 // .OPENPMD_TEMPLATE_OPERATOR()< std::complex< long double > >(
376 // std::forward< Args >( args )... );
377 case Datatype::UNDEFINED:
378 return detail::
379 CallUndefinedDatatype<0, ReturnType, Action, Args &&...>::call(
380 std::forward<Args>(args)...);
381 default:
382 throw std::runtime_error(
383 "Internal error: Encountered unknown datatype (switchType) ->" +
384 std::to_string(static_cast<int>(dt)));
385 }
386}
387#endif // openPMD_HAVE_ADIOS2
388} // namespace openPMD
Internal errors that should not happen.
Definition Error.hpp:103
Public definitions of openPMD-api.
Definition Date.cpp:29
auto switchAdios2VariableType(Datatype dt, Args &&...args) -> decltype(Action::template call< char >(std::forward< Args >(args)...))
Generalizes switching over an openPMD datatype.
Definition ADIOS2Auxiliary.hpp:327
Datatype
Concrete datatype of an object available at runtime.
Definition Datatype.hpp:51
auto switchAdios2AttributeType(Datatype dt, Args &&...args) -> decltype(Action::template call< char >(std::forward< Args >(args)...))
Generalizes switching over an openPMD datatype.
Definition ADIOS2Auxiliary.hpp:247
STL namespace.
Definition ADIOS2Auxiliary.hpp:166
Definition ADIOS2Auxiliary.hpp:120
Definition ADIOS2Auxiliary.hpp:143