Block-Structured AMR Software Framework
Loading...
Searching...
No Matches
AMReX_ForkJoin.H
Go to the documentation of this file.
1#ifndef AMREX_FORKJOIN_H
2#define AMREX_FORKJOIN_H
3#include <AMReX_Config.H>
4
6#include <AMReX_MultiFab.H>
7#include <utility>
8
9namespace amrex {
10
12{
13 public:
14
15 enum class Strategy {
16 single,
17 duplicate,
18 split,
19 };
20 enum class Intent { in, out, inout };
21
23 struct ComponentSet {
27 ComponentSet() = default;
28 ComponentSet(int lo_, int hi_) : lo(lo_), hi(hi_) {}
29 int lo;
30 int hi;
31 };
32
33 ForkJoin (const Vector<int> &task_rank_n);
34
35 ForkJoin (const Vector<double> &task_rank_pct);
36
37 ForkJoin (int ntasks)
38 : ForkJoin( Vector<double>(ntasks, 1.0 / ntasks) ) { }
39
40 int NTasks () const { return static_cast<int>(split_bounds.size() - 1); }
41
42 int MyTask () const { return task_me; }
43
44 bool Verbose () const { return flag_verbose; }
45
46 void SetVerbose (bool verbose_in) { flag_verbose = verbose_in; }
47
48 ComponentSet ComponentBounds(const std::string& name, int idx=0) const;
49
50 int NProcsTask (int task) const {
51 AMREX_ASSERT(task + 1 < split_bounds.size());
52 return split_bounds[task + 1] - split_bounds[task];
53 }
54
55 void reg_mf (MultiFab &mf, const std::string &name, int idx,
56 Strategy strategy, Intent intent, int owner = -1);
57
58 void reg_mf (MultiFab &mf, const std::string &name,
59 Strategy strategy, Intent intent, int owner = -1) {
60 reg_mf(mf, name, 0, strategy, intent, owner);
61 }
62
66 void reg_mf (const MultiFab &mf, const std::string &name, int idx,
67 Strategy strategy, Intent intent, int owner = -1) {
69 "const MultiFab must be registered read-only");
70 reg_mf(const_cast<MultiFab&>(mf), name, idx, strategy, intent, owner);
71 }
72 void reg_mf (const MultiFab &mf, const std::string &name,
73 Strategy strategy, Intent intent, int owner = -1) {
74 reg_mf(mf, name, 0, strategy, intent, owner);
75 }
76
77 void reg_mf_vec (const Vector<MultiFab *> &mfs, const std::string &name,
78 Strategy strategy, Intent intent, int owner = -1) {
79 data[name].reserve(mfs.size());
80 for (int i = 0; i < mfs.size(); ++i) {
81 reg_mf(*mfs[i], name, i, strategy, intent, owner);
82 }
83 }
84
86 void reg_mf_vec (const Vector<MultiFab const *> &mfs, const std::string &name,
87 Strategy strategy, Intent intent, int owner = -1) {
88 data[name].reserve(mfs.size());
89 for (int i = 0; i < mfs.size(); ++i) {
90 reg_mf(*mfs[i], name, i, strategy, intent, owner);
91 }
92 }
93
95 void modify_ngrow (const std::string &name, int idx, IntVect ngrow);
96 void modify_ngrow (const std::string &name, IntVect ngrow) {
97 modify_ngrow(name, 0, ngrow);
98 }
99
101 void modify_split (const std::string &name, int idx, Vector<ComponentSet> comp_split);
102 void modify_split (const std::string &name, Vector<ComponentSet> comp_split) {
103 modify_split(name, 0, std::move(comp_split));
104 }
105
106 // TODO: may want to de-register MFs if they change across invocations
107
108 MultiFab &get_mf (const std::string &name, int idx = 0) {
109 AMREX_ASSERT_WITH_MESSAGE(data.count(name) > 0 && idx < data[name].size(), "get_mf(): name or index not found");
110 AMREX_ASSERT(task_me >= 0 && task_me < data[name][idx].forked.size());
111 return data[name][idx].forked[task_me];
112 }
113
115 Vector<MultiFab *> get_mf_vec (const std::string &name) {
116 int dim = static_cast<int>(data.at(name).size());
117 Vector<MultiFab *> result(dim);
118 for (int idx = 0; idx < dim; ++idx) {
119 result[idx] = &get_mf(name, idx);
120 }
121 return result;
122 }
123
124 void set_task_output_dir (const std::string & dir)
125 {
126 task_output_dir = dir;
127 }
128
129 static void set_task_output_file (const std::string & filename)
130 {
132 }
133
134 template <class F>
135 void fork_join (const F &fn)
136 {
137 flag_invoked = true; // set invoked flag
138 const int io_rank = 0; // team's sub-rank 0 does IO
139 create_task_output_dir();
140 MPI_Comm task_comm = split_tasks();
141 copy_data_to_tasks(); // move data to local tasks
142 ParallelContext::push(task_comm, task_me, io_rank);
143 set_task_output_file(get_io_filename());
144 fn(*this);
146#ifdef BL_USE_MPI
147 MPI_Comm_free(&task_comm);
148#endif
149 copy_data_from_tasks(); // move local data back
150 }
151
152 private:
153
154 struct MFFork
155 {
156 MultiFab *orig = nullptr;
157 Strategy strategy;
158 Intent intent;
159 int owner_task;
160 IntVect ngrow;
161 Vector<ComponentSet> comp_split;
162 Vector<MultiFab> forked;
163
164 MFFork () = default;
165 ~MFFork () = default;
166 MFFork (const MFFork&) = delete;
167 MFFork& operator= (const MFFork&) = delete;
168 MFFork (MFFork&&) = default;
169 MFFork& operator= (MFFork&&) = default;
170 MFFork (MultiFab *omf, Strategy s, Intent i, int own,
171 const IntVect &ng,
173 : orig(omf), strategy(s), intent(i), owner_task(own), ngrow(ng), comp_split(std::move(cs)) {}
174
175 [[nodiscard]] bool empty() const { return orig == nullptr; }
176 };
177
178 bool flag_verbose = false;
179 bool flag_invoked = false;
180 Vector<int> split_bounds;
181 int task_me = -1;
182 std::map<BoxArray::RefID, Vector<std::unique_ptr<DistributionMapping>>> dms;
183 std::unordered_map<std::string, Vector<MFFork>> data;
184 std::string task_output_dir;
185
186 void init(const Vector<int> &task_rank_n);
187
192 const DistributionMapping &get_dm (const BoxArray& ba, int task_idx,
193 const DistributionMapping& dm_orig);
194
198 void copy_data_to_tasks ();
199
203 void copy_data_from_tasks ();
204
206 MPI_Comm split_tasks ();
207
209 void create_task_output_dir ();
210
212 std::string get_io_filename (bool flag_unique = false);
213};
214
215}
216
217#endif // AMREX_FORKJOIN_H
#define AMREX_ASSERT_WITH_MESSAGE(EX, MSG)
Definition AMReX_BLassert.H:37
#define AMREX_ASSERT(EX)
Definition AMReX_BLassert.H:38
Definition AMReX_ForkJoin.H:12
int NTasks() const
Definition AMReX_ForkJoin.H:40
ForkJoin(int ntasks)
Definition AMReX_ForkJoin.H:37
void fork_join(const F &fn)
Definition AMReX_ForkJoin.H:135
void reg_mf(const MultiFab &mf, const std::string &name, int idx, Strategy strategy, Intent intent, int owner=-1)
Definition AMReX_ForkJoin.H:66
Intent
Definition AMReX_ForkJoin.H:20
int NProcsTask(int task) const
Definition AMReX_ForkJoin.H:50
MultiFab & get_mf(const std::string &name, int idx=0)
Definition AMReX_ForkJoin.H:108
void reg_mf_vec(const Vector< MultiFab * > &mfs, const std::string &name, Strategy strategy, Intent intent, int owner=-1)
Definition AMReX_ForkJoin.H:77
void reg_mf(MultiFab &mf, const std::string &name, int idx, Strategy strategy, Intent intent, int owner=-1)
Definition AMReX_ForkJoin.cpp:107
Strategy
Definition AMReX_ForkJoin.H:15
@ duplicate
all tasks get a copy of whole MF
@ single
one task gets a copy of whole MF
@ split
split MF components across tasks
void modify_ngrow(const std::string &name, IntVect ngrow)
Definition AMReX_ForkJoin.H:96
void modify_ngrow(const std::string &name, int idx, IntVect ngrow)
modify the number of grow cells associated with the multifab
Definition AMReX_ForkJoin.cpp:141
void set_task_output_dir(const std::string &dir)
Definition AMReX_ForkJoin.H:124
ComponentSet ComponentBounds(const std::string &name, int idx=0) const
Definition AMReX_ForkJoin.cpp:171
void reg_mf(const MultiFab &mf, const std::string &name, Strategy strategy, Intent intent, int owner=-1)
Definition AMReX_ForkJoin.H:72
Vector< MultiFab * > get_mf_vec(const std::string &name)
vector of pointers to all MFs under a name
Definition AMReX_ForkJoin.H:115
bool Verbose() const
Definition AMReX_ForkJoin.H:44
void SetVerbose(bool verbose_in)
Definition AMReX_ForkJoin.H:46
static void set_task_output_file(const std::string &filename)
Definition AMReX_ForkJoin.H:129
void modify_split(const std::string &name, int idx, Vector< ComponentSet > comp_split)
modify how the multifab is split along components across the tasks
Definition AMReX_ForkJoin.cpp:155
void reg_mf_vec(const Vector< MultiFab const * > &mfs, const std::string &name, Strategy strategy, Intent intent, int owner=-1)
overload in case of vector of pointer to const MultiFab
Definition AMReX_ForkJoin.H:86
void reg_mf(MultiFab &mf, const std::string &name, Strategy strategy, Intent intent, int owner=-1)
Definition AMReX_ForkJoin.H:58
int MyTask() const
Definition AMReX_ForkJoin.H:42
void modify_split(const std::string &name, Vector< ComponentSet > comp_split)
Definition AMReX_ForkJoin.H:102
A collection (stored as an array) of FArrayBox objects.
Definition AMReX_MultiFab.H:40
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:28
Long size() const noexcept
Definition AMReX_Vector.H:53
void push(MPI_Comm c)
Definition AMReX_ParallelContext.H:102
void pop()
Note that it's the user's responsibility to free the MPI_Comm.
Definition AMReX_ParallelContext.H:108
void set_last_frame_ofs(const std::string &filename)
Definition AMReX_ParallelContext.H:104
int MPI_Comm
Definition AMReX_ccse-mpi.H:51
Definition AMReX_Amr.cpp:49
if strategy == split, use this to specify how to split components across tasks
Definition AMReX_ForkJoin.H:23
int lo
inclusive bound
Definition AMReX_ForkJoin.H:29
ComponentSet(int lo_, int hi_)
Definition AMReX_ForkJoin.H:28
int hi
exclusive bound
Definition AMReX_ForkJoin.H:30