Galois
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
LC_Linear_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_LINEAR_GRAPH_H
21 #define GALOIS_GRAPHS_LC_LINEAR_GRAPH_H
22 
23 #include <type_traits>
24 
25 #include <boost/mpl/if.hpp>
26 
27 #include "galois/config.h"
28 #include "galois/LargeArray.h"
30 #include "galois/graphs/Details.h"
31 
32 namespace galois {
33 namespace graphs {
34 
43 template <typename NodeTy, typename EdgeTy, bool HasNoLockable = false,
44  bool UseNumaAlloc = false, bool HasOutOfLineLockable = false,
45  bool HasId = false, typename FileEdgeTy = EdgeTy>
47  : private boost::noncopyable,
48  private internal::LocalIteratorFeature<UseNumaAlloc>,
49  private internal::OutOfLineLockableFeature<HasOutOfLineLockable &&
50  !HasNoLockable> {
51  template <typename Graph>
52  friend class LC_InOut_Graph;
53 
54 public:
55  template <bool _has_id>
56  struct with_id {
57  typedef LC_Linear_Graph<NodeTy, EdgeTy, HasNoLockable, UseNumaAlloc,
58  HasOutOfLineLockable, _has_id, FileEdgeTy>
60  };
61 
62  template <typename _node_data>
63  struct with_node_data {
64  typedef LC_Linear_Graph<_node_data, EdgeTy, HasNoLockable, UseNumaAlloc,
65  HasOutOfLineLockable, HasId, FileEdgeTy>
67  };
68 
69  template <typename _edge_data>
70  struct with_edge_data {
71  typedef LC_Linear_Graph<NodeTy, _edge_data, HasNoLockable, UseNumaAlloc,
72  HasOutOfLineLockable, HasId, FileEdgeTy>
74  };
75 
76  template <typename _file_edge_data>
78  typedef LC_Linear_Graph<NodeTy, EdgeTy, HasNoLockable, UseNumaAlloc,
79  HasOutOfLineLockable, HasId, _file_edge_data>
81  };
82 
83  template <bool _has_no_lockable>
85  typedef LC_Linear_Graph<NodeTy, EdgeTy, _has_no_lockable, UseNumaAlloc,
86  HasOutOfLineLockable, HasId, FileEdgeTy>
88  };
89 
90  template <bool _use_numa_alloc>
91  struct with_numa_alloc {
92  typedef LC_Linear_Graph<NodeTy, EdgeTy, HasNoLockable, _use_numa_alloc,
93  HasOutOfLineLockable, HasId, FileEdgeTy>
95  };
96 
97  template <bool _has_out_of_line_lockable>
99  typedef LC_Linear_Graph<NodeTy, EdgeTy, HasNoLockable, UseNumaAlloc,
100  _has_out_of_line_lockable,
101  _has_out_of_line_lockable || HasId, FileEdgeTy>
103  };
104 
106 
107 protected:
108  class NodeInfo;
109  typedef internal::EdgeInfoBase<NodeInfo*, EdgeTy> EdgeInfo;
111  typedef internal::NodeInfoBaseTypes<NodeTy,
112  !HasNoLockable && !HasOutOfLineLockable>
114 
115  class NodeInfo
116  : public internal::NodeInfoBase<NodeTy,
117  !HasNoLockable && !HasOutOfLineLockable>,
118  public internal::IntrusiveId<
119  typename boost::mpl::if_c<HasId, uint32_t, void>::type> {
120  friend class LC_Linear_Graph;
121  int numEdges;
122 
123  EdgeInfo* edgeBegin() {
124  NodeInfo* n = this;
125  ++n; // start of edges
126  return reinterpret_cast<EdgeInfo*>(n);
127  }
128 
129  EdgeInfo* edgeEnd() {
130  EdgeInfo* ei = edgeBegin();
131  ei += numEdges;
132  return ei;
133  }
134 
135  NodeInfo* next() {
136  NodeInfo* ni = this;
137  EdgeInfo* ei = edgeEnd();
138  while (reinterpret_cast<char*>(ni) < reinterpret_cast<char*>(ei))
139  ++ni;
140  return ni;
141  }
142  };
143 
144 public:
145  typedef NodeInfo* GraphNode;
146  typedef EdgeTy edge_data_type;
147  typedef FileEdgeTy file_edge_data_type;
148  typedef NodeTy node_data_type;
149  typedef typename NodeInfoTypes::reference node_data_reference;
152  typedef NodeInfo** iterator;
153  typedef NodeInfo* const* const_iterator;
156  typedef int ReadGraphAuxData;
157 
158 protected:
160  uint64_t numNodes;
161  uint64_t numEdges;
163 
164  template <bool _A1 = HasNoLockable, bool _A2 = HasOutOfLineLockable>
166  typename std::enable_if<!_A1 && !_A2>::type* = 0) {
167  galois::runtime::acquire(N, mflag);
168  }
169 
170  template <bool _A1 = HasOutOfLineLockable, bool _A2 = HasNoLockable>
172  typename std::enable_if<_A1 && !_A2>::type* = 0) {
173  this->outOfLineAcquire(getId(N), mflag);
174  }
175 
176  template <bool _A1 = HasOutOfLineLockable, bool _A2 = HasNoLockable>
178  typename std::enable_if<_A2>::type* = 0) {}
179 
180  edge_iterator raw_begin(GraphNode N) { return N->edgeBegin(); }
181 
182  edge_iterator raw_end(GraphNode N) { return N->edgeEnd(); }
183 
184  template <bool _A1 = EdgeInfo::has_value,
187  typename FileGraph::edge_iterator nn, EdgeInfo* edge,
188  typename std::enable_if<!_A1 || _A2>::type* = 0) {
189  typedef LargeArray<FileEdgeTy> FED;
190  if (EdgeInfo::has_value)
191  edge->construct(graph.getEdgeData<typename FED::value_type>(nn));
192  }
193 
194  template <bool _A1 = EdgeInfo::has_value,
197  EdgeInfo* edge,
198  typename std::enable_if<_A1 && !_A2>::type* = 0) {
199  edge->construct();
200  }
201 
202  template <bool _Enable = HasId>
203  size_t getId(GraphNode N, typename std::enable_if<_Enable>::type* = 0) {
204  return N->getId();
205  }
206 
207  template <bool _Enable = HasId>
208  GraphNode getNode(size_t n, typename std::enable_if<_Enable>::type* = 0) {
209  return nodes[n];
210  }
211 
212 public:
214  for (typename Nodes::iterator ii = nodes.begin(), ei = nodes.end();
215  ii != ei; ++ii) {
216  NodeInfo* n = *ii;
217  EdgeInfo* edgeBegin = n->edgeBegin();
218  EdgeInfo* edgeEnd = n->edgeEnd();
219 
220  if (EdgeInfo::has_value) {
221  while (edgeBegin != edgeEnd) {
222  edgeBegin->destroy();
223  ++edgeBegin;
224  }
225  }
226  n->~NodeInfo();
227  }
228  }
229 
231  MethodFlag mflag = MethodFlag::WRITE) {
232  // galois::runtime::checkWrite(mflag, false);
233  acquireNode(N, mflag);
234  return N->getData();
235  }
236 
239  MethodFlag GALOIS_UNUSED(mflag) = MethodFlag::UNPROTECTED) const {
240  // galois::runtime::checkWrite(mflag, false);
241  return ni->get();
242  }
243 
244  GraphNode getEdgeDst(edge_iterator ni) const { return ni->dst; }
245 
246  size_t size() const { return numNodes; }
247  size_t sizeEdges() const { return numEdges; }
248  iterator begin() { return &nodes[0]; }
249  iterator end() { return &nodes[numNodes]; }
250  const_iterator begin() const { return &nodes[0]; }
251  const_iterator end() const { return &nodes[numNodes]; }
252 
253  local_iterator local_begin() { return &nodes[this->localBegin(numNodes)]; }
254  local_iterator local_end() { return &nodes[this->localEnd(numNodes)]; }
256  return &nodes[this->localBegin(numNodes)];
257  }
259  return &nodes[this->localEnd(numNodes)];
260  }
261 
263  acquireNode(N, mflag);
264  if (galois::runtime::shouldLock(mflag)) {
265  for (edge_iterator ii = N->edgeBegin(), ee = N->edgeEnd(); ii != ee;
266  ++ii) {
267  acquireNode(ii->dst, mflag);
268  }
269  }
270  return N->edgeBegin();
271  }
272 
274  acquireNode(N, mflag);
275  return N->edgeEnd();
276  }
277 
280  return internal::make_no_deref_range(edge_begin(N, mflag),
281  edge_end(N, mflag));
282  }
283 
286  return edges(N, mflag);
287  }
288 
292  template <typename CompTy>
294  const CompTy& comp = std::less<EdgeTy>(),
295  MethodFlag mflag = MethodFlag::WRITE) {
296  acquireNode(N, mflag);
297  std::sort(N->edgeBegin(), N->edgeEnd(),
298  internal::EdgeSortCompWrapper<EdgeInfo, CompTy>(comp));
299  }
300 
305  template <typename CompTy>
306  void sortEdges(GraphNode N, const CompTy& comp,
307  MethodFlag mflag = MethodFlag::WRITE) {
308  acquireNode(N, mflag);
309  std::sort(N->edgeBegin(), N->edgeEnd(), comp);
310  }
311 
312  void allocateFrom(FileGraph& graph, const ReadGraphAuxData&) {
313  numNodes = graph.size();
314  numEdges = graph.sizeEdges();
315  if (UseNumaAlloc) {
316  data.allocateLocal(sizeof(NodeInfo) * numNodes * 2 +
317  sizeof(EdgeInfo) * numEdges);
319  this->outOfLineAllocateLocal(numNodes);
320  } else {
321  data.allocateInterleaved(sizeof(NodeInfo) * numNodes * 2 +
322  sizeof(EdgeInfo) * numEdges);
324  this->outOfLineAllocateInterleaved(numNodes);
325  }
326  }
327 
328  void constructNodesFrom(FileGraph& graph, unsigned tid, unsigned total,
329  const ReadGraphAuxData&) {
330  auto r = graph
331  .divideByNode(Nodes::size_of::value + 2 * sizeof(NodeInfo) +
332  LC_Linear_Graph::size_of_out_of_line::value,
333  sizeof(EdgeInfo), tid, total)
334  .first;
335 
336  this->setLocalRange(*r.first, *r.second);
337  NodeInfo* curNode = reinterpret_cast<NodeInfo*>(data.data());
338 
339  size_t id = *r.first;
340  size_t edges = *graph.edge_begin(*r.first);
341  size_t bytes = edges * sizeof(EdgeInfo) + 2 * (id + 1) * sizeof(NodeInfo);
342  curNode += bytes / sizeof(NodeInfo);
343  for (FileGraph::iterator ii = r.first, ei = r.second; ii != ei;
344  ++ii, ++id) {
345  nodes.constructAt(*ii);
346  new (curNode) NodeInfo();
347  // curNode->construct();
348  curNode->setId(id);
349  curNode->numEdges =
350  std::distance(graph.edge_begin(*ii), graph.edge_end(*ii));
351  nodes[*ii] = curNode;
352  curNode = curNode->next();
353  }
354  }
355 
356  void constructEdgesFrom(FileGraph& graph, unsigned tid, unsigned total,
357  const ReadGraphAuxData&) {
358  auto r = graph
359  .divideByNode(Nodes::size_of::value + 2 * sizeof(NodeInfo) +
360  LC_Linear_Graph::size_of_out_of_line::value,
361  sizeof(EdgeInfo), tid, total)
362  .first;
363 
364  for (FileGraph::iterator ii = r.first, ei = r.second; ii != ei; ++ii) {
365  EdgeInfo* edge = nodes[*ii]->edgeBegin();
366  for (FileGraph::edge_iterator nn = graph.edge_begin(*ii),
367  en = graph.edge_end(*ii);
368  nn != en; ++nn) {
369  constructEdgeValue(graph, nn, edge);
370  edge->dst = nodes[graph.getEdgeDst(nn)];
371  ++edge;
372  }
373  }
374  }
375 };
376 
377 } // namespace graphs
378 } // namespace galois
379 
380 #endif
LC_Linear_Graph< NodeTy, _edge_data, HasNoLockable, UseNumaAlloc, HasOutOfLineLockable, HasId, FileEdgeTy > type
Definition: LC_Linear_Graph.h:73
Definition: LC_Linear_Graph.h:63
Local computation graph (i.e., graph structure does not change).
Definition: LC_Linear_Graph.h:46
GraphNode getNode(size_t n, typename std::enable_if< _Enable >::type *=0)
Definition: LC_Linear_Graph.h:208
size_t size() const
Definition: LC_Linear_Graph.h:246
Definition: LC_Linear_Graph.h:91
LargeArray< NodeInfo * > Nodes
Definition: LC_Linear_Graph.h:110
void constructEdgesFrom(FileGraph &graph, unsigned tid, unsigned total, const ReadGraphAuxData &)
Definition: LC_Linear_Graph.h:356
void constructNodesFrom(FileGraph &graph, unsigned tid, unsigned total, const ReadGraphAuxData &)
Definition: LC_Linear_Graph.h:328
void sortEdgesByEdgeData(GraphNode N, const CompTy &comp=std::less< EdgeTy >(), MethodFlag mflag=MethodFlag::WRITE)
Sorts outgoing edges of a node.
Definition: LC_Linear_Graph.h:293
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.
size_t size() const
Returns the number of nodes in the (sub)graph.
Definition: FileGraph.h:545
runtime::iterable< NoDerefIterator< edge_iterator > > out_edges(GraphNode N, MethodFlag mflag=MethodFlag::WRITE)
Definition: LC_Linear_Graph.h:285
node_data_reference getData(GraphNode N, MethodFlag mflag=MethodFlag::WRITE)
Definition: LC_Linear_Graph.h:230
size_t getId(GraphNode N, typename std::enable_if< _Enable >::type *=0)
Definition: LC_Linear_Graph.h:203
uint64_t numEdges
Definition: LC_Linear_Graph.h:161
edge_iterator edge_begin(GraphNode N, MethodFlag mflag=MethodFlag::WRITE)
Definition: LC_Linear_Graph.h:262
edge_iterator edge_end(GraphNode N, MethodFlag mflag=MethodFlag::WRITE)
Definition: LC_Linear_Graph.h:273
boost::counting_iterator< uint64_t > iterator
uint64 boost counting iterator
Definition: FileGraph.h:408
EdgeInfo * edge_iterator
Definition: LC_Linear_Graph.h:151
local_iterator local_end()
Definition: LC_Linear_Graph.h:254
EdgeInfo::reference edge_data_reference
Definition: LC_Linear_Graph.h:150
LargeArray< char > data
Definition: LC_Linear_Graph.h:159
LC_Linear_Graph< NodeTy, EdgeTy, _has_no_lockable, UseNumaAlloc, HasOutOfLineLockable, HasId, FileEdgeTy > type
Definition: LC_Linear_Graph.h:87
GraphNode getEdgeDst(edge_iterator it)
Gets the destination of some edge.
Definition: FileGraph.cpp:669
boost::counting_iterator< uint64_t > edge_iterator
Edge iterators (boost iterator)
Definition: FileGraph.h:248
Definition: Iterable.h:36
GraphNode getEdgeDst(edge_iterator ni) const
Definition: LC_Linear_Graph.h:244
local_iterator local_begin()
Definition: LC_Linear_Graph.h:253
iterator local_iterator
Definition: LC_Linear_Graph.h:154
size_t sizeEdges() const
Definition: LC_Linear_Graph.h:247
uint64_t numNodes
Definition: LC_Linear_Graph.h:160
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 allocateLocal(size_type n)
Allocates using Thread Local memory policy.
Definition: LargeArray.h:220
internal::EdgeInfoBase< NodeInfo *, EdgeTy > EdgeInfo
Definition: LC_Linear_Graph.h:108
~LC_Linear_Graph()
Definition: LC_Linear_Graph.h:213
void sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp)
Definition: ParallelSTL.h:247
internal::NodeInfoBaseTypes< NodeTy,!HasNoLockable &&!HasOutOfLineLockable > NodeInfoTypes
Definition: LC_Linear_Graph.h:113
Modify a LC_Graph to have in and out edges.
Definition: LC_InOut_Graph.h:39
LC_Linear_Graph< _node_data, EdgeTy, HasNoLockable, UseNumaAlloc, HasOutOfLineLockable, HasId, FileEdgeTy > type
Definition: LC_Linear_Graph.h:66
EdgeTy & reference
Definition: LazyObject.h:96
void allocateInterleaved(size_type n)
[allocatefunctions] Allocates interleaved across NUMA (memory) nodes.
Definition: LargeArray.h:206
void acquireNode(GraphNode N, MethodFlag mflag, typename std::enable_if< _A1 &&!_A2 >::type *=0)
Definition: LC_Linear_Graph.h:171
void allocateFrom(FileGraph &graph, const ReadGraphAuxData &)
Definition: LC_Linear_Graph.h:312
const_local_iterator local_end() const
Definition: LC_Linear_Graph.h:258
const_local_iterator local_begin() const
Definition: LC_Linear_Graph.h:255
const_iterator end() const
Definition: LC_Linear_Graph.h:251
pointer iterator
Definition: LargeArray.h:67
LC_Linear_Graph< NodeTy, EdgeTy, HasNoLockable, UseNumaAlloc, HasOutOfLineLockable, HasId, _file_edge_data > type
Definition: LC_Linear_Graph.h:80
iterator end()
Definition: LC_Linear_Graph.h:249
const_iterator const_local_iterator
Definition: LC_Linear_Graph.h:155
Definition: LC_Linear_Graph.h:56
const_iterator begin() const
Definition: LC_Linear_Graph.h:250
NodeInfo *const * const_iterator
Definition: LC_Linear_Graph.h:153
NodeInfo * GraphNode
Definition: LC_Linear_Graph.h:145
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
MethodFlag
What should the runtime do when executing a method.
Definition: MethodFlags.h:34
Definition: LC_Linear_Graph.h:70
LC_Linear_Graph< NodeTy, EdgeTy, HasNoLockable, UseNumaAlloc, _has_out_of_line_lockable, _has_out_of_line_lockable||HasId, FileEdgeTy > type
Definition: LC_Linear_Graph.h:102
NodeInfoTypes::reference node_data_reference
Definition: LC_Linear_Graph.h:149
edge_data_reference getEdgeData(edge_iterator ni, MethodFlag GALOIS_UNUSED(mflag)=MethodFlag::UNPROTECTED) const
Definition: LC_Linear_Graph.h:238
iterator begin()
Definition: LC_Linear_Graph.h:248
edge_iterator raw_begin(GraphNode N)
Definition: LC_Linear_Graph.h:180
LC_Linear_Graph< NodeTy, EdgeTy, HasNoLockable, _use_numa_alloc, HasOutOfLineLockable, HasId, FileEdgeTy > type
Definition: LC_Linear_Graph.h:94
int ReadGraphAuxData
Definition: LC_Linear_Graph.h:156
read_with_aux_graph_tag read_tag
Definition: LC_Linear_Graph.h:105
EdgeTy & getEdgeData(GraphNode src, GraphNode dst)
Get edge data of an edge between 2 nodes.
Definition: FileGraph.h:241
Definition: LC_Linear_Graph.h:115
void constructAt(size_type n, Args &&...args)
Definition: LargeArray.h:260
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
runtime::iterable< NoDerefIterator< edge_iterator > > edges(GraphNode N, MethodFlag mflag=MethodFlag::WRITE)
Definition: LC_Linear_Graph.h:279
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
size_t sizeEdges() const
Returns the number of edges in the (sub)graph.
Definition: FileGraph.h:548
const_pointer data() const
Definition: LargeArray.h:292
void acquireNode(GraphNode N, MethodFlag mflag, typename std::enable_if<!_A1 &&!_A2 >::type *=0)
Definition: LC_Linear_Graph.h:165
iterator end()
Definition: LargeArray.h:201
edge_iterator raw_end(GraphNode N)
Definition: LC_Linear_Graph.h:182
LC_Linear_Graph< NodeTy, EdgeTy, HasNoLockable, UseNumaAlloc, HasOutOfLineLockable, _has_id, FileEdgeTy > type
Definition: LC_Linear_Graph.h:59
Graph that mmaps Galois gr files for access.
Definition: FileGraph.h:57
T value_type
Definition: Executor_ParaMeter.h:111
Nodes nodes
Definition: LC_Linear_Graph.h:162
void sortEdges(GraphNode N, const CompTy &comp, MethodFlag mflag=MethodFlag::WRITE)
Sorts outgoing edges of a node.
Definition: LC_Linear_Graph.h:306
void acquireNode(GraphNode, MethodFlag, typename std::enable_if< _A2 >::type *=0)
Definition: LC_Linear_Graph.h:177
NodeInfo ** iterator
Definition: LC_Linear_Graph.h:152
void constructEdgeValue(FileGraph &graph, typename FileGraph::edge_iterator nn, EdgeInfo *edge, typename std::enable_if<!_A1||_A2 >::type *=0)
Definition: LC_Linear_Graph.h:186
void construct(Args &&...args)
[allocatefunctions]
Definition: LargeArray.h:254
NodeTy node_data_type
Definition: LC_Linear_Graph.h:148
iterator begin()
Definition: LargeArray.h:199
EdgeTy edge_data_type
Definition: LC_Linear_Graph.h:146
FileEdgeTy file_edge_data_type
Definition: LC_Linear_Graph.h:147
void constructEdgeValue(FileGraph &, typename FileGraph::edge_iterator, EdgeInfo *edge, typename std::enable_if< _A1 &&!_A2 >::type *=0)
Definition: LC_Linear_Graph.h:196