Galois
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
LC_InOut_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_GRAPHS_LC_INOUT_GRAPH_H
21 #define GALOIS_GRAPHS_LC_INOUT_GRAPH_H
22 
23 #include <boost/iterator/iterator_facade.hpp>
24 #include <boost/fusion/include/vector.hpp>
25 #include <boost/fusion/include/at_c.hpp>
26 
27 #include "galois/config.h"
28 #include "galois/graphs/Details.h"
29 #include "galois/Galois.h"
30 
31 namespace galois {
32 namespace graphs {
33 
38 template <typename GraphTy>
39 class LC_InOut_Graph : public GraphTy::template with_id<true>::type {
40 public:
41  template <typename _node_data>
42  struct with_node_data {
43  typedef LC_InOut_Graph<
44  typename GraphTy::template with_node_data<_node_data>::type>
46  };
47 
48  template <typename _edge_data>
49  struct with_edge_data {
50  typedef LC_InOut_Graph<
51  typename GraphTy::template with_edge_data<_edge_data>::type>
53  };
54 
55 private:
56  template <typename G>
57  friend void readGraphDispatch(G&, read_lc_inout_graph_tag, const std::string&,
58  const std::string&);
59 
60  typedef typename GraphTy ::template with_id<true>::type Super;
61  typedef
62  typename GraphTy ::template with_id<true>::type ::template with_node_data<
63  void>::type ::template with_no_lockable<true>::type InGraph;
64  InGraph inGraph;
65  bool asymmetric;
66 
67  typename InGraph::GraphNode inGraphNode(typename Super::GraphNode n) {
68  return inGraph.getNode(idFromNode(n));
69  }
70 
71  void createAsymmetric() { asymmetric = true; }
72 
73 public:
74  typedef Super out_graph_type;
75  typedef InGraph in_graph_type;
76  typedef typename Super::GraphNode GraphNode;
77  typedef typename Super::file_edge_data_type file_edge_data_type;
80  typedef typename Super::edge_data_reference edge_data_reference;
81  typedef typename Super::node_data_reference node_data_reference;
82  typedef typename Super::edge_iterator edge_iterator;
83  typedef typename Super::iterator iterator;
84  typedef typename Super::const_iterator const_iterator;
85  typedef typename Super::local_iterator local_iterator;
86  typedef typename Super::const_local_iterator const_local_iterator;
88 
89  // Union of edge_iterator and InGraph::edge_iterator
91  : public boost::iterator_facade<in_edge_iterator, void*,
92  std::random_access_iterator_tag, void*> {
94  friend class LC_InOut_Graph;
95  typedef edge_iterator Iterator0;
96  typedef typename InGraph::edge_iterator Iterator1;
97  typedef boost::fusion::vector<Iterator0, Iterator1> Iterators;
98 
99  Iterators its;
100  LC_InOut_Graph* self;
101  int type;
102 
103  void increment() {
104  if (type == 0)
105  ++boost::fusion::at_c<0>(its);
106  else
107  ++boost::fusion::at_c<1>(its);
108  }
109 
110  void advance(unsigned n) {
111  if (type == 0)
112  boost::fusion::at_c<0>(its) += n;
113  else
114  boost::fusion::at_c<1>(its) += n;
115  }
116 
117  bool equal(const in_edge_iterator& o) const {
118  if (type != o.type)
119  return false;
120  if (type == 0) {
121  return boost::fusion::at_c<0>(its) == boost::fusion::at_c<0>(o.its);
122  } else {
123  return boost::fusion::at_c<1>(its) == boost::fusion::at_c<1>(o.its);
124  }
125  }
126 
127  typename in_edge_iterator::difference_type
128  distance_to(const in_edge_iterator& lhs) const {
129  if (type == 0)
130  return boost::fusion::at_c<0>(lhs.its) - boost::fusion::at_c<0>(its);
131  else
132  return boost::fusion::at_c<1>(lhs.its) - boost::fusion::at_c<1>(its);
133  }
134 
135  void* dereference() const { return 0; }
136 
137  public:
138  in_edge_iterator() : type(0) {}
139  in_edge_iterator(Iterator0 it) : type(0) {
140  boost::fusion::at_c<0>(its) = it;
141  }
142  in_edge_iterator(Iterator1 it, int) : type(1) {
143  boost::fusion::at_c<1>(its) = it;
144  }
145  };
146 
147  LC_InOut_Graph() : asymmetric(false) {}
148 
151  MethodFlag GALOIS_UNUSED(mflag) = MethodFlag::UNPROTECTED) {
152  // galois::runtime::checkWrite(mflag, false);
153  if (ni.type == 0) {
154  return this->getEdgeData(boost::fusion::at_c<0>(ni.its));
155  } else {
156  return inGraph.getEdgeData(boost::fusion::at_c<1>(ni.its));
157  }
158  }
159 
161  if (ni.type == 0) {
162  return this->getEdgeDst(boost::fusion::at_c<0>(ni.its));
163  } else {
164  return nodeFromId(
165  inGraph.getId(inGraph.getEdgeDst(boost::fusion::at_c<1>(ni.its))));
166  }
167  }
168 
170  MethodFlag mflag = MethodFlag::WRITE) {
171  this->acquireNode(N, mflag);
172  if (!asymmetric) {
173  if (galois::runtime::shouldLock(mflag)) {
174  for (edge_iterator ii = this->raw_begin(N), ei = this->raw_end(N);
175  ii != ei; ++ii) {
176  this->acquireNode(this->getEdgeDst(ii), mflag);
177  }
178  }
179  return in_edge_iterator(this->raw_begin(N));
180  } else {
181  if (galois::runtime::shouldLock(mflag)) {
182  for (typename InGraph::edge_iterator
183  ii = inGraph.raw_begin(inGraphNode(N)),
184  ei = inGraph.raw_end(inGraphNode(N));
185  ii != ei; ++ii) {
186  this->acquireNode(nodeFromId(inGraph.getId(inGraph.getEdgeDst(ii))),
187  mflag);
188  }
189  }
190  return in_edge_iterator(inGraph.raw_begin(inGraphNode(N)), 0);
191  }
192  }
193 
195  MethodFlag mflag = MethodFlag::WRITE) {
196  this->acquireNode(N, mflag);
197  if (!asymmetric) {
198  return in_edge_iterator(this->raw_end(N));
199  } else {
200  return in_edge_iterator(inGraph.raw_end(inGraphNode(N)), 0);
201  }
202  }
203 
204  internal::InEdgesIterator<LC_InOut_Graph>
206  return internal::InEdgesIterator<LC_InOut_Graph>(*this, N, mflag);
207  }
208 
213  template <typename CompTy>
215  GraphNode N,
216  const CompTy& comp = std::less<typename GraphTy::edge_data_type>(),
217  MethodFlag mflag = MethodFlag::WRITE) {
218  this->acquireNode(N, mflag);
219  if (!asymmetric) {
220  std::sort(this->edge_sort_begin(N), this->edge_sort_end(N),
221  internal::EdgeSortCompWrapper<
223  CompTy>(comp));
224  } else {
225  std::sort(inGraph.edge_sort_begin(inGraphNode(N)),
226  inGraph.edge_sort_end(inGraphNode(N)),
227  internal::EdgeSortCompWrapper<
229  CompTy>(comp));
230  }
231  }
232 
237  template <typename CompTy>
238  void sortInEdges(GraphNode N, const CompTy& comp,
239  MethodFlag mflag = MethodFlag::WRITE) {
240  this->acquireNode(N, mflag);
241  if (!asymmetric) {
242  std::sort(this->edge_sort_begin(N), this->edge_sort_end(N), comp);
243  } else {
244  std::sort(inGraph.edge_sort_begin(inGraphNode(N)),
245  inGraph.edge_sort_end(inGraphNode(N)), comp);
246  }
247  }
248 
253  this->acquireNode(N, mflag);
254  if (!asymmetric) {
255  typedef EdgeSortValue<GraphNode, edge_data_type> EdgeSortVal;
256  std::sort(this->edge_sort_begin(N), this->edge_sort_end(N),
257  [=](const EdgeSortVal& e1, const EdgeSortVal& e2) {
258  return e1.dst < e2.dst;
259  });
260  } else {
261  typedef EdgeSortValue<typename InGraph::GraphNode,
262  typename InGraph::edge_data_type>
263  InEdgeSortVal;
264  std::sort(inGraph.edge_sort_begin(inGraphNode(N)),
265  inGraph.edge_sort_end(inGraphNode(N)),
266  [=](const InEdgeSortVal& e1, const InEdgeSortVal& e2) {
267  return e1.dst < e2.dst;
268  });
269  }
270  }
271 
277  galois::iterate(*this),
278  [=](GraphNode N) { this->sortInEdgesByDst(N, mflag); },
279  galois::steal());
280  }
281 
282  size_t idFromNode(GraphNode N) { return this->getId(N); }
283 
284  GraphNode nodeFromId(size_t N) { return this->getNode(N); }
285 };
286 
287 } // namespace graphs
288 } // namespace galois
289 #endif
void sortInEdges(GraphNode N, const CompTy &comp, MethodFlag mflag=MethodFlag::WRITE)
Sorts incoming edges of a node.
Definition: LC_InOut_Graph.h:238
LC_InOut_Graph< typename GraphTy::template with_node_data< _node_data >::type > type
Definition: LC_InOut_Graph.h:45
read_lc_inout_graph_tag read_tag
Definition: LC_InOut_Graph.h:87
size_t idFromNode(GraphNode N)
Definition: LC_InOut_Graph.h:282
Super::const_iterator const_iterator
Definition: LC_InOut_Graph.h:84
void sortInEdgesByEdgeData(GraphNode N, const CompTy &comp=std::less< typename GraphTy::edge_data_type >(), MethodFlag mflag=MethodFlag::WRITE)
Sorts incoming edges of a node.
Definition: LC_InOut_Graph.h:214
void sortAllInEdgesByDst(MethodFlag mflag=MethodFlag::WRITE)
Sorts incoming edges of all nodes.
Definition: LC_InOut_Graph.h:275
InGraph in_graph_type
Definition: LC_InOut_Graph.h:75
LC_InOut_Graph< typename GraphTy::template with_edge_data< _edge_data >::type > type
Definition: LC_InOut_Graph.h:52
Super::edge_data_type edge_data_type
Definition: LC_InOut_Graph.h:78
void sortInEdgesByDst(GraphNode N, MethodFlag mflag=MethodFlag::WRITE)
Sorts incoming edges of a node.
Definition: LC_InOut_Graph.h:252
friend class boost::iterator_core_access
Definition: LC_InOut_Graph.h:93
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
internal::InEdgesIterator< LC_InOut_Graph > in_edges(GraphNode N, MethodFlag mflag=MethodFlag::WRITE)
Definition: LC_InOut_Graph.h:205
void sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp)
Definition: ParallelSTL.h:247
Modify a LC_Graph to have in and out edges.
Definition: LC_InOut_Graph.h:39
LC_InOut_Graph()
Definition: LC_InOut_Graph.h:147
Proxy object for internal EdgeSortReference.
Definition: Details.h:56
in_edge_iterator(Iterator1 it, int)
Definition: LC_InOut_Graph.h:142
Definition: Traits.h:206
Definition: LC_InOut_Graph.h:49
MethodFlag
What should the runtime do when executing a method.
Definition: MethodFlags.h:34
Super::node_data_type node_data_type
Definition: LC_InOut_Graph.h:79
in_edge_iterator in_edge_begin(GraphNode N, MethodFlag mflag=MethodFlag::WRITE)
Definition: LC_InOut_Graph.h:169
Super::edge_iterator edge_iterator
Definition: LC_InOut_Graph.h:82
void do_all(const RangeFunc &rangeMaker, FunctionTy &&fn, const Args &...args)
Standard do-all loop.
Definition: Loops.h:71
Super::local_iterator local_iterator
Definition: LC_InOut_Graph.h:85
GraphNode getInEdgeDst(in_edge_iterator ni)
Definition: LC_InOut_Graph.h:160
unsigned int node_data_type
Definition: EdgeHostDecls.h:34
Super::file_edge_data_type file_edge_data_type
Definition: LC_InOut_Graph.h:77
in_edge_iterator in_edge_end(GraphNode N, MethodFlag mflag=MethodFlag::WRITE)
Definition: LC_InOut_Graph.h:194
friend void readGraphDispatch(G &, read_lc_inout_graph_tag, const std::string &, const std::string &)
Super::edge_data_reference edge_data_reference
Definition: LC_InOut_Graph.h:80
Super::const_local_iterator const_local_iterator
Definition: LC_InOut_Graph.h:86
in_edge_iterator(Iterator0 it)
Definition: LC_InOut_Graph.h:139
in_edge_iterator()
Definition: LC_InOut_Graph.h:138
auto iterate(C &cont)
Definition: Range.h:323
Super out_graph_type
Definition: LC_InOut_Graph.h:74
Super::GraphNode GraphNode
Definition: LC_InOut_Graph.h:76
unsigned edge_data_type
Definition: EdgeHostDecls.h:35
edge_data_reference getInEdgeData(in_edge_iterator ni, MethodFlag GALOIS_UNUSED(mflag)=MethodFlag::UNPROTECTED)
Definition: LC_InOut_Graph.h:150
Super::iterator iterator
Definition: LC_InOut_Graph.h:83
GraphNode nodeFromId(size_t N)
Definition: LC_InOut_Graph.h:284
Super::node_data_reference node_data_reference
Definition: LC_InOut_Graph.h:81
Definition: LC_InOut_Graph.h:42