XGCa
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
xgc_io.hpp
Go to the documentation of this file.
1 #ifndef XGC_IO_HPP
2 #define XGC_IO_HPP
3 #include "space_settings.hpp"
4 
5 #ifdef ADIOS2
6 #include "adios2.hpp"
7 // If ADIOS2 is being used, XGC_IO_Stream is ADIOS2Stream
9 typedef adios2::Mode XGC_IO_Mode;
10 #else
11 // If ADIOS2 is not being used, spoof IO since there is currently no alternative
12 enum class XGC_IO_Mode{
13 Write,
14 Append,
15 Read,
17 };
18 
20 public:
22  XGC_IO_Stream(const std::string &IOName){}
23 
24  void Init(const std::string &IOName){}
25  void Open(const std::string &StreamName, const XGC_IO_Mode mode){}
26 #ifdef USE_MPI
27  void Open(const std::string &StreamName, const XGC_IO_Mode mode, const MPI_Comm &comm){}
28 #endif
29  void Close(){}
30 };
31 #endif
32 
33 // Returns an unmanaged view wrapping the input scalar
34 template<typename T>
35 inline View<T*, HostType, Kokkos::MemoryTraits<Kokkos::Unmanaged>> scalar_view_wrap(T& scalar){
36  return View<T*, HostType, Kokkos::MemoryTraits<Kokkos::Unmanaged>>(&scalar, 1);
37 }
38 
39 struct IOData{
40 #ifdef ADIOS2
41  // These virtual functions must be defined in derived classes
42  virtual void adios_def_and_shape(const ADIOS2Stream& stream) const = 0;
43  virtual void adios_put(const ADIOS2Stream& stream) const = 0;
44  virtual void adios_get(const ADIOS2Stream& stream) = 0;
45 #endif
46  virtual ~IOData(){}
47 };
48 
49 // IOScalar is a helper struct to handle an scalar being written/read with ADIOS2
50 template<class T>
51 struct IOScalar : public IOData {
52  using value_type = T;
53  std::string name;
57 
58  // Input value is not const; assign address
59  IOScalar(const std::string& name_in, T& value_in)
60  : name(name_in),
61  var_is_const(false),
62  value_addr(&value_in),
63  value(value_in){}
64 
65  // Input value is const; assign value
66  IOScalar(const std::string& name_in, const T& value_in)
67  : name(name_in),
68  var_is_const(true),
69  value(value_in){}
70 
71 #ifdef ADIOS2
72  void adios_def_and_shape(const ADIOS2Stream& stream) const {
73  if(!stream.io->InquireVariable<T>(name)){
74  stream.io->DefineVariable<T>(name);
75  }
76  }
77 
78  void adios_put(const ADIOS2Stream& stream) const {
79  stream.engine->Put(name, value);
80  }
81 
82  void adios_get(const ADIOS2Stream& stream) {
83  if(var_is_const) printf("\nError: Tried to read into const variable\n"); // Should be compiletime check?
84  else stream.engine->Get(name, *value_addr);
85  }
86 #endif
87 };
88 
89 // The purpose of this struct is to be able to pass types other than long long int/size_t into the adios2::Dims initialization.
90 struct UpcastVector {
91  std::vector<size_t> vec;
92 
93  UpcastVector() = default;
94 
95  template <typename... Args>
96  UpcastVector(Args... args) {
97  addValues(args...);
98  }
99 
100  template <typename First, typename... Rest>
101  void addValues(First first, Rest... rest) {
102  vec.push_back(static_cast<size_t>(first));
103  if constexpr (sizeof...(rest) > 0) {
104  addValues(rest...);
105  }
106  }
107 };
108 
109 
110 // IOArray is a helper struct to represent an array being written/read with ADIOS2
111 template<class T>
112 struct IOArray : public IOData {
113  using view_type = T;
114  using dim_type = std::vector<size_t>;
115  std::string name;
117 
118  // These are std::vector<size_t>
122 
123  // Dims arguments are implicitly converted to size_t
124  // If the view has fewer dimensions than full_size and offsets, pad with outer dimensions of size 1, i.e. assume that
125  // the intention is for the data to be written/read contiguously.
126  IOArray(const std::string& name_in, const T& view_in, const UpcastVector& full_size_in, const UpcastVector& offsets_in)
127  : name(name_in),
128  view(view_in), // shallow copy of view
129  full_size(full_size_in.vec),
130  offsets(offsets_in.vec),
131  size(full_size.size()) // size needs to have the same length (i.e. refer to the same number of dimensions) as full_size
132  {
133  // If the input view has fewer dimensions than the global view, treat the outermost dimensions as size 1
134  int dim_offset = size.size() - T::rank;
135  // Write the dimensions of the view into size
136  for(int i=0; i<size.size(); i++){
137  if(i - dim_offset >= 0){
138  size[i] = view.extent(i - dim_offset);
139  }else{
140  size[i] = 1; // Outer dimension doesn't exist, set it to 1
141  }
142  }
143  }
144 
145  // Constructor without full size or offset --> full_size = size, offset = 0
146  IOArray(const std::string& name_in, const T& view_in)
147  : name(name_in),
148  view(view_in), // shallow copy of view
149  full_size(T::rank),
150  offsets(T::rank),
151  size(T::rank)
152  {
153  // Write the dimensions of the view into size
154  for(int i=0; i<size.size(); i++){
155  size[i] = view.extent(i);
156 
157  // full_size = size, offsets are 0
158  full_size[i] = size[i];
159  offsets[i] = 0;
160  }
161  }
162 #ifdef ADIOS2
163  void adios_def_and_shape(const ADIOS2Stream& stream) const {
164  auto TAG = stream.io->InquireVariable<typename T::value_type>(name);
165  if(!TAG){
166  TAG = stream.io->DefineVariable<typename T::value_type>(name, full_size, offsets, size);
167  }else{
168  TAG.SetShape(full_size);
169  }
170  }
171 
172  void adios_put(const ADIOS2Stream& stream) const {
173  auto TAG = stream.io->InquireVariable<typename T::value_type>(name);
174  TAG.SetSelection({offsets, size});
175  stream.engine->Put<typename T::value_type>(TAG, view.data(), adios2::Mode::Sync);
176  }
177 
178  void adios_get(const ADIOS2Stream& stream) {
179  auto TAG = stream.io->InquireVariable<typename T::value_type>(name);
180  TAG.SetSelection({offsets, size});
181  stream.engine->Get<typename T::value_type>(TAG, view.data());
182  }
183 #endif
184 };
185 
186 /* This class contains a vector of data ready to be written/read with ADIOS2 */
187 class XGC_IO{
188  std::vector<std::unique_ptr<IOData>> io_data;
189 
190  public:
191 
192  // Adds a single new entry to the data vector
193  template<class T>
194  void add(const T& new_data){
195  io_data.push_back(std::make_unique<T>(new_data));
196  }
197 
198  // Adds an unspecified number of entries to the data vector
199  template<class T, class... Ts>
200  void add(const T& new_data, const Ts&... new_data_rest){
201  add(new_data);
202  add(new_data_rest...);
203  }
204 
205  // Writes the data to the stream
206  void write(const XGC_IO_Stream& stream) const{
207 #ifdef ADIOS2
208  // Define and shape all data
209  for(int i=0; i<io_data.size(); i++)
210  io_data[i]->adios_def_and_shape(stream);
211 
212  // Stage all data for writing
213  for(int i=0; i<io_data.size(); i++)
214  io_data[i]->adios_put(stream);
215 
216  // Perform puts
217  stream.engine->PerformPuts();
218 #endif
219  }
220 
221  // Reads the data from the stream
222  void read(const XGC_IO_Stream& stream) {
223 #ifdef ADIOS2
224  // Stage all data for reading
225  for(int i=0; i<io_data.size(); i++)
226  io_data[i]->adios_get(stream);
227 
228  // Perform gets
229  stream.engine->PerformGets();
230 #endif
231  }
232 };
233 
234 #endif
Definition: xgc_io.hpp:90
void write(const XGC_IO_Stream &stream) const
Definition: xgc_io.hpp:206
void Open(const std::string &StreamName, const XGC_IO_Mode mode)
Definition: xgc_io.hpp:25
IOScalar(const std::string &name_in, T &value_in)
Definition: xgc_io.hpp:59
Definition: xgc_io.hpp:39
Definition: xgc_io.hpp:187
dim_type size
Definition: xgc_io.hpp:121
dim_type offsets
Definition: xgc_io.hpp:120
std::vector< std::unique_ptr< IOData > > io_data
Definition: xgc_io.hpp:188
std::vector< size_t > vec
Definition: xgc_io.hpp:91
IOScalar(const std::string &name_in, const T &value_in)
Definition: xgc_io.hpp:66
Definition: xgc_io.hpp:51
void read(const XGC_IO_Stream &stream)
Definition: xgc_io.hpp:222
IOArray(const std::string &name_in, const T &view_in, const UpcastVector &full_size_in, const UpcastVector &offsets_in)
Definition: xgc_io.hpp:126
XGC_IO_Stream()
Definition: xgc_io.hpp:21
bool var_is_const
Definition: xgc_io.hpp:56
void add(const T &new_data)
Definition: xgc_io.hpp:194
std::string name
Definition: xgc_io.hpp:53
void addValues(First first, Rest...rest)
Definition: xgc_io.hpp:101
virtual ~IOData()
Definition: xgc_io.hpp:46
T view_type
Definition: xgc_io.hpp:113
value_type value
Definition: xgc_io.hpp:55
View< T *, HostType, Kokkos::MemoryTraits< Kokkos::Unmanaged > > scalar_view_wrap(T &scalar)
Definition: xgc_io.hpp:35
Definition: xgc_io.hpp:112
UpcastVector(Args...args)
Definition: xgc_io.hpp:96
EnginePtr engine
Definition: adios2.hpp:30
Definition: adios2.hpp:26
UpcastVector()=default
std::vector< size_t > dim_type
Definition: xgc_io.hpp:114
XGC_IO_Stream(const std::string &IOName)
Definition: xgc_io.hpp:22
void add(const T &new_data, const Ts &...new_data_rest)
Definition: xgc_io.hpp:200
Definition: xgc_io.hpp:19
XGC_IO_Mode
Definition: xgc_io.hpp:12
IOArray(const std::string &name_in, const T &view_in)
Definition: xgc_io.hpp:146
std::string name
Definition: xgc_io.hpp:115
IOPtr io
Definition: adios2.hpp:29
void Close()
Definition: xgc_io.hpp:29
T value_type
Definition: xgc_io.hpp:52
void Init(const std::string &IOName)
Definition: xgc_io.hpp:24
view_type view
Definition: xgc_io.hpp:116
value_type * value_addr
Definition: xgc_io.hpp:54
dim_type full_size
Definition: xgc_io.hpp:119