fpmas-metamodel 1.0
Loading...
Searching...
No Matches
metamodel.h
Go to the documentation of this file.
1#pragma once
2
3#include "fpmas/model/spatial/graph_builder.h"
4
5#include "output.h"
6#include "dot.h"
7#include "probe.h"
8
18 public:
22 virtual std::string getName() const = 0;
26 virtual fpmas::api::model::Model& getModel() = 0;
30 virtual fpmas::api::model::AgentGroup& cellGroup() = 0;
34 virtual fpmas::api::model::AgentGroup& agentGroup() = 0;
38 virtual DotOutput& getDotOutput() = 0;
39
43 virtual BasicMetaModel* init() = 0;
47 virtual void run() = 0;
48
49 virtual ~BasicMetaModel() {
50 }
51};
52
63template<typename BaseModel, typename AgentType>
64class MetaModel : public BasicMetaModel {
65 private:
66 typedef typename BaseModel::CellType CellType;
67
68 // Cell behaviors
69 fpmas::model::IdleBehavior idle_behavior;
70 Behavior<MetaCell> cell_update_edge_weights_behavior {
72 };
73 Behavior<MetaCell> cell_read_all_cell_behavior {
75 };
76 Behavior<MetaCell> cell_write_all_cell_behavior {
78 };
79 Behavior<MetaCell> cell_read_one_cell_behavior {
81 };
82 Behavior<MetaCell> cell_write_one_cell_behavior {
84 };
85 Behavior<MetaCell> cell_read_all_write_one_cell_behavior {
87 };
88 Behavior<MetaCell> cell_read_all_write_all_cell_behavior {
90 };
91
92 // Agent behaviors
93 Behavior<AgentType> create_relations_from_neighborhood {
94 &AgentType::create_relations_from_neighborhood
95 };
96 Behavior<AgentType> create_relations_from_contacts {
97 &AgentType::create_relations_from_contacts
98 };
99 Behavior<AgentType> handle_new_contacts {
100 &AgentType::handle_new_contacts
101 };
102 Behavior<AgentType> move_behavior {
103 &AgentType::move
104 };
105
106 fpmas::scheduler::detail::LambdaTask sync_graph_task {
107 [this] () {this->model.graph().synchronize();}
108 };
109 fpmas::scheduler::Job sync_graph {{sync_graph_task}};
110
111 protected:
115 BaseModel model;
116
117 private:
118 std::string name;
119 fpmas::utils::perf::Monitor monitor;
120
121 fpmas::utils::perf::Probe lb_algorithm_probe {"LB_ALGORITHM"};
122 fpmas::utils::perf::Probe sync_probe {"SYNC"};
123 fpmas::utils::perf::Probe graph_balance_probe {"GRAPH_BALANCE"};
124
125 GraphBalanceProbe graph_balance_probe_job;
126 SyncProbeTask sync_probe_task;
127
128 MetaModelCsvOutput csv_output;
129 CellsLocationOutput cells_location_output;
130 CellsUtilityOutput cells_utility_output;
131 AgentsOutput agents_output;
132 DotOutput dot_output;
133 ModelConfig config;
134
135 protected:
141 virtual void buildCells(const ModelConfig& config) = 0;
148 virtual void buildAgents(const ModelConfig& config) = 0;
149
150 public:
164 MetaModel(
165 std::string name, ModelConfig config,
166 fpmas::api::scheduler::Scheduler& scheduler,
167 fpmas::api::runtime::Runtime& runtime,
168 fpmas::api::model::LoadBalancing& lb_algorithm,
169 fpmas::scheduler::TimeStep lb_period
170 );
171
172 // BasicMetaModel implementation //
173
175
176 void run() override {
177 model.runtime().run(config.num_steps);
178 }
179
180 std::string getName() const override {
181 return name;
182 }
183
184 fpmas::api::model::Model& getModel() override {
185 return model;
186 }
187
188 fpmas::api::model::AgentGroup& cellGroup() override {
189 return model.cellGroup();
190 }
191
192 fpmas::api::model::AgentGroup& agentGroup() override {
193 return model.getGroup(AGENT_GROUP);
194 }
195
197 return dot_output;
198 }
199};
200
201template<typename BaseModel, typename AgentType>
203 std::string name, ModelConfig config,
204 fpmas::api::scheduler::Scheduler& scheduler,
205 fpmas::api::runtime::Runtime& runtime,
206 fpmas::api::model::LoadBalancing& lb_algorithm,
207 fpmas::scheduler::TimeStep lb_period
208 ) :
209 name(name),
210 model(scheduler, runtime, lb_algorithm),
211 graph_balance_probe_job(
212 model.graph(), lb_algorithm, lb_algorithm_probe, graph_balance_probe),
213 csv_output(
214 *this,
215 lb_algorithm_probe,
216 graph_balance_probe,
217 ReaderWriter::local_read_probe,
218 ReaderWriter::local_write_probe,
219 ReaderWriter::distant_read_probe,
220 ReaderWriter::distant_write_probe,
221 sync_probe,
222 monitor),
223 sync_probe_task(sync_probe, model.graph()),
224 cells_location_output(*this, this->name, config.grid_width, config.grid_height),
225 cells_utility_output(*this, config.grid_width, config.grid_height),
226 agents_output(*this, config.grid_width, config.grid_height),
227 dot_output(*this, this->name + ".%t"),
228 config(config) {
229 switch(config.cell_interactions) {
230 case Interactions::READ_ALL:
231 model.buildGroup(
232 CELL_GROUP,
233 cell_read_all_cell_behavior
234 );
235 break;
236 case Interactions::WRITE_ALL:
237 model.buildGroup(
238 CELL_GROUP,
239 cell_write_all_cell_behavior
240 );
241 break;
242 case Interactions::READ_ONE:
243 model.buildGroup(
244 CELL_GROUP,
245 cell_read_one_cell_behavior
246 );
247 break;
248 case Interactions::WRITE_ONE:
249 model.buildGroup(
250 CELL_GROUP,
251 cell_write_one_cell_behavior
252 );
253 break;
254 case Interactions::READ_ALL_WRITE_ONE:
255 model.buildGroup(
256 CELL_GROUP,
257 cell_read_all_write_one_cell_behavior
258 );
259 break;
260 case Interactions::READ_ALL_WRITE_ALL:
261 model.buildGroup(
262 CELL_GROUP,
263 cell_read_all_write_all_cell_behavior
264 );
265 break;
266 default:
267 model.buildGroup(
268 CELL_GROUP,
269 idle_behavior
270 );
271 break;
272 }
273 auto& create_relations_neighbors_group = model.buildGroup(
274 RELATIONS_FROM_NEIGHBORS_GROUP, create_relations_from_neighborhood
275 );
276 auto& create_relations_contacts_group = model.buildGroup(
277 RELATIONS_FROM_CONTACTS_GROUP, create_relations_from_contacts
278 );
279 auto& handle_new_contacts_group = model.buildGroup(
280 HANDLE_NEW_CONTACTS_GROUP, handle_new_contacts
281 );
282 auto& move_group = model.buildMoveGroup(
283 MOVE_GROUP, move_behavior
284 );
285
286
287 scheduler.schedule(0, lb_period, graph_balance_probe_job.job);
288 if(config.occupation_rate > 0.0) {
289 if(config.agent_interactions == AgentInteractions::CONTACTS) {
290 scheduler.schedule(
291 0.20, config.refresh_local_contacts,
292 create_relations_neighbors_group.jobs()
293 );
294 scheduler.schedule(
295 0.21, config.refresh_distant_contacts,
296 create_relations_contacts_group.jobs()
297 );
298 scheduler.schedule(
299 0.22, config.refresh_distant_contacts,
300 handle_new_contacts_group.jobs()
301 );
302 }
303 scheduler.schedule(0.23, 1, move_group.jobs());
304 }
305 if(config.dynamic_cell_edge_weights) {
306 auto& update_cell_edge_weights_group = model.buildGroup(
307 UPDATE_CELL_EDGE_WEIGHTS_GROUP,
308 cell_update_edge_weights_behavior);
309 scheduler.schedule(0.24, 1, update_cell_edge_weights_group.jobs());
310 }
311
312 if(config.cell_interactions != Interactions::NONE) {
313 model.getGroup(CELL_GROUP).agentExecutionJob().setEndTask(sync_probe_task);
314 scheduler.schedule(0.25, 1, model.getGroup(CELL_GROUP).jobs());
315 }
316 scheduler.schedule(0.30, 1, csv_output.jobs());
317
318 fpmas::scheduler::TimeStep last_lb_date
319 = ((config.num_steps-1) / lb_period) * lb_period;
320 // Clears distant nodes
321 if(config.json_output && config.environment == Environment::GRID) {
322 if(config.json_output_period > 0) {
323 // JSON cell output
324 scheduler.schedule(0.33, config.json_output_period, cells_location_output.job());
325 // JSON agent output
326 if(config.occupation_rate > 0.0)
327 scheduler.schedule(0.34, config.json_output_period, agents_output.job());
328
329 } else {
330 // If json_output_period <= 0, the json output is only performed
331 // at the end of the simulation.
332
333 // JSON cell output
334 scheduler.schedule(last_lb_date + 0.02, cells_location_output.job());
335 // JSON agent output
336 if(config.occupation_rate > 0.0)
337 scheduler.schedule(last_lb_date + 0.03, agents_output.job());
338 }
339
340 }
341 if(config.dot_output)
342 // Dot output
343 scheduler.schedule(last_lb_date + 0.04, dot_output.job());
344}
345
346template<typename BaseModel, typename AgentType>
348 buildCells(config);
349 model.graph().synchronize();
350
351 buildAgents(config);
352 // Static node weights
353 for(auto cell : model.cellGroup().localAgents())
354 cell->node()->setWeight(config.cell_weight);
355 for(auto agent : model.getGroup(AGENT_GROUP).localAgents())
356 agent->node()->setWeight(config.agent_weight);
357
358 model.graph().synchronize();
359
360 return this;
361}
362
366template<template<typename> class SyncMode>
368 public MetaModel<GridModel<SyncMode, MetaGridCell>, MetaGridAgent> {
369 public:
370 using MetaModel<GridModel<SyncMode, MetaGridCell>, MetaGridAgent>
372
391 void buildCells(const ModelConfig& config) override;
392
401 void buildAgents(const ModelConfig& config) override;
402};
403
404template<template<typename> class SyncMode>
406 std::unique_ptr<UtilityFunction> utility_function;
407 switch(config.utility) {
408 case Utility::UNIFORM:
409 utility_function.reset(new UniformUtility);
410 break;
411 case Utility::LINEAR:
412 utility_function.reset(new LinearUtility);
413 break;
414 case Utility::INVERSE:
415 utility_function.reset(new InverseUtility);
416 break;
417 case Utility::STEP:
418 utility_function.reset(new StepUtility);
419 break;
420 }
421 MetaGridCellFactory cell_factory(
422 *utility_function, config.grid_attractors, config.cell_size);
423 MooreGrid<MetaGridCell>::Builder grid(
424 cell_factory, config.grid_width, config.grid_height);
425 fpmas::api::model::GroupList cell_groups;
427 cell_groups.push_back(this->model.getGroup(CELL_GROUP));
428 auto local_cells = grid.build(this->model, cell_groups);
429 if(config.json_output)
430 CellsUtilityOutput(*this, config.grid_width, config.grid_height)
431 .dump();
432}
433
434template<template<typename> class SyncMode>
436 fpmas::model::UniformGridAgentMapping mapping(
437 config.grid_width, config.grid_height,
438 config.grid_width * config.grid_height * config.occupation_rate
439 );
440 fpmas::model::GridAgentBuilder<MetaGridCell> agent_builder;
441 fpmas::model::DefaultSpatialAgentFactory<MetaGridAgent> agent_factory;
442
443 agent_builder.build(
444 this->model,
445 {
446 this->model.getGroup(RELATIONS_FROM_NEIGHBORS_GROUP),
447 this->model.getGroup(RELATIONS_FROM_CONTACTS_GROUP),
448 this->model.getGroup(HANDLE_NEW_CONTACTS_GROUP),
449 this->model.getGroup(MOVE_GROUP)
450 },
451 agent_factory, mapping);
452}
453
460template<template<typename> class SyncMode>
462 public MetaModel<SpatialModel<SyncMode, MetaGraphCell>, MetaGraphAgent> {
463 public:
464 using MetaModel<SpatialModel<SyncMode, MetaGraphCell>, MetaGraphAgent>
466
481 void buildCells(const ModelConfig& config) override;
482
492 void buildAgents(const ModelConfig& config) override;
493 };
494
495template<template<typename> class SyncMode>
497 fpmas::random::PoissonDistribution<std::size_t> edge_dist(config.output_degree);
498 fpmas::api::graph::DistributedGraphBuilder<fpmas::model::AgentPtr>* builder;
499 switch(config.environment) {
501 builder = new DistributedUniformGraphBuilder(edge_dist);
502 break;
504 builder = new DistributedClusteredGraphBuilder(edge_dist);
505 break;
507 builder = new SmallWorldGraphBuilder(config.p, config.output_degree);
508 break;
509 default:
510 // Grid type
511 break;
512 }
513 MetaGraphCellFactory graph_cell_factory(config.cell_size);
514 CellNetworkBuilder<MetaGraphCell> cell_network_builder(
515 *builder, config.num_cells,
516 graph_cell_factory
517 );
518 fpmas::api::model::GroupList cell_groups;
520 cell_groups.push_back(this->model.getGroup(UPDATE_CELL_EDGE_WEIGHTS_GROUP));
522 cell_groups.push_back(this->model.getGroup(CELL_GROUP));
523 cell_network_builder.build(this->model, cell_groups);
524
525 delete builder;
526
527 GraphRange<MetaGraphCell>::synchronize(this->model);
528}
529
530template<template<typename> class SyncMode>
532 fpmas::model::UniformAgentMapping mapping(
533 this->getModel().getMpiCommunicator(),
534 this->cellGroup(),
535 config.num_cells * config.occupation_rate
536 );
537 fpmas::model::SpatialAgentBuilder<MetaGraphCell> agent_builder;
538 fpmas::model::DefaultSpatialAgentFactory<MetaGraphAgent> agent_factory;
539 agent_builder.build(
540 this->model,
541 {
542 this->model.getGroup(RELATIONS_FROM_NEIGHBORS_GROUP),
543 this->model.getGroup(RELATIONS_FROM_CONTACTS_GROUP),
544 this->model.getGroup(HANDLE_NEW_CONTACTS_GROUP),
545 this->model.getGroup(MOVE_GROUP)
546 },
547 agent_factory, mapping);
548}
549
555 private:
556 Environment environment;
557 SyncMode sync_mode;
558
559 public:
566 MetaModelFactory(Environment environment, SyncMode sync_mode);
567
582 std::string name, ModelConfig config,
583 fpmas::api::scheduler::Scheduler& scheduler,
584 fpmas::api::runtime::Runtime& runtime,
585 fpmas::api::model::LoadBalancing& lb_algorithm,
586 fpmas::scheduler::TimeStep lb_period
587 );
588};
589
Definition: output.h:359
Definition: metamodel.h:17
virtual fpmas::api::model::AgentGroup & cellGroup()=0
virtual fpmas::api::model::Model & getModel()=0
virtual DotOutput & getDotOutput()=0
virtual void run()=0
virtual BasicMetaModel * init()=0
virtual fpmas::api::model::AgentGroup & agentGroup()=0
virtual std::string getName() const =0
Definition: output.h:169
Definition: output.h:127
void dump() override
Definition: dot.h:190
Definition: probe.h:66
fpmas::scheduler::Job job
Definition: probe.h:80
Definition: cell.h:311
virtual void read_one_cell()=0
virtual void read_all_write_one_cell()=0
virtual void read_all_write_all_cell()=0
void update_edge_weights()
virtual void write_one_cell()=0
virtual void read_all_cell()=0
virtual void write_all_cell()=0
Definition: agent.h:436
Definition: cell.h:386
Definition: metamodel.h:462
void buildCells(const ModelConfig &config) override
Definition: metamodel.h:496
void buildAgents(const ModelConfig &config) override
Definition: metamodel.h:531
Definition: agent.h:422
Definition: cell.h:351
Definition: metamodel.h:368
void buildCells(const ModelConfig &config) override
Definition: metamodel.h:405
void buildAgents(const ModelConfig &config) override
Definition: metamodel.h:435
Definition: output.h:71
const fpmas::scheduler::JobList & jobs()
Definition: output.h:112
Definition: metamodel.h:64
std::string getName() const override
Definition: metamodel.h:180
fpmas::api::model::Model & getModel() override
Definition: metamodel.h:184
MetaModel(std::string name, ModelConfig config, fpmas::api::scheduler::Scheduler &scheduler, fpmas::api::runtime::Runtime &runtime, fpmas::api::model::LoadBalancing &lb_algorithm, fpmas::scheduler::TimeStep lb_period)
Definition: metamodel.h:202
fpmas::api::model::AgentGroup & cellGroup() override
Definition: metamodel.h:188
void run() override
Definition: metamodel.h:176
MetaModel< BaseModel, AgentType > * init() override
Definition: metamodel.h:347
fpmas::api::model::AgentGroup & agentGroup() override
Definition: metamodel.h:192
virtual void buildCells(const ModelConfig &config)=0
BaseModel model
Definition: metamodel.h:115
virtual void buildAgents(const ModelConfig &config)=0
DotOutput & getDotOutput() override
Definition: metamodel.h:196
Definition: probe.h:126
SyncMode
Definition: config.h:221
#define AGENT_GROUP
Definition: config.h:27
Environment
Definition: config.h:37
std::size_t output_degree
Definition: config.h:315
bool json_output
Definition: config.h:347
float p
Definition: config.h:323
Utility utility
Definition: config.h:331
int json_output_period
Definition: config.h:354
bool dot_output
Definition: config.h:359
std::vector< GridAttractor > grid_attractors
Definition: config.h:336
Environment environment
Definition: config.h:297
std::size_t num_cells
Definition: config.h:310
std::size_t grid_width
Definition: config.h:301
std::size_t grid_height
Definition: config.h:305
Definition: cell.h:300
Definition: metamodel.h:554
MetaModelFactory(Environment environment, SyncMode sync_mode)
BasicMetaModel * build(std::string name, ModelConfig config, fpmas::api::scheduler::Scheduler &scheduler, fpmas::api::runtime::Runtime &runtime, fpmas::api::model::LoadBalancing &lb_algorithm, fpmas::scheduler::TimeStep lb_period)
Definition: config.h:433
std::size_t cell_size
Definition: config.h:468
bool dynamic_cell_edge_weights
Definition: config.h:458
AgentInteractions agent_interactions
Definition: config.h:446
fpmas::api::scheduler::TimeStep refresh_local_contacts
Definition: config.h:479
fpmas::api::scheduler::TimeStep num_steps
Definition: config.h:442
float occupation_rate
Definition: config.h:438
fpmas::api::scheduler::TimeStep refresh_distant_contacts
Definition: config.h:486
Interactions cell_interactions
Definition: config.h:452
Definition: interactions.h:24
Definition: cell.h:342
Definition: cell.h:290