Serialbox  2.2.0
Data serialization library and tools for C/C++, Python and Fortran
FortranWrapper.cpp
1 /*===-- serialbox-c/FortranWrapper.cpp ----------------------------------------------*- C++ -*-===*\
2  *
3  * S E R I A L B O X
4  *
5  * This file is distributed under terms of BSD license.
6  * See LICENSE.txt for more information
7  *
8  *===------------------------------------------------------------------------------------------===//
9  *
10  *! \file
11  *! This file contains some abstractions for the Fortran interface.
12  *
13 \*===------------------------------------------------------------------------------------------===*/
14 
15 #include "serialbox-c/FortranWrapper.h"
16 #include "serialbox-c/Serializer.h"
17 #include "serialbox-c/Utility.h"
23 
24 using namespace serialboxC;
26 using serialbox::TypeID;
27 
28 namespace {
29 void make_4D(std::vector<int>& v) {
30  if(v.size() > 4)
31  throw Exception(
32  "The FortranWrapper supports up to 4 dimensions (field with %i dimensions was passed).",
33  v.size());
34  else
35  v.resize(4, 0);
36 }
37 
38 std::vector<int> make_strides(int istride, int jstride, int kstride, int lstride) {
39  std::vector<int> strides;
40  if(istride >= 0)
41  strides.push_back(istride);
42  if(jstride >= 0)
43  strides.push_back(jstride);
44  if(kstride >= 0)
45  strides.push_back(kstride);
46  if(lstride >= 0)
47  strides.push_back(lstride);
48  return strides;
49 }
50 }
51 
52 /*===------------------------------------------------------------------------------------------===*\
53  * Serializer
54 \*===------------------------------------------------------------------------------------------===*/
55 
56 void serialboxFortranSerializerWrite(void* serializer, const void* savepoint, const char* name,
57  void* originPtr, int istride, int jstride, int kstride,
58  int lstride) {
59  auto strides = ::make_strides(istride, jstride, kstride, lstride);
60  serialboxSerializerWrite(static_cast<serialboxSerializer_t*>(serializer), name,
61  static_cast<const serialboxSavepoint_t*>(savepoint), originPtr,
62  strides.data(), strides.size());
63 }
64 
65 void serialboxFortranSerializerRead(void* serializer, const void* savepoint, const char* name,
66  void* originPtr, int istride, int jstride, int kstride,
67  int lstride) {
68  auto strides = ::make_strides(istride, jstride, kstride, lstride);
69  serialboxSerializerRead(static_cast<serialboxSerializer_t*>(serializer), name,
70  static_cast<const serialboxSavepoint_t*>(savepoint), originPtr,
71  strides.data(), strides.size());
72 }
73 
75  Serializer* ser = toSerializer(static_cast<serialboxSerializer_t*>(serializer));
76  std::cout << ser << std::endl;
77 }
78 
79 template <class ArrayType1, class ArrayType2>
80 static void checkRank(const char* name, ArrayType1&& array, ArrayType2&& arrayRef) {
81  const int rank = (array[0] > 0 ? 1 : 0) + (array[1] > 0 ? 1 : 0) + (array[2] > 0 ? 1 : 0) +
82  (array[3] > 0 ? 1 : 0);
83 
84  const int refRank = (arrayRef[0] > 0 ? 1 : 0) + (arrayRef[1] > 0 ? 1 : 0) +
85  (arrayRef[2] > 0 ? 1 : 0) + (arrayRef[3] > 0 ? 1 : 0);
86 
87  bool scalar = rank == 0 && refRank == 1 && arrayRef[0] == 1;
88 
89  if(rank != refRank && !scalar)
90  throw Exception("field '%s' has rank %i but field with rank %i was passed", name, refRank,
91  rank);
92 }
93 
94 void serialboxFortranSerializerCheckField(const void* serializer, const char* name, int* type,
95  int* isize, int* jsize, int* ksize, int* lsize) {
96 
97  const Serializer* ser = toConstSerializer(static_cast<const serialboxSerializer_t*>(serializer));
98 
99  try {
100  const auto& info = ser->getFieldMetainfoImplOf(name);
101 
102  std::array<int, 4> actualSizes{{*isize, *jsize, *ksize, *lsize}};
103  auto refSizes = info.dims();
104  ::make_4D(refSizes);
105 
106  // Check rank
107  checkRank(name, actualSizes, refSizes);
108 
109  // Check type (be careful with converting *type as it is an arbitrary int)
110  TypeID typeID = *type <= Float64 ? (TypeID)*type : TypeID::Invalid;
111  if(typeID != info.type())
112  throw Exception("field '%s' has type '%s' but was registered as type '%s'", name,
113  serialbox::TypeUtil::toString(info.type()),
115 
116  // Reorder and check dimensions
117  for(int i = 0; i < 4; ++i) {
118  if(actualSizes[i] == refSizes[i])
119  continue;
120 
121  if(refSizes[i] == 1) {
122  for(int j = 3; j > i; --j)
123  actualSizes[j] = actualSizes[j - 1];
124  actualSizes[i] = 1;
125  continue;
126  } else
127  throw Exception("dimensions of field '%s' do not match registered ones:"
128  "\nRegistered as: [ %i, %i, %i, %i ]"
129  "\nGiven as: [ %i, %i, %i, %i ]",
130  name, refSizes[0], refSizes[1], refSizes[2], refSizes[3], actualSizes[0],
131  actualSizes[1], actualSizes[2], actualSizes[3]);
132  }
133  } catch(std::exception& e) {
134  serialboxFatalError(e.what());
135  }
136 }
137 
138 void serialboxFortranComputeStrides(void* serializer, const char* fieldname, const void* basePtr,
139  const void* iplus1, const void* jplus1, const void* kplus1,
140  const void* lplus1, int* istride, int* jstride, int* kstride,
141  int* lstride) {
142  Serializer* ser = toSerializer(static_cast<serialboxSerializer_t*>(serializer));
143 
144  try {
145  const auto& info = ser->getFieldMetainfoImplOf(fieldname);
146 
147  std::array<long, 4> strides{
148  {reinterpret_cast<const char*>(iplus1) - reinterpret_cast<const char*>(basePtr),
149  reinterpret_cast<const char*>(jplus1) - reinterpret_cast<const char*>(basePtr),
150  reinterpret_cast<const char*>(kplus1) - reinterpret_cast<const char*>(basePtr),
151  reinterpret_cast<const char*>(lplus1) - reinterpret_cast<const char*>(basePtr)}};
152 
153  // Reorder strides
154  for(int i = 2; i >= 0; --i)
155  if(strides[i] == 0)
156  strides[i] = strides[i + 1];
157 
158  // Convert to unit-strides
159  const int bytesPerElement = serialbox::TypeUtil::sizeOf(info.type());
160  *istride = strides[0] / bytesPerElement;
161  *jstride = strides[1] / bytesPerElement;
162  *kstride = strides[2] / bytesPerElement;
163  *lstride = strides[3] / bytesPerElement;
164 
165  } catch(std::exception& e) {
166  serialboxFatalError(e.what());
167  }
168 }
169 
170 void serialboxFortranSerializerGetFieldDimensions(const void* serializer, const char* name,
171  int* isize, int* jsize, int* ksize, int* lsize) {
172 
173  const Serializer* ser = toConstSerializer(static_cast<const serialboxSerializer_t*>(serializer));
174 
175  auto dims = ser->getFieldMetainfoImplOf(name).dims();
176 
177  ::make_4D(dims);
178 
179  *isize = dims[0];
180  *jsize = dims[1];
181  *ksize = dims[2];
182  *lsize = dims[3];
183 }
184 
185 void serialboxFortranSerializerGetFieldHalos(const void* serializer, const char* name,
186  int* iMinusHalo, int* iPlusHalo, int* jMinusHalo,
187  int* jPlusHalo, int* kMinusHalo, int* kPlusHalo,
188  int* lMinusHalo, int* lPlusHalo) {
189 
190  char *notUsedHere_storedName, *notUsedHere_elementType;
191  int notUsedHere_bytesPerElement, notUsedHere_rank;
192  int notUsedHere_iSize, notUsedHere_jSize, notUsedHere_kSize, notUsedHere_lSize;
193 
195  static_cast<const serialboxSerializer_t*>(serializer), name, &notUsedHere_storedName,
196  &notUsedHere_elementType, &notUsedHere_bytesPerElement, &notUsedHere_rank, &notUsedHere_iSize,
197  &notUsedHere_jSize, &notUsedHere_kSize, &notUsedHere_lSize, iMinusHalo, iPlusHalo, jMinusHalo,
198  jPlusHalo, kMinusHalo, kPlusHalo, lMinusHalo, lPlusHalo);
199 }
200 
201 void serialboxFortranSerializerAddMetainfoBoolean(void* serializer, const char* key, int value) {
202  Serializer* ser = toSerializer(static_cast<serialboxSerializer_t*>(serializer));
203  try {
204  ser->addGlobalMetainfo(key, (bool)value);
205  } catch(std::exception& e) {
206  serialboxFatalError(e.what());
207  }
208 }
209 
210 void serialboxFortranSerializerAddMetainfoInt32(void* serializer, const char* key, int value) {
211  Serializer* ser = toSerializer(static_cast<serialboxSerializer_t*>(serializer));
212  try {
213  ser->addGlobalMetainfo(key, value);
214  } catch(std::exception& e) {
215  serialboxFatalError(e.what());
216  }
217 }
218 
219 void serialboxFortranSerializerAddMetainfoFloat32(void* serializer, const char* key, float value) {
220  Serializer* ser = toSerializer(static_cast<serialboxSerializer_t*>(serializer));
221  try {
222  ser->addGlobalMetainfo(key, value);
223  } catch(std::exception& e) {
224  serialboxFatalError(e.what());
225  }
226 }
227 
228 void serialboxFortranSerializerAddMetainfoFloat64(void* serializer, const char* key, double value) {
229  Serializer* ser = toSerializer(static_cast<serialboxSerializer_t*>(serializer));
230  try {
231  ser->addGlobalMetainfo(key, value);
232  } catch(std::exception& e) {
233  serialboxFatalError(e.what());
234  }
235 }
236 
237 void serialboxFortranSerializerAddMetainfoString(void* serializer, const char* key,
238  const char* value) {
239  Serializer* ser = toSerializer(static_cast<serialboxSerializer_t*>(serializer));
240  try {
241  ser->addGlobalMetainfo(key, value);
242  } catch(std::exception& e) {
243  serialboxFatalError(e.what());
244  }
245 }
246 
247 void serialboxFortranSerializerRegisterField(void* serializer, const char* name, int type,
248  int bytesPerElement, int iSize, int jSize, int kSize,
249  int lSize, int iMinusHalo, int iPlusHalo,
250  int jMinusHalo, int jPlusHalo, int kMinusHalo,
251  int kPlusHalo, int lMinusHalo, int lPlusHalo) {
252  serialboxSerializerAddField2(static_cast<serialboxSerializer_t*>(serializer), name, type,
253  bytesPerElement, iSize, jSize, kSize, lSize, iMinusHalo, iPlusHalo,
254  jMinusHalo, jPlusHalo, kMinusHalo, kPlusHalo, lMinusHalo, lPlusHalo);
255 }
256 
257 /*===------------------------------------------------------------------------------------------===*\
258  * FieldMetainfoImpl
259 \*===------------------------------------------------------------------------------------------===*/
260 
261 void serialboxFortranSerializerAddFieldMetainfoBoolean(void* serializer, const char* field,
262  const char* key, int value) {
263  Serializer* ser = toSerializer(static_cast<serialboxSerializer_t*>(serializer));
264  try {
265  if(!ser->addFieldMetainfoImpl(field, key, (bool)value))
266  throw Exception(
267  "cannot add element with key '%s' to field meta-info of '%s': element already exists",
268  key, field);
269  } catch(std::exception& e) {
270  serialboxFatalError(e.what());
271  }
272 }
273 
274 void serialboxFortranSerializerAddFieldMetainfoInt32(void* serializer, const char* field,
275  const char* key, int value) {
276  Serializer* ser = toSerializer(static_cast<serialboxSerializer_t*>(serializer));
277  try {
278  if(!ser->addFieldMetainfoImpl(field, key, value))
279  throw Exception(
280  "cannot add element with key '%s' to field meta-info of '%s': element already exists",
281  key, field);
282  } catch(std::exception& e) {
283  serialboxFatalError(e.what());
284  }
285 }
286 
287 void serialboxFortranSerializerAddFieldMetainfoFloat32(void* serializer, const char* field,
288  const char* key, float value) {
289  Serializer* ser = toSerializer(static_cast<serialboxSerializer_t*>(serializer));
290  try {
291  if(!ser->addFieldMetainfoImpl(field, key, value))
292  throw Exception(
293  "cannot add element with key '%s' to field meta-info of '%s': element already exists",
294  key, field);
295  } catch(std::exception& e) {
296  serialboxFatalError(e.what());
297  }
298 }
299 
300 void serialboxFortranSerializerAddFieldMetainfoFloat64(void* serializer, const char* field,
301  const char* key, double value) {
302  Serializer* ser = toSerializer(static_cast<serialboxSerializer_t*>(serializer));
303  try {
304  if(!ser->addFieldMetainfoImpl(field, key, value))
305  throw Exception(
306  "cannot add element with key '%s' to field meta-info of '%s': element already exists",
307  key, field);
308  } catch(std::exception& e) {
309  serialboxFatalError(e.what());
310  }
311 }
312 
313 void serialboxFortranSerializerAddFieldMetainfoString(void* serializer, const char* field,
314  const char* key, const char* value) {
315  Serializer* ser = toSerializer(static_cast<serialboxSerializer_t*>(serializer));
316  try {
317  if(!ser->addFieldMetainfoImpl(field, key, value))
318  throw Exception(
319  "cannot add element with key '%s' to field meta-info of '%s': element already exists",
320  key, field);
321  } catch(std::exception& e) {
322  serialboxFatalError(e.what());
323  }
324 }
325 
326 /*===------------------------------------------------------------------------------------------===*\
327  * Savepoint
328 \*===------------------------------------------------------------------------------------------===*/
329 
330 void serialboxFortranSavepointAddMetainfoBoolean(void* savepoint, const char* key, int value) {
331  Savepoint* sp = toSavepoint(static_cast<serialboxSavepoint_t*>(savepoint));
332  try {
333  sp->addMetainfo(key, (bool)value);
334  } catch(std::exception& e) {
335  serialboxFatalError(e.what());
336  }
337 }
338 
339 void serialboxFortranSavepointAddMetainfoInt32(void* savepoint, const char* key, int value) {
340  Savepoint* sp = toSavepoint(static_cast<serialboxSavepoint_t*>(savepoint));
341  try {
342  sp->addMetainfo(key, value);
343  } catch(std::exception& e) {
344  serialboxFatalError(e.what());
345  }
346 }
347 
348 void serialboxFortranSavepointAddMetainfoFloat32(void* savepoint, const char* key, float value) {
349  Savepoint* sp = toSavepoint(static_cast<serialboxSavepoint_t*>(savepoint));
350  try {
351  sp->addMetainfo(key, value);
352  } catch(std::exception& e) {
353  serialboxFatalError(e.what());
354  }
355 }
356 
357 void serialboxFortranSavepointAddMetainfoFloat64(void* savepoint, const char* key, double value) {
358  Savepoint* sp = toSavepoint(static_cast<serialboxSavepoint_t*>(savepoint));
359  try {
360  sp->addMetainfo(key, value);
361  } catch(std::exception& e) {
362  serialboxFatalError(e.what());
363  }
364 }
365 
366 void serialboxFortranSavepointAddMetainfoString(void* savepoint, const char* key,
367  const char* value) {
368  Savepoint* sp = toSavepoint(static_cast<serialboxSavepoint_t*>(savepoint));
369  try {
370  sp->addMetainfo(key, value);
371  } catch(std::exception& e) {
372  serialboxFatalError(e.what());
373  }
374 }
void serialboxFortranSerializerWrite(void *serializer, const void *savepoint, const char *name, void *originPtr, int istride, int jstride, int kstride, int lstride)
Wrapper for serialboxSerializerWrite.
void serialboxSerializerWrite(serialboxSerializer_t *serializer, const char *name, const serialboxSavepoint_t *savepoint, void *originPtr, const int *strides, int numStrides)
Serialize field name (given by originPtr and strides) at savepoint to disk.
Definition: Serializer.cpp:389
void serialboxFortranSerializerRegisterField(void *serializer, const char *name, int type, int bytesPerElement, int iSize, int jSize, int kSize, int lSize, int iMinusHalo, int iPlusHalo, int jMinusHalo, int jPlusHalo, int kMinusHalo, int kPlusHalo, int lMinusHalo, int lPlusHalo)
Register field within the serializer.
static int sizeOf(TypeID id)
Get size of the type.
Definition: Type.cpp:73
void serialboxSerializerGetFieldMetainfo2(const serialboxSerializer_t *serializer, const char *name, char **storedName, char **elementType, int *bytesPerElement, int *rank, int *iSize, int *jSize, int *kSize, int *lSize, int *iMinusHalo, int *iPlusHalo, int *jMinusHalo, int *jPlusHalo, int *kMinusHalo, int *kPlusHalo, int *lMinusHalo, int *lPlusHalo)
Get values of standard meta info pairs of field with name name
Definition: Serializer.cpp:328
TypeID
Type-id of types recognized by serialbox.
Definition: Type.h:55
void serialboxFortranSavepointAddMetainfoBoolean(void *savepoint, const char *key, int value)
Add a meta-information key=value pair to the savepoint
void serialboxFortranSerializerAddFieldMetainfoBoolean(void *serializer, const char *field, const char *key, int value)
Add a meta-information key=value pair to field of the serializer.
void serialboxFortranComputeStrides(void *serializer, const char *fieldname, const void *basePtr, const void *iplus1, const void *jplus1, const void *kplus1, const void *lplus1, int *istride, int *jstride, int *kstride, int *lstride)
Compute unit-strides of registered field fieldname
int serialboxSerializerAddField2(serialboxSerializer_t *serializer, const char *name, int type, int bytesPerElement, int iSize, int jSize, int kSize, int lSize, int iMinusHalo, int iPlusHalo, int jMinusHalo, int jPlusHalo, int kMinusHalo, int kPlusHalo, int lMinusHalo, int lPlusHalo)
Register field within the serializer.
Definition: Serializer.cpp:245
void serialboxFortranSerializerGetFieldHalos(const void *serializer, const char *name, int *iMinusHalo, int *iPlusHalo, int *jMinusHalo, int *jPlusHalo, int *kMinusHalo, int *kPlusHalo, int *lMinusHalo, int *lPlusHalo)
Returns the halos of the field name
serialbox::Exception exception
Exception class which stores a human-readable error description.
Definition: Exception.h:33
void serialboxFortranSerializerGetFieldDimensions(const void *serializer, const char *name, int *isize, int *jsize, int *ksize, int *lsize)
Returns the dimensions of the field name
void serialboxSerializerRead(serialboxSerializer_t *serializer, const char *name, const serialboxSavepoint_t *savepoint, void *originPtr, const int *strides, int numStrides)
Deserialize field name (given by originPtr and strides) at savepoint from disk.
Definition: Serializer.cpp:404
static std::string toString(TypeID id)
Convert to string.
Definition: Type.cpp:35
void serialboxFortranSerializerRead(void *serializer, const void *savepoint, const char *name, void *originPtr, int istride, int jstride, int kstride, int lstride)
Wrapper for serialboxSerializerRead.
void serialboxFatalError(const char *reason)
Report a fatal error.
void serialboxFortranSerializerCheckField(const void *serializer, const char *name, int *type, int *isize, int *jsize, int *ksize, int *lsize)
Perform consistency checks concerning dimensions and type of the field name
Exception class which stores a human-readable error description.
Definition: Exception.h:30
void serialboxFortranSerializerAddMetainfoBoolean(void *serializer, const char *key, int value)
Add a global meta-information key=value pair to the Serializer.
void serialboxFortranSerializerPrintDebugInfo(void *serializer)
Print debug information (i.e convert serializer to string)