1#ifndef FPMAS_RING_GRAPH_BUILDER_H
2#define FPMAS_RING_GRAPH_BUILDER_H
15namespace fpmas {
namespace graph {
60 template<
typename LocalNodeIterator>
61 std::vector<api::graph::DistributedNode<T>*> build_distant_nodes(
67 const std::vector<std::size_t>& node_counts,
71 LocalNodeIterator local_nodes_iterator,
75 std::function<
int (
int )> next_rank
77 template<
typename NodeIterator>
80 NodeIterator local_node_iterator,
81 std::size_t local_node_count,
82 NodeIterator link_node_iterator,
96 : k(k), ring_type(ring_type) {
99 std::vector<api::graph::DistributedNode<T>*>
build(
105 template<
typename T>
template <
typename LocalNodeIterator>
106 std::vector<api::graph::DistributedNode<T>*> RingGraphBuilder<T>
107 ::build_distant_nodes(
110 const std::vector<std::size_t>& node_counts,
111 LocalNodeIterator local_nodes_iterator,
112 std::function<
int (
int)> next_rank
122 std::unordered_map<int, std::size_t> node_count_requests;
123 std::unordered_map<int, std::list<DistributedId>> ids_requests;
132 std::size_t count = 0;
139 std::vector<int> ranks;
144 int _next_rank = next_rank(level);
147 std::size_t node_count = std::min(
150 node_counts[_next_rank], k-count
152 node_count_requests[_next_rank] = node_count;
155 ranks.push_back(_next_rank);
158 node_count_requests = int_mpi.allToAll(node_count_requests);
161 for(
auto item : node_count_requests) {
164 auto it = local_nodes_iterator;
169 std::list<DistributedId>& ids = ids_requests[item.first];
170 for(std::size_t i = 0; i < item.second; i++)
173 ids.push_back((*it++)->getId());
176 ids_requests = list_id_mpi.allToAll(ids_requests);
179 std::vector<api::graph::DistributedNode<T>*> built_nodes;
180 for(
auto rank : ranks)
181 for(
auto node_id : ids_requests[rank])
182 built_nodes.push_back(
189 template<
typename NodeIterator>
190 void RingGraphBuilder<T>::link_loop(
191 api::graph::DistributedGraph<T>& graph,
192 NodeIterator local_node_iterator,
193 std::size_t local_node_count,
194 NodeIterator link_node_iterator,
208 NodeIterator local_node = local_node_iterator;
209 for(std::size_t n = 0; n < local_node_count; n++) {
210 NodeIterator link_node = link_node_iterator;
213 std::advance(link_node, n);
216 for(std::size_t i = 0; i < k; i++) {
220 graph.link(*local_node, *link_node, layer);
225 graph.synchronizationMode().getSyncLinker().synchronize();
234 std::list<api::graph::DistributedNode<T>*> local_nodes;
236 local_nodes.push_back(node_builder.
buildNode(graph));
246 std::vector<std::size_t> node_counts = int_mpi.
allGather(local_nodes.size());
253 std::list<api::graph::DistributedNode<T>*> link_nodes = local_nodes;
255 auto distant_nodes = build_distant_nodes(
261 [rank, size] (
int level) ->
int {
264 return (rank+level)%size;
272 for(
auto node : distant_nodes)
273 link_nodes.push_back(node);
279 local_nodes.begin(), local_nodes.size(),
280 link_nodes.begin(), layer
282 }
if(ring_type ==
CYCLE) {
286 std::list<api::graph::DistributedNode<T>*> link_nodes = local_nodes;
288 auto distant_nodes = build_distant_nodes(
293 local_nodes.rbegin(),
294 [rank, size] (
int current_level) ->
int {
297 return (rank+size-current_level)%size;
305 for(
auto node : distant_nodes)
306 link_nodes.push_front(node);
312 local_nodes.rbegin(), local_nodes.size(),
313 link_nodes.rbegin(), layer
317 return {local_nodes.begin(), local_nodes.end()};
virtual int getRank() const =0
virtual int getSize() const =0
Definition: graph_builder.h:154
Definition: distributed_graph.h:169
virtual api::communication::MpiCommunicator & getMpiCommunicator()=0
Definition: graph_builder.h:89
virtual std::size_t localNodeCount()=0
virtual DistributedNode< T > * buildDistantNode(DistributedId id, int location, DistributedGraph< T > &graph)=0
virtual DistributedNode< T > * buildNode(DistributedGraph< T > &graph)=0
std::vector< T > allGather(const T &) override
Definition: communication.h:492
Definition: ring_graph_builder.h:55
RingGraphBuilder(std::size_t k, RingType ring_type=CYCLE)
Definition: ring_graph_builder.h:95
std::vector< api::graph::DistributedNode< T > * > build(api::graph::DistributedNodeBuilder< T > &node_builder, api::graph::LayerId layer, api::graph::DistributedGraph< T > &graph) override
Definition: ring_graph_builder.h:229
int LayerId
Definition: edge.h:13
RingType
Definition: ring_graph_builder.h:19
@ LOOP
Definition: ring_graph_builder.h:23
@ CYCLE
Definition: ring_graph_builder.h:27
Definition: communication.h:590