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 > struct ToDatatypeHelper
47  {
48  static std::string type( );
49  };
50 
51  template < typename T > struct ToDatatypeHelper< std::vector< T > >
52  {
53  static std::string type( );
54  };
55 
56  template < typename T, size_t n >
57  struct ToDatatypeHelper< std::array< T, n > >
58  {
59  static std::string type( );
60  };
61 
62  template <> struct ToDatatypeHelper< bool >
63  {
64  static std::string type( );
65  };
66 
67  struct ToDatatype
68  {
69  template < typename T > std::string operator( )( );
70 
71 
72  template < int n > std::string operator( )( );
73  };
74 
81  Datatype fromADIOS2Type( std::string const & dt, bool verbose = true );
82 
83  enum class VariableOrAttribute : unsigned char
84  {
85  Variable,
86  Attribute
87  };
88 
90  {
91  template< typename T >
92  Extent
93  operator()(
94  adios2::IO &,
95  std::string const & attributeName,
96  VariableOrAttribute );
97 
98  template < int n, typename... Params >
99  Extent operator( )( Params &&... );
100  };
101 
114  Datatype
115  attributeInfo(
116  adios2::IO & IO,
117  std::string const & attributeName,
118  bool verbose,
119  VariableOrAttribute voa = VariableOrAttribute::Attribute );
120 } // namespace detail
121 
122 #if defined( _MSC_VER ) && !defined( __INTEL_COMPILER ) && !defined( __clang__ )
123 #define OPENPMD_TEMPLATE_OPERATOR operator
124 #else
125 #define OPENPMD_TEMPLATE_OPERATOR template operator
126 #endif
127 
146 template< typename Action, typename... Args >
147 auto switchAdios2AttributeType( Datatype dt, Action action, Args &&... args )
148  -> decltype(
149  action.OPENPMD_TEMPLATE_OPERATOR() < char >
150  ( std::forward< Args >( args )... ) )
151 {
152  using ReturnType = decltype(
153  action.OPENPMD_TEMPLATE_OPERATOR() < char >
154  ( std::forward< Args >( args )... ) );
155  switch( dt )
156  {
157  case Datatype::CHAR:
158  return action.OPENPMD_TEMPLATE_OPERATOR()< char >(
159  std::forward< Args >( args )... );
160  case Datatype::UCHAR:
161  return action.OPENPMD_TEMPLATE_OPERATOR()< unsigned char >(
162  std::forward< Args >( args )... );
163  case Datatype::SHORT:
164  return action.OPENPMD_TEMPLATE_OPERATOR()< short >(
165  std::forward< Args >( args )... );
166  case Datatype::INT:
167  return action.OPENPMD_TEMPLATE_OPERATOR()< int >(
168  std::forward< Args >( args )... );
169  case Datatype::LONG:
170  return action.OPENPMD_TEMPLATE_OPERATOR()< long >(
171  std::forward< Args >( args )... );
172  case Datatype::LONGLONG:
173  return action.OPENPMD_TEMPLATE_OPERATOR()< long long >(
174  std::forward< Args >( args )... );
175  case Datatype::USHORT:
176  return action.OPENPMD_TEMPLATE_OPERATOR()< unsigned short >(
177  std::forward< Args >( args )... );
178  case Datatype::UINT:
179  return action.OPENPMD_TEMPLATE_OPERATOR()< unsigned int >(
180  std::forward< Args >( args )... );
181  case Datatype::ULONG:
182  return action.OPENPMD_TEMPLATE_OPERATOR()< unsigned long >(
183  std::forward< Args >( args )... );
184  case Datatype::ULONGLONG:
185  return action.OPENPMD_TEMPLATE_OPERATOR()< unsigned long long >(
186  std::forward< Args >( args )... );
187  case Datatype::FLOAT:
188  return action.OPENPMD_TEMPLATE_OPERATOR()< float >(
189  std::forward< Args >( args )... );
190  case Datatype::DOUBLE:
191  return action.OPENPMD_TEMPLATE_OPERATOR()< double >(
192  std::forward< Args >( args )... );
193  case Datatype::LONG_DOUBLE:
194  return action.OPENPMD_TEMPLATE_OPERATOR()< long double >(
195  std::forward< Args >( args )... );
196  case Datatype::CFLOAT:
197  return action.OPENPMD_TEMPLATE_OPERATOR()< std::complex< float > >(
198  std::forward< Args >( args )... );
199  case Datatype::CDOUBLE:
200  return action.OPENPMD_TEMPLATE_OPERATOR()< std::complex< double > >(
201  std::forward< Args >( args )... );
202  // missing std::complex< long double > type in ADIOS2 v2.6.0
203  // case Datatype::CLONG_DOUBLE:
204  // return action
205  // .OPENPMD_TEMPLATE_OPERATOR()< std::complex< long double > >(
206  // std::forward< Args >( args )... );
207  case Datatype::STRING:
208  return action.OPENPMD_TEMPLATE_OPERATOR()< std::string >(
209  std::forward< Args >( args )... );
210  case Datatype::DATATYPE:
212  HIGHEST_DATATYPE,
213  ReturnType,
214  Action,
215  void,
216  Args &&... >::
217  call( std::move( action ), std::forward< Args >( args )... );
218  case Datatype::UNDEFINED:
220  LOWEST_DATATYPE,
221  ReturnType,
222  Action,
223  void,
224  Args &&... >::
225  call( std::move( action ), std::forward< Args >( args )... );
226  default:
227  throw std::runtime_error(
228  "Internal error: Encountered unknown datatype (switchType) ->" +
229  std::to_string( static_cast< int >( dt ) ) );
230  }
231 }
232 
252 template< typename Action, typename... Args >
253 auto switchAdios2VariableType( Datatype dt, Action action, Args &&... args )
254  -> decltype(
255  action.OPENPMD_TEMPLATE_OPERATOR() < char >
256  ( std::forward< Args >( args )... ) )
257 {
258  using ReturnType = decltype(
259  action.OPENPMD_TEMPLATE_OPERATOR() < char >
260  ( std::forward< Args >( args )... ) );
261  switch( dt )
262  {
263  case Datatype::CHAR:
264  return action.OPENPMD_TEMPLATE_OPERATOR()< char >(
265  std::forward< Args >( args )... );
266  case Datatype::UCHAR:
267  return action.OPENPMD_TEMPLATE_OPERATOR()< unsigned char >(
268  std::forward< Args >( args )... );
269  case Datatype::SHORT:
270  return action.OPENPMD_TEMPLATE_OPERATOR()< short >(
271  std::forward< Args >( args )... );
272  case Datatype::INT:
273  return action.OPENPMD_TEMPLATE_OPERATOR()< int >(
274  std::forward< Args >( args )... );
275  case Datatype::LONG:
276  return action.OPENPMD_TEMPLATE_OPERATOR()< long >(
277  std::forward< Args >( args )... );
278  case Datatype::LONGLONG:
279  return action.OPENPMD_TEMPLATE_OPERATOR()< long long >(
280  std::forward< Args >( args )... );
281  case Datatype::USHORT:
282  return action.OPENPMD_TEMPLATE_OPERATOR()< unsigned short >(
283  std::forward< Args >( args )... );
284  case Datatype::UINT:
285  return action.OPENPMD_TEMPLATE_OPERATOR()< unsigned int >(
286  std::forward< Args >( args )... );
287  case Datatype::ULONG:
288  return action.OPENPMD_TEMPLATE_OPERATOR()< unsigned long >(
289  std::forward< Args >( args )... );
290  case Datatype::ULONGLONG:
291  return action.OPENPMD_TEMPLATE_OPERATOR()< unsigned long long >(
292  std::forward< Args >( args )... );
293  case Datatype::FLOAT:
294  return action.OPENPMD_TEMPLATE_OPERATOR()< float >(
295  std::forward< Args >( args )... );
296  case Datatype::DOUBLE:
297  return action.OPENPMD_TEMPLATE_OPERATOR()< double >(
298  std::forward< Args >( args )... );
299  case Datatype::LONG_DOUBLE:
300  return action.OPENPMD_TEMPLATE_OPERATOR()< long double >(
301  std::forward< Args >( args )... );
302  case Datatype::CFLOAT:
303  return action.OPENPMD_TEMPLATE_OPERATOR()< std::complex< float > >(
304  std::forward< Args >( args )... );
305  case Datatype::CDOUBLE:
306  return action.OPENPMD_TEMPLATE_OPERATOR()< std::complex< double > >(
307  std::forward< Args >( args )... );
308  // missing std::complex< long double > type in ADIOS2 v2.6.0
309  // case Datatype::CLONG_DOUBLE:
310  // return action
311  // .OPENPMD_TEMPLATE_OPERATOR()< std::complex< long double > >(
312  // std::forward< Args >( args )... );
313  case Datatype::DATATYPE:
315  HIGHEST_DATATYPE,
316  ReturnType,
317  Action,
318  void,
319  Args &&... >::
320  call( std::move( action ), std::forward< Args >( args )... );
321  case Datatype::UNDEFINED:
323  LOWEST_DATATYPE,
324  ReturnType,
325  Action,
326  void,
327  Args &&... >::
328  call( std::move( action ), std::forward< Args >( args )... );
329  default:
330  throw std::runtime_error(
331  "Internal error: Encountered unknown datatype (switchType) ->" +
332  std::to_string( static_cast< int >( dt ) ) );
333  }
334 }
335 
336 #undef OPENPMD_TEMPLATE_OPERATOR
337 } // namespace openPMD
338 
339 #endif // openPMD_HAVE_ADIOS2
Definition: ADIOS2Auxiliary.hpp:67
auto switchAdios2VariableType(Datatype dt, Action action, Args &&... args) -> decltype(action. template operator()< char >(std::forward< Args >(args)...))
Generalizes switching over an openPMD datatype.
Definition: ADIOS2Auxiliary.hpp:253
Purpose of this struct is to detect at compile time whether Action::template operator()<0>() exists...
Definition: DatatypeHelpers.hpp:82
STL namespace.
Definition: ADIOS2Auxiliary.hpp:89
auto switchAdios2AttributeType(Datatype dt, Action action, Args &&... args) -> decltype(action. template operator()< char >(std::forward< Args >(args)...))
Generalizes switching over an openPMD datatype.
Definition: ADIOS2Auxiliary.hpp:147
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:50
Definition: Container.cpp:51
Public definitions of openPMD-api.
Definition: Date.cpp:29
Definition: ADIOS2Auxiliary.hpp:46