Chi-Tech
sweepscheduler_dog.cc
Go to the documentation of this file.
1#include "sweepscheduler.h"
2
4
5#include "chi_runtime.h"
6#include "chi_mpi.h"
7#include "chi_log.h"
8
9#include <sstream>
10#include <algorithm>
11
12// ###################################################################
13/**Initializes the Depth-Of-Graph algorithm.*/
15{
16 //================================================== Load all anglesets
17 // in preperation for
18 // sorting
19 //======================================== Loop over angleset groups
20 for (size_t q = 0; q < angle_agg_.angle_set_groups.size(); q++)
21 {
22 TAngleSetGroup& angleset_group = angle_agg_.angle_set_groups[q];
23
24 //================================= Loop over anglesets in group
25 size_t num_anglesets = angleset_group.AngleSets().size();
26 for (size_t as = 0; as < num_anglesets; as++)
27 {
28 auto angleset = angleset_group.AngleSets()[as];
29 const auto& spds =
30 dynamic_cast<const SPDS_AdamsAdamsHawkins&>(angleset->GetSPDS());
31
32 const TLEVELED_GRAPH& leveled_graph = spds.GetGlobalSweepPlanes();
33
34 //========================== Find location depth
35 int loc_depth = -1;
36 for (size_t level = 0; level < leveled_graph.size(); level++)
37 {
38 for (size_t index = 0; index < leveled_graph[level].item_id.size();
39 index++)
40 {
41 if (leveled_graph[level].item_id[index] == Chi::mpi.location_id)
42 {
43 loc_depth = static_cast<int>(leveled_graph.size() - level);
44 break;
45 }
46 } // for locations in plane
47 } // for sweep planes
48
49 //========================== Set up rule values
50 if (loc_depth >= 0)
51 {
52 RULE_VALUES new_rule_vals(angleset);
53 new_rule_vals.depth_of_graph = loc_depth;
54 new_rule_vals.set_index = as + q * num_anglesets;
55
56 const auto& omega = spds.Omega();
57 new_rule_vals.sign_of_omegax = (omega.x >= 0) ? 2 : 1;
58 new_rule_vals.sign_of_omegay = (omega.y >= 0) ? 2 : 1;
59 new_rule_vals.sign_of_omegaz = (omega.z >= 0) ? 2 : 1;
60
61 rule_values_.push_back(new_rule_vals);
62 }
63 else
64 {
66 << "Location depth not found in Depth-Of-Graph algorithm.";
67 Chi::Exit(EXIT_FAILURE);
68 }
69
70 } // for anglesets
71 } // for quadrants/anglesetgroups
72
73 //================================================== Init sort functions
74 struct
75 {
76 bool operator()(const RULE_VALUES& a, const RULE_VALUES& b)
77 {
78 return a.depth_of_graph > b.depth_of_graph;
79 }
80 } compare_D;
81
82 struct
83 {
84 bool operator()(const RULE_VALUES& a, const RULE_VALUES& b)
85 {
86 return (a.depth_of_graph == b.depth_of_graph) and
88 }
89 } compare_omega_x;
90
91 struct
92 {
93 bool operator()(const RULE_VALUES& a, const RULE_VALUES& b)
94 {
95 return (a.depth_of_graph == b.depth_of_graph) and
98 }
99 } compare_omega_y;
100
101 struct
102 {
103 bool operator()(const RULE_VALUES& a, const RULE_VALUES& b)
104 {
105 return (a.depth_of_graph == b.depth_of_graph) and
106 (a.sign_of_omegax == b.sign_of_omegax) and
107 (a.sign_of_omegay == b.sign_of_omegay) and
109 }
110 } compare_omega_z;
111
112 //================================================== Sort
113 std::stable_sort(rule_values_.begin(), rule_values_.end(), compare_D);
114 std::stable_sort(rule_values_.begin(), rule_values_.end(), compare_omega_x);
115 std::stable_sort(rule_values_.begin(), rule_values_.end(), compare_omega_y);
116 std::stable_sort(rule_values_.begin(), rule_values_.end(), compare_omega_z);
117}
118
119// ###################################################################
120/**Executes the Depth-Of-Graph algorithm.*/
122 SweepChunk& sweep_chunk)
123{
124 typedef ExecutionPermission ExePerm;
125 typedef AngleSetStatus Status;
126
128
129 auto ev_info =
130 std::make_shared<chi::ChiLog::EventInfo>(std::string("Sweep initiated"));
131
133 sweep_event_tag_, chi::ChiLog::EventType::SINGLE_OCCURRENCE, ev_info);
134
135 //==================================================== Loop till done
136 bool finished = false;
137 size_t scheduled_angleset = 0;
138 while (!finished)
139 {
140 finished = true;
141 for (auto& rule_value : rule_values_)
142 {
143 auto angleset = rule_value.angle_set;
144
145 //=============================== Query angleset status
146 // Status will here be one of the following:
147 // - RECEIVING.
148 // Meaning it is either waiting for messages or actively receiving it
149 // - READY_TO_EXECUTE.
150 // Meaning it has received all upstream data and can be executed
151 // - FINISHED.
152 // Meaning the angleset has executed its sweep chunk
153 Status status = angleset->AngleSetAdvance(sweep_chunk,
154 sweep_timing_events_tag_,
155 ExePerm::NO_EXEC_IF_READY);
156
157 //=============================== Execute if ready and allowed
158 // If this angleset is the one scheduled to run
159 // and it is ready then it will be given permission
160 if (status == Status::READY_TO_EXECUTE)
161 {
162 std::stringstream message_i;
163 message_i << "Angleset " << angleset->GetID() << " executed on location "
165
166 auto ev_info_i =
167 std::make_shared<chi::ChiLog::EventInfo>(message_i.str());
168
169 Chi::log.LogEvent(sweep_event_tag_,
171 ev_info_i);
172
173 status = angleset->AngleSetAdvance(sweep_chunk,
174 sweep_timing_events_tag_,
175 ExePerm::EXECUTE);
176
177 std::stringstream message_f;
178 message_f << "Angleset " << angleset->GetID() << " finished on location "
180
181 auto ev_info_f =
182 std::make_shared<chi::ChiLog::EventInfo>(message_f.str());
183
184 Chi::log.LogEvent(sweep_event_tag_,
186 ev_info_f);
187
188 scheduled_angleset++; // Schedule the next angleset
189 }
190
191 if (status != Status::FINISHED) finished = false;
192 } // for each angleset rule
193 } // while not finished
194
195 //================================================== Receive delayed data
197 bool received_delayed_data = false;
198 while (not received_delayed_data)
199 {
200 received_delayed_data = true;
201
202 for (auto& angle_set_group : angle_agg_.angle_set_groups)
203 for (auto& angle_set : angle_set_group.AngleSets())
204 {
205 if (angle_set->FlushSendBuffers() == Status::MESSAGES_PENDING)
206 received_delayed_data = false;
207
208 if (not angle_set->ReceiveDelayedData())
209 received_delayed_data = false;
210 }
211 }
212
213 //================================================== Reset all
214 for (auto& angle_set_group : angle_agg_.angle_set_groups)
215 for (auto& angle_set : angle_set_group.AngleSets())
216 angle_set->ResetSweepBuffers();
217
218 for (auto& [bid, bndry] : angle_agg_.sim_boundaries)
219 {
221 {
222 auto rbndry = std::static_pointer_cast<
224 rbndry->ResetAnglesReadyStatus();
225 }
226 }
227
229}
static void Exit(int error_code)
Definition: chi_runtime.cc:342
static chi::ChiLog & log
Definition: chi_runtime.h:81
static chi::MPI_Info & mpi
Definition: chi_runtime.h:78
LogStream LogAllError()
Definition: chi_log.h:239
@ SINGLE_OCCURRENCE
Signals a single occurrence.
@ EVENT_BEGIN
Signals the begin of an event.
@ EVENT_END
Signals the end of an event.
void LogEvent(size_t ev_tag, EventType ev_type, const std::shared_ptr< EventInfo > &ev_info)
Definition: chi_log.cc:204
void Barrier() const
Definition: mpi_info.cc:38
const int & location_id
Current process rank.
Definition: mpi_info.h:26
std::vector< AngleSetGroup > angle_set_groups
std::vector< std::shared_ptr< AngleSet > > & AngleSets()
Definition: anglesetgroup.h:11
const std::vector< STDG > & GetGlobalSweepPlanes() const
std::vector< RULE_VALUES > rule_values_
void ScheduleAlgoDOG(SweepChunk &sweep_chunk)
@ REFLECTING
Reflecting boundary condition about a normal.
std::vector< TGSPO > TLEVELED_GRAPH