openPMD-api
ADIOS2Auxiliary.hpp
1 /* Copyright 2017-2021 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 
22 #pragma once
23 
24 #include "openPMD/config.hpp"
25 #if openPMD_HAVE_ADIOS2
26 #include "openPMD/Dataset.hpp"
27 #include "openPMD/Datatype.hpp"
28 #include "openPMD/DatatypeHelpers.hpp"
29 
30 #include <adios2.h>
31 
32 #include <complex>
33 #include <stdexcept>
34 #include <utility>
35 #include <vector>
36 
37 namespace openPMD
38 {
39 namespace detail
40 {
41  // ADIOS2 does not natively support boolean values
42  // Since we need them for attributes,
43  // we represent booleans as unsigned chars
44  using bool_representation = unsigned char;
45 
46  template <typename T>
48  {
49  static std::string type();
50  };
51 
52  template <typename T>
53  struct ToDatatypeHelper<std::vector<T>>
54  {
55  static std::string type();
56  };
57 
58  template <typename T, size_t n>
59  struct ToDatatypeHelper<std::array<T, n>>
60  {
61  static std::string type();
62  };
63 
64  template <>
65  struct ToDatatypeHelper<bool>
66  {
67  static std::string type();
68  };
69 
70  struct ToDatatype
71  {
72  template <typename T>
73  std::string operator()();
74 
75  template <int n>
76  std::string operator()();
77  };
78 
85  Datatype fromADIOS2Type(std::string const &dt, bool verbose = true);
86 
87  enum class VariableOrAttribute : unsigned char
88  {
89  Variable,
90  Attribute
91  };
92 
94  {
95  template <typename T>
96  static Extent call(
97  adios2::IO &,
98  std::string const &attributeName,
99  VariableOrAttribute);
100 
101  template <int n, typename... Params>
102  static Extent call(Params &&...);
103  };
104 
117  Datatype attributeInfo(
118  adios2::IO &IO,
119  std::string const &attributeName,
120  bool verbose,
121  VariableOrAttribute voa = VariableOrAttribute::Attribute);
122 } // namespace detail
123 
139 template <typename Action, typename... Args>
140 auto switchAdios2AttributeType(Datatype dt, Args &&...args)
141  -> decltype(Action::template call<char>(std::forward<Args>(args)...))
142 {
143  using ReturnType =
144  decltype(Action::template call<char>(std::forward<Args>(args)...));
145  switch (dt)
146  {
147  case Datatype::CHAR:
148  return Action::template call<char>(std::forward<Args>(args)...);
149  case Datatype::UCHAR:
150  return Action::template call<unsigned char>(
151  std::forward<Args>(args)...);
152  case Datatype::SCHAR:
153  return Action::template call<signed char>(std::forward<Args>(args)...);
154  case Datatype::SHORT:
155  return Action::template call<short>(std::forward<Args>(args)...);
156  case Datatype::INT:
157  return Action::template call<int>(std::forward<Args>(args)...);
158  case Datatype::LONG:
159  return Action::template call<long>(std::forward<Args>(args)...);
160  case Datatype::LONGLONG:
161  return Action::template call<long long>(std::forward<Args>(args)...);
162  case Datatype::USHORT:
163  return Action::template call<unsigned short>(
164  std::forward<Args>(args)...);
165  case Datatype::UINT:
166  return Action::template call<unsigned int>(std::forward<Args>(args)...);
167  case Datatype::ULONG:
168  return Action::template call<unsigned long>(
169  std::forward<Args>(args)...);
170  case Datatype::ULONGLONG:
171  return Action::template call<unsigned long long>(
172  std::forward<Args>(args)...);
173  case Datatype::FLOAT:
174  return Action::template call<float>(std::forward<Args>(args)...);
175  case Datatype::DOUBLE:
176  return Action::template call<double>(std::forward<Args>(args)...);
177  case Datatype::LONG_DOUBLE:
178  return Action::template call<long double>(std::forward<Args>(args)...);
179  case Datatype::CFLOAT:
180  return Action::template call<std::complex<float>>(
181  std::forward<Args>(args)...);
182  case Datatype::CDOUBLE:
183  return Action::template call<std::complex<double>>(
184  std::forward<Args>(args)...);
185  // missing std::complex< long double > type in ADIOS2 v2.6.0
186  // case Datatype::CLONG_DOUBLE:
187  // return action
188  // .OPENPMD_TEMPLATE_OPERATOR()< std::complex< long double > >(
189  // std::forward< Args >( args )... );
190  case Datatype::STRING:
191  return Action::template call<std::string>(std::forward<Args>(args)...);
192  case Datatype::UNDEFINED:
193  return detail::
194  CallUndefinedDatatype<0, ReturnType, Action, Args &&...>::call(
195  std::forward<Args>(args)...);
196  default:
197  throw std::runtime_error(
198  "Internal error: Encountered unknown datatype (switchType) ->" +
199  std::to_string(static_cast<int>(dt)));
200  }
201 }
202 
219 template <typename Action, typename... Args>
220 auto switchAdios2VariableType(Datatype dt, Args &&...args)
221  -> decltype(Action::template call<char>(std::forward<Args>(args)...))
222 {
223  using ReturnType =
224  decltype(Action::template call<char>(std::forward<Args>(args)...));
225  switch (dt)
226  {
227  case Datatype::CHAR:
228  return Action::template call<char>(std::forward<Args>(args)...);
229  case Datatype::UCHAR:
230  return Action::template call<unsigned char>(
231  std::forward<Args>(args)...);
232  case Datatype::SCHAR:
233  return Action::template call<signed char>(std::forward<Args>(args)...);
234  case Datatype::SHORT:
235  return Action::template call<short>(std::forward<Args>(args)...);
236  case Datatype::INT:
237  return Action::template call<int>(std::forward<Args>(args)...);
238  case Datatype::LONG:
239  return Action::template call<long>(std::forward<Args>(args)...);
240  case Datatype::LONGLONG:
241  return Action::template call<long long>(std::forward<Args>(args)...);
242  case Datatype::USHORT:
243  return Action::template call<unsigned short>(
244  std::forward<Args>(args)...);
245  case Datatype::UINT:
246  return Action::template call<unsigned int>(std::forward<Args>(args)...);
247  case Datatype::ULONG:
248  return Action::template call<unsigned long>(
249  std::forward<Args>(args)...);
250  case Datatype::ULONGLONG:
251  return Action::template call<unsigned long long>(
252  std::forward<Args>(args)...);
253  case Datatype::FLOAT:
254  return Action::template call<float>(std::forward<Args>(args)...);
255  case Datatype::DOUBLE:
256  return Action::template call<double>(std::forward<Args>(args)...);
257  case Datatype::LONG_DOUBLE:
258  return Action::template call<long double>(std::forward<Args>(args)...);
259  case Datatype::CFLOAT:
260  return Action::template call<std::complex<float>>(
261  std::forward<Args>(args)...);
262  case Datatype::CDOUBLE:
263  return Action::template call<std::complex<double>>(
264  std::forward<Args>(args)...);
265  // missing std::complex< long double > type in ADIOS2 v2.6.0
266  // case Datatype::CLONG_DOUBLE:
267  // return action
268  // .OPENPMD_TEMPLATE_OPERATOR()< std::complex< long double > >(
269  // std::forward< Args >( args )... );
270  case Datatype::UNDEFINED:
271  return detail::
272  CallUndefinedDatatype<0, ReturnType, Action, Args &&...>::call(
273  std::forward<Args>(args)...);
274  default:
275  throw std::runtime_error(
276  "Internal error: Encountered unknown datatype (switchType) ->" +
277  std::to_string(static_cast<int>(dt)));
278  }
279 }
280 } // namespace openPMD
281 
282 #endif // openPMD_HAVE_ADIOS2
auto switchAdios2VariableType(Datatype dt, Args &&...args) -> decltype(Action::template call< char >(std::forward< Args >(args)...))
Generalizes switching over an openPMD datatype.
Definition: ADIOS2Auxiliary.hpp:220
Definition: ADIOS2Auxiliary.hpp:70
auto switchAdios2AttributeType(Datatype dt, Args &&...args) -> decltype(Action::template call< char >(std::forward< Args >(args)...))
Generalizes switching over an openPMD datatype.
Definition: ADIOS2Auxiliary.hpp:140
STL namespace.
Definition: ADIOS2Auxiliary.hpp:93
Datatype
Concrete datatype of an object available at runtime.
Definition: Datatype.hpp:45
Varidic datatype supporting at least all formats for attributes specified in the openPMD standard...
Definition: Attribute.hpp:54
Definition: Container.cpp:51
Public definitions of openPMD-api.
Definition: ADIOS2Auxiliary.hpp:47