Hipace
InsituUtil.H
Go to the documentation of this file.
1 /* Copyright 2022
2  *
3  * This file is part of HiPACE++.
4  *
5  * Authors: AlexanderSinn
6  * License: BSD-3-Clause-LBNL
7  */
8 #ifndef HIPACE_INSITUUTIL_H_
9 #define HIPACE_INSITUUTIL_H_
10 
11 #include <AMReX_AmrCore.H>
12 #include <fstream>
13 #include <iostream>
14 #include <sstream>
15 #include <string>
16 #include <type_traits>
17 #include <vector>
18 
19 namespace insitu_utils
20 {
21 
22 // generate NumPy structured datatypes, both JSON describing the type and binary data of the type
23 struct DataNode {
24  std::string m_name; // name of a field
25  std::string m_format; // NumPy simple datatype
26  const char * m_data_location; // pointer to write binary data
27  std::size_t m_data_size; // size in bytes to write binary data
28  amrex::Vector<DataNode> m_structured_format; // used if this node contains a structured datatype
29 
30  // constructor for nodes containing a simple datatype
31  template<class T>
32  DataNode (const std::string& name, const T* data, std::size_t size = 1) : m_name{name} {
33  std::string type_letter = "";
34  if (std::is_integral_v<T> && std::is_signed_v<T>) type_letter = "i"; // int
35  else if (std::is_integral_v<T> && std::is_unsigned_v<T>) type_letter = "u"; // unsiged int
36  else if (std::is_same_v<T, amrex::GpuComplex<amrex::Real>>) type_letter = "c"; // complex
37  else if (std::is_floating_point_v<T>) type_letter = "f"; // float, double
38  else amrex::Abort("DataNode (): unknown type T");
39 
40  // "(size,)" for sub-arrays, "<" for little-endian
41  m_format = (size > 1 ? "(" + std::to_string(size) + ",)" : "")
42  + "<" + type_letter + std::to_string(sizeof(T));
43  m_data_location = reinterpret_cast<const char *>(data);
44  m_data_size = sizeof(T) * size;
45  }
46 
47  // constructor for nodes containing a structured datatype
48  DataNode (const std::string& name, const amrex::Vector<DataNode>& structured_format)
49  : m_name{name}, m_data_location{nullptr}, m_structured_format{structured_format} {}
50 };
51 
52 // write JSON header describing the datatype
53 inline void write_header (const amrex::Vector<DataNode>& nodes, std::ofstream& ofs,
54  const std::string& indent = "") {
55  //{
56  // "names": [
57  // ... list of names (strings)
58  // ],
59  // "formats": [
60  // ... list of datatypes (strings or another structured datatype, same as this)
61  // ]
62  //}
63  ofs << indent << "{\n" << indent << " \"names\": [\n";
64  for (int i=0; i<nodes.size(); ++i) {
65  ofs << indent << " \"" << nodes[i].m_name << "\"" << (i+1==nodes.size()?"\n":",\n");
66  }
67  ofs << indent << " ],\n" << indent << " \"formats\": [\n";
68  for (int i=0; i<nodes.size(); ++i) {
69  if (nodes[i].m_data_location) {
70  ofs << indent << " \"" << nodes[i].m_format << "\"";
71  } else {
72  // recursive call for nested structured datatypes
73  write_header(nodes[i].m_structured_format, ofs, " ");
74  }
75  ofs << (i+1==nodes.size()?"\n":",\n");
76  }
77  ofs << indent << " ]\n" << indent << "}";
78 }
79 
80 // write binary data in the order of the structured datatype
81 inline void write_data (const amrex::Vector<DataNode>& nodes, std::ofstream& ofs) {
82  for (auto& dn : nodes) {
83  if (dn.m_data_location) {
84  ofs.write(dn.m_data_location, dn.m_data_size);
85  } else {
86  // recursive call for nested structured datatypes
87  write_data(dn.m_structured_format, ofs);
88  }
89  }
90 }
91 
92 }
93 
94 #endif
Long size() const noexcept
int i
Definition: MakeOpenBoundary.py:152
AMREX_GPU_HOST_DEVICE Long size(T const &b) noexcept
void Abort(const std::string &msg)
Definition: InsituUtil.H:20
void write_header(const amrex::Vector< DataNode > &nodes, std::ofstream &ofs, const std::string &indent="")
Definition: InsituUtil.H:53
void write_data(const amrex::Vector< DataNode > &nodes, std::ofstream &ofs)
Definition: InsituUtil.H:81
Definition: InsituUtil.H:23
std::size_t m_data_size
Definition: InsituUtil.H:27
const char * m_data_location
Definition: InsituUtil.H:26
std::string m_format
Definition: InsituUtil.H:25
std::string m_name
Definition: InsituUtil.H:24
amrex::Vector< DataNode > m_structured_format
Definition: InsituUtil.H:28
DataNode(const std::string &name, const amrex::Vector< DataNode > &structured_format)
Definition: InsituUtil.H:48
DataNode(const std::string &name, const T *data, std::size_t size=1)
Definition: InsituUtil.H:32