Galois
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
MorphHyperGraph.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 
26 #ifndef GALOIS_GRAPHS_MORPHHYPERGRAPH_H
27 #define GALOIS_GRAPHS_MORPHHYPERGRAPH_H
28 
29 #include <algorithm>
30 #include <map>
31 #include <set>
32 #include <type_traits>
33 #include <vector>
34 
35 #include <boost/container/small_vector.hpp>
36 #include <boost/functional.hpp>
37 #include <boost/iterator/transform_iterator.hpp>
38 #include <boost/iterator/filter_iterator.hpp>
39 
40 #include "galois/Bag.h"
41 #include "galois/config.h"
42 #include "galois/Galois.h"
44 #include "galois/graphs/Details.h"
45 #include "galois/gstl.h"
46 
47 #ifdef AUX_MAP
49 #else
52 #endif
53 
54 namespace galois {
55 namespace graphs {
56 
57 namespace internal {
61 template <typename NTy, typename ETy, bool DirectedButNotInOut>
62 struct UEdgeInfoBase;
63 
64 template <typename NTy, typename ETy>
65 struct UEdgeInfoBase<NTy, ETy, true> {
66  typedef ETy& reference;
67 
68  NTy* N;
69  ETy Ea;
70 
71  inline NTy* first() {
72  assert(N);
73  return N;
74  }
75  inline NTy* first() const {
76  assert(N);
77  return N;
78  }
79  inline ETy* second() { return &Ea; }
80  inline const ETy* second() const { return &Ea; }
81 
82  template <typename... Args>
83  UEdgeInfoBase(NTy* n, ETy*, bool, Args&&... args)
84  : N(n), Ea(std::forward<Args>(args)...) {}
85 
86  template <typename... Args>
87  UEdgeInfoBase(NTy* n, ETy& v, bool, Args&&...) : N(n) {
88  Ea = v;
89  }
90 
91  static size_t sizeOfSecond() { return sizeof(ETy); }
92  bool isInEdge() const { return false; }
93 };
94 
95 template <typename NTy, typename ETy>
96 struct UEdgeInfoBase<NTy, ETy, false> {
97  typedef ETy& reference;
98 
99  NTy* N;
100  ETy* Ea;
101 
102  inline NTy* first() {
103  assert(N);
104  return (NTy*)((uintptr_t)N & ~1);
105  }
106  inline NTy* first() const {
107  assert(N);
108  return (NTy*)((uintptr_t)N & ~1);
109  }
110  inline ETy* second() { return Ea; }
111  inline const ETy* second() const { return Ea; }
112  template <typename... Args>
113  UEdgeInfoBase(NTy* n, ETy* v, bool f, Args&&...)
114  : N((NTy*)((uintptr_t)n | f)), Ea(v) {}
115  static size_t sizeOfSecond() { return sizeof(ETy); }
116  bool isInEdge() const { return (uintptr_t)N & 1; }
117 };
118 
119 template <typename NTy>
120 struct UEdgeInfoBase<NTy, void, true> {
121  typedef char& reference;
122 
123  NTy* N;
124  inline NTy* first() { return N; }
125  inline NTy* first() const { return N; }
126  inline char* second() const { return static_cast<char*>(NULL); }
127  inline char* addr() const { return second(); }
128  template <typename... Args>
129  UEdgeInfoBase(NTy* n, void*, bool, Args&&...) : N(n) {}
130  static size_t sizeOfSecond() { return 0; }
131  bool isInEdge() const { return false; }
132 };
133 
134 template <typename NTy>
135 struct UEdgeInfoBase<NTy, void, false> {
136  typedef char& reference;
137 
138  NTy* N;
139  inline NTy* first() { return (NTy*)((uintptr_t)N & ~1); }
140  inline NTy* first() const { return (NTy*)((uintptr_t)N & ~1); }
141  inline char* second() const { return static_cast<char*>(NULL); }
142  inline char* addr() const { return second(); }
143  template <typename... Args>
144  UEdgeInfoBase(NTy* n, void*, bool f, Args&&...)
145  : N((NTy*)((uintptr_t)n | f)) {}
146  static size_t sizeOfSecond() { return 0; }
147  bool isInEdge() const { return (uintptr_t)N & 1; }
148 };
149 
150 /*
151  * Only graphs w/ in-out/symmetric edges and non-void edge data,
152  * i.e. ETy != void and DirectedNotInOut = false,
153  * need to allocate memory for edge data
154  */
155 template <typename ETy, bool DirectedNotInOut>
156 struct EdgeFactory {
158  template <typename... Args>
159  ETy* mkEdge(Args&&... args) {
160  return &mem.emplace(std::forward<Args>(args)...);
161  }
162  void delEdge(ETy*) {}
163  bool mustDel() const { return false; }
164 };
165 
166 template <typename ETy>
167 struct EdgeFactory<ETy, true> {
168  template <typename... Args>
169  ETy* mkEdge(Args&&...) {
170  return nullptr;
171  }
172  void delEdge(ETy*) {}
173  bool mustDel() const { return false; }
174 };
175 
176 template <>
177 struct EdgeFactory<void, false> {
178  template <typename... Args>
179  void* mkEdge(Args&&...) {
180  return static_cast<void*>(NULL);
181  }
182  void delEdge(void*) {}
183  bool mustDel() const { return false; }
184 };
185 
186 } // namespace internal
187 
244 template <typename NodeTy, typename EdgeTy, bool Directional,
245  bool InOut = false, bool HasNoLockable = false,
246  bool SortedNeighbors = false, typename FileEdgeTy = EdgeTy>
247 class MorphHyperGraph : private boost::noncopyable {
248 public:
253  template <bool _has_no_lockable>
256  using type = MorphHyperGraph<NodeTy, EdgeTy, Directional, InOut,
257  _has_no_lockable, SortedNeighbors, FileEdgeTy>;
258  };
259 
263  template <typename _node_data>
264  struct with_node_data {
266  using type = MorphHyperGraph<_node_data, EdgeTy, Directional, InOut,
267  HasNoLockable, SortedNeighbors, FileEdgeTy>;
268  };
269 
273  template <typename _edge_data>
274  struct with_edge_data {
276  using type = MorphHyperGraph<NodeTy, _edge_data, Directional, InOut,
277  HasNoLockable, SortedNeighbors, FileEdgeTy>;
278  };
279 
283  template <typename _file_edge_data>
286  using type =
287  MorphHyperGraph<NodeTy, EdgeTy, Directional, InOut, HasNoLockable,
288  SortedNeighbors, _file_edge_data>;
289  };
290 
294  template <bool _directional>
297  using type = MorphHyperGraph<NodeTy, EdgeTy, _directional, InOut,
298  HasNoLockable, SortedNeighbors, FileEdgeTy>;
299  };
300 
304  template <bool _sorted_neighbors>
307  using type = MorphHyperGraph<NodeTy, EdgeTy, Directional, InOut,
308  HasNoLockable, _sorted_neighbors, FileEdgeTy>;
309  };
310 
313 
314 private:
315  template <typename T>
316  struct first_eq_and_valid {
317  T N2;
318  first_eq_and_valid(T& n) : N2(n) {}
319  template <typename T2>
320  bool operator()(const T2& ii) const {
321  return ii.first() == N2 && ii.first() && ii.first()->active;
322  }
323  };
324 
325  struct first_not_valid {
326  template <typename T2>
327  bool operator()(const T2& ii) const {
328  return !ii.first() || !ii.first()->active;
329  }
330  };
331 
332  template <typename T>
333  struct first_lt {
334  template <typename T2>
335  bool operator()(const T& N2, const T2& ii) const {
336  assert(ii.first() && "UNEXPECTED: invalid item in edgelist");
337  return N2 < ii.first();
338  }
339  template <typename T2>
340  bool operator()(const T2& ii, const T& N2) const {
341  assert(ii.first() && "UNEXPECTED: invalid item in edgelist");
342  return ii.first() < N2;
343  }
344  };
345 
346  // forward declaration for graph node type
347  class gNode;
348  struct gNodeTypes
349  : public internal::NodeInfoBaseTypes<NodeTy, !HasNoLockable> {
351  using EdgeInfo =
352  internal::UEdgeInfoBase<gNode, EdgeTy, Directional & !InOut>;
353 
355  // typedef galois::gstl::Vector<EdgeInfo> EdgesTy;
356  using EdgesTy = boost::container::small_vector<
358 
359  using iterator = typename EdgesTy::iterator;
360  };
361 
362  class gNode : public internal::NodeInfoBase<NodeTy, !HasNoLockable>,
363  public gNodeTypes {
365  friend class MorphHyperGraph;
367  using NodeInfo = internal::NodeInfoBase<NodeTy, !HasNoLockable>;
369  using iterator = typename gNode::iterator;
371  using EdgeInfo = typename gNode::EdgeInfo;
372 
374  typename gNodeTypes::EdgesTy edges;
375 
377  bool active;
378 
380  iterator begin() { return edges.begin(); }
382  iterator end() { return edges.end(); }
383 
386  void erase(iterator ii) {
387  if (SortedNeighbors) {
388  // For sorted case remove the element, moving following
389  // elements back to fill the space.
390  edges.erase(ii);
391  } else {
392  // We don't need to preserve the order, so move the last edge
393  // into this place and then remove last edge.
394  *ii = edges.back();
395  edges.pop_back();
396  }
397  }
398 
402  void erase(gNode* N, bool inEdge = false) {
403  iterator ii = find(N, inEdge);
404  if (ii != end())
405  edges.erase(ii);
406  }
407 
411  iterator find(gNode* N, bool inEdge = false) {
412  iterator ii, ei = edges.end();
413  // find starting point to start search
414  if (SortedNeighbors) {
415  assert(std::is_sorted(edges.begin(), edges.end(),
416  [=](const EdgeInfo& e1, const EdgeInfo& e2) {
417  return e1.first() < e2.first();
418  }));
419  ii =
420  std::lower_bound(edges.begin(), edges.end(), N, first_lt<gNode*>());
421  } else {
422  ii = edges.begin();
423  }
424 
425  first_eq_and_valid<gNode*> checker(N);
426  ii = std::find_if(ii, ei, checker);
427  while (ii != ei && ii->isInEdge() != inEdge) {
428  ++ii;
429  ii = std::find_if(ii, ei, checker);
430  };
431  return ii;
432  }
433 
437  void resizeEdges(size_t size) {
438  edges.resize(size, EdgeInfo(new gNode(), 0));
439  }
440 
444  template <typename... Args>
445  iterator createEdge(gNode* N, EdgeTy* v, bool inEdge, Args&&... args) {
446  iterator ii;
447  if (SortedNeighbors) {
448  // If neighbors are sorted, find appropriate insertion point.
449  // Insert before first neighbor that is too far.
450  ii =
451  std::upper_bound(edges.begin(), edges.end(), N, first_lt<gNode*>());
452  } else {
453  ii = edges.end();
454  }
455 
456  return edges.insert(ii,
457  EdgeInfo(N, v, inEdge, std::forward<Args>(args)...));
458  }
459 
464  template <typename... Args>
465  iterator createEdgeWithReuse(gNode* N, EdgeTy* v, bool inEdge,
466  Args&&... args) {
467  // First check for holes
468  iterator ii, ei;
469  if (SortedNeighbors) {
470  // If neighbors are sorted, find acceptable range for insertion.
471  ii =
472  std::lower_bound(edges.begin(), edges.end(), N, first_lt<gNode*>());
473  ei = std::upper_bound(ii, edges.end(), N, first_lt<gNode*>());
474  } else {
475  // If not sorted, we can insert anywhere in the list.
476  ii = edges.begin();
477  ei = edges.end();
478  }
479  ii = std::find_if(ii, ei, first_not_valid());
480  if (ii != ei) {
481  // FIXME: We could move elements around (short distances).
482  *ii = EdgeInfo(N, v, inEdge, std::forward<Args>(args)...);
483  return ii;
484  }
485  return edges.insert(ei,
486  EdgeInfo(N, v, inEdge, std::forward<Args>(args)...));
487  }
488 
489  template <bool _A1 = HasNoLockable>
490  void acquire(MethodFlag mflag, typename std::enable_if<!_A1>::type* = 0) {
491  galois::runtime::acquire(this, mflag);
492  }
493 
494  template <bool _A1 = HasNoLockable>
495  void acquire(MethodFlag, typename std::enable_if<_A1>::type* = 0) {}
496 
497  public:
498  int gain;
499  template <typename... Args>
500  gNode(Args&&... args)
501  : NodeInfo(std::forward<Args>(args)...), active(false) {}
502  };
503 
504  // The graph manages the lifetimes of the data in the nodes and edges
506  using NodeListTy = galois::InsertBag<gNode>;
507  using Bnodes = galois::InsertBag<gNode*>;
509  NodeListTy nodes;
510  Bnodes cells;
511  Bnodes nets;
512 
513  internal::EdgeFactory<EdgeTy, Directional && !InOut> edgesF;
514 
515  // Helpers for iterator classes
516  struct is_node : public std::unary_function<gNode&, bool> {
517  bool operator()(const gNode& g) const { return g.active; }
518  };
519  struct is_edge
520  : public std::unary_function<typename gNodeTypes::EdgeInfo&, bool> {
521  bool operator()(typename gNodeTypes::EdgeInfo& e) const {
522  return e.first()->active;
523  }
524  };
525  struct is_in_edge
526  : public std::unary_function<typename gNodeTypes::EdgeInfo&, bool> {
527  bool operator()(typename gNodeTypes::EdgeInfo& e) const {
528  return e.first()->active && e.isInEdge();
529  }
530  };
531  struct is_out_edge
532  : public std::unary_function<typename gNodeTypes::EdgeInfo&, bool> {
533  bool operator()(typename gNodeTypes::EdgeInfo& e) const {
534  return e.first()->active && !e.isInEdge();
535  }
536  };
537  struct makeGraphNode : public std::unary_function<gNode&, gNode*> {
538  gNode* operator()(gNode& data) const { return &data; }
539  };
540 
541 public:
542  using GraphNode = gNode*;
545  using edge_data_type = EdgeTy;
547  using file_edge_data_type = FileEdgeTy;
549  using node_data_type = NodeTy;
551  using edge_iterator =
552  typename boost::filter_iterator<is_out_edge,
553  typename gNodeTypes::iterator>;
555  using in_edge_iterator =
556  typename boost::filter_iterator<is_in_edge,
557  typename gNodeTypes::iterator>;
558 
560  using edge_data_reference = typename gNodeTypes::EdgeInfo::reference;
562  using node_data_reference = typename gNodeTypes::reference;
564  using iterator = boost::transform_iterator<
565  makeGraphNode,
566  boost::filter_iterator<is_node, typename NodeListTy::iterator>>;
567 
571  std::list<int> freeCells;
572 
575 #ifdef AUX_MAP
576  struct ReadGraphAuxData {
579  LargeArray<GraphNode> nodes;
583  inNghs;
584  };
585 #else
586  struct AuxNode {
595  };
598 
601  constexpr static const bool DirectedNotInOut = (Directional && !InOut);
603  using ReadGraphAuxData =
604  typename std::conditional<DirectedNotInOut, LargeArray<GraphNode>,
606 #endif
607 
608 private:
609  template <typename... Args>
610  edge_iterator createEdgeWithReuse(GraphNode src, GraphNode dst,
611  galois::MethodFlag mflag, Args&&... args) {
612  assert(src);
613  assert(dst);
614  // galois::runtime::checkWrite(mflag, true);
615  src->acquire(mflag);
616  typename gNode::iterator ii = src->find(dst);
617  // add edge only if it doesn't already exist
618  if (ii == src->end()) {
619  if (Directional && !InOut) {
620  ii = src->createEdgeWithReuse(dst, 0, false,
621  std::forward<Args>(args)...);
622  } else {
623  dst->acquire(mflag);
624  EdgeTy* e = edgesF.mkEdge(std::forward<Args>(args)...);
625  ii = dst->createEdgeWithReuse(src, e, Directional ? true : false,
626  std::forward<Args>(args)...);
627  ii = src->createEdgeWithReuse(dst, e, false,
628  std::forward<Args>(args)...);
629  }
630  }
631  return boost::make_filter_iterator(is_out_edge(), ii, src->end());
632  }
633 
634  template <typename... Args>
635  edge_iterator createEdge(GraphNode src, GraphNode dst,
636  galois::MethodFlag mflag, Args&&... args) {
637  assert(src);
638  assert(dst);
639  // galois::runtime::checkWrite(mflag, true);
640  src->acquire(mflag);
641  typename gNode::iterator ii = src->end();
642  // add edge only if it doesn't already exist
643  if (ii == src->end()) {
644  if (Directional && !InOut) {
645  ii = src->createEdge(dst, 0, false, std::forward<Args>(args)...);
646  } else {
647  dst->acquire(mflag);
648  EdgeTy* e = edgesF.mkEdge(std::forward<Args>(args)...);
649  ii = dst->createEdge(src, e, Directional ? true : false,
650  std::forward<Args>(args)...);
651  ii = src->createEdge(dst, e, false, std::forward<Args>(args)...);
652  }
653  }
654  return boost::make_filter_iterator(is_out_edge(), ii, src->end());
655  }
656 
661  template <typename... Args>
662  EdgeTy* createOutEdge(GraphNode src, GraphNode dst, galois::MethodFlag mflag,
663  Args&&... args) {
664  assert(src);
665  assert(dst);
666 
667  src->acquire(mflag);
668  typename gNode::iterator ii = src->end();
669  if (ii == src->end()) {
670  dst->acquire(mflag);
671  EdgeTy* e = edgesF.mkEdge(std::forward<Args>(args)...);
672  ii = src->createEdge(dst, e, false, std::forward<Args>(args)...);
673  return e;
674  }
675  return nullptr;
676  }
677 
683  template <typename... Args>
684  void createInEdge(GraphNode src, GraphNode dst, EdgeTy* e,
685  galois::MethodFlag mflag, Args&&... args) {
686  assert(src);
687  assert(dst);
688 
689  dst->acquire(mflag);
690  typename gNode::iterator ii = dst->end();
691  if (ii == dst->end()) {
692  src->acquire(mflag);
693  ii = dst->createEdge(src, e, Directional ? true : false,
694  std::forward<Args>(args)...);
695  }
696  }
697 
698  template <bool _A1 = LargeArray<EdgeTy>::has_value,
699  bool _A2 = LargeArray<FileEdgeTy>::has_value>
700  EdgeTy*
701  constructOutEdgeValue(FileGraph& graph, typename FileGraph::edge_iterator nn,
702  GraphNode src, GraphNode dst,
703  typename std::enable_if<!_A1 || _A2>::type* = 0) {
704  typedef typename LargeArray<FileEdgeTy>::value_type FEDV;
705  typedef LargeArray<EdgeTy> ED;
706  if (ED::has_value) {
707  return createOutEdge(src, dst, galois::MethodFlag::UNPROTECTED,
708  graph.getEdgeData<FEDV>(nn));
709  } else {
710  return createOutEdge(src, dst, galois::MethodFlag::UNPROTECTED);
711  }
712  }
713 
714  template <bool _A1 = LargeArray<EdgeTy>::has_value,
715  bool _A2 = LargeArray<FileEdgeTy>::has_value>
716  EdgeTy*
717  constructOutEdgeValue(FileGraph&, typename FileGraph::edge_iterator,
718  GraphNode src, GraphNode dst,
719  typename std::enable_if<_A1 && !_A2>::type* = 0) {
720  return createOutEdge(src, dst, galois::MethodFlag::UNPROTECTED);
721  }
722 
723  // will reuse edge data from outgoing edges
724  void constructInEdgeValue(FileGraph&, EdgeTy* e, GraphNode src,
725  GraphNode dst) {
726  createInEdge(src, dst, e, galois::MethodFlag::UNPROTECTED);
727  }
728 
729 public
730  :
731 
738  template <typename... Args>
739  GraphNode createNode(Args&&... args) {
740  gNode* N = &(nodes.emplace(std::forward<Args>(args)...));
741  N->active = false;
742  return GraphNode(N);
743  }
744 
748  void addNode(const GraphNode& n,
750  // galois::runtime::checkWrite(mflag, true);
751  n->acquire(mflag);
752  n->active = true;
753  }
754 
757  getData(const GraphNode& n,
758  galois::MethodFlag mflag = MethodFlag::WRITE) const {
759  assert(n);
760  // galois::runtime::checkWrite(mflag, false);
761  n->acquire(mflag);
762  return n->getData();
763  }
764 
767  bool containsNode(const GraphNode& n,
768  galois::MethodFlag mflag = MethodFlag::WRITE) const {
769  assert(n);
770  n->acquire(mflag);
771  return n->active;
772  }
773 
781  assert(n);
782  // galois::runtime::checkWrite(mflag, true);
783  n->acquire(mflag);
784  gNode* N = n;
785  if (N->active) {
786  N->active = false;
787  N->edges.clear();
788  }
789  }
790 
795  void resizeEdges(GraphNode src, size_t size,
797  assert(src);
798  // galois::runtime::checkWrite(mflag, false);
799  src->acquire(mflag);
800  src->resizeEdges(size);
801  }
802 
812  return createEdgeWithReuse(src, dst, mflag);
813  }
814 
817  template <typename... Args>
819  galois::MethodFlag mflag, Args&&... args) {
820  return createEdge(src, dst, mflag, std::forward<Args>(args)...);
821  }
822 
826  assert(src);
827  // galois::runtime::checkWrite(mflag, true);
828  src->acquire(mflag);
829  if (Directional && !InOut) {
830  src->erase(dst.base());
831  } else {
832  dst->first()->acquire(mflag);
833  // EdgeTy* e = dst->second();
834  dst->first()->erase(
835  src, Directional ? true : false); // erase incoming/symmetric edge
836  src->erase(dst.base());
837  }
838  }
839 
843  assert(src);
844  assert(dst);
845  src->acquire(mflag);
846  typename gNodeTypes::iterator ii = src->find(dst), ei = src->end();
847  is_out_edge edge_predicate;
848  if (ii != ei && edge_predicate(*ii)) {
849  // After finding edge, lock dst and verify still active
850  dst->acquire(mflag);
851  if (!edge_predicate(*ii))
852  // I think we need this too, else we'll return some random iterator.
853  ii = ei;
854  } else {
855  ii = ei;
856  }
857  return boost::make_filter_iterator(edge_predicate, ii, ei);
858  }
859 
865  assert(src);
866  assert(dst);
867  src->acquire(mflag);
868  assert(std::is_sorted(src->begin(), src->end(),
869  [=](const typename gNode::EdgeInfo& e1,
870  const typename gNode::EdgeInfo& e2) {
871  return e1.first() < e2.first();
872  }));
873 
874  auto ei = src->end();
875 
876  // jump directly to edges with destination we are looking for
877  auto ii =
878  std::lower_bound(src->begin(), src->end(), dst, first_lt<gNode*>());
879 
880  first_eq_and_valid<gNode*> checker(dst);
881  ii = std::find_if(ii, ei, checker); // bug if ei set to upper_bound
882  // ignore in edges
883  while (ii != ei && ii->isInEdge()) {
884  ++ii;
885  ii = std::find_if(ii, ei, checker);
886  };
887 
888  // make sure destination node is active else return end iterator
889  is_out_edge edge_predicate;
890  if (ii != ei) {
891  dst->acquire(mflag);
892  if (!edge_predicate(*ii)) {
893  ii = ei;
894  }
895  }
896  return boost::make_filter_iterator(edge_predicate, ii, ei);
897  }
898 
901  template <bool _Undirected = !Directional>
904  typename std::enable_if<_Undirected>::type* = 0) {
905  // incoming neighbors are the same as outgoing neighbors in undirected
906  // graphs
907  return findEdge(src, dst, mflag);
908  }
909 
912  template <bool _DirectedInOut = (Directional && InOut)>
916  typename std::enable_if<_DirectedInOut>::type* = 0) {
917  assert(src);
918  assert(dst);
919  src->acquire(mflag);
920  typename gNodeTypes::iterator ii = src->find(dst, true), ei = src->end();
921  is_in_edge edge_predicate;
922  if (ii != ei && edge_predicate(*ii)) {
923  // After finding edges, lock dst and verify still active
924  dst->acquire(mflag);
925  if (!edge_predicate(*ii))
926  // need this to avoid returning a random iterator
927  ii = ei;
928  } else
929  ii = ei;
930  return boost::make_filter_iterator(edge_predicate, ii, ei);
931  }
932 
943  assert(ii->first()->active);
944  // galois::runtime::checkWrite(mflag, false);
945  ii->first()->acquire(mflag);
946  return *ii->second();
947  }
948 
955  assert(ii->first()->active);
956  // galois::runtime::checkWrite(mflag, false);
957  ii->first()->acquire(mflag);
958  return *ii->second();
959  }
960 
963  assert(ii->first()->active);
964  return GraphNode(ii->first());
965  }
966 
969  assert(ii->first()->active);
970  return GraphNode(ii->first());
971  }
972 
976  acquire(N, mflag);
977  typedef typename gNode::EdgeInfo EdgeInfo;
978  std::sort(N->begin(), N->end(),
979  [=](const EdgeInfo& e1, const EdgeInfo& e2) {
980  return e1.first() < e2.first();
981  });
982  }
983 
987  galois::iterate(*this),
988  [=](GraphNode N) { this->sortEdgesByDst(N, mflag); }, galois::steal());
989  }
990 
991  // General Things
994  acquire(N, mflag);
995  typedef typename gNode::EdgeInfo EdgeInfo;
996  std::sort(N->begin(), N->end(),
997  [=](const EdgeInfo& e1, const EdgeInfo& e2) {
998  return getallneighbor(e1.first()).size() <
999  getallneighbor(e2.first()).size();
1000  });
1001  }
1002 
1003  // Sort cells in a net by their degree
1006  [=](GraphNode N) { this->sortEdgesByDeg(N, mflag); });
1007  }
1008 
1012  assert(N);
1013  N->acquire(mflag);
1014 
1015  if (galois::runtime::shouldLock(mflag)) {
1016  for (typename gNode::iterator ii = N->begin(), ee = N->end(); ii != ee;
1017  ++ii) {
1018  if (ii->first()->active && !ii->isInEdge())
1019  ii->first()->acquire(mflag);
1020  }
1021  }
1022  return boost::make_filter_iterator(is_out_edge(), N->begin(), N->end());
1023  }
1024 
1026  template <bool _Undirected = !Directional>
1029  typename std::enable_if<!_Undirected>::type* = 0) {
1030  assert(N);
1031  N->acquire(mflag);
1032 
1033  if (galois::runtime::shouldLock(mflag)) {
1034  for (typename gNode::iterator ii = N->begin(), ee = N->end(); ii != ee;
1035  ++ii) {
1036  if (ii->first()->active && ii->isInEdge())
1037  ii->first()->acquire(mflag);
1038  }
1039  }
1040  return boost::make_filter_iterator(is_in_edge(), N->begin(), N->end());
1041  }
1042 
1045  template <bool _Undirected = !Directional>
1048  typename std::enable_if<_Undirected>::type* = 0) {
1049  return edge_begin(N, mflag);
1050  }
1051 
1055  galois::MethodFlag GALOIS_UNUSED(mflag) = MethodFlag::WRITE) {
1056  assert(N);
1057  // Acquiring lock is not necessary: no valid use for an end pointer should
1058  // ever require it
1059  // N->acquire(mflag);
1060  return boost::make_filter_iterator(is_out_edge(), N->end(), N->end());
1061  }
1062 
1064  template <bool _Undirected = !Directional>
1067  galois::MethodFlag GALOIS_UNUSED(mflag) = MethodFlag::WRITE,
1068  typename std::enable_if<!_Undirected>::type* = 0) {
1069  assert(N);
1070  // Acquiring lock is not necessary: no valid use for an end pointer should
1071  // ever require it
1072  // N->acquire(mflag);
1073  return boost::make_filter_iterator(is_in_edge(), N->end(), N->end());
1074  }
1075 
1077  template <bool _Undirected = !Directional>
1080  typename std::enable_if<_Undirected>::type* = 0) {
1081  return edge_end(N, mflag);
1082  }
1083 
1087  return internal::make_no_deref_range(edge_begin(N, mflag),
1088  edge_end(N, mflag));
1089  }
1090 
1092  template <bool _Undirected = !Directional>
1095  typename std::enable_if<!_Undirected>::type* = 0) {
1096  return internal::make_no_deref_range(in_edge_begin(N, mflag),
1097  in_edge_end(N, mflag));
1098  }
1099 
1102  template <bool _Undirected = !Directional>
1105  typename std::enable_if<_Undirected>::type* = 0) {
1106  return edges(N, mflag);
1107  }
1108 
1113  internal::EdgesIterator<MorphHyperGraph>
1115  return internal::EdgesIterator<MorphHyperGraph>(*this, N, mflag);
1116  }
1117 
1122  return boost::make_transform_iterator(
1123  boost::make_filter_iterator(is_node(), nodes.begin(), nodes.end()),
1124  makeGraphNode());
1125  }
1126 
1129  return boost::make_transform_iterator(
1130  boost::make_filter_iterator(is_node(), nodes.end(), nodes.end()),
1131  makeGraphNode());
1132  }
1133 
1136 
1139  return boost::make_transform_iterator(
1140  boost::make_filter_iterator(is_node(), nodes.local_begin(),
1141  nodes.local_end()),
1142  makeGraphNode());
1143  }
1144 
1147  return boost::make_transform_iterator(
1148  boost::make_filter_iterator(is_node(), nodes.local_end(),
1149  nodes.local_end()),
1150  makeGraphNode());
1151  }
1152 
1156  unsigned int size() { return std::distance(begin(), end()); }
1157 
1159  size_t sizeOfEdgeData() const { return gNode::EdgeInfo::sizeOfSecond(); }
1160 
1161 #ifdef AUX_MAP
1162 
1169  void allocateFrom(FileGraph& graph, ReadGraphAuxData& aux) {
1170  size_t numNodes = graph.size();
1171  aux.nodes.allocateInterleaved(numNodes);
1172  }
1173 
1183  void constructNodesFrom(FileGraph& graph, unsigned tid, unsigned total,
1184  ReadGraphAuxData& aux) {
1185  auto r = graph
1186  .divideByNode(sizeof(gNode), sizeof(typename gNode::EdgeInfo),
1187  tid, total)
1188  .first;
1189  for (FileGraph::iterator ii = r.first, ei = r.second; ii != ei; ++ii) {
1190  aux.nodes[*ii] = createNode();
1191  addNode(aux.nodes[*ii], galois::MethodFlag::UNPROTECTED);
1192  }
1193  }
1194 
1205  void constructOutEdgesFrom(FileGraph& graph, unsigned tid, unsigned total,
1206  ReadGraphAuxData& aux) {
1207  auto r = graph
1208  .divideByNode(sizeof(gNode), sizeof(typename gNode::EdgeInfo),
1209  tid, total)
1210  .first;
1211  auto& map = aux.inNghs.get();
1212 
1213  for (FileGraph::iterator ii = r.first, ei = r.second; ii != ei; ++ii) {
1214  for (FileGraph::edge_iterator nn = graph.edge_begin(*ii),
1215  en = graph.edge_end(*ii);
1216  nn != en; ++nn) {
1217  auto dstID = graph.getEdgeDst(nn);
1218  auto src = aux.nodes[*ii], dst = aux.nodes[dstID];
1219  auto e = constructOutEdgeValue(graph, nn, src, dst);
1220  if (!Directional || InOut) {
1221  map[dstID].push_back({src, e});
1222  }
1223  }
1224  }
1225  }
1226 
1237  void constructInEdgesFrom(FileGraph& graph, unsigned tid, unsigned total,
1238  const ReadGraphAuxData& aux) {
1239  // only do it if not directioal or an inout graph
1240  if (!Directional || InOut) {
1241  auto r = graph
1242  .divideByNode(sizeof(gNode),
1243  sizeof(typename gNode::EdgeInfo), tid, total)
1244  .first;
1245 
1246  for (size_t i = 0; i < aux.inNghs.numRows(); ++i) {
1247  const auto& map = aux.inNghs.get(i);
1248  auto ii = map.lower_bound(*(r.first)); // inclusive begin
1249  auto ei = map.lower_bound(*(r.second)); // exclusive end
1250  for (; ii != ei; ++ii) {
1251  auto dst = aux.nodes[ii->first];
1252  for (const auto& ie : ii->second) {
1253  constructInEdgeValue(graph, ie.second, ie.first, dst);
1254  }
1255  }
1256  }
1257  }
1258  }
1259 #else
1260 
1268  size_t numNodes = graph.size();
1269  aux.allocateInterleaved(numNodes);
1270 
1271  if (!DirectedNotInOut) {
1272  galois::do_all(galois::iterate(0ul, aux.size()),
1273  [&](size_t index) { aux.constructAt(index); });
1274  }
1275  }
1276 
1287  template <bool V = DirectedNotInOut>
1288  std::enable_if_t<!V> constructNodesFrom(FileGraph& graph, unsigned tid,
1289  unsigned total,
1290  ReadGraphAuxData& aux) {
1291  auto r = graph
1292  .divideByNode(sizeof(gNode), sizeof(typename gNode::EdgeInfo),
1293  tid, total)
1294  .first;
1295  for (FileGraph::iterator ii = r.first, ei = r.second; ii != ei; ++ii) {
1296  auto& auxNode = aux[*ii].get();
1297  auxNode.n = createNode();
1299  }
1300  }
1301 
1312  template <bool V = DirectedNotInOut>
1313  std::enable_if_t<V> constructNodesFrom(FileGraph& graph, unsigned tid,
1314  unsigned total,
1315  ReadGraphAuxData& aux) {
1316  auto r = graph
1317  .divideByNode(sizeof(gNode), sizeof(typename gNode::EdgeInfo),
1318  tid, total)
1319  .first;
1320  for (FileGraph::iterator ii = r.first, ei = r.second; ii != ei; ++ii) {
1321  aux[*ii] = createNode();
1323  }
1324  }
1325 
1337  template <bool V = DirectedNotInOut>
1338  std::enable_if_t<!V> constructOutEdgesFrom(FileGraph& graph, unsigned tid,
1339  unsigned total,
1340  ReadGraphAuxData& aux) {
1341  auto r = graph
1342  .divideByNode(sizeof(gNode), sizeof(typename gNode::EdgeInfo),
1343  tid, total)
1344  .first;
1345 
1346  for (FileGraph::iterator ii = r.first, ei = r.second; ii != ei; ++ii) {
1347  for (FileGraph::edge_iterator nn = graph.edge_begin(*ii),
1348  en = graph.edge_end(*ii);
1349  nn != en; ++nn) {
1350  auto src = aux[*ii].get().n;
1351  auto& dstAux = aux[graph.getEdgeDst(nn)].get();
1352  auto e = constructOutEdgeValue(graph, nn, src, dstAux.n);
1353  dstAux.lock.lock();
1354  dstAux.inNghs.push_back({src, e});
1355  dstAux.lock.unlock();
1356  }
1357  }
1358  }
1359 
1371  template <bool V = DirectedNotInOut>
1372  std::enable_if_t<V> constructOutEdgesFrom(FileGraph& graph, unsigned tid,
1373  unsigned total,
1374  const ReadGraphAuxData& aux) {
1375  auto r = graph
1376  .divideByNode(sizeof(gNode), sizeof(typename gNode::EdgeInfo),
1377  tid, total)
1378  .first;
1379 
1380  for (FileGraph::iterator ii = r.first, ei = r.second; ii != ei; ++ii) {
1381  for (FileGraph::edge_iterator nn = graph.edge_begin(*ii),
1382  en = graph.edge_end(*ii);
1383  nn != en; ++nn) {
1384  constructOutEdgeValue(graph, nn, aux[*ii], aux[graph.getEdgeDst(nn)]);
1385  }
1386  }
1387  }
1388 
1399  template <bool V = DirectedNotInOut>
1400  std::enable_if_t<!V> constructInEdgesFrom(FileGraph& graph, unsigned tid,
1401  unsigned total,
1402  ReadGraphAuxData& aux) {
1403  auto r = graph
1404  .divideByNode(sizeof(gNode), sizeof(typename gNode::EdgeInfo),
1405  tid, total)
1406  .first;
1407 
1408  for (FileGraph::iterator ii = r.first, ei = r.second; ii != ei; ++ii) {
1409  auto& auxNode = aux[*ii].get();
1410  for (auto ie : auxNode.inNghs) {
1411  constructInEdgeValue(graph, ie.second, ie.first, auxNode.n);
1412  }
1413  }
1414  }
1415 
1418  template <bool V = DirectedNotInOut>
1419  std::enable_if_t<V> constructInEdgesFrom(FileGraph&, unsigned, unsigned,
1420  ReadGraphAuxData&) {}
1421 #endif
1423 
1424  gstl::Vector<GraphNode> neighbors;
1425  // if (findEdge(N, H)) {
1426  for (auto it : edges(H)) {
1427  auto n = getEdgeDst(it);
1428  if (n != N)
1429  neighbors.push_back(n);
1430  }
1431  // }
1432  return neighbors;
1433  }
1434  // get all the neighbors
1436 
1437  gstl::Vector<GraphNode> neighbors;
1438  for (auto it : edges(N)) {
1439  auto hedge = getEdgeDst(it);
1440  for (auto h : edges(hedge)) {
1441  auto hneighbor = getEdgeDst(h);
1442  if (hneighbor != N)
1443  neighbors.push_back(hneighbor);
1444  }
1445  }
1446 
1447  return neighbors;
1448  }
1449  // get all the nets on a cell
1452  for (auto net : edges(N)) {
1453  auto nnet = getEdgeDst(net);
1454  n.push_back(nnet);
1455  }
1456  return n;
1457  }
1458 
1459  // get all the cells on a net
1462  for (auto net : edges(N)) {
1463  auto hedge = getEdgeDst(net);
1464  cells.push_back(hedge);
1465  }
1466  return cells;
1467  }
1468 
1469  void addHyperedge(GraphNode n) { nets.push_back(n); }
1470  void addCell(GraphNode n) { cells.push_back(n); }
1471  Bnodes& cellList() { return cells; }
1472 
1473  Bnodes& getNets() { return nets; }
1474 
1476  for (auto n : edges(N)) {
1477  GraphNode n1 = getEdgeDst(n);
1478  for (auto c : edges(C)) {
1479  GraphNode n2 = getEdgeDst(c);
1480  if (n2 == n1)
1481  return n1;
1482  }
1483  }
1484  }
1485  //
1486  std::vector<GraphNode> getallneighbornets(GraphNode N) {
1487  std::vector<GraphNode> nets;
1488  for (auto n : edges(N)) {
1489  GraphNode n1 = getEdgeDst(n);
1490  nets.push_back(n1);
1491  }
1492  return nets;
1493  }
1494 };
1495 
1496 } // namespace graphs
1497 } // namespace galois
1498 #endif
void addNode(const GraphNode &n, galois::MethodFlag mflag=MethodFlag::WRITE)
Adds a node to the graph.
Definition: MorphHyperGraph.h:748
internal::EdgesIterator< MorphHyperGraph > out_edges(GraphNode N, MethodFlag mflag=MethodFlag::WRITE)
An object with begin() and end() methods to iterate over the outgoing edges of N. ...
Definition: MorphHyperGraph.h:1114
galois::substrate::SimpleLock lock
lock for wrapped graph node
Definition: MorphHyperGraph.h:590
gstl::Vector< int > maxgain
Definition: MorphHyperGraph.h:573
std::enable_if_t< V > constructInEdgesFrom(FileGraph &, unsigned, unsigned, ReadGraphAuxData &)
If a directed graph and no in-edges exist (i.e.
Definition: MorphHyperGraph.h:1419
node_data_reference getData(const GraphNode &n, galois::MethodFlag mflag=MethodFlag::WRITE) const
Gets the node data for a node.
Definition: MorphHyperGraph.h:757
gNode * GraphNode
Graph node handle.
Definition: MorphHyperGraph.h:543
reference emplace(Args &&...args)
Thread safe bag insertion.
Definition: Bag.h:260
gstl::Vector< GraphNode > getNets(GraphNode N)
Definition: MorphHyperGraph.h:1450
GraphNode getEdgeDst(edge_iterator ii)
Returns the destination of an edge.
Definition: MorphHyperGraph.h:962
void sortCellDegree(MethodFlag mflag=MethodFlag::WRITE)
Definition: MorphHyperGraph.h:1004
Struct used to define if neighbors are sorted or not in the graph.
Definition: MorphHyperGraph.h:305
Definition: CacheLineStorage.h:32
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.
iterator local_iterator
local iterator over nodes
Definition: MorphHyperGraph.h:1135
void sortAllEdgesByDst(MethodFlag mflag=MethodFlag::WRITE)
Sort all edges by destination.
Definition: MorphHyperGraph.h:985
iterator begin()
Definition: Bag.h:238
size_t size() const
Returns the number of nodes in the (sub)graph.
Definition: FileGraph.h:545
gstl::Vector< GraphNode > getCells(GraphNode N)
Definition: MorphHyperGraph.h:1460
void addCell(GraphNode n)
Definition: MorphHyperGraph.h:1470
typename gNodeTypes::EdgeInfo::reference edge_data_reference
Reference to edge data.
Definition: MorphHyperGraph.h:560
boost::counting_iterator< uint64_t > iterator
uint64 boost counting iterator
Definition: FileGraph.h:408
Struct used to define the HasNoLockable template parameter as a type in the struct.
Definition: MorphHyperGraph.h:254
Struct used to define the type of edge data in the graph.
Definition: MorphHyperGraph.h:274
typename boost::filter_iterator< is_in_edge, typename gNodeTypes::iterator > in_edge_iterator
In Edge iterator.
Definition: MorphHyperGraph.h:557
void sortEdgesByDeg(GraphNode N, galois::MethodFlag mflag=MethodFlag::WRITE)
Definition: MorphHyperGraph.h:992
GraphNode getEdgeDst(edge_iterator it)
Gets the destination of some edge.
Definition: FileGraph.cpp:669
std::enable_if_t< V > constructNodesFrom(FileGraph &graph, unsigned tid, unsigned total, ReadGraphAuxData &aux)
Constructs the MorphGraph nodes given a FileGraph to construct it from.
Definition: MorphHyperGraph.h:1313
edge_data_reference getEdgeData(in_edge_iterator ii, galois::MethodFlag mflag=MethodFlag::UNPROTECTED) const
Get edge data for an in-edge.
Definition: MorphHyperGraph.h:953
typename std::conditional< DirectedNotInOut, LargeArray< GraphNode >, LargeArray< AuxNodePadded >>::type ReadGraphAuxData
Large array that contains auxiliary data for each node (AuxNodes)
Definition: MorphHyperGraph.h:605
in_edge_iterator in_edge_end(GraphNode N, galois::MethodFlag GALOIS_UNUSED(mflag)=MethodFlag::WRITE, typename std::enable_if<!_Undirected >::type *=0)
Returns the end of an in-neighbor edge iterator.
Definition: MorphHyperGraph.h:1066
GraphNode createNode(Args &&...args)
Creates a new node holding the indicated data.
Definition: MorphHyperGraph.h:739
boost::counting_iterator< uint64_t > edge_iterator
Edge iterators (boost iterator)
Definition: FileGraph.h:248
Definition: Iterable.h:36
local_iterator local_begin()
Definition: Bag.h:243
GraphNode getneighbornet(GraphNode N, GraphNode C)
Definition: MorphHyperGraph.h:1475
A graph that can have new nodes and edges added to it.
Definition: MorphHyperGraph.h:247
Bnodes & getNets()
Definition: MorphHyperGraph.h:1473
uint64_t GraphNode
type of a node
Definition: FileGraph.h:60
edge_iterator edge_end(GraphNode N, galois::MethodFlag GALOIS_UNUSED(mflag)=MethodFlag::WRITE)
Returns the end of the neighbor edge iterator.
Definition: MorphHyperGraph.h:1054
std::enable_if_t<!V > constructOutEdgesFrom(FileGraph &graph, unsigned tid, unsigned total, ReadGraphAuxData &aux)
Constructs the MorphGraph edges given a FileGraph to construct it from and already created nodes...
Definition: MorphHyperGraph.h:1338
local_iterator local_begin()
Return the beginning of local range of nodes.
Definition: MorphHyperGraph.h:1138
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
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: MorphHyperGraph.h:780
gstl::Vector< GraphNode > getneighbor(GraphNode N, GraphNode H)
Definition: MorphHyperGraph.h:1422
void sortEdgesByDst(GraphNode N, galois::MethodFlag mflag=MethodFlag::WRITE)
Sorts edge of a node by destination.
Definition: MorphHyperGraph.h:974
iterator begin()
Returns an iterator to all the nodes in the graph.
Definition: MorphHyperGraph.h:1121
in_edge_iterator in_edge_begin(GraphNode N, galois::MethodFlag mflag=MethodFlag::WRITE, typename std::enable_if<!_Undirected >::type *=0)
Returns an iterator to the in-neighbors of a node.
Definition: MorphHyperGraph.h:1028
std::vector< GraphNode > getallneighbornets(GraphNode N)
Definition: MorphHyperGraph.h:1486
std::enable_if_t< V > constructOutEdgesFrom(FileGraph &graph, unsigned tid, unsigned total, const ReadGraphAuxData &aux)
Constructs the MorphGraph edges given a FileGraph to construct it from and already created nodes...
Definition: MorphHyperGraph.h:1372
galois::gstl::Vector< std::pair< GraphNode, EdgeTy * > > inNghs
stores in neighbors
Definition: MorphHyperGraph.h:594
void resizeEdges(GraphNode src, size_t size, galois::MethodFlag mflag=MethodFlag::WRITE)
Resize the edges of the node.
Definition: MorphHyperGraph.h:795
void sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp)
Definition: ParallelSTL.h:247
FileEdgeTy file_edge_data_type
Edge data type of file we are loading this graph from.
Definition: MorphHyperGraph.h:547
gstl::Vector< GraphNode > getallneighbor(GraphNode N)
Definition: MorphHyperGraph.h:1435
iterator end()
Definition: Bag.h:239
edge_data_reference getEdgeData(edge_iterator ii, galois::MethodFlag mflag=MethodFlag::UNPROTECTED) const
Returns the edge data associated with the edge.
Definition: MorphHyperGraph.h:941
edge_iterator findEdgeSortedByDst(GraphNode src, GraphNode dst, galois::MethodFlag mflag=MethodFlag::WRITE)
Find/return edge between src/dst if it exists; assumes that edges are sorted by destination.
Definition: MorphHyperGraph.h:863
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: MorphHyperGraph.h:818
boost::transform_iterator< makeGraphNode, boost::filter_iterator< is_node, typename NodeListTy::iterator >> iterator
Node iterator.
Definition: MorphHyperGraph.h:566
Struct used to define the type of node data in the graph.
Definition: MorphHyperGraph.h:264
std::vector< T, Pow2Alloc< T >> Vector
[STL vector using Pow_2_VarSizeAlloc]
Definition: gstl.h:52
Struct used to define the type of file edge data in the graph.
Definition: MorphHyperGraph.h:284
Bnodes & cellList()
Definition: MorphHyperGraph.h:1471
Unordered collection of elements.
Definition: Bag.h:42
int total_area
Definition: MorphHyperGraph.h:570
Definition: runtime/Mem.h:864
iterator end()
Returns the end of the node iterator. Not thread-safe.
Definition: MorphHyperGraph.h:1128
local_iterator local_end()
Return the end of local range of nodes.
Definition: MorphHyperGraph.h:1146
Definition: Traits.h:206
void removeEdge(GraphNode src, edge_iterator dst, galois::MethodFlag mflag=MethodFlag::WRITE)
Removes an edge from the graph.
Definition: MorphHyperGraph.h:824
gstl::Vector< GraphNode > locked_cells
Definition: MorphHyperGraph.h:568
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
edge_iterator edge_begin(GraphNode N, galois::MethodFlag mflag=MethodFlag::WRITE)
Returns an iterator to the neighbors of a node.
Definition: MorphHyperGraph.h:1010
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
gstl::Vector< int > balance
Definition: MorphHyperGraph.h:574
unsigned int size()
Returns the number of nodes in the graph.
Definition: MorphHyperGraph.h:1156
typename galois::substrate::CacheLineStorage< AuxNode > AuxNodePadded
Padded version of AuxNode.
Definition: MorphHyperGraph.h:597
void operator()(void)
Definition: Executor_ParaMeter.h:417
size_t sizeOfEdgeData() const
Returns the size of edge data.
Definition: MorphHyperGraph.h:1159
void do_all(const RangeFunc &rangeMaker, FunctionTy &&fn, const Args &...args)
Standard do-all loop.
Definition: Loops.h:71
runtime::iterable< NoDerefIterator< edge_iterator > > in_edges(GraphNode N, galois::MethodFlag mflag=MethodFlag::WRITE, typename std::enable_if< _Undirected >::type *=0)
Return a range of in-edges that can be iterated over by C++ for-each Undirected case, equivalent to out-edge iteration.
Definition: MorphHyperGraph.h:1104
EdgeTy edge_data_type
Edge data type.
Definition: MorphHyperGraph.h:545
edge_iterator in_edge_end(GraphNode N, galois::MethodFlag mflag=MethodFlag::WRITE, typename std::enable_if< _Undirected >::type *=0)
Returns the end of an in-neighbor edge iterator, undirected case.
Definition: MorphHyperGraph.h:1078
int max_cell_area
Definition: MorphHyperGraph.h:569
std::enable_if_t<!V > constructNodesFrom(FileGraph &graph, unsigned tid, unsigned total, ReadGraphAuxData &aux)
Constructs the MorphGraph nodes given a FileGraph to construct it from.
Definition: MorphHyperGraph.h:1288
SimpleLock is a spinlock.
Definition: SimpleLock.h:36
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 addEdge(GraphNode src, GraphNode dst, galois::MethodFlag mflag=MethodFlag::WRITE)
Adds an edge to graph, replacing existing value if edge already exists.
Definition: MorphHyperGraph.h:810
void addHyperedge(GraphNode n)
Definition: MorphHyperGraph.h:1469
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
reference push_back(ItemTy &&val)
Thread safe bag insertion.
Definition: Bag.h:298
GraphNode getEdgeDst(in_edge_iterator ii)
Returns the destination of an in-edge.
Definition: MorphHyperGraph.h:968
Definition: PerThreadContainer.h:523
Graph that mmaps Galois gr files for access.
Definition: FileGraph.h:57
auto iterate(C &cont)
Definition: Range.h:323
bool containsNode(const GraphNode &n, galois::MethodFlag mflag=MethodFlag::WRITE) const
Checks if a node is in the graph.
Definition: MorphHyperGraph.h:767
InputIterator find_if(InputIterator first, InputIterator last, Predicate pred)
Definition: ParallelSTL.h:70
static constexpr const bool DirectedNotInOut
True if a node is both directional and not storing both in and out edges.
Definition: MorphHyperGraph.h:601
std::list< int > freeCells
Definition: MorphHyperGraph.h:571
Struct used to define directionality of the graph.
Definition: MorphHyperGraph.h:295
in_edge_iterator findInEdge(GraphNode src, GraphNode dst, galois::MethodFlag mflag=MethodFlag::WRITE, typename std::enable_if< _DirectedInOut >::type *=0)
Find if an incoming edge between src and dst exists for directed in-out graphs.
Definition: MorphHyperGraph.h:914
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)
Return a range of edges that can be iterated over by C++ for-each.
Definition: MorphHyperGraph.h:1086
edge_iterator in_edge_begin(GraphNode N, galois::MethodFlag mflag=MethodFlag::WRITE, typename std::enable_if< _Undirected >::type *=0)
Returns an iterator to the in-neighbors of a node; undirected case in which it&#39;s the same as a regula...
Definition: MorphHyperGraph.h:1046
GraphNode n
single graph node wrapped by this struct
Definition: MorphHyperGraph.h:592
runtime::iterable< NoDerefIterator< in_edge_iterator > > in_edges(GraphNode N, galois::MethodFlag mflag=MethodFlag::WRITE, typename std::enable_if<!_Undirected >::type *=0)
Return a range of in-edges that can be iterated over by C++ for-each.
Definition: MorphHyperGraph.h:1094
typename gNodeTypes::reference node_data_reference
Reference to node data.
Definition: MorphHyperGraph.h:562
std::enable_if_t<!V > constructInEdgesFrom(FileGraph &graph, unsigned tid, unsigned total, ReadGraphAuxData &aux)
Constructs the MorphGraph in-edges given a FileGraph to construct it from and already created nodes...
Definition: MorphHyperGraph.h:1400
typename boost::filter_iterator< is_out_edge, typename gNodeTypes::iterator > edge_iterator
(Out or Undirected) Edge iterator
Definition: MorphHyperGraph.h:553
edge_iterator findEdge(GraphNode src, GraphNode dst, galois::MethodFlag mflag=MethodFlag::WRITE)
Finds if an edge between src and dst exists.
Definition: MorphHyperGraph.h:841
edge_iterator findInEdge(GraphNode src, GraphNode dst, galois::MethodFlag mflag=MethodFlag::WRITE, typename std::enable_if< _Undirected >::type *=0)
Find a particular in-edge: note this function activates for the undirected graph case, so it just calls the regular out-edge finding function.
Definition: MorphHyperGraph.h:902
NodeTy node_data_type
Node data type.
Definition: MorphHyperGraph.h:549
void allocateFrom(FileGraph &graph, ReadGraphAuxData &aux)
Allocate memory for nodes given a file graph with a particular number of nodes.
Definition: MorphHyperGraph.h:1267