fpmas 1.6
clustered_graph_builder.h
Go to the documentation of this file.
1#ifndef FPMAS_CLUSTERED_GRAPH_BUILDER_H
2#define FPMAS_CLUSTERED_GRAPH_BUILDER_H
3
13
14#include <list>
15
16namespace fpmas { namespace graph {
17 namespace detail {
21 struct Point {
25 double x;
29 double y;
30
37 Point(double x, double y) : x(x), y(y) {}
38
46 static double distance(const Point& p1, const Point& p2) {
47 return std::pow(p2.y - p1.y, 2) + std::pow(p2.x - p1.x, 2);
48 }
49 };
50
54 template<typename T>
64
72 : p(p), node(node) {}
73 };
74
82 template<typename T>
96
106 Point p,
108 int location)
110 }
111 };
112
113
119 private:
120 Point& p;
121 public:
128 : p(p) {}
129
138 bool operator()(const Point& p1, const Point& p2) {
139 return Point::distance(p1, p) < Point::distance(p2, p);
140 }
141 };
142 }
143
149 template<typename T>
151 public api::graph::GraphBuilder<T>,
152 private RandomGraphBuilder {
153 private:
154 /*
155 * Function object that returns a random x coordinate.
156 */
157 std::function<double()> x;
158 /*
159 * Function object that returns a random y coordinate.
160 */
161 std::function<double()> y;
162
163 static random::UniformRealDistribution<double> default_xy_dist;
164
165 public:
187 template<typename Generator_t, typename EdgeDist, typename X_Dist, typename Y_Dist>
189 Generator_t& generator,
190 EdgeDist& edge_distribution,
191 X_Dist& x_distribution,
192 Y_Dist& y_distribution
193 ) :
194 RandomGraphBuilder(generator, edge_distribution),
195 // Generator, x_distribution and y_distribution are
196 // catched in a lambda to avoid class template
197 // parameters usage
198 x([&generator, &x_distribution] () {
199 return x_distribution(generator);
200 }),
201 y([&generator, &y_distribution] () {
202 return y_distribution(generator);
203 }) {
204 }
205
226 template<typename EdgeDist, typename X_Dist, typename Y_Dist>
228 EdgeDist& edge_distribution,
229 X_Dist& x_distribution,
230 Y_Dist& y_distribution
232 RandomGraphBuilder::rd, edge_distribution,
233 x_distribution, y_distribution) {
234 }
235
252 template<typename Generator_t, typename Distribution_t>
254 Generator_t& generator,
255 Distribution_t& edge_distribution
256 ) :
258 generator, edge_distribution,
259 default_xy_dist, default_xy_dist) {
260 }
261
280 std::vector<api::graph::DistributedNode<T>*> build(
281 api::graph::NodeBuilder<T>& node_builder,
283 api::graph::DistributedGraph<T>& graph) override;
284 };
285
286 template<typename T>
288 ClusteredGraphBuilder<T>::default_xy_dist {0, 1000};
289
290 template<typename T>
291 std::vector<api::graph::DistributedNode<T>*> ClusteredGraphBuilder<T>
293 std::vector<api::graph::DistributedNode<T>*> raw_built_nodes;
294 std::vector<detail::LocalizedNode<T>> built_nodes;
295 while(node_builder.nodeCount() != 0) {
296 auto* node = node_builder.buildNode(graph);
297 built_nodes.push_back({
298 {this->x(), this->y()},
299 node
300 });
301 raw_built_nodes.push_back(node);
302 }
303
304 for(auto& node : built_nodes) {
305 std::size_t edge_count = std::min(
306 this->num_edge(), built_nodes.size()-1
307 );
308
309 detail::DistanceComparator comp(node.p);
310 std::list<detail::LocalizedNode<T>> nearest_nodes;
311 std::size_t i = 0;
312 while(nearest_nodes.size() < edge_count) {
313 auto local_node = built_nodes[i];
314 if(local_node.node != node.node) {
315 auto it = nearest_nodes.begin();
316 while(it != nearest_nodes.end() && comp((*it).p, local_node.p))
317 it++;
318 nearest_nodes.insert(it, local_node);
319 }
320 i++;
321 }
322
323 for(std::size_t j = i; j < built_nodes.size(); j++) {
324 auto local_node = built_nodes[j];
325 if(local_node.node != node.node) {
326 auto it = nearest_nodes.begin();
327 while(it != nearest_nodes.end() && comp((*it).p, local_node.p))
328 it++;
329 if(it != nearest_nodes.end()) {
330 nearest_nodes.insert(it, local_node);
331 nearest_nodes.pop_back();
332 }
333 }
334 }
335
336 for(auto nearest_node : nearest_nodes)
337 graph.link(node.node, nearest_node.node, layer);
338 }
339 return raw_built_nodes;
340 }
341
348 template<typename T>
351 private RandomGraphBuilder {
352 private:
353 /*
354 * Function object that returns a random x coordinate.
355 */
356 std::function<double()> x;
357 /*
358 * Function object that returns a random y coordinate.
359 */
360 std::function<double()> y;
361
362 double x0;
363 double y0;
364 double X;
365 double Y;
366
367 static random::UniformRealDistribution<double> default_xy_dist;
368
369 public:
393 template<typename EdgeDist, typename X_Dist, typename Y_Dist>
396 EdgeDist& edge_distribution,
397 X_Dist& x_distribution,
398 Y_Dist& y_distribution
399 ) :
400 RandomGraphBuilder(generator, edge_distribution),
401 x([&generator, &x_distribution] () {return x_distribution(generator);}),
402 y([&generator, &y_distribution] () {return y_distribution(generator);}),
403 x0(x_distribution.min()), y0(y_distribution.min()),
404 X(x_distribution.max()-x0), Y(y_distribution.max()-y0) {
405 }
406
424 template<typename EdgeDist, typename X_Dist, typename Y_Dist>
426 EdgeDist& edge_distribution,
427 X_Dist& x_distribution,
428 Y_Dist& y_distribution
429 ) :
431 RandomGraphBuilder::distributed_rd, edge_distribution,
432 x_distribution, y_distribution) {
433 }
434
435
450 template<typename EdgeDist>
453 EdgeDist& edge_distribution
454 ) :
456 generator, edge_distribution,
457 default_xy_dist, default_xy_dist){
458 }
459
472 template<typename EdgeDist>
474 EdgeDist& edge_distribution
475 ) :
477 RandomGraphBuilder::distributed_rd, edge_distribution,
478 default_xy_dist, default_xy_dist){
479 }
480
492 std::vector<api::graph::DistributedNode<T>*> build(
495 api::graph::DistributedGraph<T>& graph) override;
496 };
497
498 template<typename T>
500 DistributedClusteredGraphBuilder<T>::default_xy_dist {0, 1000};
501
502 template<typename T>
503 std::vector<api::graph::DistributedNode<T>*> DistributedClusteredGraphBuilder<T>
508 fpmas::model::FastProcessMapping process_mapping(X, Y, graph.getMpiCommunicator());
509
511 std::vector<detail::LocalizedNode<T>> local_built_nodes;
512 while(node_builder.localNodeCount() != 0) {
513 auto* node = node_builder.buildNode(graph);
514 double x = this->x();
515 double y = this->y();
516 local_built_nodes.push_back({
517 {x, y},
518 node
519 });
520 // Builds and gathers coordinates on each process according to the
521 // FastProcessMapping to reduce the count of DISTANT nodes
522 partition[node->getId()] = process_mapping.process({
523 (int) x - (int) x0, (int) y - (int) y0
524 });
525 }
526
527 std::vector<detail::LocalizedNodeView<T>> all_built_nodes;
528 for(auto node : local_built_nodes)
529 all_built_nodes.push_back({
530 node.p, node.node->getId(), partition[node.node->getId()]
531 });
532
534 graph.getMpiCommunicator()
535 );
536
537 all_built_nodes = fpmas::communication::all_reduce(
538 mpi, all_built_nodes, fpmas::utils::Concat()
539 );
540
541 graph.distribute(partition);
542 local_built_nodes.clear();
543 std::vector<api::graph::DistributedNode<T>*> raw_built_nodes;
544 {
545 const auto& local_nodes = graph.getLocationManager().getLocalNodes();
546 for(auto& item : all_built_nodes) {
547 auto it = local_nodes.find(item.node_id);
548 if(it != local_nodes.end()) {
549 local_built_nodes.push_back({item.p, it->second});
550 raw_built_nodes.push_back(it->second);
551 }
552 }
553 }
554
555 const auto& graph_nodes = graph.getNodes();
556 for(auto& node : local_built_nodes) {
557 std::size_t edge_count = std::min(
558 this->num_edge(), all_built_nodes.size()-1
559 );
560 detail::DistanceComparator comp(node.p);
561 std::list<detail::LocalizedNodeView<T>> nearest_nodes;
562 std::size_t i = 0;
563 while(nearest_nodes.size() < edge_count) {
564 auto local_node = all_built_nodes[i];
565 if(local_node.node_id != node.node->getId()) {
566 auto it = nearest_nodes.begin();
567 while(it != nearest_nodes.end() && comp((*it).p, local_node.p))
568 it++;
569 nearest_nodes.insert(it, local_node);
570 }
571 i++;
572 }
573
574 for(std::size_t j = i; j < all_built_nodes.size(); j++) {
575 auto local_node = all_built_nodes[j];
576 if(local_node.node_id != node.node->getId()) {
577 auto it = nearest_nodes.begin();
578 while(it != nearest_nodes.end() && comp((*it).p, local_node.p))
579 it++;
580 if(it != nearest_nodes.end()) {
581 nearest_nodes.insert(it, local_node);
582 nearest_nodes.pop_back();
583 }
584 }
585 }
586
587 for(auto nearest_node : nearest_nodes) {
589 auto it = graph_nodes.find(nearest_node.node_id);
590 if(it != graph_nodes.end()) {
591 target_node = it->second;
592 } else {
593 target_node = node_builder.buildDistantNode(
594 nearest_node.node_id, nearest_node.location, graph
595 );
596 }
597 graph.link(node.node, target_node, layer);
598 }
599 }
600
601 // Commits new links
602 graph.synchronizationMode().getSyncLinker().synchronize();
603
604 return raw_built_nodes;
605 }
606}}
607
608namespace nlohmann {
612 template<typename T>
613 struct adl_serializer<fpmas::graph::detail::LocalizedNodeView<T>> {
614
622 template<typename JsonType>
623 static void to_json(
624 JsonType& j,
626 ) {
627 j = {{node.p.x, node.p.y}, node.node_id, node.location};
628 }
629
636 template<typename JsonType>
638 return {
639 {
640 j.at(0).at(0).template get<double>(),
641 j.at(0).at(1).template get<double>()
642 },
643 j[1].template get<fpmas::api::graph::DistributedId>(),
644 j.at(2).template get<int>()
645 };
646 }
647 };
648}
649
650namespace fpmas { namespace io { namespace datapack {
658 template<typename T>
659 struct Serializer<graph::detail::LocalizedNodeView<T>> {
660
665 static std::size_t size(
667 return 2*p.size<double>() + p.size<DistributedId>() + p.size<int>();
668 }
669
676 static void to_datapack(
677 ObjectPack& pack,
679 pack.put(node.p.x);
680 pack.put(node.p.y);
681 pack.put(node.node_id);
682 pack.put(node.location);
683 }
684
692 // Call order guaranteed, DO NOT CALL gets FROM THE CONSTRUCTOR
693 double x = pack.get<double>();
694 double y = pack.get<double>();
695 DistributedId id = pack.get<DistributedId>();
696 int location = pack.get<int>();
697 return {{x, y}, id, location};
698 }
699
700 };
701}}}
702#endif
Definition: graph_builder.h:154
Definition: distributed_graph.h:169
virtual api::communication::MpiCommunicator & getMpiCommunicator()=0
virtual void distribute(PartitionMap partition)=0
virtual synchro::SyncMode< T > & synchronizationMode()=0
virtual DistributedEdge< T > * link(DistributedNode< T > *source, DistributedNode< T > *target, LayerId layer_id)=0
virtual LocationManager< T > & getLocationManager()=0
Definition: distributed_id.h:89
Definition: graph_builder.h:89
virtual std::size_t localNodeCount()=0
virtual DistributedNode< T > * buildDistantNode(DistributedId id, int location, DistributedGraph< T > &graph)=0
Definition: distributed_node.h:28
Definition: graph_builder.h:54
virtual const NodeMap & getNodes() const =0
Definition: graph_builder.h:23
virtual std::size_t nodeCount()=0
virtual DistributedNode< T > * buildNode(DistributedGraph< T > &graph)=0
Definition: clustered_graph_builder.h:152
ClusteredGraphBuilder(Generator_t &generator, Distribution_t &edge_distribution)
Definition: clustered_graph_builder.h:253
ClusteredGraphBuilder(EdgeDist &edge_distribution, X_Dist &x_distribution, Y_Dist &y_distribution)
Definition: clustered_graph_builder.h:227
ClusteredGraphBuilder(Generator_t &generator, EdgeDist &edge_distribution, X_Dist &x_distribution, Y_Dist &y_distribution)
Definition: clustered_graph_builder.h:188
std::vector< api::graph::DistributedNode< T > * > build(api::graph::NodeBuilder< T > &node_builder, api::graph::LayerId layer, api::graph::DistributedGraph< T > &graph) override
Definition: clustered_graph_builder.h:292
Definition: clustered_graph_builder.h:351
DistributedClusteredGraphBuilder(EdgeDist &edge_distribution, X_Dist &x_distribution, Y_Dist &y_distribution)
Definition: clustered_graph_builder.h:425
DistributedClusteredGraphBuilder(random::DistributedGenerator<> &generator, EdgeDist &edge_distribution, X_Dist &x_distribution, Y_Dist &y_distribution)
Definition: clustered_graph_builder.h:394
std::vector< api::graph::DistributedNode< T > * > build(api::graph::DistributedNodeBuilder< T > &node_builder, api::graph::LayerId layer, api::graph::DistributedGraph< T > &graph) override
Definition: clustered_graph_builder.h:504
DistributedClusteredGraphBuilder(EdgeDist &edge_distribution)
Definition: clustered_graph_builder.h:473
DistributedClusteredGraphBuilder(random::DistributedGenerator<> &generator, EdgeDist &edge_distribution)
Definition: clustered_graph_builder.h:451
Definition: random_graph_builder.h:19
static random::mt19937_64 rd
Definition: random_graph_builder.h:59
static random::DistributedGenerator distributed_rd
Definition: random_graph_builder.h:52
Definition: clustered_graph_builder.h:118
bool operator()(const Point &p1, const Point &p2)
Definition: clustered_graph_builder.h:138
DistanceComparator(Point &p)
Definition: clustered_graph_builder.h:127
Definition: datapack.h:301
std::size_t size() const
Definition: datapack.h:367
void put(const T &item)
Definition: datapack.h:447
T get() const
Definition: datapack.h:459
Definition: grid_load_balancing.h:287
int process(DiscretePoint point) const override
Definition: grid_load_balancing.cpp:205
Definition: generator.h:322
Definition: distribution.h:24
std::unordered_map< DistributedId, int, api::graph::IdHash< DistributedId > > PartitionMap
Definition: load_balancing.h:19
int LayerId
Definition: edge.h:13
T all_reduce(api::communication::TypedMpi< T > &mpi, const T &data, BinaryOp binary_op=BinaryOp())
Definition: communication.h:634
std::size_t edge_count(api::graph::DistributedGraph< T > &graph)
Definition: analysis.h:41
Definition: fpmas.cpp:3
Definition: communication.h:585
Definition: clustered_graph_builder.h:83
int location
Definition: clustered_graph_builder.h:95
LocalizedNodeView(Point p, fpmas::api::graph::DistributedId node_id, int location)
Definition: clustered_graph_builder.h:105
Point p
Definition: clustered_graph_builder.h:87
fpmas::api::graph::DistributedId node_id
Definition: clustered_graph_builder.h:91
Definition: clustered_graph_builder.h:55
api::graph::DistributedNode< T > * node
Definition: clustered_graph_builder.h:63
LocalizedNode(Point p, api::graph::DistributedNode< T > *node)
Definition: clustered_graph_builder.h:71
Point p
Definition: clustered_graph_builder.h:59
Definition: clustered_graph_builder.h:21
static double distance(const Point &p1, const Point &p2)
Definition: clustered_graph_builder.h:46
double x
Definition: clustered_graph_builder.h:25
double y
Definition: clustered_graph_builder.h:29
Point(double x, double y)
Definition: clustered_graph_builder.h:37
static graph::detail::LocalizedNodeView< T > from_datapack(const ObjectPack &pack)
Definition: clustered_graph_builder.h:691
static std::size_t size(const ObjectPack &p, const graph::detail::LocalizedNodeView< T > &)
Definition: clustered_graph_builder.h:665
static void to_datapack(ObjectPack &pack, const graph::detail::LocalizedNodeView< T > &node)
Definition: clustered_graph_builder.h:676
Definition: datapack.h:55
Definition: functional.h:94
static void to_json(JsonType &j, const fpmas::graph::detail::LocalizedNodeView< T > &node)
Definition: clustered_graph_builder.h:623
static fpmas::graph::detail::LocalizedNodeView< T > from_json(const JsonType &j)
Definition: clustered_graph_builder.h:637