1#ifndef FPMAS_GHOST_MODE_H
2#define FPMAS_GHOST_MODE_H
11#include "../data_update_pack.h"
12#include "../synchro.h"
13#include "single_thread_mutex.h"
15namespace fpmas {
namespace synchro {
31 const T&
read()
override {
return this->
data();};
61 std::unordered_map<int, std::vector<DistributedId>> buildRequests();
62 std::unordered_map<int, std::vector<DistributedId>> buildRequests(
66 std::unordered_map<
int, std::vector<DistributedId>> requests
82 : data_mpi(data_mpi), id_mpi(id_mpi), graph(graph) {}
96 void GhostDataSync<T>::_synchronize(
97 std::unordered_map<
int, std::vector<DistributedId>> requests) {
99 graph.getMpiCommunicator().getRank(),
"GHOST_MODE",
100 "Synchronizing graph data...",
""
102 requests = id_mpi.migrate(requests);
104 std::unordered_map<int, std::vector<NodeUpdatePack<T>>> updated_data;
105 for(
auto list : requests) {
106 for(
auto id : list.second) {
108 graph.getMpiCommunicator().getRank(),
"GHOST_MODE",
111 auto node = graph.getNode(
id);
112 updated_data[list.first].push_back({
113 id, node->data(), node->getWeight()
118 updated_data = data_mpi.migrate(updated_data);
119 for(
auto list : updated_data) {
120 for(
auto& data : list.second) {
121 auto local_node = graph.getNode(data.id);
124 std::move(data.updated_data)
126 local_node->setWeight(data.updated_weight);
131 graph.getMpiCommunicator().getRank(),
"GHOST_MODE",
132 "Graph data synchronized.",
""
137 std::unordered_map<int, std::vector<DistributedId>> GhostDataSync<T>
138 ::buildRequests(std::unordered_set<api::graph::DistributedNode<T>*> nodes) {
139 std::unordered_map<int, std::vector<DistributedId>> requests;
140 for(
auto node : nodes) {
143 graph.getMpiCommunicator().getRank(),
"GHOST_MODE",
144 "Request %s from %i",
147 requests[node->location()].push_back(node->getId());
157 graph.getMpiCommunicator().getRank(),
"GHOST_MODE",
158 "Synchronizing graph data...",
""
161 std::unordered_map<int, std::vector<DistributedId>> requests
162 = buildRequests(nodes);
163 _synchronize(requests);
164 for(
auto node : nodes)
165 node->mutex()->synchronize();
171 std::unordered_map<int, std::vector<DistributedId>> requests;
172 for(
auto node : graph.getLocationManager().getDistantNodes()) {
174 graph.getMpiCommunicator().getRank(),
"GHOST_MODE",
175 "Request %s from %i",
178 requests[node.second->location()].push_back(node.first);
186 graph.getMpiCommunicator().getRank(),
"GHOST_MODE",
187 "Synchronizing graph data...",
"");
189 std::unordered_map<int, std::vector<DistributedId>> requests
191 _synchronize(requests);
192 for(
auto node : graph.getNodes())
193 node.second->mutex()->synchronize();
237 std::vector<EdgePtr> link_buffer;
238 std::unordered_map<int, std::vector<DistributedId>> unlink_migration;
239 std::unordered_map<int, std::vector<DistributedId>> remove_node_buffer;
240 std::vector<NodeApi*> local_nodes_to_remove;
265 : edge_mpi(edge_mpi), id_mpi(id_mpi), graph(graph) {}
291 FPMAS_LOGI(graph.getMpiCommunicator().getRank(),
292 "GHOST_MODE",
"Synchronizing graph links...",
"");
296 std::vector<EdgePtr> edges_to_clear;
297 std::unordered_map<int, std::vector<EdgePtr>> link_migration;
298 for(
auto edge : link_buffer) {
299 auto src = edge->getSourceNode();
301 link_migration[src->location()].push_back(edge);
303 auto tgt = edge->getTargetNode();
305 link_migration[tgt->location()].push_back(edge);
309 edges_to_clear.push_back(edge);
312 link_migration = edge_mpi.migrate(link_migration);
314 for(
auto import_list : link_migration) {
315 for (
auto edge : import_list.second) {
316 graph.importEdge(edge);
324 remove_node_buffer = id_mpi.migrate(remove_node_buffer);
325 for(
auto import_list : remove_node_buffer) {
327 auto* node = graph.getNode(node_id);
328 for(
auto edge : node->getOutgoingEdges())
330 for(
auto edge : node->getIncomingEdges())
338 unlink_migration = id_mpi.migrate(unlink_migration);
339 for(
auto import_list : unlink_migration) {
341 if(graph.getEdges().count(
id) > 0) {
342 auto edge = graph.getEdge(
id);
347 unlink_migration.clear();
349 for(
auto edge : edges_to_clear)
352 for(
auto import_list : remove_node_buffer)
353 for(
auto node_id : import_list.second)
354 local_nodes_to_remove.push_back(graph.getNode(node_id));
355 remove_node_buffer.clear();
357 for(
auto node : local_nodes_to_remove) {
360 local_nodes_to_remove.clear();
362 FPMAS_LOGI(graph.getMpiCommunicator().getRank(),
363 "GHOST_MODE",
"Graph links synchronized.",
"");
369 link_buffer.push_back(
const_cast<EdgeApi*
>(edge));
377 std::remove(link_buffer.begin(), link_buffer.end(), edge),
382 unlink_migration[src->location()].push_back(edge->
getId());
386 unlink_migration[tgt->location()].push_back(edge->
getId());
394 remove_node_buffer[node->
location()].push_back(node->
getId());
401 local_nodes_to_remove.push_back(node);
423 this->synchronize_links();
448 template<
typename T,
template<
typename>
class Mutex>
467 : id_mpi(comm), data_mpi(comm), edge_mpi(comm),
468 data_sync(data_mpi, id_mpi, graph), sync_linker(edge_mpi, id_mpi, graph) {}
476 return new Mutex<T>(node->
data());
Definition: communication.h:251
Definition: communication.h:637
Definition: distributed_edge.h:91
virtual LocationState state() const =0
Definition: distributed_graph.h:169
Definition: distributed_id.h:89
Definition: distributed_node.h:28
virtual LocationState state() const =0
virtual int location() const =0
virtual IdType getId() const =0
virtual NodeType * getSourceNode() const =0
virtual NodeType * getTargetNode() const =0
virtual const std::vector< EdgeType * > getIncomingEdges() const =0
virtual IdType getId() const =0
virtual const std::vector< EdgeType * > getOutgoingEdges() const =0
Definition: sync_mode.h:26
Definition: sync_mode.h:79
Definition: sync_mode.h:120
Definition: ptr_wrapper.h:21
Definition: ghost_mode.h:45
void synchronize() override
Definition: ghost_mode.h:184
api::communication::TypedMpi< DistributedId > IdMpi
Definition: ghost_mode.h:54
GhostDataSync(DataMpi &data_mpi, IdMpi &id_mpi, api::graph::DistributedGraph< T > &graph)
Definition: ghost_mode.h:78
api::communication::TypedMpi< NodeUpdatePack< T > > DataMpi
Definition: ghost_mode.h:50
Definition: ghost_mode.h:449
GhostDataSync< T > & getDataSync() override
Definition: ghost_mode.h:484
Mutex< T > * buildMutex(api::graph::DistributedNode< T > *node) override
Definition: ghost_mode.h:475
GhostSyncLinker< T > & getSyncLinker() override
Definition: ghost_mode.h:491
GhostMode(api::graph::DistributedGraph< T > &graph, api::communication::MpiCommunicator &comm)
Definition: ghost_mode.h:464
Definition: ghost_mode.h:27
const T & read() override
Definition: ghost_mode.h:31
void synchronize() override
Definition: ghost_mode.h:35
void releaseAcquire() override
Definition: ghost_mode.h:34
void releaseRead() override
Definition: ghost_mode.h:32
T & acquire() override
Definition: ghost_mode.h:33
Definition: ghost_mode.h:214
void unlink(EdgeApi *edge) override
Definition: ghost_mode.h:374
api::communication::TypedMpi< DistributedId > IdMpi
Definition: ghost_mode.h:235
void removeNode(NodeApi *node) override
Definition: ghost_mode.h:392
api::graph::DistributedNode< T > NodeApi
Definition: ghost_mode.h:223
void link(EdgeApi *edge) override
Definition: ghost_mode.h:367
api::utils::PtrWrapper< EdgeApi > EdgePtr
Definition: ghost_mode.h:227
api::graph::DistributedEdge< T > EdgeApi
Definition: ghost_mode.h:219
void synchronize_links()
Definition: ghost_mode.h:290
api::communication::TypedMpi< EdgePtr > EdgeMpi
Definition: ghost_mode.h:231
GhostSyncLinkerBase(EdgeMpi &edge_mpi, IdMpi &id_mpi, api::graph::DistributedGraph< T > &graph)
Definition: ghost_mode.h:262
Definition: ghost_mode.h:414
void synchronize() override
Definition: ghost_mode.h:422
Definition: single_thread_mutex.h:13
T & data() override
Definition: single_thread_mutex.h:29
#define FPMAS_C_STR(arg)
Definition: macros.h:24
LocationState
Definition: location_state.h:15
@ DISTANT
Definition: location_state.h:28
static void update(T &local_data, T &&updated_data)
Definition: synchro.h:31