fpmas 1.6
dist_move_algo.h
Go to the documentation of this file.
1#ifndef FPMAS_DIST_MOVE_ALGO_H
2#define FPMAS_DIST_MOVE_ALGO_H
3
9#include "../model.h"
10
11namespace fpmas { namespace model {
31 template<typename RangeType, unsigned int MaxRangeSize, typename CellType>
33 private:
34 std::size_t _step;
35 std::size_t max_step;
36
37 public:
45 static const RangeType range(MaxRangeSize);
46 max_step = range.radius(nullptr);
47 }
48
52 void init(
55 std::vector<CellType*>) override {
56 _step = 0;
57 }
58
62 void step() override {
63 _step++;
64 }
65
72 bool end() override {
73 return _step >= max_step;
74 }
75 };
76
98 template<typename CellType>
100 private:
101 std::size_t _step;
102 std::size_t max_step;
103 public:
112 void init(
114 std::vector<api::model::SpatialAgent<CellType>*> agents,
115 std::vector<CellType*>) override {
116 std::size_t local_max = 0;
117 for(auto agent : agents) {
118 std::size_t radius = std::max(
119 agent->mobilityRange().radius(agent->locationCell()),
120 agent->perceptionRange().radius(agent->locationCell())
121 );
122 if(radius > local_max)
123 local_max = radius;
124 }
126 std::vector<std::size_t> local_max_list = mpi.allGather(local_max);
127 this->max_step = *std::max_element(local_max_list.begin(), local_max_list.end());
128
129 _step = 0;
130 }
131
132 void step() override {
133 _step++;
134 }
135 bool end() override {
136 return _step >= max_step;
137 }
138 };
139
140
144 template<typename CellType>
146 private:
147 class AlgoTask : public scheduler::TaskBase<api::scheduler::Task> {
148 private:
149 typedef api::model::CellBehavior CellBehavior;
150 typedef api::model::SpatialAgentBehavior AgentBehavior;
151
152 DistributedMoveAlgorithm& dist_move_algo;
153
154 public:
155 AlgoTask(DistributedMoveAlgorithm& dist_move_algo)
156 : dist_move_algo(dist_move_algo) {}
157
161 void run() override;
162 };
163
165 api::model::AgentGroup& move_agent_group;
166 api::model::AgentGroup& cell_group;
168
169 AlgoTask algo_task;
170 scheduler::Job algo_job;
171
172 public:
178 api::model::AgentGroup& move_agent_group,
179 api::model::AgentGroup& cell_group,
181 ) :
182 model(model), move_agent_group(move_agent_group),
183 cell_group(cell_group), end(end), algo_task(*this) {
184 algo_job.add(algo_task);
185 }
186
190 api::scheduler::JobList jobs() const override {
191 return {algo_job};
192 }
193
195 }
196 };
197
198 template<typename CellType>
199 void DistributedMoveAlgorithm<CellType>::AlgoTask::run() {
200 FPMAS_LOGD(this->dist_move_algo.model.getMpiCommunicator().getRank(),
201 "DMA", "Running DistributedMoveAlgorithm...", "");
202 using api::model::SpatialAgent;
203
204
205 std::vector<SpatialAgent<CellType>*> agents;
206 for(auto agent : dist_move_algo.move_agent_group.localAgents()) {
207 // The algorithm is only applied to agents that updated their
208 // location since the last DistributedMoveAlgorithm execution
209 if(agent->node()->getOutgoingEdges(
210 api::model::SpatialModelLayers::NEW_LOCATION).size() > 0)
211 agents.push_back(
212 static_cast<SpatialAgent<CellType>*>(agent));
213 }
214
215 // Agents to which the algorithm is NOT applied might still
216 // perceive moving agent: those perceptions are obsolete, but
217 // might not have been removed in the
218 // SpatialAgent::updateLocation() method.
219 for(auto agent : agents) {
220 for(auto perceiver : agent->node()->getIncomingEdges(fpmas::api::model::PERCEPTION)) {
221 dist_move_algo.model.graph().unlink(perceiver);
222 }
223 }
224 // Commits unlinks
225 dist_move_algo.model.graph()
226 .synchronizationMode().getSyncLinker().synchronize();
227
228 std::vector<CellType*> cells;
229 for(auto cell : dist_move_algo.cell_group.localAgents()) {
230 cells.push_back(static_cast<CellType*>(cell));
231 // Initializes all cells. Eventually initializes cell
232 // bufferedSuccessors().
233 cells.back()->init();
234 // Synchronizes the cell mutex. In GlobalGhostMode, this
235 // notably stores cell bufferedSuccessors() into the ghost
236 // copy, so that following ReadGuards have a consistent
237 // behavior.
238 cells.back()->node()->mutex()->synchronize();
239 }
240
241 // Initializes the generic end condition
242 dist_move_algo.end.init(
243 dist_move_algo.model.getMpiCommunicator(),
244 agents, cells
245 );
246
247 // Assumed to loop until the mobility and
248 // perception fields of all agents are up to
249 // date
250 while(!dist_move_algo.end.end()) {
251 for(auto cell : cells) {
252 // Grows mobility and perception fields
253 cell->handleNewLocation();
254 cell->handleMove();
255 cell->handlePerceive();
256 }
257
258 // Synchronizes new links
259 dist_move_algo.model.graph()
260 .synchronizationMode().getSyncLinker().synchronize();
261
262 // Synchronizes only newly imported cells
263 dist_move_algo.model.graph()
264 .synchronize(
265 dist_move_algo.model.graph().getUnsyncNodes(), false
266 );
267
268 for(auto agent : agents) {
269 // Crops and build mobility and
270 // perception fields
271 agent->handleNewMove();
272 agent->handleNewPerceive();
273 }
274 // No new nodes can be imported in the previous step (since
275 // edges are only replaced / removed), so a link
276 // synchronization is enough
277 dist_move_algo.model.graph()
278 .synchronizationMode().getSyncLinker().synchronize();
279
280 dist_move_algo.end.step();
281 }
282 for(auto cell : cells) {
283 // Update agent perceptions (creates
284 // PERCEPTION links)
285 cell->updatePerceptions(dist_move_algo.move_agent_group);
286 }
287 // Synchronizes perception links
288 dist_move_algo.model.graph()
289 .synchronizationMode().getSyncLinker().synchronize();
290
291 // Synchronizes data of DISTANT agents that might have been created
292 // when updating perceptions
293 dist_move_algo.model.graph()
294 .synchronize(
295 dist_move_algo.model.graph().getUnsyncNodes(), false
296 );
297
298 FPMAS_LOGD(this->dist_move_algo.model.getMpiCommunicator().getRank(),
299 "DMA", "Done.", "");
300 }
301}}
302#endif
Definition: communication.h:251
Definition: model.h:547
Definition: spatial_model.h:32
Definition: spatial_model.h:425
Definition: spatial_model.h:376
Definition: spatial_model.h:185
Definition: spatial_model.h:234
std::vector< T > allGather(const T &) override
Definition: communication.h:492
Definition: dist_move_algo.h:145
DistributedMoveAlgorithm(api::model::SpatialModel< CellType > &model, api::model::AgentGroup &move_agent_group, api::model::AgentGroup &cell_group, api::model::EndCondition< CellType > &end)
Definition: dist_move_algo.h:176
api::scheduler::JobList jobs() const override
Definition: dist_move_algo.h:190
Definition: dist_move_algo.h:99
bool end() override
Definition: dist_move_algo.h:135
void step() override
Definition: dist_move_algo.h:132
void init(api::communication::MpiCommunicator &comm, std::vector< api::model::SpatialAgent< CellType > * > agents, std::vector< CellType * >) override
Definition: dist_move_algo.h:112
Definition: dist_move_algo.h:32
void init(api::communication::MpiCommunicator &, std::vector< api::model::SpatialAgent< CellType > * >, std::vector< CellType * >) override
Definition: dist_move_algo.h:52
StaticEndCondition()
Definition: dist_move_algo.h:44
bool end() override
Definition: dist_move_algo.h:72
void step() override
Definition: dist_move_algo.h:62
Definition: scheduler.h:169
void add(api::scheduler::Task &) override
Definition: scheduler.cpp:38
Definition: scheduler.h:33
std::vector< std::reference_wrapper< const Job > > JobList
Definition: scheduler.h:215
Definition: fpmas.cpp:3
Definition: communication.h:585