59 #ifndef DIST_MAP_GRAPH_HPP_
60 #define DIST_MAP_GRAPH_HPP_
62 #include "Vector/map_vector.hpp"
63 #include "Graph/map_graph.hpp"
64 #include <unordered_map>
65 #include "Packer_Unpacker/Packer.hpp"
66 #include "Packer_Unpacker/Unpacker.hpp"
67 #include "VCluster/VCluster.hpp"
70 #define DIST_GRAPH_ERROR 7001
72 template<
typename V,
typename E,
76 template<
typename>
class layout_v_base,
77 template<
typename>
class layout_e_base,
84 typedef boost::fusion::vector<size_t, size_t> type;
88 static const unsigned int id = 0;
89 static const unsigned int gid = 1;
90 static const unsigned int max_prop = 2;
96 inline void setid(
size_t id_)
98 boost::fusion::at_c<0>(data) = id_;
101 inline void setgid(
size_t gid_)
103 boost::fusion::at_c<1>(data) = gid_;
106 template<
unsigned int id>
inline auto get() -> decltype(boost::fusion::at_c < id > (data))
108 return boost::fusion::at_c<id>(data);
111 template<
unsigned int id>
inline auto get()
const ->
const decltype(boost::fusion::at_c < id > (data))
113 return boost::fusion::at_c<id>(data);
123 boost::fusion::at_c<0>(data) = p.template get<0>();
124 boost::fusion::at_c<1>(data) = p.template get<1>();
129 static bool noPointers()
138 typedef boost::fusion::vector<size_t, size_t> type;
142 static const unsigned int sgid = 0;
143 static const unsigned int dgid = 1;
144 static const unsigned int max_prop = 2;
150 template<
unsigned int id>
inline auto get() -> decltype(boost::fusion::at_c < id > (data))
152 return boost::fusion::at_c<id>(data);
155 template<
unsigned int id>
inline auto get()
const ->
const decltype(boost::fusion::at_c < id > (data))
157 return boost::fusion::at_c<id>(data);
167 boost::fusion::at_c<0>(data) = p.template get<0>();
168 boost::fusion::at_c<1>(data) = p.template get<1>();
173 static bool noPointers()
202 template<
typename V,
typename E =
no_edge,
245 std::unordered_map<size_t, size_t>
id2glb;
248 std::unordered_map<size_t, size_t>
glb2id;
325 template<
typename CheckPolicy = NoCheck>
inline size_t addEdge_(
size_t v1,
size_t v2)
328 if (CheckPolicy::valid(v1,
v.
size()) ==
false)
330 if (CheckPolicy::valid(v2,
v.
size()) ==
false)
334 size_t id_x_end =
v_l.template get<0>(v1);
340 for (
size_t s = 0; s < id_x_end; s++)
342 if (
e_l.template get<e_map::vid>(v1 *
v_slot + s) == v2)
344 std::cerr <<
"Error graph: the edge already exist\n";
360 for (
size_t i = 0; i <
v.
size(); i++)
363 g_new.
v.set(i,
v, 2 * i);
381 e_l.template get<e_map::vid>(v1 *
v_slot + id_x_end) = v2;
389 ++
v_l.template get<0>(v1);
404 static void *
gr_receive(
size_t msg_i,
size_t total_msg,
size_t total_p,
size_t i,
size_t ri,
void * ptr)
408 v->get(i).allocate(msg_i);
410 return v->get(i).getPointer();
423 static void *
on_receive(
size_t msg_i,
size_t total_msg,
size_t total_p,
size_t i,
size_t ri,
void * ptr)
427 v->get(i).resize(msg_i /
sizeof(
size_t));
429 return &(v->get(i).get(0));
441 sgp.get(p).send_v.clear();
442 sgp.get(p).send_v_m.clear();
443 sgp.get(p).send_e.clear();
444 sgp.get(p).send_e_m.clear();
445 sgp.get(p).send_es.clear();
446 sgp.get(p).send_el.clear();
447 sgp.get(p).isEmpty =
true;
463 sgp.get(p).send_v = s_v;
464 sgp.get(p).send_v_m = s_v_m;
465 sgp.get(p).send_e = s_e;
466 sgp.get(p).send_e_m = s_e_m;
467 sgp.get(p).send_es = s_es;
468 sgp.get(p).send_el = s_el;
469 sgp.get(p).isEmpty =
true;
490 for (
size_t i = 0; i < this->
getNVertex(); ++i)
496 for (
size_t j = 0; j < this->
getNChilds(i); j++)
521 for (
size_t j = 0; j <
v_td.
size(); ++j)
523 if (i ==
v_td.get(j))
551 template<
bool addAsGhosts>
567 nvts +=
sgp.get(i).send_v.size();
574 if (
sgp.get(i).isEmpty)
580 size_t vp_size =
sgp.get(pc).send_v.size();
587 for (
size_t j = 0; j < vp_size; j++)
599 for (
size_t k = 0; k <
sgp.get(pc).send_es.get(j); k++)
625 for (
size_t j = 0; j < vp_size; j++)
637 for (
size_t k = 0; k <
sgp.get(pc).send_es.get(j); k++)
643 Packer<decltype(
sgp.get(pc).send_e_m.get(0)),
HeapMemory>::pack(mem,
sgp.get(pc).send_e_m.get(e_it), sts);
653 size.add(pmem.
size());
676 for (
size_t j = prev; j < prev + r_size; j++)
685 add_vertex(v_n, vm.template get<v_info::id>(), vm.template get<v_info::gid>());
688 ghs_map.insert( { vm.template get<v_info::gid>(),
false });
695 for (
size_t k = 0; k < s; k++)
710 addEdge(j, el_n, e_n, e_i);
745 for (
size_t i = 1; i <= recv.size(); ++i)
768 std::unordered_map<size_t, IdnProc> on_toup;
773 std::map<size_t, size_t> old_glob2loc(
glb2loc.begin(),
glb2loc.end());
783 for (
auto it : old_glob2loc)
786 IdnProc nidpid = { j, p_id };
787 on_toup.insert( {
v_m.get(it.second).template get<v_info::id>(), nidpid });
790 on_info.get(
getInfoProc(it.first)).add(
v_m.get(it.second).template get<v_info::id>());
794 map_v(j,
v_m.get(it.second).template get<v_info::gid>(), it.second);
809 fillSendRecvStructs<size_t>(on_info, prc, size, ptr);
819 for (
size_t j = 0; j < on_vs.get(i).
size() - 1; j += 2)
821 IdnProc nidpid = { on_vs.get(i).get(j + 1), i };
822 on_toup.insert( { on_vs.get(i).get(j), nidpid });
830 auto search = on_toup.find(glbi_map.at(k.first).id);
831 if (search != on_toup.end())
833 GlobalVInfo t = { (search->second).
id, (search->second).pid };
834 glbi_map.at(k.first) = t;
858 vni.get(pid).add(vid);
863 rmi_m.insert( { vid, glbi_map.at(vid).id });
868 rmi_m.insert( { vid,
glb2id.at(vid) });
877 fillSendRecvStructs<size_t>(vni, prc, size, ptr);
889 for (
size_t i = 0; i < req_rmi.size(); ++i)
891 for (
size_t j = 0; j < req_rmi.get(i).
size(); ++j)
893 resp_rmi.get(i).add(glbi_map.at(req_rmi.get(i).get(j)).
id);
898 fillSendRecvStructs<size_t>(resp_rmi, prc, size, ptr);
904 for (
size_t i = 0; i < rmi.size(); ++i)
906 for (
size_t j = 0; j < rmi.get(i).
size(); ++j)
908 rmi_m.insert( { vni.get(i).get(j), rmi.get(i).get(j) });
932 info.id =
v_m.get(i).template get<v_info::id>();
934 glbi_map.insert( {
v_m.get(i).template get<v_info::gid>(), info });
972 for (
size_t i = 0; i < vec.size(); ++i)
977 size.add(vec.get(i).size() *
sizeof(T));
978 ptr.add(vec.get(i).getPointer());
1011 dup.
v.swap(
v.duplicate());
1012 dup.
v_m.swap(
v_m.duplicate());
1013 dup.
v_l.swap(
v_l.duplicate());
1017 dup.
e.swap(
e.duplicate());
1018 dup.
e_m.swap(
e_m.duplicate());
1019 dup.
e_l.swap(
e_l.duplicate());
1032 vcl(create_vcluster())
1043 :
vcl(create_vcluster())
1079 v_m.resize(n_vertex);
1081 v_l.resize(n_vertex);
1194 template<
unsigned int i>
auto vertex_p(
size_t id) -> decltype(
v.template get<i>(
id) )
1196 return v.template get<i>(id);
1209 return v.template get<i>(id);
1235 return v.get(
id.
get(0));
1249 return v.get(
id.
get());
1259 auto vertex(
size_t id)
const ->
const decltype(
v.get(
id) )
1275 return v.get(
id.
get(0));
1289 return v.get(
id.
get());
1303 return v_m.get(
id.
get());
1320 std::cerr << __FILE__ <<
":" << __LINE__ <<
" The vertex with global id " <<
id <<
" is not in this sub-graph. Try to call reqVertex(" <<
id <<
") and sync() first.\n";
1321 ACTION_ON_ERROR(DIST_GRAPH_ERROR);
1326 return v.get(
glb2loc.find(
id)->second);
1341 }
catch (
const std::out_of_range& oor)
1343 std::cerr <<
"The vertex with global id " <<
id <<
" is not in this sub-graph. Try to call reqVertex(" <<
id <<
") and sync() first.\n";
1363 }
catch (
const std::out_of_range& oor)
1365 std::cout <<
"Node not found by glb: " <<
id << std::endl;
1396 return v_m.get(i).template get<v_info::id>();
1406 return v_m.get(i).template get<v_info::gid>();
1416 auto search =
glb2id.find(
id);
1418 if (search !=
glb2id.end())
1437 void map_v(
size_t n,
size_t g,
size_t l)
1439 id2glb.insert( { n, g });
1440 glb2id.insert( { g, n });
1442 v_m.get(l).template get<v_info::id>() = n;
1473 return e.template get<i>(id);
1484 template<
unsigned int i>
auto edge_p(
size_t id) -> decltype (
e.template get<i>(
id) )
1486 return e.template get<i>(id);
1498 return e.get(
id.
get(0));
1510 return e.get(
e_l.template get<e_map::eid>(ek.pos *
v_slot + ek.pos_e));
1527 }
catch (
const std::out_of_range& oor)
1529 std::cout <<
"The source vertex of this edge is not in this graph.\n";
1532 return e.get(
e_l.template get<e_map::eid>(v *
v_slot + ek.pos_e));
1544 auto edge(
size_t id)
const ->
const decltype (
e.get(
id) )
1558 return v_l.template get<0>(c);
1570 return v_l.template get<0>(c.get());
1585 }
catch (
const std::out_of_range& oor)
1587 std::cout <<
"The source vertex of this edge is not in this graph.\n";
1590 return v_l.template get<0>(
v);
1603 return e.get(
e_l.template get<e_map::eid>(
v *
v_slot + v_e));
1616 return e_m.get(
e_l.template get<e_map::eid>(
v *
v_slot + v_e));
1627 inline auto getEdge(
size_t v,
size_t v_e) -> decltype(
e.get(0))
1632 }
catch (
const std::out_of_range& oor)
1634 std::cout <<
"The source vertex of this edge is not in this graph.\n";
1637 return e.get(
e_l.template get<e_map::eid>(
v *
v_slot + v_e));
1651 if (i >=
v_l.template get<0>(v))
1653 std::cerr <<
"Error " << __FILE__ <<
" line: " << __LINE__ <<
" vertex " << v <<
" does not have edge " << i <<
" on processor " <<
vcl.
getProcessUnitID() <<
"\n";
1658 std::cerr <<
"Error " << __FILE__ <<
" " << __LINE__ <<
" vertex " << v <<
" does not have edge " << i <<
" on processor " <<
vcl.
getProcessUnitID() <<
" (" <<
e.
size() <<
"<=" <<
e_l.template get<e_map::eid>(v *
v_slot + i) <<
")\n";
1662 return e_l.template get<e_map::vid>(v *
v_slot + i);
1675 return e_l.template get<e_map::vid>(i);
1689 if (i >=
v_l.template get<0>(v.get()))
1691 std::cerr <<
"Error " << __FILE__ <<
" line: " << __LINE__ <<
" vertex " << v.get() <<
" does not have edge " << i <<
"\n";
1694 if (
e.
size() <=
e_l.template get<e_map::eid>(v.get() *
v_slot + i))
1696 std::cerr <<
"Error " << __FILE__ <<
" " << __LINE__ <<
" vertex " << v.get() <<
" does not have edge " << i <<
"\n";
1701 return e_l.template get<e_map::vid>(v.get() *
v_slot + i);
1714 vm.template get<v_info::id>() =
id;
1715 vm.template get<v_info::gid>() = gid;
1724 id2glb.insert( { id, gid });
1730 glb2id.insert( { gid,
id });
1749 vm.template get<v_info::id>() =
id;
1750 vm.template get<v_info::gid>() = gid;
1759 id2glb.insert( { id, gid });
1765 glb2id.insert( { gid,
id });
1792 v_m.template get<v_info::id>(l) = i;
1794 v_m.template get<v_info::gid>(l) = g;
1800 glb2id.insert( { g, i });
1803 id2glb.insert( { i, g });
1806 inline auto addEdge(
size_t v1,
size_t v2,
size_t srcgid,
size_t dstgid) -> decltype(
e.get(0))
1809 long int id_x_end = addEdge_<NoCheck>(v1, v2);
1811 if (id_x_end == NO_EDGE)
1815 e_m.template get<e_info::sgid>(id_x_end) = srcgid;
1816 e_m.template get<e_info::dgid>(id_x_end) = dstgid;
1819 return e.get(id_x_end);
1822 inline auto addEdge(
size_t v1,
size_t v2,
size_t srcgid,
size_t dstgid,
const E &
ed) -> decltype(
e.get(0))
1825 long int id_x_end = addEdge_<NoCheck>(v1, v2);
1827 if (id_x_end == NO_EDGE)
1831 e.set(id_x_end,
ed);
1834 e_m.template get<e_info::sgid>(id_x_end) = srcgid;
1835 e_m.template get<e_info::dgid>(id_x_end) = dstgid;
1838 return e.get(id_x_end);
1844 long int id_x_end = addEdge_<NoCheck>(v1, v2);
1846 if (id_x_end == NO_EDGE)
1850 e.set(id_x_end,
ed);
1851 e_m.set(id_x_end, ei);
1854 return e.get(id_x_end);
1857 inline auto addEdge(
size_t v1,
size_t v2,
const E &
ed,
const e_info & ei) -> decltype(
e.get(0))
1860 long int id_x_end = addEdge_<NoCheck>(v1, v2);
1862 if (id_x_end == NO_EDGE)
1866 e.set(id_x_end,
ed);
1867 e_m.set(id_x_end, ei);
1870 return e.get(id_x_end);
1881 size_t eid =
e_l.template get<e_map::eid>(v1 *
v_slot + s);
1882 return e_m.template get<e_info::sgid>(eid);
1893 size_t eid =
e_l.template get<e_map::eid>(v1 *
v_slot + s);
1894 return e_m.template get<e_info::dgid>(eid);
1902 template<
typename CheckPolicy = NoCheck>
inline void add_edge(
size_t v1,
size_t v2)
1914 EdgeReq er = { v1, v2, 0, 0 };
1921 long int id_x_end = addEdge_<CheckPolicy>(
glb2loc.at(v1),
glb2id.at(v2));
1924 if (id_x_end == NO_EDGE)
1928 e_m.get(id_x_end).template get<e_info::sgid>() = v1;
1929 e_m.get(id_x_end).template get<e_info::dgid>() = v2;
1941 for (
size_t i = 0; i <
e_queue.size(); ++i)
1952 long int id_x_end = addEdge_<>(req.v1n, req.v2n);
1955 if (id_x_end == NO_EDGE)
1959 e_m.get(id_x_end).template get<e_info::sgid>() = req.v1;
1960 e_m.get(id_x_end).template get<e_info::dgid>() = req.v2;
1990 size_t v_slot_tmp =
v_slot;
2018 size_t v_slot_tmp =
v_slot;
2020 g.v_slot = v_slot_tmp;
2032 return v.getIterator();
2096 auto search =
ghs_map.find(
id);
2136 e.resize(
e.
size() - epos);
2151 template<
bool toRemove = true>
2157 std::cerr <<
"Warning: " << __FILE__ <<
":" << __LINE__ <<
" target processor is equal the local processor\n";
2162 if (
sgp.get(t).isEmpty)
2163 sgp.get(t).isEmpty =
false;
2169 sgp.get(t).send_v_m.add(
v_m.get(i));
2195 if (
sgp.get(i).isEmpty)
2214 exchangeVertices<false>();
2261 fillSendRecvStructs<size_t>(
vr_queue, prc, size, ptr);
2267 for (
size_t i = 0; i < resp.size(); ++i)
2269 reqs.get(i).clear();
2271 for (
size_t j = 0; j < resp.get(i).
size(); ++j)
2275 reqs.get(i).add(
glbi_map.at(resp.get(i).get(j)).pid);
2276 }
catch (
const std::out_of_range& oor)
2278 std::cout << resp.get(i).get(j) <<
" not found in global info map (proc: " <<
vcl.
getProcessUnitID() <<
")\n";
2284 fillSendRecvStructs<size_t>(reqs, prc, size, ptr);
2303 for (
size_t j = 0; j < vr_queue.get(i).
size(); ++j)
2305 reqs.get(resp.get(i).get(j)).add(vr_queue.get(i).get(j));
2311 for (
size_t j = 0; j < vr_queue.get(i).
size(); ++j)
2313 reqs.get(
glbi_map.at(vr_queue.get(i).get(j)).pid).add(vr_queue.get(i).get(j));
2319 fillSendRecvStructs<size_t>(reqs, prc, size, ptr);
2328 for (
size_t i = 0; i < resp.size(); ++i)
2330 for (
size_t j = 0; j < resp.get(i).
size(); ++j)
2334 q_move<false>(
glb2loc.at(resp.get(i).get(j)), i);
2335 }
catch (
const std::out_of_range& oor)
2337 std::cout << resp.get(i).get(j) <<
" not found in global to local map (proc: " <<
vcl.
getProcessUnitID() <<
")\n";
2343 exchangeVertices<true>();
2374 template<
typename V,
typename E>
void exchangeVertices()
Send and receive vertices and update current graph.
void clear()
operator to clear the whole graph
void syncEdge()
Execute a synchronization through processor to finalize the add of the edges requested in the e_queue...
auto vertex_p(size_t id) -> decltype(v.template get< i >(id))
operator to access the vertex
DistGraph_CSR()
Constructor.
void add_vertex(const V &vrt, size_t id, size_t gid)
Add vertex vrt with global id and id properties.
openfpm::vector< V > send_v
vertex send buffer
size_t getTotNVertex() const
Return the total number of the vertices.
void q_move(size_t i, size_t t)
Prepare to send vertex i from the local processor to the target processor.
Transform the boost::fusion::vector into memory specification (memory_traits)
size_t getChild(size_t v, size_t i) const
Get the child edge.
DistGraph_CSR(Vcluster &vcl, DistGraph_CSR< V, E, Memory > &&g)
Copy constructor.
void deleteMovedVertices()
Remove from this graph the vertices that have been sent.
static void * gr_receive(size_t msg_i, size_t total_msg, size_t total_p, size_t i, size_t ri, void *ptr)
Callback to set the size of the receiving vector.
auto edge(size_t id) const -> const decltype(e.get(id))
operator to access the edge
openfpm::vector< size_t > send_es
For each vertex contain the number of children.
auto edge_p(grid_key_dx< 1 > id) -> decltype(e.template get< i >(id))
Access the edge.
Grow policy define how the vector should grow every time we exceed the size.
openfpm::vector< e_info > send_e_m
edge info send buffer
grid_key_dx is the key to access any element in the grid
openfpm::vector< idx_t > fvtxdist
Fixed distribution vector, it never changes, it maintains always the first decomposition and topology...
size_t getProcessUnitID()
Get the process unit id.
size_t nodeById(size_t id) const
operator to access the vertex position index by id property
size_t getVertexGlobalId(size_t i) const
Get the id of a vertex given its index position.
void execute()
Execute all the requests.
auto vertex(grid_key_dx< 1 > id) -> decltype(v.get(id.get(0)))
operator to access the vertex
Structure needed to get vertex position by global id.
openfpm::vector< idx_t > vtxdist
Distribution vector.
void getDecompositionVector(openfpm::vector< idx_t > &v)
Operator to access the decomposition vector.
void map_v(size_t n, size_t g, size_t l)
operator to update all the hashmap
std::unordered_map< size_t, bool > ghs_map
Map containing the ghost vertices of this graph, if bool is false the ghost will be deleted in the ne...
auto edge_p(size_t id) -> decltype(e.template get< i >(id))
Access the edge.
void swap(DistGraph_CSR< V, E > &g)
Swap the memory of g with this graph.
size_t getChildDstGid(size_t v1, size_t s)
Get the global id of edge's destination vertex.
size_t getNEdge(size_t v) const
Return the number of children of a vertex given its global id.
openfpm::vector< size_t > v_td
Array containing the sent vertices and that will be deleted from the graph.
size_t getNEdge() const
Return the number of edges.
openfpm::vector< SendGraphPack > sgp
Pack storing that data to send to other processors.
Structure to store a add request of an edge.
std::unordered_map< size_t, size_t > id2glb
Map to access to the global vertex id given the vertex id.
Vcluster & vcl
Vcluster communication object.
bool isToDelete(size_t i)
Check it the vertex i must be deleted or not.
void reqVertex(size_t gid)
Put a vertex request in queue.
openfpm::vector< e_map, Memory, typename memory_traits_lin< e_map >::type, layout_e_base, grow_p, openfpm::vect_isel< e_map >::value > e_l
Structure that store for each vertex the adjacent the vertex id and edge id (for property into e) ...
openfpm::vector< E, Memory, layout_e, layout_e_base, grow_p, openfpm::vect_isel< E >::value >::container E_container
Object container for the edge, for example can be encap<...> (map_grid or openfpm::vector) ...
Simplified implementation of DistGraph_CSR.
void deleteGhosts()
Remove all the ghosts from this graph.
openfpm::vector< E, Memory, layout_e, layout_e_base, grow_p, openfpm::vect_isel< E >::value > e
Structure that store the edge properties.
bool moveQueueIsEmpty()
Check if the move queue is empty.
auto getChildEdge(size_t v, size_t v_e) -> decltype(e.get(0))
Get the vertex edge.
DistGraph_CSR(const DistGraph_CSR &dg)
Constructor.
edge_iterator< DistGraph_CSR< V, E, Memory > > getEdgeIterator() const
Get the vertex iterator.
virtual size_t size() const
the the size of the allocated memory
void sendrecvMultipleMessagesNBX(openfpm::vector< size_t > &prc, openfpm::vector< T > &data, openfpm::vector< size_t > prc_recv, openfpm::vector< size_t > &recv_sz, void *(*msg_alloc)(size_t, size_t, size_t, size_t, size_t, void *), void *ptr_arg, long int opt=NONE)
Send and receive multiple messages.
void updateVtxdist()
Update the distribution vector vtxdist.
openfpm::vector< e_info, Memory, typename layout_e_base< e_info >::type, layout_e_base, grow_p, openfpm::vect_isel< e_info >::value > e_m
Structure that store the edge properties.
This class allocate, and destroy CPU memory.
size_t getNVertex() const
Return the number of the vertices in this subgraph.
size_t getChild(size_t i) const
Get the child edge.
void sync()
Execute all vertex requests and add them as ghosts inside this graph, they will be available until a ...
Implementation of VCluster class.
openfpm::vector< V, Memory, layout_v, layout_v_base, grow_p, openfpm::vect_isel< V >::value > v
Structure that store the vertex properties.
bool isGhost(size_t id)
Check if a vertex is a ghost vertex (not belonging to this processor)
std::unordered_map< size_t, size_t > glb2id
Map to access the vertex id given the global vertex id.
std::unordered_map< size_t, GlobalVInfo > glbi_map
TODO update description from pdf.
void fillSendRecvStructs(openfpm::vector< openfpm::vector< T >> &vec, openfpm::vector< size_t > &prc, openfpm::vector< size_t > &size, openfpm::vector< void * > &ptr)
Fill the prc, size and ptr structures with the data of vec.
auto vertex(size_t id) const -> const decltype(v.get(id))
Function to access the vertexes.
void remap()
Re-map received vertices in order to have ordered vertex ids.
DistGraph_CSR< V, E, Memory > & operator=(DistGraph_CSR< V, E, Memory > &&g)
Copy the graph.
void add_vertex(const encapc< dim, V, Mem > &vrt, size_t id, size_t gid)
Add vertex vrt with global id and id properties.
size_t getNChilds(typename openfpm::vector< V, Memory, layout_v, layout_v_base, grow_p, openfpm::vect_isel< V >::value >::iterator_key &c)
Return the number of childs of a vertex.
static size_t packRequest(const T &obj, size_t &req)
Error, no implementation.
DistGraph_CSR< V, E, Memory > & operator=(const DistGraph_CSR< V, E, Memory > &g)
Copy the graph.
It analyze the type given and it select correctly the implementation for vector.
void resetExchange()
Init communication structures.
size_t getVertexId(size_t i) const
Get the id of a vertex given its index position.
auto edge(grid_key_dx< 1 > id) const -> const decltype(e.get(id.get(0)))
Access the edge.
size_t getVProcessor(size_t v)
Get the processor of the the given vertex id, CAN be used BEFORE re-mapping starts.
size_t getChild(typename openfpm::vector< V, Memory, layout_v, layout_v_base, grow_p, openfpm::vect_isel< V >::value >::iterator_key &v, size_t i)
Get the child edge.
auto vertex(openfpm::vector_key_iterator id) -> decltype(v.get(0))
operator to access the vertex
DistGraph_CSR(size_t n_vertex, size_t n_slot)
Constructor.
openfpm::vector< size_t > send_el
For each edge contain the child vertex id.
size_t getInfoProc(size_t vid)
Get the processor id of the processor containing the vertex with global id vid.
auto vertex(openfpm::vector_key_iterator id) const -> const decltype(v.get(0))
operator to access the vertex
openfpm::vector< v_info, Memory, typename memory_traits_lin< v_info >::type, memory_traits_lin, grow_p, openfpm::vect_isel< v_info >::value > v_m
Structure that store the vertex id and global id.
virtual void incRef()
Increment the reference counter.
Structure that store a graph in CSR format or basically in compressed adjacency matrix format...
void initDistributionVector()
Initialize the vtxdist and the fvtxdist.
static void * on_receive(size_t msg_i, size_t total_msg, size_t total_p, size_t i, size_t ri, void *ptr)
Callback of the sendrecv to set the size of the array received.
Struct containing the (sub)graph to send.
void redistribute()
Redistribute function that wraps different stages of the redistribution.
auto vertex_info(openfpm::vector_key_iterator id) const -> const decltype(v_m.get(0))
operator to access the vertex info
openfpm::vector< size_t, Memory, typename layout_v_base< size_t >::type, layout_v_base, grow_p, openfpm::vect_isel< size_t >::value > v_l
Structure that store the number of adjacent vertex in e_l for each vertex.
auto vertex_p(grid_key_dx< 1 > id) -> decltype(v.template get< i >(id))
Access the vertex.
void * getPointerBase()
The the base pointer of the preallocate memory.
openfpm::vector< E, Memory, layout_e, layout_e_base, grow_p, openfpm::vect_isel< E >::value > e_invalid
invalid edge element, when a function try to create an in valid edge this object is returned ...
static void unpack(ExtPreAlloc< Mem >, T &obj)
Error, no implementation.
void initGlbimap()
Initialize the fixed structure for global mapping. See glbiv for details.
void swap(DistGraph_CSR< V, E > &&g)
Swap the memory of g with this graph.
openfpm::vector< V, Memory, layout_v, layout_v_base, grow_p, openfpm::vect_isel< V >::value >::container V_container
Object container for the vertex, for example can be encap<...> (map_grid or openfpm::vector) ...
void setGlobalMap(size_t g, size_t l, size_t i)
map global id to local id
DistGraph_CSR< V, E, Memory, layout_v, layout_e, layout_v_base, layout_e_base, grow_p > duplicate() const
It duplicate the graph.
size_t getNChilds(size_t c) const
Return the number of children of a vertex.
openfpm::vector< idx_t > * getVtxdist()
Operator to access the decomposition vector.
auto getChildInfo(size_t v, size_t v_e) -> decltype(e_m.get(0))
Get the vertex edge info.
size_t v1n
source vertex global index
auto getEdge(size_t v, size_t v_e) -> decltype(e.get(0))
Get the vertex edge given the vertex global id as source.
auto edge(edge_key ek) const -> const decltype(e.get(0))
operator to access the edge
auto getVertex(size_t id) const -> const decltype(v.get(0))
Function to access the vertexes.
void add_edge(size_t v1, size_t v2)
Add an edge between vertices v1 end v2, needs syncEdge() to complete the action.
void add_vertex(const V &vrt, size_t gid)
Add vertex vrt with global id and id properties.
size_t v_slot
number of slot per vertex
This class is a container for the memory interface like HeapMemory CudaMemory.
openfpm::vector< EdgeReq > e_queue
Queue of requests to add edges.
auto getVertex(size_t id) -> decltype(v.get(id))
Function to access the vertexes.
openfpm::vector< E > send_e
edge send buffer
DistGraph_CSR(DistGraph_CSR &&dg)
Constructor.
size_t addEdge_(size_t v1, size_t v2)
add edge on the graph
auto vertex(grid_key_dx< 1 > id) const -> const decltype(v.get(id.get(0)))
operator to access the vertex
bool vertexIsInThisGraph(size_t id)
Check if the vertex with GLOBAL id is in this graph.
auto getEdge(edge_key ek) const -> const decltype(e.get(0))
operator to access the edge
std::unordered_map< size_t, size_t > glb2loc
Map to access the local vertex id given the global one.
openfpm::vector< v_info > send_v_m
vertex info send buffer
static void pack(ExtPreAlloc< Mem >, const T &obj)
Error, no implementation.
auto getVertexIterator() const -> decltype(v.getIterator())
Get the vertex iterator.
size_t getProcessingUnits()
Get the total number of processors.
DistGraph_CSR(size_t n_vertex)
Constructor.
size_t getChildSrcGid(size_t v1, size_t s)
Get the global id of edge's source vertex.
bool allGather(T &send, openfpm::vector< T, Mem, gr > &v)
Gather the data from all processors.
auto vertex(size_t id) -> decltype(v.get(id))
Function to access the vertexes.
void init()
Once added all the vertices this function must be called to initialize all the properties, useless if a graph factory is used.
size_t v2n
destination vertex global index
void initDistributionVector(openfpm::vector< idx_t > &v)
Operator to access the decomposition vector.
openfpm::vector< openfpm::vector< size_t > > vr_queue
Queue of vertex requests.