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