46#include "Vector/map_vector.hpp"
47#include <unordered_map>
49#include "metis_util.hpp"
62 typedef boost::fusion::vector<>
type;
70 static inline bool noPointers()
76template<
typename V,
typename E,
78 template <
typename>
class layout_v_base,
79 template <
typename>
class layout_e_base,
93 typedef boost::fusion::vector<size_t, size_t> type;
97 static const unsigned int vid = 0;
98 static const unsigned int eid = 1;
99 static const unsigned int max_prop = 2;
103 inline void setvid(
size_t vid_)
105 boost::fusion::at_c<0>(data) = vid_;
108 inline void seteid(
size_t eid_)
110 boost::fusion::at_c<1>(data) = eid_;
113 static inline bool noPointers()
166template<
typename Graph>
198 if (ek.
pos_e + 1 >=
g.getNChilds(ek.
pos))
205 while (ek.
pos <
g.getNVertex() &&
g.getNChilds(ek.
pos) == 0)
229 if (ek.
pos <
g.getNVertex())
299template<
typename V,
typename E =
no_edge,
335 template<
typename CheckPolicy = NoCheck>
inline size_t addEdge_(
size_t v1,
size_t v2)
338 if (CheckPolicy::valid(v1,
v.size()) ==
false)
339 return (
size_t)NO_EDGE;
340 if (CheckPolicy::valid(v2,
v.size()) ==
false)
341 return (
size_t)NO_EDGE;
344 size_t id_x_end =
v_l.template get<0>(v1);
349 if (v1 >=
v.size() || v2 >=
v.size())
351 std::cout <<
"Warning graph: creating an edge between vertex that does not exist" << std::endl;
356 for (
size_t s = 0; s < id_x_end; s++)
358 if (
e_l.template get<e_map::vid>(v1 *
v_slot + s) == v2)
360 std::cerr <<
"Error graph: the edge already exist" << std::endl;
378 for (
size_t i = 0; i <
v.size(); i++)
382 g_new.
v.set(i,
v, 2 * i);
394 if (id_x_end >=
e_l.size())
402 e_l.template get<e_map::vid>(v1 *
v_slot + id_x_end) = v2;
403 e_l.template get<e_map::eid>(v1 *
v_slot + id_x_end) =
e.size();
406 e.resize(
e.size() + 1);
409 ++
v_l.template get<0>(v1);
467 dup.
v.swap(
v.duplicate());
468 dup.
v_l.swap(
v_l.duplicate());
469 dup.
e.swap(
e.duplicate());
470 dup.
e_l.swap(
e_l.duplicate());
512 v_l.resize(n_vertex);
570 template<
unsigned int i>
auto vertex_p(
size_t id) ->
decltype(
v.template get<i>(
id) )
572 return v.template get<i>(
id);
586 return v.template get<i>(
id);
596 auto vertex(
size_t id) ->
decltype(
v.get(
id) )
610 return v.get(
id.get(0));
622 return v.get(
id.get());
632 auto vertex(
size_t id)
const ->
const decltype(
v.get(
id) )
648 return v.get(
id.get(0));
660 return v.get(
id.get());
707 return e.template get<i>(
id);
718 template<
unsigned int i>
auto edge_p(
size_t id) ->
decltype (
e.template get<i>(
id) )
720 return e.template get<i>(
id);
733 return e.get(
e_l.template get<e_map::eid>(ek.pos *
v_slot + ek.pos_e));
743 auto edge(
size_t id)
const ->
const decltype (
e.get(
id) )
757 return e.get(
id.get(0));
772 return v_l.template get<0>(c);
786 return v_l.template get<0>(c.get());
800 return e.get(
e_l.template get<e_map::eid>(
v *
v_slot + v_e));
815 if (i >=
v_l.template get<0>(
v))
817 std::cerr <<
"Error " << __FILE__ <<
" line: " << __LINE__ <<
" vertex " <<
v <<
" does not have edge " << i << std::endl;
820 if (i >=
v_l.template get<0>(
v))
822 std::cerr <<
"Error " << __FILE__ <<
" " << __LINE__ <<
" vertex " <<
v <<
" does not have edge "<< i << std::endl;
826 return e_l.template get<e_map::vid>(
v *
v_slot + i);
840 if (i >=
v_l.template get<0>(
v.get()))
842 std::cerr <<
"Error " << __FILE__ <<
" line: " << __LINE__ <<
" vertex " <<
v.get() <<
" does not have edge " << i << std::endl;
845 if (
e.size() <=
e_l.template get<e_map::eid>(
v.get() *
v_slot + i))
847 std::cerr <<
"Error " << __FILE__ <<
" " << __LINE__ <<
" vertex " <<
v.get() <<
" does not have edge "<< i << std::endl;
852 return e_l.template get<e_map::vid>(
v.get() *
v_slot + i);
900 template<
typename CheckPolicy = NoCheck>
inline auto addEdge(
size_t v1,
size_t v2,
const E &
ed) ->
decltype(
e.get(0))
902 long int id_x_end = addEdge_<CheckPolicy>(v1, v2);
905 if (id_x_end == NO_EDGE)
911 return e.get(id_x_end);
924 template<
typename CheckPolicy = NoCheck>
inline auto addEdge(
size_t v1,
size_t v2) ->
decltype(
e.get(0))
927 long int id_x_end = addEdge_<CheckPolicy>(v1, v2);
929 if (id_x_end == NO_EDGE)
933 return e.get(id_x_end);
952 template<
typename CheckPolicy = NoCheck,
int sg
id,
int dg
id>
inline auto addEdge(
size_t v1,
size_t v2,
size_t srcgid,
size_t dstgid) ->
decltype(
e.get(0))
955 long int id_x_end = addEdge_<CheckPolicy>(v1, v2);
957 if (id_x_end == NO_EDGE)
961 e.get(id_x_end).template get<sgid>() = srcgid;
962 e.get(id_x_end).template get<dgid>() = dstgid;
965 return e.get(id_x_end);
986 size_t v_slot_tmp = g.
v_slot;
1008 size_t v_slot_tmp = g.v_slot;
1023 return v.getIterator();
1086template<
typename V,
typename E>
Simplified implementation of Graph_CSR.
Structure that store a graph in CSR format or basically in compressed adjacency matrix format.
auto vertex(size_t id) -> decltype(v.get(id))
Function to access the vertex.
auto edge_p(grid_key_dx< 1 > id) -> decltype(e.template get< i >(id))
Access the edge.
auto vertex(grid_key_dx< 1 > id) const -> const decltype(v.get(id.get(0)))
Fuction to access the vertex.
void addVertex(const V &vrt)
add vertex
size_t getChild(size_t v, size_t i) const
Get the child vertex id.
Graph_CSR(size_t n_vertex)
Constructor.
size_t getNEdge() const
Return the number of edges.
auto getVertexIterator() const -> decltype(v.getIterator())
Get the vertex iterator.
auto vertex(openfpm::vector_key_iterator id) const -> const decltype(v.get(0))
operator to access the vertex
auto addEdge(size_t v1, size_t v2) -> decltype(e.get(0))
add edge on the graph
openfpm::vector< e_map, Memory, 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)
void swap(Graph_CSR< V, E > &&g)
swap the memory of g with this graph
openfpm::vector< E, Memory, layout_e_base, grow_p, openfpm::vect_isel< E >::value > e
Structure that store the edge properties.
Graph_CSR(size_t n_vertex, size_t n_slot)
Constructor.
auto vertex_p(size_t id) -> decltype(v.template get< i >(id))
operator to access the vertex
Graph_CSR< V, E, Memory > & operator=(const Graph_CSR< V, E, Memory > &g)
size_t v_slot
number of slot per vertex
auto getChildEdge(size_t v, size_t v_e) -> decltype(e.get(0))
Get the vertex edge.
openfpm::vector< V, Memory, 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)
edge_iterator< Graph_CSR< V, E, Memory > > getEdgeIterator() const
Get the vertex iterator.
openfpm::vector< V, Memory, layout_v_base, grow_p, openfpm::vect_isel< V >::value > v
Structure that store the vertex properties.
bool operator==(const Graph_CSR< V, E, Memory, layout_v_base, layout_e_base, grow_p > &g) const
Check if two graph exactly match.
size_t getChild(typename openfpm::vector< V, Memory, layout_v_base, grow_p >::iterator_key &v, size_t i)
Get the child edge.
void addVertex()
add an empty vertex
void destroy()
operator to clear the whole graph
auto addEdge(size_t v1, size_t v2, size_t srcgid, size_t dstgid) -> decltype(e.get(0))
add edge on the graph and fill source and destination informations
size_t getNChilds(size_t c) const
Return the number of childs of a vertex.
auto vertex_p(grid_key_dx< 1 > id) -> decltype(v.template get< i >(id))
Access the vertex.
size_t getNChilds(typename openfpm::vector< V, Memory, layout_v_base, grow_p, openfpm::vect_isel< V >::value >::iterator_key &c)
Return the number of childs of a vertex.
auto edge_p(size_t id) -> decltype(e.template get< i >(id))
Access the edge.
openfpm::vector< E, Memory, 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
void clear()
operator to clear the whole graph
auto vertex(openfpm::vector_key_iterator id) -> decltype(v.get(0))
Fuction to access the vertex.
size_t addEdge_(size_t v1, size_t v2)
add edge on the graph
void swap(Graph_CSR< V, E > &g)
swap the memory of g with this graph
size_t getNVertex() const
Return the number of the vertex.
openfpm::vector< size_t, Memory, 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 edge(edge_key ek) const -> const decltype(e.get(0))
operator to access the edge
auto vertex(size_t id) const -> const decltype(v.get(id))
Function to access the vertex.
Graph_CSR< V, E, Memory, layout_v_base, layout_e_base, grow_p > duplicate() const
It duplicate the graph.
auto addEdge(size_t v1, size_t v2, const E &ed) -> decltype(e.get(0))
add edge on the graph
auto vertex(grid_key_dx< 1 > id) -> decltype(v.get(id.get(0)))
Function to access the vertex.
auto edge(size_t id) const -> const decltype(e.get(id))
operator to access the edge
auto edge(grid_key_dx< 1 > id) const -> const decltype(e.get(id.get(0)))
Access the edge.
Graph_CSR< V, E, Memory > & operator=(Graph_CSR< V, E, Memory > &&g)
Graph_CSR(Graph_CSR< V, E, Memory > &&g)
Copy constructor.
openfpm::vector< E, Memory, 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)
This class allocate, and destroy CPU memory.
Structure used inside GraphCSR an edge.
size_t target()
Return the target node.
bool isNext()
Check if there is the next element.
size_t source()
Return the source node.
edge_iterator & operator++()
Get the next element.
edge_iterator(const Graph &g)
Constructor.
edge_key get()
Get the actual key.
size_t pos
Actual source node.
void begin()
Reset the counter.
size_t & target_t()
Return the target of this edge.
size_t & source()
Get the source id of this edge.
size_t pos_e
Actual target node.
grid_key_dx is the key to access any element in the grid
static const unsigned int max_prop
no properties
boost::fusion::vector type
type in case of no edge
Grow policy define how the vector should grow every time we exceed the size.
Implementation of 1-D std::vector like structure.
Transform the boost::fusion::vector into memory specification (memory_traits)
It analyze the type given and it select correctly the implementation for vector.