Hipace
MultiBuffer.H
Go to the documentation of this file.
1 /* Copyright 2023
2  *
3  * This file is part of HiPACE++.
4  *
5  * Authors: AlexanderSinn
6  * License: BSD-3-Clause-LBNL
7  */
8 #ifndef HIPACE_MultiBuffer_H_
9 #define HIPACE_MultiBuffer_H_
10 
11 #include <AMReX_AmrCore.H>
13 #include "laser/MultiLaser.H"
14 
16 {
17 
18 public:
19 
20  // initialize MultiBuffer and open initial receive requests
21  void initialize (int nslices, int nbeams, bool buffer_on_host, bool use_laser,
22  amrex::Box laser_box, int max_leading_slices, int max_trailing_slices);
23 
24  // receive data from previous rank and unpack it into MultiBeam and MultiLaser
25  void get_data (int slice, MultiBeam& beams, MultiLaser& laser, int beam_slice);
26 
27  // pack data from MultiBeam and MultiLaser into buffer and send it to the next rank
28  void put_data (int slice, MultiBeam& beams, MultiLaser& laser, int beam_slice,
29  bool is_last_time_step);
30 
31  // receive physical time from previous rank
32  amrex::Real get_time ();
33 
34  // send physical time to next rank
35  void put_time (amrex::Real time);
36 
37  // destructor to clean up all open MPI requests
38  ~MultiBuffer();
39 
40 private:
41 
42  // to keep track of per-slice buffer location
43  enum struct memory_location {
44  nowhere,
45  pinned,
46  device
47  };
48 
49  // to keep track of per-slice MPI communication status
50  enum comm_progress : int {
63  };
64 
65  // to specify the input for get_buffer_offset
66  enum struct offset_type {
67  beam_idcpu,
68  beam_real,
69  beam_int,
70  laser,
71  total
72  };
73 
74  // struct to store per-slice data
75  struct DataNode {
76  char* m_buffer = nullptr;
77  std::size_t m_buffer_size = 0;
79  comm_progress m_progress = comm_progress::uninitialized;
80  MPI_Request m_request = MPI_REQUEST_NULL;
81  comm_progress m_metadata_progress = comm_progress::uninitialized;
82  MPI_Request m_metadata_request = MPI_REQUEST_NULL;
83  };
84 
85 #ifdef AMREX_USE_MPI
86  using storage_type = amrex::ParallelDescriptor::lull_t;
87 #else
88  using storage_type = unsigned long long[8];
89 #endif
90 
91  // round up the capacity of a buffer so there are never any alignment problems
92  static constexpr std::size_t buffer_size_roundup = alignof(amrex::Real) / alignof(int);
93 
94  // 2D array for all metadata
96  // per-slice data
98 
99  // MPI parameters
100  bool m_is_head_rank = false;
101  bool m_is_serial = true;
102  int m_rank_send_to = 0;
107  MPI_Comm m_comm = MPI_COMM_NULL;
108 
109  // general parameters
110  bool m_buffer_on_host = true;
111  int m_nslices = 0;
112  int m_nbeams = 0;
113  bool m_use_laser = false;
114  int m_laser_ncomp = 4;
116  int m_max_leading_slices = std::numeric_limits<int>::max();
117  int m_max_trailing_slices = std::numeric_limits<int>::max();
118 
119  // parameters to send physical time
120  amrex::Real m_time_send_buffer = 0.;
121  MPI_Request m_time_send_request = MPI_REQUEST_NULL;
122  bool m_time_send_started = false;
123 
124  // slice index of where to continue making async progress
125  std::array<int, comm_progress::nprogress> m_async_metadata_slice {};
126  std::array<int, comm_progress::nprogress> m_async_data_slice {};
127 
128  // helper functions to read 2D metadata array
129  std::size_t get_metadata_size ();
130  std::size_t* get_metadata_location (int slice);
131 
132  // helper functions to allocate and free buffers using the correct arena
133  void allocate_buffer (int slice);
134  void free_buffer (int slice);
135 
136  // function containing main progress loop to deal with asynchronous MPI requests
137  void make_progress (int slice, bool is_blocking, int current_slice);
138 
139  // write MultiBeam sizes into the metadata array
140  void write_metadata (int slice, MultiBeam& beams, int beam_slice);
141 
142  // helper function to get location of individual arrays inside a buffer
144  int ibeam, int comp);
145 
146  // copy gpu array into buffer at buffer_offset, either dtoh or dtod
147  void memcpy_to_buffer (int slice, std::size_t buffer_offset,
148  const void* src_ptr, std::size_t num_bytes);
149 
150  // copy buffer array at buffer_offset into gpu array, either htod or dtod
151  void memcpy_from_buffer (int slice, std::size_t buffer_offset,
152  void* dst_ptr, std::size_t num_bytes);
153 
154  // pack MultiBeam and MultiLaser into buffer
155  void pack_data (int slice, MultiBeam& beams, MultiLaser& laser, int beam_slice);
156 
157 public: // needed for ParallelFor
158 
159  // unpack MultiBeam and MultiLaser from buffer
160  void unpack_data (int slice, MultiBeam& beams, MultiLaser& laser, int beam_slice);
161 
162 };
163 
164 #endif
int MPI_Comm
int MPI_Request
Definition: MultiBeam.H:15
Definition: MultiBuffer.H:16
offset_type
Definition: MultiBuffer.H:66
amrex::ParallelDescriptor::lull_t storage_type
Definition: MultiBuffer.H:86
void memcpy_from_buffer(int slice, std::size_t buffer_offset, void *dst_ptr, std::size_t num_bytes)
Definition: MultiBuffer.cpp:578
amrex::Gpu::PinnedVector< std::size_t > m_metadata
Definition: MultiBuffer.H:95
~MultiBuffer()
Definition: MultiBuffer.cpp:108
void pack_data(int slice, MultiBeam &beams, MultiLaser &laser, int beam_slice)
Definition: MultiBuffer.cpp:593
int m_tag_time_start
Definition: MultiBuffer.H:104
int m_tag_buffer_start
Definition: MultiBuffer.H:105
std::array< int, comm_progress::nprogress > m_async_data_slice
Definition: MultiBuffer.H:126
amrex::Box m_laser_slice_box
Definition: MultiBuffer.H:115
amrex::Vector< DataNode > m_datanodes
Definition: MultiBuffer.H:97
amrex::Real m_time_send_buffer
Definition: MultiBuffer.H:120
int m_rank_receive_from
Definition: MultiBuffer.H:103
MPI_Request m_time_send_request
Definition: MultiBuffer.H:121
void allocate_buffer(int slice)
Definition: MultiBuffer.cpp:25
int m_max_trailing_slices
Definition: MultiBuffer.H:117
bool m_time_send_started
Definition: MultiBuffer.H:122
void initialize(int nslices, int nbeams, bool buffer_on_host, bool use_laser, amrex::Box laser_box, int max_leading_slices, int max_trailing_slices)
Definition: MultiBuffer.cpp:52
amrex::Real get_time()
Definition: MultiBuffer.cpp:440
std::size_t * get_metadata_location(int slice)
Definition: MultiBuffer.cpp:21
void unpack_data(int slice, MultiBeam &beams, MultiLaser &laser, int beam_slice)
Definition: MultiBuffer.cpp:643
comm_progress
Definition: MultiBuffer.H:50
@ in_use
Definition: MultiBuffer.H:61
@ received
Definition: MultiBuffer.H:58
@ sent
Definition: MultiBuffer.H:56
@ receive_started
Definition: MultiBuffer.H:57
@ sim_completed
Definition: MultiBuffer.H:52
@ async_progress_end
Definition: MultiBuffer.H:59
@ nprogress
Definition: MultiBuffer.H:62
@ ready_to_define
Definition: MultiBuffer.H:60
@ ready_to_send
Definition: MultiBuffer.H:54
@ async_progress_begin
Definition: MultiBuffer.H:53
@ uninitialized
Definition: MultiBuffer.H:51
@ send_started
Definition: MultiBuffer.H:55
int m_laser_ncomp
Definition: MultiBuffer.H:114
void get_data(int slice, MultiBeam &beams, MultiLaser &laser, int beam_slice)
Definition: MultiBuffer.cpp:323
int m_tag_metadata_start
Definition: MultiBuffer.H:106
int m_nbeams
Definition: MultiBuffer.H:112
static constexpr std::size_t buffer_size_roundup
Definition: MultiBuffer.H:92
bool m_is_head_rank
Definition: MultiBuffer.H:100
void free_buffer(int slice)
Definition: MultiBuffer.cpp:40
int m_max_leading_slices
Definition: MultiBuffer.H:116
bool m_use_laser
Definition: MultiBuffer.H:113
bool m_buffer_on_host
Definition: MultiBuffer.H:110
std::size_t get_metadata_size()
Definition: MultiBuffer.cpp:13
std::array< int, comm_progress::nprogress > m_async_metadata_slice
Definition: MultiBuffer.H:125
void memcpy_to_buffer(int slice, std::size_t buffer_offset, const void *src_ptr, std::size_t num_bytes)
Definition: MultiBuffer.cpp:563
int m_rank_send_to
Definition: MultiBuffer.H:102
MPI_Comm m_comm
Definition: MultiBuffer.H:107
void write_metadata(int slice, MultiBeam &beams, int beam_slice)
Definition: MultiBuffer.cpp:489
bool m_is_serial
Definition: MultiBuffer.H:101
void put_time(amrex::Real time)
Definition: MultiBuffer.cpp:463
int m_nslices
Definition: MultiBuffer.H:111
void put_data(int slice, MultiBeam &beams, MultiLaser &laser, int beam_slice, bool is_last_time_step)
Definition: MultiBuffer.cpp:347
void make_progress(int slice, bool is_blocking, int current_slice)
Definition: MultiBuffer.cpp:175
std::size_t get_buffer_offset(int slice, offset_type type, MultiBeam &beams, int ibeam, int comp)
Definition: MultiBuffer.cpp:503
memory_location
Definition: MultiBuffer.H:43
Definition: MultiLaser.H:99
slice
Definition: MultiLaser.H:73
type
Definition: checksumAPI.py:112
Definition: MultiBuffer.H:75
MPI_Request m_metadata_request
Definition: MultiBuffer.H:82
MPI_Request m_request
Definition: MultiBuffer.H:80
comm_progress m_progress
Definition: MultiBuffer.H:79
char * m_buffer
Definition: MultiBuffer.H:76
std::size_t m_buffer_size
Definition: MultiBuffer.H:77
memory_location m_location
Definition: MultiBuffer.H:78
comm_progress m_metadata_progress
Definition: MultiBuffer.H:81