fpmas 1.5
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
11
12#include <list>
13
14namespace fpmas { namespace graph {
15 namespace detail {
19 struct Point {
23 double x;
27 double y;
28
35 Point(double x, double y) : x(x), y(y) {}
36
44 static double distance(const Point& p1, const Point& p2) {
45 return std::pow(p2.y - p1.y, 2) + std::pow(p2.x - p1.x, 2);
46 }
47 };
48
52 template<typename T>
62
70 : p(p), node(node) {}
71 };
72
80 template<typename T>
94
104 Point p,
106 int location)
108 }
109 };
110
111
117 private:
118 Point& p;
119 public:
126 : p(p) {}
127
136 bool operator()(const Point& p1, const Point& p2) {
137 return Point::distance(p1, p) < Point::distance(p2, p);
138 }
139 };
140 }
141
147 template<typename T>
149 public api::graph::GraphBuilder<T>,
150 private RandomGraphBuilder {
151 private:
152 /*
153 * Function object that returns a random x coordinate.
154 */
155 std::function<double()> x;
156 /*
157 * Function object that returns a random y coordinate.
158 */
159 std::function<double()> y;
160
161 static random::UniformRealDistribution<double> default_xy_dist;
162
163 public:
185 template<typename Generator_t, typename EdgeDist, typename X_Dist, typename Y_Dist>
187 Generator_t& generator,
188 EdgeDist& edge_distribution,
189 X_Dist& x_distribution,
190 Y_Dist& y_distribution
191 ) :
192 RandomGraphBuilder(generator, edge_distribution),
193 // Generator, x_distribution and y_distribution are
194 // catched in a lambda to avoid class template
195 // parameters usage
196 x([&generator, &x_distribution] () {
197 return x_distribution(generator);
198 }),
199 y([&generator, &y_distribution] () {
200 return y_distribution(generator);
201 }) {
202 }
203
224 template<typename EdgeDist, typename X_Dist, typename Y_Dist>
226 EdgeDist& edge_distribution,
227 X_Dist& x_distribution,
228 Y_Dist& y_distribution
230 RandomGraphBuilder::rd, edge_distribution,
231 x_distribution, y_distribution) {
232 }
233
250 template<typename Generator_t, typename Distribution_t>
252 Generator_t& generator,
253 Distribution_t& edge_distribution
254 ) :
256 generator, edge_distribution,
257 default_xy_dist, default_xy_dist) {
258 }
259
278 std::vector<api::graph::DistributedNode<T>*> build(
279 api::graph::NodeBuilder<T>& node_builder,
281 api::graph::DistributedGraph<T>& graph) override;
282 };
283
284 template<typename T>
286 ClusteredGraphBuilder<T>::default_xy_dist {0, 1000};
287
288 template<typename T>
289 std::vector<api::graph::DistributedNode<T>*> ClusteredGraphBuilder<T>
291 std::vector<api::graph::DistributedNode<T>*> raw_built_nodes;
292 std::vector<detail::LocalizedNode<T>> built_nodes;
293 while(node_builder.nodeCount() != 0) {
294 auto* node = node_builder.buildNode(graph);
295 built_nodes.push_back({
296 {this->x(), this->y()},
297 node
298 });
299 raw_built_nodes.push_back(node);
300 }
301
302 for(auto& node : built_nodes) {
303 std::size_t edge_count = std::min(
304 this->num_edge(), built_nodes.size()-1
305 );
306
307 detail::DistanceComparator comp(node.p);
308 std::list<detail::LocalizedNode<T>> nearest_nodes;
309 std::size_t i = 0;
310 while(nearest_nodes.size() < edge_count) {
311 auto local_node = built_nodes[i];
312 if(local_node.node != node.node) {
313 auto it = nearest_nodes.begin();
314 while(it != nearest_nodes.end() && comp((*it).p, local_node.p))
315 it++;
316 nearest_nodes.insert(it, local_node);
317 }
318 i++;
319 }
320
321 for(std::size_t j = i; j < built_nodes.size(); j++) {
322 auto local_node = built_nodes[j];
323 if(local_node.node != node.node) {
324 auto it = nearest_nodes.begin();
325 while(it != nearest_nodes.end() && comp((*it).p, local_node.p))
326 it++;
327 if(it != nearest_nodes.end()) {
328 nearest_nodes.insert(it, local_node);
329 nearest_nodes.pop_back();
330 }
331 }
332 }
333
334 for(auto nearest_node : nearest_nodes)
335 graph.link(node.node, nearest_node.node, layer);
336 }
337 return raw_built_nodes;
338 }
339
346 template<typename T>
349 private RandomGraphBuilder {
350 private:
351 /*
352 * Function object that returns a random x coordinate.
353 */
354 std::function<double()> x;
355 /*
356 * Function object that returns a random y coordinate.
357 */
358 std::function<double()> y;
359
360 static random::UniformRealDistribution<double> default_xy_dist;
361
362 public:
386 template<typename EdgeDist, typename X_Dist, typename Y_Dist>
389 EdgeDist& edge_distribution,
390 X_Dist& x_distribution,
391 Y_Dist& y_distribution
392 ) :
393 RandomGraphBuilder(generator, edge_distribution),
394 x([&generator, &x_distribution] () {return x_distribution(generator);}),
395 y([&generator, &y_distribution] () {return y_distribution(generator);}) {
396 }
397
415 template<typename EdgeDist, typename X_Dist, typename Y_Dist>
417 EdgeDist& edge_distribution,
418 X_Dist& x_distribution,
419 Y_Dist& y_distribution
420 ) :
422 RandomGraphBuilder::distributed_rd, edge_distribution,
423 x_distribution, y_distribution) {
424 }
425
426
441 template<typename EdgeDist>
444 EdgeDist& edge_distribution
445 ) :
447 generator, edge_distribution,
448 default_xy_dist, default_xy_dist){
449 }
450
463 template<typename EdgeDist>
465 EdgeDist& edge_distribution
466 ) :
468 RandomGraphBuilder::distributed_rd, edge_distribution,
469 default_xy_dist, default_xy_dist){
470 }
471
483 std::vector<api::graph::DistributedNode<T>*> build(
486 api::graph::DistributedGraph<T>& graph) override;
487 };
488
489 template<typename T>
491 DistributedClusteredGraphBuilder<T>::default_xy_dist {0, 1000};
492
493 template<typename T>
494 std::vector<api::graph::DistributedNode<T>*> DistributedClusteredGraphBuilder<T>
499 std::vector<api::graph::DistributedNode<T>*> raw_built_nodes;
500 std::vector<detail::LocalizedNode<T>> built_nodes;
501 while(node_builder.localNodeCount() != 0) {
502 auto* node = node_builder.buildNode(graph);
503 built_nodes.push_back({
504 {this->x(), this->y()},
505 node
506 });
507 raw_built_nodes.push_back(node);
508 }
509 std::vector<detail::LocalizedNodeView<T>> built_nodes_buffer;
510 for(auto node : built_nodes)
511 built_nodes_buffer.push_back({
512 node.p, node.node->getId(), node.node->location()
513 });
514
516 graph.getMpiCommunicator()
517 );
518
519 built_nodes_buffer = fpmas::communication::all_reduce(
520 mpi, built_nodes_buffer, fpmas::utils::Concat()
521 );
522
523 for(auto& node : built_nodes) {
524 std::size_t edge_count = std::min(
525 this->num_edge(), built_nodes_buffer.size()-1
526 );
527 detail::DistanceComparator comp(node.p);
528 std::list<detail::LocalizedNodeView<T>> nearest_nodes;
529 std::size_t i = 0;
530 while(nearest_nodes.size() < edge_count) {
531 auto local_node = built_nodes_buffer[i];
532 if(local_node.node_id != node.node->getId()) {
533 auto it = nearest_nodes.begin();
534 while(it != nearest_nodes.end() && comp((*it).p, local_node.p))
535 it++;
536 nearest_nodes.insert(it, local_node);
537 }
538 i++;
539 }
540
541 for(std::size_t j = i; j < built_nodes_buffer.size(); j++) {
542 auto local_node = built_nodes_buffer[j];
543 if(local_node.node_id != node.node->getId()) {
544 auto it = nearest_nodes.begin();
545 while(it != nearest_nodes.end() && comp((*it).p, local_node.p))
546 it++;
547 if(it != nearest_nodes.end()) {
548 nearest_nodes.insert(it, local_node);
549 nearest_nodes.pop_back();
550 }
551 }
552 }
553
554 for(auto nearest_node : nearest_nodes) {
556 try {
557 target_node = graph.getNode(nearest_node.node_id);
558 } catch(const std::out_of_range&) {
559 target_node = node_builder.buildDistantNode(
560 nearest_node.node_id, nearest_node.location, graph
561 );
562 }
563 graph.link(node.node, target_node, layer);
564 }
565 }
566
567 // Commits new links
568 graph.synchronizationMode().getSyncLinker().synchronize();
569
570 return raw_built_nodes;
571 }
572}}
573
574namespace nlohmann {
578 template<typename T>
579 struct adl_serializer<fpmas::graph::detail::LocalizedNodeView<T>> {
580
588 template<typename JsonType>
589 static void to_json(
590 JsonType& j,
592 ) {
593 j = {{node.p.x, node.p.y}, node.node_id, node.location};
594 }
595
602 template<typename JsonType>
604 return {
605 {
606 j.at(0).at(0).template get<double>(),
607 j.at(0).at(1).template get<double>()
608 },
609 j[1].template get<fpmas::api::graph::DistributedId>(),
610 j.at(2).template get<int>()
611 };
612 }
613 };
614}
615
616namespace fpmas { namespace io { namespace datapack {
624 template<typename T>
625 struct Serializer<graph::detail::LocalizedNodeView<T>> {
626
631 static std::size_t size(
633 return 2*p.size<double>() + p.size<DistributedId>() + p.size<int>();
634 }
635
642 static void to_datapack(
643 ObjectPack& pack,
645 pack.put(node.p.x);
646 pack.put(node.p.y);
647 pack.put(node.node_id);
648 pack.put(node.location);
649 }
650
658 return {
659 {pack.get<double>(), pack.get<double>()},
660 pack.get<DistributedId>(),
661 pack.get<int>()
662 };
663
664 }
665
666 };
667}}}
668#endif
Definition: graph_builder.h:154
Definition: distributed_graph.h:169
virtual api::communication::MpiCommunicator & getMpiCommunicator()=0
virtual synchro::SyncMode< T > & synchronizationMode()=0
virtual DistributedEdge< T > * link(DistributedNode< T > *source, DistributedNode< T > *target, LayerId layer_id)=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 NodeType * getNode(NodeIdType id)=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:150
ClusteredGraphBuilder(Generator_t &generator, Distribution_t &edge_distribution)
Definition: clustered_graph_builder.h:251
ClusteredGraphBuilder(EdgeDist &edge_distribution, X_Dist &x_distribution, Y_Dist &y_distribution)
Definition: clustered_graph_builder.h:225
ClusteredGraphBuilder(Generator_t &generator, EdgeDist &edge_distribution, X_Dist &x_distribution, Y_Dist &y_distribution)
Definition: clustered_graph_builder.h:186
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:290
Definition: clustered_graph_builder.h:349
DistributedClusteredGraphBuilder(EdgeDist &edge_distribution, X_Dist &x_distribution, Y_Dist &y_distribution)
Definition: clustered_graph_builder.h:416
DistributedClusteredGraphBuilder(random::DistributedGenerator<> &generator, EdgeDist &edge_distribution, X_Dist &x_distribution, Y_Dist &y_distribution)
Definition: clustered_graph_builder.h:387
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:495
DistributedClusteredGraphBuilder(EdgeDist &edge_distribution)
Definition: clustered_graph_builder.h:464
DistributedClusteredGraphBuilder(random::DistributedGenerator<> &generator, EdgeDist &edge_distribution)
Definition: clustered_graph_builder.h:442
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:116
bool operator()(const Point &p1, const Point &p2)
Definition: clustered_graph_builder.h:136
DistanceComparator(Point &p)
Definition: clustered_graph_builder.h:125
Definition: datapack.h:275
std::size_t size() const
Definition: datapack.h:341
void put(const T &item)
Definition: datapack.h:421
T get() const
Definition: datapack.h:433
Definition: generator.h:322
Definition: distribution.h:24
int LayerId
Definition: edge.h:13
T all_reduce(api::communication::TypedMpi< T > &mpi, const T &data, BinaryOp binary_op=BinaryOp())
Definition: communication.h:639
Definition: fpmas.cpp:3
Definition: communication.h:590
Definition: clustered_graph_builder.h:81
int location
Definition: clustered_graph_builder.h:93
LocalizedNodeView(Point p, fpmas::api::graph::DistributedId node_id, int location)
Definition: clustered_graph_builder.h:103
Point p
Definition: clustered_graph_builder.h:85
fpmas::api::graph::DistributedId node_id
Definition: clustered_graph_builder.h:89
Definition: clustered_graph_builder.h:53
api::graph::DistributedNode< T > * node
Definition: clustered_graph_builder.h:61
LocalizedNode(Point p, api::graph::DistributedNode< T > *node)
Definition: clustered_graph_builder.h:69
Point p
Definition: clustered_graph_builder.h:57
Definition: clustered_graph_builder.h:19
static double distance(const Point &p1, const Point &p2)
Definition: clustered_graph_builder.h:44
double x
Definition: clustered_graph_builder.h:23
double y
Definition: clustered_graph_builder.h:27
Point(double x, double y)
Definition: clustered_graph_builder.h:35
static graph::detail::LocalizedNodeView< T > from_datapack(const ObjectPack &pack)
Definition: clustered_graph_builder.h:657
static std::size_t size(const ObjectPack &p, const graph::detail::LocalizedNodeView< T > &)
Definition: clustered_graph_builder.h:631
static void to_datapack(ObjectPack &pack, const graph::detail::LocalizedNodeView< T > &node)
Definition: clustered_graph_builder.h:642
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:589
static fpmas::graph::detail::LocalizedNodeView< T > from_json(const JsonType &j)
Definition: clustered_graph_builder.h:603