Galois
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Morph_SepInOut_Graph.h
Go to the documentation of this file.
1 /*
2  * This file belongs to the Galois project, a C++ library for exploiting
3  * parallelism. The code is being released under the terms of the 3-Clause BSD
4  * License (a copy is located in LICENSE.txt at the top-level directory).
5  *
6  * Copyright (C) 2018, The University of Texas at Austin. All rights reserved.
7  * UNIVERSITY EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES CONCERNING THIS
8  * SOFTWARE AND DOCUMENTATION, INCLUDING ANY WARRANTIES OF MERCHANTABILITY,
9  * FITNESS FOR ANY PARTICULAR PURPOSE, NON-INFRINGEMENT AND WARRANTIES OF
10  * PERFORMANCE, AND ANY WARRANTY THAT MIGHT OTHERWISE ARISE FROM COURSE OF
11  * DEALING OR USAGE OF TRADE. NO WARRANTY IS EITHER EXPRESS OR IMPLIED WITH
12  * RESPECT TO THE USE OF THE SOFTWARE OR DOCUMENTATION. Under no circumstances
13  * shall University be liable for incidental, special, indirect, direct or
14  * consequential damages or loss of profits, interruption of business, or
15  * related expenses which may arise from use of Software or Documentation,
16  * including but not limited to those resulting from defects in Software and/or
17  * Documentation, or loss or inaccuracy of data of any kind.
18  */
19 
20 #ifndef GALOIS_GRAPH_MORPH_SEPINOUT_GRAPH_H
21 #define GALOIS_GRAPH_MORPH_SEPINOUT_GRAPH_H
22 
23 #include <algorithm>
24 #include <map>
25 #include <set>
26 #include <type_traits>
27 #include <vector>
28 
29 #include <boost/container/small_vector.hpp>
30 #include <boost/functional.hpp>
31 #include <boost/iterator/filter_iterator.hpp>
32 #include <boost/iterator/transform_iterator.hpp>
33 
34 #include "galois/Bag.h"
35 #include "galois/Galois.h"
36 #include "galois/graphs/Details.h"
38 #include "galois/gstl.h"
39 
40 #ifdef AUX_MAP
42 #else
45 #endif
46 
47 namespace galois {
49 namespace graphs {
50 
51 namespace internal {
55 template <typename NTy, typename ETy, bool DirectedButNotInOut>
56 struct UEdgeInfoBase;
57 
58 template <typename NTy, typename ETy>
59 struct UEdgeInfoBase<NTy, ETy, true> {
60  typedef ETy& reference;
61 
62  NTy* N;
63  ETy Ea;
64 
65  inline NTy* first() {
66  assert(N);
67  return N;
68  }
69  inline NTy const* first() const {
70  assert(N);
71  return N;
72  }
73  inline ETy* second() { return &Ea; }
74  inline const ETy* second() const { return &Ea; }
75 
76  template <typename... Args>
77  UEdgeInfoBase(NTy* n, ETy*, bool, Args&&... args)
78  : N(n), Ea(std::forward<Args>(args)...) {}
79 
80  template <typename... Args>
81  UEdgeInfoBase(NTy* n, ETy& v, bool, Args&&...) : N(n) {
82  Ea = v;
83  }
84 
85  static size_t sizeOfSecond() { return sizeof(ETy); }
86  bool isInEdge() const { return false; }
87 };
88 
89 template <typename NTy, typename ETy>
90 struct UEdgeInfoBase<NTy, ETy, false> {
91  typedef ETy& reference;
92 
93  NTy* N;
94  ETy* Ea;
95 
96  inline NTy* first() {
97  assert(N);
98  return (NTy*)((uintptr_t)N & ~1);
99  }
100  inline NTy const* first() const {
101  assert(N);
102  return (NTy*)((uintptr_t)N & ~1);
103  }
104  inline ETy* second() { return Ea; }
105  inline const ETy* second() const { return Ea; }
106  template <typename... Args>
107  UEdgeInfoBase(NTy* n, ETy* v, bool f, Args&&...)
108  : N((NTy*)((uintptr_t)n | f)), Ea(v) {}
109  static size_t sizeOfSecond() { return sizeof(ETy); }
110  bool isInEdge() const { return (uintptr_t)N & 1; }
111 };
112 
113 template <typename NTy>
114 struct UEdgeInfoBase<NTy, void, true> {
115  typedef char& reference;
116 
117  NTy* N;
118  inline NTy* first() { return N; }
119  inline NTy const* first() const { return N; }
120  inline char* second() const { return static_cast<char*>(NULL); }
121  inline char* addr() const { return second(); }
122  template <typename... Args>
123  UEdgeInfoBase(NTy* n, void*, bool, Args&&...) : N(n) {}
124  static size_t sizeOfSecond() { return 0; }
125  bool isInEdge() const { return false; }
126 };
127 
128 template <typename NTy>
129 struct UEdgeInfoBase<NTy, void, false> {
130  typedef char& reference;
131 
132  NTy* N;
133  inline NTy* first() { return (NTy*)((uintptr_t)N & ~1); }
134  inline NTy const* first() const { return (NTy*)((uintptr_t)N & ~1); }
135  inline char* second() const { return static_cast<char*>(NULL); }
136  inline char* addr() const { return second(); }
137  template <typename... Args>
138  UEdgeInfoBase(NTy* n, void*, bool f, Args&&...)
139  : N((NTy*)((uintptr_t)n | f)) {}
140  static size_t sizeOfSecond() { return 0; }
141  bool isInEdge() const { return (uintptr_t)N & 1; }
142 };
143 
144 /*
145  * Only graphs w/ in-out/symmetric edges and non-void edge data,
146  * i.e. ETy != void and DirectedNotInOut = false,
147  * need to allocate memory for edge data
148  */
149 template <typename ETy, bool DirectedNotInOut>
150 struct EdgeFactory {
152  template <typename... Args>
153  ETy* mkEdge(Args&&... args) {
154  return &mem.emplace(std::forward<Args>(args)...);
155  }
156  void delEdge(ETy*) {}
157  bool mustDel() const { return false; }
158 };
159 
160 template <typename ETy>
161 struct EdgeFactory<ETy, true> {
162  template <typename... Args>
163  ETy* mkEdge(Args&&...) {
164  return nullptr;
165  }
166  void delEdge(ETy*) {}
167  bool mustDel() const { return false; }
168 };
169 
170 template <>
171 struct EdgeFactory<void, false> {
172  template <typename... Args>
173  void* mkEdge(Args&&...) {
174  return static_cast<void*>(NULL);
175  }
176  void delEdge(void*) {}
177  bool mustDel() const { return false; }
178 };
179 
180 } // namespace internal
181 
233 template <typename NodeTy, typename EdgeTy, bool Directional,
234  bool InOut = false, bool HasNoLockable = false,
235  bool SortedNeighbors = false, typename FileEdgeTy = EdgeTy>
236 class Morph_SepInOut_Graph : private boost::noncopyable {
237 public:
239  template <bool _has_no_lockable>
241  typedef Morph_SepInOut_Graph<NodeTy, EdgeTy, Directional, InOut,
242  _has_no_lockable, SortedNeighbors, FileEdgeTy>
244  };
245 
246  template <typename _node_data>
247  struct with_node_data {
248  typedef Morph_SepInOut_Graph<_node_data, EdgeTy, Directional, InOut,
249  HasNoLockable, SortedNeighbors, FileEdgeTy>
251  };
252 
253  template <typename _edge_data>
254  struct with_edge_data {
255  typedef Morph_SepInOut_Graph<NodeTy, _edge_data, Directional, InOut,
256  HasNoLockable, SortedNeighbors, FileEdgeTy>
258  };
259 
260  template <typename _file_edge_data>
262  typedef Morph_SepInOut_Graph<NodeTy, EdgeTy, Directional, InOut,
263  HasNoLockable, SortedNeighbors,
264  _file_edge_data>
266  };
267 
268  template <bool _directional>
270  typedef Morph_SepInOut_Graph<NodeTy, EdgeTy, _directional, InOut,
271  HasNoLockable, SortedNeighbors, FileEdgeTy>
273  };
274 
275  template <bool _sorted_neighbors>
277  typedef Morph_SepInOut_Graph<NodeTy, EdgeTy, Directional, InOut,
278  HasNoLockable, _sorted_neighbors, FileEdgeTy>
280  };
281 
283 
284 private:
285  template <typename T>
286  struct first_eq_and_valid {
287  T N2;
288  first_eq_and_valid(T& n) : N2(n) {}
289  template <typename T2>
290  bool operator()(const T2& ii) const {
291  return ii.first() == N2 && ii.first() && ii.first()->active;
292  }
293  };
294 
295  struct first_not_valid {
296  template <typename T2>
297  bool operator()(const T2& ii) const {
298  return !ii.first() || !ii.first()->active;
299  }
300  };
301 
302  template <typename T>
303  struct first_lt {
304  template <typename T2>
305  bool operator()(const T& N2, const T2& ii) const {
306  assert(ii.first() && "UNEXPECTED: invalid item in edgelist");
307  return N2 < ii.first();
308  }
309  template <typename T2>
310  bool operator()(const T2& ii, const T& N2) const {
311  assert(ii.first() && "UNEXPECTED: invalid item in edgelist");
312  return ii.first() < N2;
313  }
314  };
315 
316  class gNode;
317  struct gNodeTypes
318  : public internal::NodeInfoBaseTypes<NodeTy, !HasNoLockable> {
320  typedef internal::UEdgeInfoBase<gNode, EdgeTy, Directional & !InOut>
321  EdgeInfo;
322 
324  // typedef llvm::SmallVector<EdgeInfo, 3> EdgesTy;
325  // typedef galois::gstl::Vector<EdgeInfo> EdgesTy;
326  typedef boost::container::small_vector<
328  EdgesTy;
329 
330  typedef typename EdgesTy::iterator iterator;
331  };
332 
333  class gNode : public internal::NodeInfoBase<NodeTy, !HasNoLockable>,
334  public gNodeTypes {
335  friend class Morph_SepInOut_Graph;
336  typedef internal::NodeInfoBase<NodeTy, !HasNoLockable> NodeInfo;
337  typename gNodeTypes::EdgesTy edges;
338  typename gNodeTypes::EdgesTy in_edges;
339  typedef typename gNode::iterator iterator;
340  typedef typename gNode::EdgeInfo EdgeInfo;
341 
342  bool active;
343 
344  iterator begin() { return edges.begin(); }
345  iterator end() { return edges.end(); }
346 
347  iterator in_edge_begin() { return in_edges.begin(); }
348  iterator in_edge_end() { return in_edges.end(); }
349 
350  void erase(iterator ii, bool inEdge = false) {
351  auto& edgelist = (inEdge) ? in_edges : edges;
352  if (SortedNeighbors) {
353  // For sorted case remove the element, moving following
354  // elements back to fill the space.
355  edgelist.erase(ii);
356  } else {
357  // We don't need to preserve the order, so move the last edge
358  // into this place and then remove last edge.
359  *ii = edgelist.back();
360  edgelist.pop_back();
361  }
362  }
363 
364  void erase(gNode* N, bool inEdge = false) {
365  iterator ii = find(N, inEdge);
366  erase(ii, inEdge);
367  }
368 
369  iterator find(gNode* N, bool inEdge = false) {
370  auto& edgelist = (inEdge) ? in_edges : edges;
371  iterator ii, ei = edgelist.end();
372  if (SortedNeighbors) {
373  assert(std::is_sorted(edgelist.begin(), edgelist.end(),
374  [=](const EdgeInfo& e1, const EdgeInfo& e2) {
375  return e1.first() < e2.first();
376  }));
377  ii = std::lower_bound(edgelist.begin(), edgelist.end(), N,
378  first_lt<gNode*>());
379  } else {
380  ii = edgelist.begin();
381  }
382 
383  first_eq_and_valid<gNode*> checker(N);
384  ii = std::find_if(ii, ei, checker);
385  while (ii != ei && ii->isInEdge() != inEdge) {
386  ++ii;
387  ii = std::find_if(ii, ei, checker);
388  };
389  return ii;
390  }
391 
392  void resizeEdges(size_t size, bool inEdge = false) {
393  auto& edgelist = (inEdge) ? in_edges : edges;
394  edgelist.resize(size, EdgeInfo(new gNode(), 0));
395  }
396 
397  template <typename... Args>
398  iterator createEdge(gNode* N, EdgeTy* v, bool inEdge, Args&&... args) {
399  iterator ii;
400  auto& edgelist = (inEdge) ? in_edges : edges;
401  if (SortedNeighbors) {
402  // If neighbors are sorted, find appropriate insertion point.
403  // Insert before first neighbor that is too far.
404  ii = std::upper_bound(edgelist.begin(), edgelist.end(), N,
405  first_lt<gNode*>());
406  } else
407  ii = edgelist.end();
408  return edgelist.insert(
409  ii, EdgeInfo(N, v, inEdge, std::forward<Args>(args)...));
410  }
411 
412  template <typename... Args>
413  iterator createEdgeWithReuse(gNode* N, EdgeTy* v, bool inEdge,
414  Args&&... args) {
415  auto& edgelist = (inEdge) ? in_edges : edges;
416  // Morph check for holes
417  iterator ii, ei;
418  if (SortedNeighbors) {
419  // If neighbors are sorted, find acceptable range for insertion.
420  ii = std::lower_bound(edgelist.begin(), edgelist.end(), N,
421  first_lt<gNode*>());
422  ei = std::upper_bound(ii, edgelist.end(), N, first_lt<gNode*>());
423  } else {
424  // If not sorted, we can insert anywhere in the list.
425  ii = edgelist.begin();
426  ei = edgelist.end();
427  }
428  ii = std::find_if(ii, ei, first_not_valid());
429  if (ii != ei) {
430  // FIXME: We could move elements around (short distances).
431  *ii = EdgeInfo(N, v, inEdge, std::forward<Args>(args)...);
432  return ii;
433  }
434  return edgelist.insert(
435  ei, EdgeInfo(N, v, inEdge, std::forward<Args>(args)...));
436  }
437 
438  template <bool _A1 = HasNoLockable>
439  void acquire(MethodFlag mflag, typename std::enable_if<!_A1>::type* = 0) {
440  galois::runtime::acquire(this, mflag);
441  }
442 
443  template <bool _A1 = HasNoLockable>
444  void acquire(MethodFlag, typename std::enable_if<_A1>::type* = 0) {}
445 
446  public:
447  template <typename... Args>
448  gNode(Args&&... args)
449  : NodeInfo(std::forward<Args>(args)...), active(false) {}
450  };
451 
452  // The graph manages the lifetimes of the data in the nodes and edges
453  typedef galois::InsertBag<gNode> NodeListTy;
454  NodeListTy nodes;
455 
456  internal::EdgeFactory<EdgeTy, Directional && !InOut> edgesF;
457 
458  // Helpers for iterator classes
459  struct is_node : public std::unary_function<gNode&, bool> {
460  bool operator()(const gNode& g) const { return g.active; }
461  };
462  struct is_edge
463  : public std::unary_function<typename gNodeTypes::EdgeInfo&, bool> {
464  bool operator()(typename gNodeTypes::EdgeInfo& e) const {
465  return e.first()->active;
466  }
467  };
468  struct is_in_edge
469  : public std::unary_function<typename gNodeTypes::EdgeInfo&, bool> {
470  bool operator()(typename gNodeTypes::EdgeInfo& e) const {
471  return e.first()->active && e.isInEdge();
472  }
473  };
474  struct is_out_edge
475  : public std::unary_function<typename gNodeTypes::EdgeInfo&, bool> {
476  bool operator()(typename gNodeTypes::EdgeInfo& e) const {
477  return e.first()->active && !e.isInEdge();
478  }
479  };
480  struct makeGraphNode : public std::unary_function<gNode&, gNode*> {
481  gNode* operator()(gNode& data) const { return &data; }
482  };
483 
484 public:
486  typedef gNode* GraphNode;
488  typedef EdgeTy edge_data_type;
490  typedef FileEdgeTy file_edge_data_type;
492  typedef NodeTy node_data_type;
494  typedef typename boost::filter_iterator<is_out_edge,
495  typename gNodeTypes::iterator>
498  typedef
499  typename boost::filter_iterator<is_in_edge, typename gNodeTypes::iterator>
502  typedef typename gNodeTypes::EdgeInfo::reference edge_data_reference;
504  typedef typename gNodeTypes::reference node_data_reference;
506  typedef boost::transform_iterator<
507  makeGraphNode,
508  boost::filter_iterator<is_node, typename NodeListTy::iterator>>
510 #ifdef AUX_MAP
511  struct ReadGraphAuxData {
512  LargeArray<GraphNode> nodes;
515  inNghs;
516  };
517 #else
518  struct AuxNode {
522  };
524 
525  constexpr static const bool DirectedNotInOut = (Directional && !InOut);
526  using ReadGraphAuxData =
527  typename std::conditional<DirectedNotInOut, LargeArray<GraphNode>,
529 #endif
530 
531 private:
532  template <typename... Args>
533  edge_iterator createEdgeWithReuse(GraphNode src, GraphNode dst,
534  galois::MethodFlag mflag, Args&&... args) {
535  assert(src);
536  assert(dst);
537  // galois::runtime::checkWrite(mflag, true);
538  src->acquire(mflag);
539  typename gNode::iterator ii = src->find(dst);
540  if (ii == src->end()) {
541  if (Directional && !InOut) {
542  ii = src->createEdgeWithReuse(dst, 0, false,
543  std::forward<Args>(args)...);
544  } else {
545  dst->acquire(mflag);
546  EdgeTy* e = edgesF.mkEdge(std::forward<Args>(args)...);
547  ii = dst->createEdgeWithReuse(src, e, Directional ? true : false,
548  std::forward<Args>(args)...);
549  ii = src->createEdgeWithReuse(dst, e, false,
550  std::forward<Args>(args)...);
551  }
552  }
553  return boost::make_filter_iterator(is_out_edge(), ii, src->end());
554  }
555 
556  template <typename... Args>
557  edge_iterator createEdge(GraphNode src, GraphNode dst,
558  galois::MethodFlag mflag, Args&&... args) {
559  assert(src);
560  assert(dst);
561  // galois::runtime::checkWrite(mflag, true);
562  src->acquire(mflag);
563  typename gNode::iterator ii = src->end();
564  if (ii == src->end()) {
565  if (Directional && !InOut) {
566  ii = src->createEdge(dst, 0, false, std::forward<Args>(args)...);
567  } else {
568  dst->acquire(mflag);
569  EdgeTy* e = edgesF.mkEdge(std::forward<Args>(args)...);
570  ii = dst->createEdge(src, e, Directional ? true : false,
571  std::forward<Args>(args)...);
572  ii = src->createEdge(dst, e, false, std::forward<Args>(args)...);
573  }
574  }
575  return boost::make_filter_iterator(is_out_edge(), ii, src->end());
576  }
577 
582  template <typename... Args>
583  EdgeTy* createOutEdge(GraphNode src, GraphNode dst, galois::MethodFlag mflag,
584  Args&&... args) {
585  assert(src);
586  assert(dst);
587 
588  src->acquire(mflag);
589  typename gNode::iterator ii = src->end();
590  if (ii == src->end()) {
591  dst->acquire(mflag);
592  EdgeTy* e = edgesF.mkEdge(std::forward<Args>(args)...);
593  ii = src->createEdge(dst, e, false, std::forward<Args>(args)...);
594  return e;
595  }
596  return nullptr;
597  }
598 
604  template <typename... Args>
605  void createInEdge(GraphNode src, GraphNode dst, EdgeTy* e,
606  galois::MethodFlag mflag, Args&&... args) {
607  assert(src);
608  assert(dst);
609 
610  dst->acquire(mflag);
611  typename gNode::iterator ii = dst->end();
612  if (ii == dst->end()) {
613  src->acquire(mflag);
614  ii = dst->createEdge(src, e, Directional ? true : false,
615  std::forward<Args>(args)...);
616  }
617  }
618 
619  template <bool _A1 = LargeArray<EdgeTy>::has_value,
620  bool _A2 = LargeArray<FileEdgeTy>::has_value>
621  EdgeTy*
622  constructOutEdgeValue(FileGraph& graph, typename FileGraph::edge_iterator nn,
623  GraphNode src, GraphNode dst,
624  typename std::enable_if<!_A1 || _A2>::type* = 0) {
625  typedef typename LargeArray<FileEdgeTy>::value_type FEDV;
626  typedef LargeArray<EdgeTy> ED;
627  if (ED::has_value) {
628  return createOutEdge(src, dst, galois::MethodFlag::UNPROTECTED,
629  graph.getEdgeData<FEDV>(nn));
630  } else {
631  return createOutEdge(src, dst, galois::MethodFlag::UNPROTECTED);
632  }
633  }
634 
635  template <bool _A1 = LargeArray<EdgeTy>::has_value,
636  bool _A2 = LargeArray<FileEdgeTy>::has_value>
637  EdgeTy*
638  constructOutEdgeValue(FileGraph&, typename FileGraph::edge_iterator,
639  GraphNode src, GraphNode dst,
640  typename std::enable_if<_A1 && !_A2>::type* = 0) {
641  return createOutEdge(src, dst, galois::MethodFlag::UNPROTECTED);
642  }
643 
644  // will reuse edge data from outgoing edges
645  void constructInEdgeValue(FileGraph&, EdgeTy* e, GraphNode src,
646  GraphNode dst) {
647  createInEdge(src, dst, e, galois::MethodFlag::UNPROTECTED);
648  }
649 
650 public:
655  template <typename... Args>
656  GraphNode createNode(Args&&... args) {
657  gNode* N = &(nodes.emplace(std::forward<Args>(args)...));
658  N->active = false;
659  return GraphNode(N);
660  }
661 
665  void addNode(const GraphNode& n,
667  // galois::runtime::checkWrite(mflag, true);
668  n->acquire(mflag);
669  n->active = true;
670  }
671 
674  getData(const GraphNode& n,
675  galois::MethodFlag mflag = MethodFlag::WRITE) const {
676  assert(n);
677  // galois::runtime::checkWrite(mflag, false);
678  n->acquire(mflag);
679  return n->getData();
680  }
681 
683  bool containsNode(const GraphNode& n,
684  galois::MethodFlag mflag = MethodFlag::WRITE) const {
685  assert(n);
686  n->acquire(mflag);
687  return n->active;
688  }
689 
694  // FIXME: handle edge memory
696  assert(n);
697  // galois::runtime::checkWrite(mflag, true);
698  n->acquire(mflag);
699  gNode* N = n;
700  if (N->active) {
701  N->active = false;
702  N->edges.clear();
703  N->in_edges.clear();
704  }
705  }
706 
711  void resizeEdges(GraphNode src, size_t size,
713  assert(src);
714  // galois::runtime::checkWrite(mflag, false);
715  src->acquire(mflag);
716  src->resizeEdges(size);
717  src->resizeEdges(size, true); // for incoming edges
718  }
719 
729  return createEdgeWithReuse(src, dst, mflag);
730  }
731 
734  template <typename... Args>
736  galois::MethodFlag mflag, Args&&... args) {
737  return createEdge(src, dst, mflag, std::forward<Args>(args)...);
738  }
739 
743  assert(src);
744  // galois::runtime::checkWrite(mflag, true);
745  src->acquire(mflag);
746  if (Directional && !InOut) {
747  src->erase(dst.base());
748  } else {
749  dst->first()->acquire(mflag);
750  // EdgeTy* e = dst->second();
751  dst->first()->erase(
752  src, Directional ? true : false); // erase incoming/symmetric edge
753  src->erase(dst.base());
754  }
755  }
756 
757  template <bool _DirectedInOut = (Directional && InOut)>
760  typename std::enable_if<_DirectedInOut>::type* = 0) {
761  assert(dst);
762 
763  dst->acquire(mflag);
764  src->first()->acquire(mflag);
765  // EdgeTy* e = src->second();
766  src->first()->erase(dst); // erase the outgoing edge
767  dst->erase(src.base(), true);
768  }
769 
773  assert(src);
774  assert(dst);
775  src->acquire(mflag);
776  typename gNodeTypes::iterator ii = src->find(dst), ei = src->end();
777  is_out_edge edge_predicate;
778  if (ii != ei && edge_predicate(*ii)) {
779  // After finding edge, lock dst and verify still active
780  dst->acquire(mflag);
781  if (!edge_predicate(*ii))
782  // I think we need this too, else we'll return some random iterator.
783  ii = ei;
784  } else
785  ii = ei;
786  return boost::make_filter_iterator(edge_predicate, ii, ei);
787  }
788 
792  assert(src);
793  assert(dst);
794  src->acquire(mflag);
795  assert(std::is_sorted(src->begin(), src->end(),
796  [=](const typename gNode::EdgeInfo& e1,
797  const typename gNode::EdgeInfo& e2) {
798  return e1.first() < e2.first();
799  }));
800 
801  auto ei = src->end();
802  auto ii =
803  std::lower_bound(src->begin(), src->end(), dst, first_lt<gNode*>());
804 
805  first_eq_and_valid<gNode*> checker(dst);
806  ii = std::find_if(ii, ei, checker); // bug if ei set to upper_bound
807  while (ii != ei && ii->isInEdge()) {
808  ++ii;
809  ii = std::find_if(ii, ei, checker);
810  };
811 
812  is_out_edge edge_predicate;
813  if (ii != ei) {
814  dst->acquire(mflag);
815  if (!edge_predicate(*ii)) {
816  ii = ei;
817  }
818  }
819  return boost::make_filter_iterator(edge_predicate, ii, ei);
820  }
821 
822  template <bool _Undirected = !Directional>
825  typename std::enable_if<_Undirected>::type* = 0) {
826  // incoming neighbors are the same as outgoing neighbors in undirected
827  // graphs
828  return findEdge(src, dst, mflag);
829  }
830 
831  // Find if an incoming edge between src and dst exists for directed in-out
832  // graphs
833  template <bool _DirectedInOut = (Directional && InOut)>
837  typename std::enable_if<_DirectedInOut>::type* = 0) {
838  assert(src);
839  assert(dst);
840  dst->acquire(mflag);
841  typename gNodeTypes::iterator ii = dst->find(src, true),
842  ei = dst->in_edge_end();
843  is_in_edge edge_predicate;
844  if (ii != ei && edge_predicate(*ii)) {
845  // After finding edges, lock dst and verify still active
846  src->acquire(mflag);
847  if (!edge_predicate(*ii))
848  // need this to avoid returning a random iterator
849  ii = ei;
850  } else
851  ii = ei;
852  return boost::make_filter_iterator(edge_predicate, ii, ei);
853  }
854 
865  assert(ii->first()->active);
866  // galois::runtime::checkWrite(mflag, false);
867  ii->first()->acquire(mflag);
868  return *ii->second();
869  }
870 
874  assert(ii->first()->active);
875  // galois::runtime::checkWrite(mflag, false);
876  ii->first()->acquire(mflag);
877  return *ii->second();
878  }
879 
882  assert(ii->first()->active);
883  return GraphNode(ii->first());
884  }
885 
887  assert(ii->first()->active);
888  return GraphNode(ii->first());
889  }
890 
893  acquire(N, mflag);
894  typedef typename gNode::EdgeInfo EdgeInfo;
895  auto eDstCompare = [=](const EdgeInfo& e1, const EdgeInfo& e2) {
896  return e1.first() < e2.first();
897  };
898  std::sort(N->begin(), N->end(), eDstCompare);
899  std::sort(N->in_edge_begin(), N->in_edge_end(), eDstCompare);
900  }
901 
904  galois::iterate(*this),
905  [=](GraphNode N) { this->sortEdgesByDst(N, mflag); }, galois::steal());
906  }
907 
909 
913  assert(N);
914  N->acquire(mflag);
915 
916  if (galois::runtime::shouldLock(mflag)) {
917  for (typename gNode::iterator ii = N->begin(), ee = N->end(); ii != ee;
918  ++ii) {
919  if (ii->first()->active && !ii->isInEdge())
920  ii->first()->acquire(mflag);
921  }
922  }
923  return boost::make_filter_iterator(is_out_edge(), N->begin(), N->end());
924  }
925 
926  template <bool _Undirected = !Directional>
929  typename std::enable_if<!_Undirected>::type* = 0) {
930  assert(N);
931  N->acquire(mflag);
932 
933  if (galois::runtime::shouldLock(mflag)) {
934  for (typename gNode::iterator ii = N->in_edge_begin(),
935  ee = N->in_edge_end();
936  ii != ee; ++ii) {
937  if (ii->first()->active && ii->isInEdge())
938  ii->first()->acquire(mflag);
939  }
940  }
941  return boost::make_filter_iterator(is_in_edge(), N->in_edge_begin(),
942  N->in_edge_end());
943  }
944 
945  template <bool _Undirected = !Directional>
948  typename std::enable_if<_Undirected>::type* = 0) {
949  return edge_begin(N, mflag);
950  }
951 
955  galois::MethodFlag GALOIS_UNUSED(mflag) = MethodFlag::WRITE) {
956  assert(N);
957  // Acquiring lock is not necessary: no valid use for an end pointer should
958  // ever require it
959  // N->acquire(mflag);
960  return boost::make_filter_iterator(is_out_edge(), N->end(), N->end());
961  }
962 
963  template <bool _Undirected = !Directional>
966  galois::MethodFlag GALOIS_UNUSED(mflag) = MethodFlag::WRITE,
967  typename std::enable_if<!_Undirected>::type* = 0) {
968  assert(N);
969  // Acquiring lock is not necessary: no valid use for an end pointer should
970  // ever require it
971  // N->acquire(mflag);
972  return boost::make_filter_iterator(is_in_edge(), N->in_edge_end(),
973  N->in_edge_end());
974  }
975 
976  template <bool _Undirected = !Directional>
979  typename std::enable_if<_Undirected>::type* = 0) {
980  return edge_end(N, mflag);
981  }
982 
985  return internal::make_no_deref_range(edge_begin(N, mflag),
986  edge_end(N, mflag));
987  }
988 
989  template <bool _Undirected = !Directional>
992  typename std::enable_if<!_Undirected>::type* = 0) {
993  return internal::make_no_deref_range(in_edge_begin(N, mflag),
994  in_edge_end(N, mflag));
995  }
996 
997  template <bool _Undirected = !Directional>
1000  typename std::enable_if<_Undirected>::type* = 0) {
1001  return edges(N, mflag);
1002  }
1003 
1008  internal::EdgesIterator<Morph_SepInOut_Graph>
1010  return internal::EdgesIterator<Morph_SepInOut_Graph>(*this, N, mflag);
1011  }
1012 
1017  return boost::make_transform_iterator(
1018  boost::make_filter_iterator(is_node(), nodes.begin(), nodes.end()),
1019  makeGraphNode());
1020  }
1021 
1024  return boost::make_transform_iterator(
1025  boost::make_filter_iterator(is_node(), nodes.end(), nodes.end()),
1026  makeGraphNode());
1027  }
1028 
1030 
1032  return boost::make_transform_iterator(
1033  boost::make_filter_iterator(is_node(), nodes.local_begin(),
1034  nodes.local_end()),
1035  makeGraphNode());
1036  }
1037 
1039  return boost::make_transform_iterator(
1040  boost::make_filter_iterator(is_node(), nodes.local_end(),
1041  nodes.local_end()),
1042  makeGraphNode());
1043  }
1044 
1048  unsigned int size() { return std::distance(begin(), end()); }
1049 
1051  size_t sizeOfEdgeData() const { return gNode::EdgeInfo::sizeOfSecond(); }
1052 
1053 #ifdef AUX_MAP
1054  void allocateFrom(FileGraph& graph, ReadGraphAuxData& aux) {
1055  size_t numNodes = graph.size();
1056  aux.nodes.allocateInterleaved(numNodes);
1057  }
1058 
1059  void constructNodesFrom(FileGraph& graph, unsigned tid, unsigned total,
1060  ReadGraphAuxData& aux) {
1061  auto r = graph
1062  .divideByNode(sizeof(gNode), sizeof(typename gNode::EdgeInfo),
1063  tid, total)
1064  .first;
1065  for (FileGraph::iterator ii = r.first, ei = r.second; ii != ei; ++ii) {
1066  aux.nodes[*ii] = createNode();
1067  addNode(aux.nodes[*ii], galois::MethodFlag::UNPROTECTED);
1068  }
1069  }
1070 
1071  void constructOutEdgesFrom(FileGraph& graph, unsigned tid, unsigned total,
1072  ReadGraphAuxData& aux) {
1073  auto r = graph
1074  .divideByNode(sizeof(gNode), sizeof(typename gNode::EdgeInfo),
1075  tid, total)
1076  .first;
1077  auto& map = aux.inNghs.get();
1078 
1079  for (FileGraph::iterator ii = r.first, ei = r.second; ii != ei; ++ii) {
1080  for (FileGraph::edge_iterator nn = graph.edge_begin(*ii),
1081  en = graph.edge_end(*ii);
1082  nn != en; ++nn) {
1083  auto dstID = graph.getEdgeDst(nn);
1084  auto src = aux.nodes[*ii], dst = aux.nodes[dstID];
1085  auto e = constructOutEdgeValue(graph, nn, src, dst);
1086  if (!Directional || InOut) {
1087  map[dstID].push_back({src, e});
1088  }
1089  }
1090  }
1091  }
1092 
1093  void constructInEdgesFrom(FileGraph& graph, unsigned tid, unsigned total,
1094  const ReadGraphAuxData& aux) {
1095  if (!Directional || InOut) {
1096  auto r = graph
1097  .divideByNode(sizeof(gNode),
1098  sizeof(typename gNode::EdgeInfo), tid, total)
1099  .first;
1100 
1101  for (size_t i = 0; i < aux.inNghs.numRows(); ++i) {
1102  const auto& map = aux.inNghs.get(i);
1103  auto ii = map.lower_bound(*(r.first)); // inclusive begin
1104  auto ei = map.lower_bound(*(r.second)); // exclusive end
1105  for (; ii != ei; ++ii) {
1106  auto dst = aux.nodes[ii->first];
1107  for (const auto& ie : ii->second) {
1108  constructInEdgeValue(graph, ie.second, ie.first, dst);
1109  }
1110  }
1111  }
1112  }
1113  }
1114 #else
1116  size_t numNodes = graph.size();
1117  aux.allocateInterleaved(numNodes);
1118 
1119  if (!DirectedNotInOut) {
1120  galois::do_all(galois::iterate(0ul, aux.size()),
1121  [&](size_t index) { aux.constructAt(index); });
1122  }
1123  }
1124 
1125  template <bool V = DirectedNotInOut>
1126  std::enable_if_t<!V> constructNodesFrom(FileGraph& graph, unsigned tid,
1127  unsigned total,
1128  ReadGraphAuxData& aux) {
1129  auto r = graph
1130  .divideByNode(sizeof(gNode), sizeof(typename gNode::EdgeInfo),
1131  tid, total)
1132  .first;
1133  for (FileGraph::iterator ii = r.first, ei = r.second; ii != ei; ++ii) {
1134  auto& auxNode = aux[*ii].get();
1135  auxNode.n = createNode();
1137  }
1138  }
1139 
1140  template <bool V = DirectedNotInOut>
1141  std::enable_if_t<V> constructNodesFrom(FileGraph& graph, unsigned tid,
1142  unsigned total,
1143  ReadGraphAuxData& aux) {
1144  auto r = graph
1145  .divideByNode(sizeof(gNode), sizeof(typename gNode::EdgeInfo),
1146  tid, total)
1147  .first;
1148  for (FileGraph::iterator ii = r.first, ei = r.second; ii != ei; ++ii) {
1149  aux[*ii] = createNode();
1151  }
1152  }
1153 
1154  template <bool V = DirectedNotInOut>
1155  std::enable_if_t<!V> constructOutEdgesFrom(FileGraph& graph, unsigned tid,
1156  unsigned total,
1157  ReadGraphAuxData& aux) {
1158  auto r = graph
1159  .divideByNode(sizeof(gNode), sizeof(typename gNode::EdgeInfo),
1160  tid, total)
1161  .first;
1162 
1163  for (FileGraph::iterator ii = r.first, ei = r.second; ii != ei; ++ii) {
1164  for (FileGraph::edge_iterator nn = graph.edge_begin(*ii),
1165  en = graph.edge_end(*ii);
1166  nn != en; ++nn) {
1167  auto src = aux[*ii].get().n;
1168  auto& dstAux = aux[graph.getEdgeDst(nn)].get();
1169  auto e = constructOutEdgeValue(graph, nn, src, dstAux.n);
1170  dstAux.lock.lock();
1171  dstAux.inNghs.push_back({src, e});
1172  dstAux.lock.unlock();
1173  }
1174  }
1175  }
1176 
1177  template <bool V = DirectedNotInOut>
1178  std::enable_if_t<V> constructOutEdgesFrom(FileGraph& graph, unsigned tid,
1179  unsigned total,
1180  const ReadGraphAuxData& aux) {
1181  auto r = graph
1182  .divideByNode(sizeof(gNode), sizeof(typename gNode::EdgeInfo),
1183  tid, total)
1184  .first;
1185 
1186  for (FileGraph::iterator ii = r.first, ei = r.second; ii != ei; ++ii) {
1187  for (FileGraph::edge_iterator nn = graph.edge_begin(*ii),
1188  en = graph.edge_end(*ii);
1189  nn != en; ++nn) {
1190  constructOutEdgeValue(graph, nn, aux[*ii], aux[graph.getEdgeDst(nn)]);
1191  }
1192  }
1193  }
1194 
1195  template <bool V = DirectedNotInOut>
1196  std::enable_if_t<!V> constructInEdgesFrom(FileGraph& graph, unsigned tid,
1197  unsigned total,
1198  ReadGraphAuxData& aux) {
1199  auto r = graph
1200  .divideByNode(sizeof(gNode), sizeof(typename gNode::EdgeInfo),
1201  tid, total)
1202  .first;
1203 
1204  for (FileGraph::iterator ii = r.first, ei = r.second; ii != ei; ++ii) {
1205  auto& auxNode = aux[*ii].get();
1206  for (auto ie : auxNode.inNghs) {
1207  constructInEdgeValue(graph, ie.second, ie.first, auxNode.n);
1208  }
1209  }
1210  }
1211 
1212  template <bool V = DirectedNotInOut>
1213  std::enable_if_t<V> constructInEdgesFrom(FileGraph&, unsigned, unsigned,
1214  ReadGraphAuxData&) {}
1215 #endif
1216 };
1217 
1218 } // namespace graphs
1219 } // namespace galois
1220 #endif
GraphNode createNode(Args &&...args)
Creates a new node holding the indicated data.
Definition: Morph_SepInOut_Graph.h:656
boost::filter_iterator< is_out_edge, typename gNodeTypes::iterator > edge_iterator
(Out or Undirected) Edge iterator
Definition: Morph_SepInOut_Graph.h:496
in_edge_iterator findInEdge(GraphNode src, GraphNode dst, galois::MethodFlag mflag=MethodFlag::WRITE, typename std::enable_if< _DirectedInOut >::type *=0)
Definition: Morph_SepInOut_Graph.h:835
internal::EdgesIterator< Morph_SepInOut_Graph > out_edges(GraphNode N, MethodFlag mflag=MethodFlag::WRITE)
An object with begin() and end() methods to iterate over the outgoing edges of N. ...
Definition: Morph_SepInOut_Graph.h:1009
reference emplace(Args &&...args)
Thread safe bag insertion.
Definition: Bag.h:260
std::enable_if_t<!V > constructOutEdgesFrom(FileGraph &graph, unsigned tid, unsigned total, ReadGraphAuxData &aux)
Definition: Morph_SepInOut_Graph.h:1155
edge_data_reference getEdgeData(in_edge_iterator ii, galois::MethodFlag mflag=MethodFlag::UNPROTECTED) const
Definition: Morph_SepInOut_Graph.h:872
std::enable_if_t< V > constructNodesFrom(FileGraph &graph, unsigned tid, unsigned total, ReadGraphAuxData &aux)
Definition: Morph_SepInOut_Graph.h:1141
Definition: Morph_SepInOut_Graph.h:247
edge_iterator findEdgeSortedByDst(GraphNode src, GraphNode dst, galois::MethodFlag mflag=MethodFlag::WRITE)
Definition: Morph_SepInOut_Graph.h:790
void resizeEdges(GraphNode src, size_t size, galois::MethodFlag mflag=MethodFlag::WRITE)
Resize the edges of the node.
Definition: Morph_SepInOut_Graph.h:711
boost::filter_iterator< is_in_edge, typename gNodeTypes::iterator > in_edge_iterator
In Edge iterator.
Definition: Morph_SepInOut_Graph.h:500
Morph_SepInOut_Graph< NodeTy, EdgeTy, Directional, InOut, HasNoLockable, SortedNeighbors, _file_edge_data > type
Definition: Morph_SepInOut_Graph.h:265
Morph_SepInOut_Graph< NodeTy, EdgeTy, Directional, InOut, _has_no_lockable, SortedNeighbors, FileEdgeTy > type
Definition: Morph_SepInOut_Graph.h:243
Definition: CacheLineStorage.h:32
read_with_aux_first_graph_tag read_tag
Definition: Morph_SepInOut_Graph.h:282
static constexpr const bool DirectedNotInOut
Definition: Morph_SepInOut_Graph.h:525
edge_iterator edge_begin(GraphNode N)
Returns the index to the beginning of global node N&#39;s outgoing edges in the outgoing edges array...
Definition: FileGraph.cpp:641
Contains FileGraph and FileGraphWriter class declarations.
edge_iterator findEdge(GraphNode src, GraphNode dst, galois::MethodFlag mflag=MethodFlag::WRITE)
Finds if an edge between src and dst exists.
Definition: Morph_SepInOut_Graph.h:771
gNodeTypes::reference node_data_reference
Reference to node data.
Definition: Morph_SepInOut_Graph.h:504
iterator begin()
Definition: Bag.h:238
size_t size() const
Returns the number of nodes in the (sub)graph.
Definition: FileGraph.h:545
galois::substrate::SimpleLock lock
Definition: Morph_SepInOut_Graph.h:519
void removeNode(GraphNode n, galois::MethodFlag mflag=MethodFlag::WRITE)
Removes a node from the graph along with all its outgoing/incoming edges for undirected graphs or out...
Definition: Morph_SepInOut_Graph.h:695
boost::counting_iterator< uint64_t > iterator
uint64 boost counting iterator
Definition: FileGraph.h:408
NodeTy node_data_type
Node data type.
Definition: Morph_SepInOut_Graph.h:492
GraphNode n
Definition: Morph_SepInOut_Graph.h:520
GraphNode getEdgeDst(edge_iterator ii)
Returns the destination of an edge.
Definition: Morph_SepInOut_Graph.h:881
GraphNode getEdgeDst(edge_iterator it)
Gets the destination of some edge.
Definition: FileGraph.cpp:669
node_data_reference getData(const GraphNode &n, galois::MethodFlag mflag=MethodFlag::WRITE) const
Gets the node data for a node.
Definition: Morph_SepInOut_Graph.h:674
local_iterator local_end()
Definition: Morph_SepInOut_Graph.h:1038
boost::counting_iterator< uint64_t > edge_iterator
Edge iterators (boost iterator)
Definition: FileGraph.h:248
iterator begin()
Returns an iterator to all the nodes in the graph.
Definition: Morph_SepInOut_Graph.h:1016
Definition: Iterable.h:36
local_iterator local_begin()
Definition: Bag.h:243
void sortAllEdgesByDst(MethodFlag mflag=MethodFlag::WRITE)
Definition: Morph_SepInOut_Graph.h:902
uint64_t GraphNode
type of a node
Definition: FileGraph.h:60
unsigned int size()
Returns the number of nodes in the graph.
Definition: Morph_SepInOut_Graph.h:1048
bool shouldLock(const galois::MethodFlag g)
Helper function to decide if the conflict detection lock should be taken.
Definition: libgalois/include/galois/runtime/Context.h:189
edge_iterator edge_end(GraphNode N, galois::MethodFlag GALOIS_UNUSED(mflag)=MethodFlag::WRITE)
Returns the end of the neighbor iterator.
Definition: Morph_SepInOut_Graph.h:954
std::enable_if_t<!V > constructNodesFrom(FileGraph &graph, unsigned tid, unsigned total, ReadGraphAuxData &aux)
Definition: Morph_SepInOut_Graph.h:1126
Definition: Morph_SepInOut_Graph.h:269
void allocateFrom(FileGraph &graph, ReadGraphAuxData &aux)
Definition: Morph_SepInOut_Graph.h:1115
void addNode(const GraphNode &n, galois::MethodFlag mflag=MethodFlag::WRITE)
Adds a node to the graph.
Definition: Morph_SepInOut_Graph.h:665
typename galois::substrate::CacheLineStorage< AuxNode > AuxNodePadded
Definition: Morph_SepInOut_Graph.h:523
void sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp)
Definition: ParallelSTL.h:247
gNode * GraphNode
Graph node handle.
Definition: Morph_SepInOut_Graph.h:486
FileEdgeTy file_edge_data_type
Edge data type of file we are loading this graph from.
Definition: Morph_SepInOut_Graph.h:490
Definition: Morph_SepInOut_Graph.h:254
size_t sizeOfEdgeData() const
Returns the size of edge data.
Definition: Morph_SepInOut_Graph.h:1051
iterator local_iterator
Definition: Morph_SepInOut_Graph.h:1029
iterator end()
Definition: Bag.h:239
std::vector< T, Pow2Alloc< T >> Vector
[STL vector using Pow_2_VarSizeAlloc]
Definition: gstl.h:52
Morph_SepInOut_Graph< NodeTy, EdgeTy, Directional, InOut, HasNoLockable, _sorted_neighbors, FileEdgeTy > type
Definition: Morph_SepInOut_Graph.h:279
void sortEdgesByDst(GraphNode N, galois::MethodFlag mflag=MethodFlag::WRITE)
Definition: Morph_SepInOut_Graph.h:891
Unordered collection of elements.
Definition: Bag.h:42
typename std::conditional< DirectedNotInOut, LargeArray< GraphNode >, LargeArray< AuxNodePadded >>::type ReadGraphAuxData
Definition: Morph_SepInOut_Graph.h:528
runtime::iterable< NoDerefIterator< in_edge_iterator > > in_edges(GraphNode N, galois::MethodFlag mflag=MethodFlag::WRITE, typename std::enable_if<!_Undirected >::type *=0)
Definition: Morph_SepInOut_Graph.h:991
Morph_SepInOut_Graph< _node_data, EdgeTy, Directional, InOut, HasNoLockable, SortedNeighbors, FileEdgeTy > type
Definition: Morph_SepInOut_Graph.h:250
std::enable_if_t< V > constructInEdgesFrom(FileGraph &, unsigned, unsigned, ReadGraphAuxData &)
Definition: Morph_SepInOut_Graph.h:1213
Definition: runtime/Mem.h:864
edge_iterator edge_begin(GraphNode N, galois::MethodFlag mflag=MethodFlag::WRITE)
Returns an iterator to the neighbors of a node.
Definition: Morph_SepInOut_Graph.h:911
Definition: Traits.h:206
Morph_SepInOut_Graph< NodeTy, _edge_data, Directional, InOut, HasNoLockable, SortedNeighbors, FileEdgeTy > type
Definition: Morph_SepInOut_Graph.h:257
void acquire(Lockable *lockable, galois::MethodFlag m)
Master function which handles conflict detection used to acquire a lockable thing.
Definition: libgalois/include/galois/runtime/Context.h:218
If true, do not use abstract locks in graph.
Definition: Morph_SepInOut_Graph.h:240
Large array of objects with proper specialization for void type and supporting various allocation and...
Definition: LargeArray.h:53
MethodFlag
What should the runtime do when executing a method.
Definition: MethodFlags.h:34
edge_iterator findInEdge(GraphNode src, GraphNode dst, galois::MethodFlag mflag=MethodFlag::WRITE, typename std::enable_if< _Undirected >::type *=0)
Definition: Morph_SepInOut_Graph.h:823
void operator()(void)
Definition: Executor_ParaMeter.h:417
GraphNode getEdgeDst(in_edge_iterator ii)
Definition: Morph_SepInOut_Graph.h:886
std::enable_if_t< V > constructOutEdgesFrom(FileGraph &graph, unsigned tid, unsigned total, const ReadGraphAuxData &aux)
Definition: Morph_SepInOut_Graph.h:1178
local_iterator local_begin()
Definition: Morph_SepInOut_Graph.h:1031
edge_data_reference getEdgeData(edge_iterator ii, galois::MethodFlag mflag=MethodFlag::UNPROTECTED) const
Returns the edge data associated with the edge.
Definition: Morph_SepInOut_Graph.h:863
void do_all(const RangeFunc &rangeMaker, FunctionTy &&fn, const Args &...args)
Standard do-all loop.
Definition: Loops.h:71
std::enable_if_t<!V > constructInEdgesFrom(FileGraph &graph, unsigned tid, unsigned total, ReadGraphAuxData &aux)
Definition: Morph_SepInOut_Graph.h:1196
in_edge_iterator in_edge_end(GraphNode N, galois::MethodFlag GALOIS_UNUSED(mflag)=MethodFlag::WRITE, typename std::enable_if<!_Undirected >::type *=0)
Definition: Morph_SepInOut_Graph.h:965
gNodeTypes::EdgeInfo::reference edge_data_reference
Reference to edge data.
Definition: Morph_SepInOut_Graph.h:502
edge_iterator in_edge_end(GraphNode N, galois::MethodFlag mflag=MethodFlag::WRITE, typename std::enable_if< _Undirected >::type *=0)
Definition: Morph_SepInOut_Graph.h:977
EdgeTy edge_data_type
Edge data type.
Definition: Morph_SepInOut_Graph.h:488
SimpleLock is a spinlock.
Definition: SimpleLock.h:36
bool containsNode(const GraphNode &n, galois::MethodFlag mflag=MethodFlag::WRITE) const
Checks if a node is in the graph.
Definition: Morph_SepInOut_Graph.h:683
void removeInEdge(GraphNode dst, in_edge_iterator src, galois::MethodFlag mflag=MethodFlag::WRITE, typename std::enable_if< _DirectedInOut >::type *=0)
Definition: Morph_SepInOut_Graph.h:758
GraphRange divideByNode(size_t nodeSize, size_t edgeSize, size_t id, size_t total)
Given a division and a total number of divisions, return a range for that particular division to work...
Definition: FileGraph.cpp:480
edge_iterator edge_end(GraphNode N)
Returns the index to the end of global node N&#39;s outgoing edges in the outgoing edges array...
Definition: FileGraph.cpp:655
edge_iterator in_edge_begin(GraphNode N, galois::MethodFlag mflag=MethodFlag::WRITE, typename std::enable_if< _Undirected >::type *=0)
Definition: Morph_SepInOut_Graph.h:946
boost::transform_iterator< makeGraphNode, boost::filter_iterator< is_node, typename NodeListTy::iterator > > iterator
Node iterator.
Definition: Morph_SepInOut_Graph.h:509
Definition: PerThreadContainer.h:523
Definition: Morph_SepInOut_Graph.h:518
galois::gstl::Vector< std::pair< GraphNode, EdgeTy * > > inNghs
Definition: Morph_SepInOut_Graph.h:521
Graph that mmaps Galois gr files for access.
Definition: FileGraph.h:57
Morph_SepInOut_Graph< NodeTy, EdgeTy, _directional, InOut, HasNoLockable, SortedNeighbors, FileEdgeTy > type
Definition: Morph_SepInOut_Graph.h:272
auto iterate(C &cont)
Definition: Range.h:323
InputIterator find_if(InputIterator first, InputIterator last, Predicate pred)
Definition: ParallelSTL.h:70
A Graph.
Definition: Morph_SepInOut_Graph.h:236
local_iterator local_end()
Definition: Bag.h:246
T value_type
Definition: Executor_ParaMeter.h:111
runtime::iterable< NoDerefIterator< edge_iterator > > edges(GraphNode N, galois::MethodFlag mflag=MethodFlag::WRITE)
Definition: Morph_SepInOut_Graph.h:984
in_edge_iterator in_edge_begin(GraphNode N, galois::MethodFlag mflag=MethodFlag::WRITE, typename std::enable_if<!_Undirected >::type *=0)
Definition: Morph_SepInOut_Graph.h:928
Definition: Morph_SepInOut_Graph.h:261
runtime::iterable< NoDerefIterator< edge_iterator > > in_edges(GraphNode N, galois::MethodFlag mflag=MethodFlag::WRITE, typename std::enable_if< _Undirected >::type *=0)
Definition: Morph_SepInOut_Graph.h:999
void removeEdge(GraphNode src, edge_iterator dst, galois::MethodFlag mflag=MethodFlag::WRITE)
Removes an edge from the graph.
Definition: Morph_SepInOut_Graph.h:741
iterator end()
Returns the end of the node iterator. Not thread-safe.
Definition: Morph_SepInOut_Graph.h:1023
edge_iterator addMultiEdge(GraphNode src, GraphNode dst, galois::MethodFlag mflag, Args &&...args)
Adds and initializes an edge to graph but does not check for duplicate edges.
Definition: Morph_SepInOut_Graph.h:735
edge_iterator addEdge(GraphNode src, GraphNode dst, galois::MethodFlag mflag=MethodFlag::WRITE)
Adds an edge to graph, replacing existing value if edge already exists.
Definition: Morph_SepInOut_Graph.h:727