OpenFPM_pdata  1.1.0
Project that contain the implementation of distributed structures
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Pages
map_graph.hpp
1 /*
2  * map_graph.hpp
3  *
4  * Created on: Nov 21, 2014
5  * Author: Pietro Incardona
6  *
7  *
8  * Graph structure that store a CSR graph format
9  *
10  * This Graph format is suppose to have a list of vertex that store an index x that indicate where
11  * in the adjacency list we have the list of all the neighborhood vertex, plus an adjacency list
12  * that store all the neighborhood for each vertex:
13  *
14  * In reality inside Graph_CSR
15  *
16  * VertexList store the Vertex index that indicate the end of the neighborhood list,
17  * the start is indicated by i * v_slot (id of the vertex, v_slot maximum number of
18  * neighborhood for a vertex)
19  *
20  * EdgeList store for each vertex at position i * v_slot (id of the vertex, v_slot maximum
21  * number of neighborhood for a vertex) the list of all the neighborhood of the vertex i
22  *
23  * Example
24  *
25  * Suppose an undirected graph of 4 vertex
26  *
27  * 1 -> 2 3 4
28  * 2 -> 1
29  * 3 -> 4 1
30  * 4 -> 1 3
31  *
32  * suppose that v_slot is 4 ( each vertex has less tha 4 neighborhood )
33  *
34  * we will have
35  *
36  * Vertex list 3 5 10 14
37  * Edge list 2 3 4 0 1 0 0 0 4 1 0 0 1 3 0 0
38  *
39  * Vertex properties and edge properties are stored in a separate structure
40  *
41  */
42 
43 #ifndef MAP_GRAPH_HPP_
44 #define MAP_GRAPH_HPP_
45 
46 #include "Vector/map_vector.hpp"
47 #include <unordered_map>
48 #ifdef METIS_GP
49 #include "metis_util.hpp"
50 #endif
51 
52 #define NO_EDGE -1
53 
57 class no_edge
58 {
59 public:
60 
62  typedef boost::fusion::vector<> type;
63 
66 
68  static const unsigned int max_prop = 0;
69 
70  static inline bool noPointers()
71  {
72  return true;
73  }
74 };
75 
76 template<typename V, typename E,
77  typename Memory,
78  typename layout_v,
79  typename layout_e,
80  template <typename> class layout_v_base,
81  template <typename> class layout_e_base,
82  typename grow_p>
83 class Graph_CSR;
84 
92 class e_map
93 {
94 public:
95  typedef boost::fusion::vector<size_t, size_t> type;
96 
97  type data;
98 
99  static const unsigned int vid = 0;
100  static const unsigned int eid = 1;
101  static const unsigned int max_prop = 2;
102 
103  // Setter method
104 
105  inline void setvid(size_t vid_)
106  {
107  boost::fusion::at_c<0>(data) = vid_;
108  }
109 
110  inline void seteid(size_t eid_)
111  {
112  boost::fusion::at_c<1>(data) = eid_;
113  }
114 
115  static inline bool noPointers()
116  {
117  return true;
118  }
119 };
120 
121 class edge_key
122 {
123 public:
124 
126  size_t pos;
127 
129  size_t pos_e;
130 
136  void begin()
137  {
138  pos = 0;
139  pos_e = 0;
140  }
141 
147  size_t & source()
148  {
149  return pos;
150  }
151 
158  size_t & target_t()
159  {
160  return pos_e;
161  }
162 };
163 
168 template<typename Graph>
170 {
172  const Graph & g;
173 
174  // Actual edge key
175  edge_key ek;
176 
177 public:
178 
185  edge_iterator(const Graph & g) :
186  g(g)
187  {
188  ek.begin();
189  }
190 
198  {
199  // Check if reach the end of the edge list
200  if (ek.pos_e + 1 >= g.getNChilds(ek.pos))
201  {
202  // increment the node position and reset
203  ek.pos++;
204  ek.pos_e = 0;
205 
206  // skip every vertex without edges
207  while (ek.pos < g.getNVertex() && g.getNChilds(ek.pos) == 0)
208  {
209  ek.pos++;
210  }
211  }
212  else
213  {
214  // increment the edge position
215  ek.pos_e++;
216  }
217 
218  return *this;
219  }
220 
229  bool isNext()
230  {
231  if (ek.pos < g.getNVertex())
232  {
234 
235  return true;
236  }
237 
239  return false;
240  }
241 
249  edge_key get()
250  {
251  return ek;
252  }
253 
259  size_t source()
260  {
261  return ek.pos;
262  }
263 
269  size_t target()
270  {
271  return g.getChild(ek.pos, ek.pos_e);
272  }
273 };
274 
301 template<typename V, typename E = no_edge,
302  typename Memory = HeapMemory,
303  typename layout_v = typename memory_traits_lin<V>::type,
304  typename layout_e = typename memory_traits_lin<E>::type,
305  template<typename> class layout_v_base = memory_traits_lin,
306  template<typename> class layout_e_base = memory_traits_lin,
307  typename grow_p = openfpm::grow_policy_double>
308 class Graph_CSR
309 {
311  size_t v_slot;
312 
315 
318 
321 
324 
327 
339  template<typename CheckPolicy = NoCheck> inline size_t addEdge_(size_t v1, size_t v2)
340  {
341  // If v1 and v2 does not satisfy some criteria return
342  if (CheckPolicy::valid(v1, v.size()) == false)
343  return NO_EDGE;
344  if (CheckPolicy::valid(v2, v.size()) == false)
345  return NO_EDGE;
346 
347  // get the number of adjacent vertex
348  size_t id_x_end = v_l.template get<0>(v1);
349 
350 #ifdef SE_CLASS1
351  // Check that v1 and v2 exist
352 
353  if (v1 >= v.size() || v2 >= v.size())
354  {
355  std::cout << "Warning graph: creating an edge between vertex that does not exist" << std::endl;
356  }
357 
358  // Check that the edge does not already exist
359 
360  for (size_t s = 0; s < id_x_end; s++)
361  {
362  if (e_l.template get<e_map::vid>(v1 * v_slot + s) == v2)
363  {
364  std::cerr << "Error graph: the edge already exist" << std::endl;
365  }
366  }
367 #endif
368 
369  // Check if there is space for another edge
370 
371  if (id_x_end >= v_slot)
372  {
373  // Unfortunately there is not space we need to reallocate memory
374  // Reallocate with double slot
375 
376  // Create an new Graph
377 
378  Graph_CSR<V, E> g_new(2 * v_slot, v.size());
379 
380  // Copy the graph
381 
382  for (size_t i = 0; i < v.size(); i++)
383  {
384  // copy the property from the old graph
385 
386  g_new.v.set(i, v, 2 * i);
387  }
388 
389  // swap the new graph with the old one
390 
391  swap(g_new);
392  }
393 
394  // Here we are sure than v and e has enough slots to store a new edge
395  // Check that e_l has enough space to store new edge
396  // should be always e.size == e_l.size
397 
398  if (id_x_end >= e_l.size())
399  {
400  // Resize the basic structure
401 
402  e_l.resize(v.size() * v_slot);
403  }
404 
405  // add in e_l the adjacent vertex for v1 and fill the edge id
406  e_l.template get<e_map::vid>(v1 * v_slot + id_x_end) = v2;
407  e_l.template get<e_map::eid>(v1 * v_slot + id_x_end) = e.size();
408 
409  // add an empty edge
410  e.resize(e.size() + 1);
411 
412  // Increment the ending point
413  ++v_l.template get<0>(v1);
414 
415  // return the created edge
416  return e.size() - 1;
417  }
418 
419 public:
420 
422  typedef V V_type;
423 
425  typedef E E_type;
426 
429 
432 
443  {
444  bool ret = true;
445 
446  // Check if they match
447 
448  ret &= (v_slot == g.v_slot);
449  ret &= (v == g.v);
450  ret &= (v_l == g.v_l);
451  ret &= (e == g.e);
452  ret &= (e_l == g.e_l);
453 
454  return ret;
455  }
456 
457 
464  {
466 
467  dup.v_slot = v_slot;
468 
470 
471  dup.v.swap(v.duplicate());
472  dup.v_l.swap(v_l.duplicate());
473  dup.e.swap(e.duplicate());
474  dup.e_l.swap(e_l.duplicate());
475  dup.e_invalid.swap(e_invalid.duplicate());
476 
477  return dup;
478  }
479 
486  :Graph_CSR(0, 16)
487  {
488  }
489 
497  Graph_CSR(size_t n_vertex) :
498  Graph_CSR(n_vertex, 16)
499  {
500  }
501 
510  Graph_CSR(size_t n_vertex, size_t n_slot)
511  :v_slot(n_slot)
512  {
514  v.resize(n_vertex);
516  v_l.resize(n_vertex);
518  v_l.fill(0);
520  e_invalid.resize(1);
521  }
522 
529  {
530  this->operator=(g);
531  }
532 
541  {
542  size_t vs_tmp = v_slot;
543  v_slot = g.v_slot;
544  g.v_slot = vs_tmp;
545  swap(g);
546 
547  return *this;
548  }
549 
556  {
557  swap(g.duplicate());
558 
559  v_slot = g.v_slot;
560 
561  return *this;
562  }
563 
574  template<unsigned int i> auto vertex_p(size_t id) -> decltype( v.template get<i>(id) )
575  {
576  return v.template get<i>(id);
577  }
578 
588  template<unsigned int i> auto vertex_p(grid_key_dx<1> id) -> decltype( v.template get<i>(id) )
589  {
590  return v.template get<i>(id);
591  }
592 
600  auto vertex(size_t id) -> decltype( v.get(id) )
601  {
602  return v.get(id);
603  }
604 
612  auto vertex(grid_key_dx<1> id) -> decltype( v.get(id.get(0)) )
613  {
614  return v.get(id.get(0));
615  }
616 
624  auto vertex(openfpm::vector_key_iterator id) -> decltype( v.get(0) )
625  {
626  return v.get(id.get());
627  }
628 
636  auto vertex(size_t id) const -> const decltype( v.get(id) )
637  {
638  return v.get(id);
639  }
640 
650  auto vertex(grid_key_dx<1> id) const -> const decltype( v.get(id.get(0)) )
651  {
652  return v.get(id.get(0));
653  }
654 
662  auto vertex(openfpm::vector_key_iterator id) const -> const decltype( v.get(0) )
663  {
664  return v.get(id.get());
665  }
666 
672  void clear()
673  {
674  v.clear();
675  e.clear();
676  v_l.clear();
677  e_l.clear();
678  e_invalid.clear();
679  }
680 
689  template<unsigned int i> auto edge_p(grid_key_dx<1> id) -> decltype ( e.template get<i>(id) )
690  {
691  return e.template get<i>(id);
692  }
693 
702  template<unsigned int i> auto edge_p(size_t id) -> decltype ( e.template get<i>(id) )
703  {
704  return e.template get<i>(id);
705  }
706 
707 
715  auto edge(edge_key ek) const -> const decltype ( e.get(0) )
716  {
717  return e.get(e_l.template get<e_map::eid>(ek.pos * v_slot + ek.pos_e));
718  }
719 
727  auto edge(size_t id) const -> const decltype ( e.get(id) )
728  {
729  return e.get(id);
730  }
731 
739  auto edge(grid_key_dx<1> id) const -> const decltype ( e.get(id.get(0)) )
740  {
741  return e.get(id.get(0));
742  }
743 
752  inline size_t getNChilds(size_t c) const
753  {
754  // Get the number of childs
755 
756  return v_l.template get<0>(c);
757  }
758 
766  inline size_t getNChilds(typename openfpm::vector<V, Memory, layout_v, layout_v_base, grow_p, openfpm::vect_isel<V>::value>::iterator_key & c)
767  {
768  // Get the number of childs
769 
770  return v_l.template get<0>(c.get());
771  }
772 
781  inline auto getChildEdge(size_t v, size_t v_e) -> decltype(e.get(0))
782  {
783  // Get the edge id
784  return e.get(e_l.template get<e_map::eid>(v * v_slot + v_e));
785  }
786 
796  inline size_t getChild(size_t v, size_t i) const
797  {
798 #ifdef SE_CLASS1
799  if (i >= v_l.template get<0>(v))
800  {
801  std::cerr << "Error " << __FILE__ << " line: " << __LINE__ << " vertex " << v << " does not have edge " << i << std::endl;
802  }
803 
804  if (i >= v_l.template get<0>(v))
805  {
806  std::cerr << "Error " << __FILE__ << " " << __LINE__ << " vertex " << v << " does not have edge "<< i << std::endl;
807  }
808 #endif
809  // Get the target vertex id
810  return e_l.template get<e_map::vid>(v * v_slot + i);
811  }
812 
822  {
823 #ifdef SE_CLASS1
824  if (i >= v_l.template get<0>(v.get()))
825  {
826  std::cerr << "Error " << __FILE__ << " line: " << __LINE__ << " vertex " << v.get() << " does not have edge " << i << std::endl;
827  }
828 
829  if (e.size() <= e_l.template get<e_map::eid>(v.get() * v_slot + i))
830  {
831  std::cerr << "Error " << __FILE__ << " " << __LINE__ << " vertex " << v.get() << " does not have edge "<< i << std::endl;
832  }
833 #endif
834 
835  // Get the edge id
836  return e_l.template get<e_map::vid>(v.get() * v_slot + i);
837  }
838 
844  inline void addVertex(const V & vrt)
845  {
846 
847  v.add(vrt);
848 
849  // Set the number of adjacent vertex for this vertex to 0
850 
851  v_l.add(0ul);
852 
853  // Add a slot for the vertex adjacency list
854 
855  e_l.resize(e_l.size() + v_slot);
856  }
857 
861  inline void addVertex()
862  {
863 
864  v.add();
865 
866  // Set the number of adjacent vertex for this vertex to 0
867 
868  v_l.add(0ul);
869 
870  // Add a slot for the vertex adjacency list
871 
872  e_l.resize(e_l.size() + v_slot);
873  }
874 
884  template<typename CheckPolicy = NoCheck> inline auto addEdge(size_t v1, size_t v2, const E & ed) -> decltype(e.get(0))
885  {
886  long int id_x_end = addEdge_<CheckPolicy>(v1, v2);
887 
888  // If there is not edge return an invalid edge, is a kind of stub object
889  if (id_x_end == NO_EDGE)
890  return e_invalid.get(0);
891 
892  // add in e_l the edge properties
893  e.set(id_x_end, ed);
894 
895  return e.get(id_x_end);
896  }
897 
908  template<typename CheckPolicy = NoCheck> inline auto addEdge(size_t v1, size_t v2) -> decltype(e.get(0))
909  {
911  long int id_x_end = addEdge_<CheckPolicy>(v1, v2);
912  // If there is not edge return an invalid edge, is a kind of stub object
913  if (id_x_end == NO_EDGE)
914  return e_invalid.get(0);
915 
917  return e.get(id_x_end);
918  }
919 
936  template<typename CheckPolicy = NoCheck, int sgid, int dgid> inline auto addEdge(size_t v1, size_t v2, size_t srcgid, size_t dstgid) -> decltype(e.get(0))
937  {
939  long int id_x_end = addEdge_<CheckPolicy>(v1, v2);
941  if (id_x_end == NO_EDGE)
942  return e_invalid.get(0);
943 
945  e.get(id_x_end).template get<sgid>() = srcgid;
946  e.get(id_x_end).template get<dgid>() = dstgid;
947 
949  return e.get(id_x_end);
950  }
951 
960  inline void swap(Graph_CSR<V, E> & g)
961  {
962  // switch the memory
963 
964  v.swap(g.v);
965  e.swap(g.e);
966  v_l.swap(g.v_l);
967  e_l.swap(g.e_l);
968  e_invalid.swap(g.e_invalid);
969 
970  size_t v_slot_tmp = g.v_slot;
971  g.v_slot = v_slot;
972  v_slot = v_slot_tmp;
973  }
974 
982  inline void swap(Graph_CSR<V, E> && g)
983  {
984  // switch the memory
985 
986  v.swap(g.v);
987  e.swap(g.e);
988  v_l.swap(g.v_l);
989  e_l.swap(g.e_l);
990  e_invalid.swap(g.e_invalid);
991 
992  size_t v_slot_tmp = g.v_slot;
993  g.v_slot = v_slot;
994  v_slot = v_slot_tmp;
995  }
996 
1005  inline auto getVertexIterator() const -> decltype(v.getIterator())
1006  {
1007  return v.getIterator();
1008  }
1009 
1019  {
1021  }
1022 
1029  inline size_t getNVertex() const
1030  {
1031  return v.size();
1032  }
1033 
1040  inline size_t getNEdge() const
1041  {
1042  return e.size();
1043  }
1044 };
1045 
1070 template<typename V, typename E>
1071 class Graph_CSR_s: public Graph_CSR<V, E>
1072 {
1073 
1074 };
1075 
1076 #endif /* MAP_GRAPH_HPP_ */
auto getVertexIterator() const -> decltype(v.getIterator())
Get the vertex iterator.
Definition: map_graph.hpp:1005
Graph_CSR< V, E, Memory > & operator=(const Graph_CSR< V, E, Memory > &g)
Definition: map_graph.hpp:555
Graph_CSR< V, E, Memory, layout_v, layout_e, layout_v_base, layout_e_base, grow_p > duplicate() const
It duplicate the graph.
Definition: map_graph.hpp:463
E E_type
Edge typedef.
Definition: map_graph.hpp:425
static const unsigned int max_prop
no properties
Definition: map_graph.hpp:68
void begin()
Reset the counter.
Definition: map_graph.hpp:136
const Graph & g
Graph.
Definition: map_graph.hpp:172
auto addEdge(size_t v1, size_t v2) -> decltype(e.get(0))
add edge on the graph
Definition: map_graph.hpp:908
Transform the boost::fusion::vector into memory specification (memory_traits)
Definition: memory_conf.hpp:93
auto vertex(openfpm::vector_key_iterator id) -> decltype(v.get(0))
Fuction to access the vertex.
Definition: map_graph.hpp:624
size_t getNEdge() const
Return the number of edges.
Definition: map_graph.hpp:1040
auto edge_p(size_t id) -> decltype(e.template get< i >(id))
Access the edge.
Definition: map_graph.hpp:702
void clear()
operator to clear the whole graph
Definition: map_graph.hpp:672
void addVertex(const V &vrt)
add vertex
Definition: map_graph.hpp:844
edge_iterator< Graph_CSR< V, E, Memory > > getEdgeIterator() const
Get the vertex iterator.
Definition: map_graph.hpp:1018
Grow policy define how the vector should grow every time we exceed the size.
grid_key_dx is the key to access any element in the grid
Definition: grid_key.hpp:18
Graph_CSR()
Constructor.
Definition: map_graph.hpp:485
size_t getChild(size_t v, size_t i) const
Get the child vertex id.
Definition: map_graph.hpp:796
Graph_CSR< V, E, Memory > & operator=(Graph_CSR< V, E, Memory > &&g)
Definition: map_graph.hpp:540
openfpm::vector< V, Memory, layout_v, layout_v_base, grow_p, openfpm::vect_isel< V >::value > v
Structure that store the vertex properties.
Definition: map_graph.hpp:314
auto vertex(grid_key_dx< 1 > id) const -> const decltype(v.get(id.get(0)))
Fuction to access the vertex.
Definition: map_graph.hpp:650
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.
Definition: map_graph.hpp:317
auto vertex(openfpm::vector_key_iterator id) const -> const decltype(v.get(0))
operator to access the vertex
Definition: map_graph.hpp:662
bool isNext()
Check if there is the next element.
Definition: map_graph.hpp:229
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) ...
Definition: map_graph.hpp:431
edge_iterator & operator++()
Get the next element.
Definition: map_graph.hpp:197
openfpm::vector< E, Memory, layout_e, layout_e_base, grow_p, openfpm::vect_isel< E >::value > e
Structure that store the edge properties.
Definition: map_graph.hpp:320
size_t v_slot
number of slot per vertex
Definition: map_graph.hpp:311
size_t size()
Stub size.
Definition: map_vector.hpp:70
edge_iterator(const Graph &g)
Constructor.
Definition: map_graph.hpp:185
openfpm::vector< e_map, Memory, typename layout_e_base< 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) ...
Definition: map_graph.hpp:323
size_t pos
Actual source node.
Definition: map_graph.hpp:126
Graph edge iterator.
Definition: map_graph.hpp:169
size_t source()
Return the source node.
Definition: map_graph.hpp:259
auto vertex_p(size_t id) -> decltype(v.template get< i >(id))
operator to access the vertex
Definition: map_graph.hpp:574
size_t pos_e
Actual target node.
Definition: map_graph.hpp:129
This class allocate, and destroy CPU memory.
Definition: HeapMemory.hpp:39
auto edge_p(grid_key_dx< 1 > id) -> decltype(e.template get< i >(id))
Access the edge.
Definition: map_graph.hpp:689
auto getChildEdge(size_t v, size_t v_e) -> decltype(e.get(0))
Get the vertex edge.
Definition: map_graph.hpp:781
size_t target()
Return the target node.
Definition: map_graph.hpp:269
bool operator==(const Graph_CSR< V, E, Memory, layout_v, layout_e, layout_v_base, layout_e_base, grow_p > &g) const
Check if two graph exactly match.
Definition: map_graph.hpp:442
auto edge(size_t id) const -> const decltype(e.get(id))
operator to access the edge
Definition: map_graph.hpp:727
size_t getChild(typename openfpm::vector< V, Memory, layout_v, layout_v_base, grow_p >::iterator_key &v, size_t i)
Get the child edge.
Definition: map_graph.hpp:821
V V_type
Vertex typedef.
Definition: map_graph.hpp:422
void swap(Graph_CSR< V, E > &&g)
swap the memory of g with this graph
Definition: map_graph.hpp:982
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
Definition: map_graph.hpp:936
size_t & target_t()
Return the target of this edge.
Definition: map_graph.hpp:158
It analyze the type given and it select correctly the implementation for vector.
Definition: vect_isel.hpp:36
class with no edge
Definition: map_graph.hpp:57
Structure that store a graph in CSR format or basically in compressed adjacency matrix format...
Definition: map_graph.hpp:83
type data
empty edge
Definition: map_graph.hpp:65
void addVertex()
add an empty vertex
Definition: map_graph.hpp:861
Graph_CSR(size_t n_vertex, size_t n_slot)
Constructor.
Definition: map_graph.hpp:510
auto addEdge(size_t v1, size_t v2, const E &ed) -> decltype(e.get(0))
add edge on the graph
Definition: map_graph.hpp:884
Graph_CSR(size_t n_vertex)
Constructor.
Definition: map_graph.hpp:497
auto vertex(size_t id) const -> const decltype(v.get(id))
Function to access the vertex.
Definition: map_graph.hpp:636
auto vertex(size_t id) -> decltype(v.get(id))
Function to access the vertex.
Definition: map_graph.hpp:600
size_t getNVertex() const
Return the number of the vertex.
Definition: map_graph.hpp:1029
void swap(Graph_CSR< V, E > &g)
swap the memory of g with this graph
Definition: map_graph.hpp:960
boost::fusion::vector type
type in case of no edge
Definition: map_graph.hpp:62
Structure used inside GraphCSR an edge.
Definition: map_graph.hpp:92
auto vertex(grid_key_dx< 1 > id) -> decltype(v.get(id.get(0)))
Function to access the vertex.
Definition: map_graph.hpp:612
size_t getNChilds(size_t c) const
Return the number of childs of a vertex.
Definition: map_graph.hpp:752
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 ...
Definition: map_graph.hpp:326
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) ...
Definition: map_graph.hpp:428
This class is a container for the memory interface like HeapMemory CudaMemory.
Definition: memory_c.hpp:31
Simplified implementation of Graph_CSR.
Definition: map_graph.hpp:1071
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.
Definition: map_graph.hpp:766
Graph_CSR(Graph_CSR< V, E, Memory > &&g)
Copy constructor.
Definition: map_graph.hpp:528
size_t & source()
Get the source id of this edge.
Definition: map_graph.hpp:147
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:61
size_t addEdge_(size_t v1, size_t v2)
add edge on the graph
Definition: map_graph.hpp:339
auto edge(edge_key ek) const -> const decltype(e.get(0))
operator to access the edge
Definition: map_graph.hpp:715
auto edge(grid_key_dx< 1 > id) const -> const decltype(e.get(id.get(0)))
Access the edge.
Definition: map_graph.hpp:739
auto vertex_p(grid_key_dx< 1 > id) -> decltype(v.template get< i >(id))
Access the vertex.
Definition: map_graph.hpp:588