openPMD-api
ADIOS1Auxiliary.hpp
1 /* Copyright 2018-2021 Fabian Koller
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/auxiliary/StringManip.hpp"
24 #include "openPMD/backend/Attribute.hpp"
25 #include "openPMD/backend/Writable.hpp"
26 #include "openPMD/IO/ADIOS/ADIOS1FilePosition.hpp"
27 
28 #include <adios_types.h>
29 
30 #include <cstring>
31 #include <exception>
32 #include <iterator>
33 #include <iostream>
34 #include <sstream>
35 #include <stack>
36 
37 
38 namespace openPMD
39 {
40 inline std::string
41 getBP1Extent(Extent const& e, std::string const& delimiter = ",")
42 {
43  switch( e.size() )
44  {
45  case 0:
46  return "";
47  case 1:
48  return std::to_string(e[0]);
49  default:
50  std::ostringstream os;
51  std::for_each(e.begin(),
52  e.end()-1,
53  [&os, &delimiter](std::uint64_t const ext) { os << std::to_string(ext) << delimiter; });
54  os << std::to_string(*e.rbegin());
55  return os.str();
56  }
57 }
58 
59 inline std::string
60 getZerosLikeBP1Extent(Extent const& e, std::string const& delimiter = ",")
61 {
62  switch( e.size() )
63  {
64  case 0:
65  return "";
66  case 1:
67  return "0";
68  default:
69  std::ostringstream os;
70  std::for_each(e.begin(),
71  e.end()-1,
72  [&os, &delimiter](std::uint64_t const) { os << "0" << delimiter; });
73  os << "0";
74  return os.str();
75  }
76 }
77 
78 inline ADIOS_DATATYPES
79 getBP1DataType(Datatype dtype)
80 {
81  using DT = Datatype;
82 
83  // note the ill-named fixed-byte adios_... types
84  // https://github.com/ornladios/ADIOS/issues/187
85  switch( dtype )
86  {
87  case DT::CHAR:
88  case DT::VEC_CHAR:
89  return adios_byte;
90  case DT::UCHAR:
91  case DT::VEC_UCHAR:
92  case DT::BOOL:
93  return adios_unsigned_byte;
94  case DT::SHORT:
95  case DT::VEC_SHORT:
96  if( sizeof(short) == 2u )
97  return adios_short;
98  else if( sizeof(short) == 4u )
99  return adios_integer;
100  else if( sizeof(long) == 8u )
101  return adios_long;
102  else
103  throw unsupported_data_error("No native equivalent for Datatype::SHORT found.");
104  case DT::INT:
105  case DT::VEC_INT:
106  if( sizeof(int) == 2u )
107  return adios_short;
108  else if( sizeof(int) == 4u )
109  return adios_integer;
110  else if( sizeof(int) == 8u )
111  return adios_long;
112  else
113  throw unsupported_data_error("No native equivalent for Datatype::INT found.");
114  case DT::LONG:
115  case DT::VEC_LONG:
116  if( sizeof(long) == 2u )
117  return adios_short;
118  else if( sizeof(long) == 4u )
119  return adios_integer;
120  else if( sizeof(long) == 8u )
121  return adios_long;
122  else
123  throw unsupported_data_error("No native equivalent for Datatype::LONG found.");
124  case DT::LONGLONG:
125  case DT::VEC_LONGLONG:
126  if( sizeof(long long) == 2u )
127  return adios_short;
128  else if( sizeof(long long) == 4u )
129  return adios_integer;
130  else if( sizeof(long long) == 8u )
131  return adios_long;
132  else
133  throw unsupported_data_error("No native equivalent for Datatype::LONGLONG found.");
134  case DT::USHORT:
135  case DT::VEC_USHORT:
136  if( sizeof(unsigned short) == 2u )
137  return adios_unsigned_short;
138  else if( sizeof(unsigned short) == 4u )
139  return adios_unsigned_integer;
140  else if( sizeof(unsigned long) == 8u )
141  return adios_unsigned_long;
142  else
143  throw unsupported_data_error("No native equivalent for Datatype::USHORT found.");
144  case DT::UINT:
145  case DT::VEC_UINT:
146  if( sizeof(unsigned int) == 2u )
147  return adios_unsigned_short;
148  else if( sizeof(unsigned int) == 4u )
149  return adios_unsigned_integer;
150  else if( sizeof(unsigned int) == 8u )
151  return adios_unsigned_long;
152  else
153  throw unsupported_data_error("No native equivalent for Datatype::UINT found.");
154  case DT::ULONG:
155  case DT::VEC_ULONG:
156  if( sizeof(unsigned long) == 2u )
157  return adios_unsigned_short;
158  else if( sizeof(unsigned long) == 4u )
159  return adios_unsigned_integer;
160  else if( sizeof(unsigned long) == 8u )
161  return adios_unsigned_long;
162  else
163  throw unsupported_data_error("No native equivalent for Datatype::ULONG found.");
164  case DT::ULONGLONG:
165  case DT::VEC_ULONGLONG:
166  if( sizeof(unsigned long long) == 2u )
167  return adios_unsigned_short;
168  else if( sizeof(unsigned long long) == 4u )
169  return adios_unsigned_integer;
170  else if( sizeof(unsigned long long) == 8u )
171  return adios_unsigned_long;
172  else
173  throw unsupported_data_error("No native equivalent for Datatype::ULONGLONG found.");
174  case DT::FLOAT:
175  case DT::VEC_FLOAT:
176  return adios_real;
177  case DT::DOUBLE:
178  case DT::ARR_DBL_7:
179  case DT::VEC_DOUBLE:
180  return adios_double;
181  case DT::LONG_DOUBLE:
182  case DT::VEC_LONG_DOUBLE:
183  return adios_long_double;
184  case DT::CFLOAT:
185  case DT::VEC_CFLOAT:
186  return adios_complex;
187  case DT::CDOUBLE:
188  case DT::VEC_CDOUBLE:
189  return adios_double_complex;
190  case DT::CLONG_DOUBLE:
191  case DT::VEC_CLONG_DOUBLE:
192  throw unsupported_data_error("No native equivalent for Datatype::CLONG_DOUBLE found.");
193  case DT::STRING:
194  return adios_string;
195  case DT::VEC_STRING:
196  return adios_string_array;
197  case DT::DATATYPE:
198  throw std::runtime_error("Meta-Datatype leaked into IO");
199  case DT::UNDEFINED:
200  throw std::runtime_error("Unknown Attribute datatype (ADIOS datatype)");
201  default:
202  throw std::runtime_error("Datatype not implemented in ADIOS IO");
203  }
204 }
205 
206 inline std::string
207 concrete_bp1_file_position(Writable* w)
208 {
209  std::stack< Writable* > hierarchy;
210  if( !w->abstractFilePosition )
211  w = w->parent;
212  while( w )
213  {
214  hierarchy.push(w);
215  w = w->parent;
216  }
217 
218  std::string pos;
219  while( !hierarchy.empty() )
220  {
221  auto const tmp_ptr = std::dynamic_pointer_cast< ADIOS1FilePosition >(hierarchy.top()->abstractFilePosition);
222  if( tmp_ptr == nullptr )
223  throw std::runtime_error("Dynamic pointer cast returned a nullptr!");
224  pos += tmp_ptr->location;
225  hierarchy.pop();
226  }
227 
228  return auxiliary::replace_all(pos, "//", "/");
229 }
230 
231 inline std::string
232 getEnvNum(std::string const& key, std::string const& defaultValue)
233 {
234  char const* env = std::getenv(key.c_str());
235  if( env != nullptr )
236  {
237  char const* tmp = env;
238  while( tmp )
239  {
240  if( isdigit(*tmp) )
241  ++tmp;
242  else
243  {
244  std::cerr << key << " is invalid" << std::endl;
245  break;
246  }
247  }
248  if( !tmp )
249  return std::string(env, std::strlen(env));
250  else
251  return defaultValue;
252  } else
253  return defaultValue;
254 }
255 
256 template<typename T>
257 inline Attribute
258 readVectorAttributeInternal( void* data, int size )
259 {
260  auto d = reinterpret_cast< T* >(data);
261  std::vector< T > v;
262  v.resize(size);
263  for( int i = 0; i < size; ++i )
264  v[i] = d[i];
265  return Attribute(v);
266 }
267 } // openPMD
Datatype
Concrete datatype of an object available at runtime.
Definition: Datatype.hpp:45
Public definitions of openPMD-api.
Definition: Date.cpp:29