HavoqGT
triangle_count.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013, Lawrence Livermore National Security, LLC.
3  * Produced at the Lawrence Livermore National Laboratory.
4  * Written by Roger Pearce <rpearce@llnl.gov>.
5  * LLNL-CODE-644630.
6  * All rights reserved.
7  *
8  * This file is part of HavoqGT, Version 0.1.
9  * For details, see https://computation.llnl.gov/casc/dcca-pub/dcca/Downloads.html
10  *
11  * Please also read this link – Our Notice and GNU Lesser General Public License.
12  * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
13  *
14  * This program is free software; you can redistribute it and/or modify it under
15  * the terms of the GNU Lesser General Public License (as published by the Free
16  * Software Foundation) version 2.1 dated February 1999.
17  *
18  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
19  * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS FOR A
20  * PARTICULAR PURPOSE. See the terms and conditions of the GNU General Public
21  * License for more details.
22  *
23  * You should have received a copy of the GNU Lesser General Public License along
24  * with this program; if not, write to the Free Software Foundation, Inc.,
25  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26  *
27  * OUR NOTICE AND TERMS AND CONDITIONS OF THE GNU GENERAL PUBLIC LICENSE
28  *
29  * Our Preamble Notice
30  *
31  * A. This notice is required to be provided under our contract with the
32  * U.S. Department of Energy (DOE). This work was produced at the Lawrence
33  * Livermore National Laboratory under Contract No. DE-AC52-07NA27344 with the DOE.
34  *
35  * B. Neither the United States Government nor Lawrence Livermore National
36  * Security, LLC nor any of their employees, makes any warranty, express or
37  * implied, or assumes any liability or responsibility for the accuracy,
38  * completeness, or usefulness of any information, apparatus, product, or process
39  * disclosed, or represents that its use would not infringe privately-owned rights.
40  *
41  * C. Also, reference herein to any specific commercial products, process, or
42  * services by trade name, trademark, manufacturer or otherwise does not
43  * necessarily constitute or imply its endorsement, recommendation, or favoring by
44  * the United States Government or Lawrence Livermore National Security, LLC. The
45  * views and opinions of authors expressed herein do not necessarily state or
46  * reflect those of the United States Government or Lawrence Livermore National
47  * Security, LLC, and shall not be used for advertising or product endorsement
48  * purposes.
49  *
50  */
51 
52 #ifndef HAVOQGT_MPI_TRIANGLE_COUNT_HPP_INCLUDED
53 #define HAVOQGT_MPI_TRIANGLE_COUNT_HPP_INCLUDED
54 
56 #include <boost/container/deque.hpp>
57 
58 
59 namespace havoqgt { namespace mpi {
60 
61 
62 template <typename Visitor>
64 {
65 
66 protected:
67  std::priority_queue< Visitor, std::deque<Visitor>,
68  std::greater<Visitor> > m_data;
69 public:
71 
72  bool push(Visitor const & task)
73  {
74  m_data.push(task);
75  return true;
76  }
77 
78  void pop()
79  {
80  m_data.pop();
81  }
82 
83  Visitor const & top() //const
84  {
85  return m_data.top();
86  }
87 
88  size_t size() const
89  {
90  return m_data.size();;
91  }
92 
93  bool empty() const
94  {
95  return m_data.empty();
96  }
97 
98  void clear()
99  {
100  m_data.clear();
101  }
102 };
103 
104 
105 template<typename Graph>
107 public:
109  typedef typename Graph::vertex_locator vertex_locator;
110 
112  vertex(),
113  first(),
114  second(),
115  last_degree(0) { }
116 
117  triangle_count_visitor(vertex_locator v):
118  vertex(v),
119  first(),
120  second(),
121  last_degree(0) { }
122 
123  triangle_count_visitor(vertex_locator v, vertex_locator f, uint32_t deg):
124  vertex(v), first(f),
125  second(),
126  last_degree(deg) { }
127 
128  triangle_count_visitor(vertex_locator v, vertex_locator f, vertex_locator s, uint32_t deg):
129  vertex(v), first(f), second(s), last_degree(deg) { }
130 
131  bool pre_visit() const {
132  //return true;//(second == std::numeric_limits<vertex_descriptor_type>::max());
133  uint32_t my_degree = m_ptr_graph->degree(vertex);
134  if( last_degree < my_degree ) {
135  return true;
136  } else if( last_degree > my_degree) {
137  return false;
138  }
139  return first < vertex;
140  }
141 
142  template<typename VisitorQueueHandle>
143  bool visit(Graph& g, VisitorQueueHandle vis_queue) const {
144 
145  if(!first.is_valid()) {
146  typedef typename Graph::edge_iterator eitr_type;
147  for(eitr_type eitr = g.edges_begin(vertex); eitr != g.edges_end(vertex); ++eitr) {
148  vertex_locator neighbor = eitr.target();
149  my_type new_visitor( neighbor, vertex, g.degree(vertex) );
150  vis_queue->queue_visitor(new_visitor);
151  }
152  } else if(!second.is_valid()) {
153  typedef typename Graph::edge_iterator eitr_type;
154  for(eitr_type eitr = g.edges_begin(vertex); eitr != g.edges_end(vertex); ++eitr) {
155  vertex_locator neighbor = eitr.target();
156  my_type new_visitor( neighbor, vertex, first, g.degree(vertex) );
157  vis_queue->queue_visitor(new_visitor);
158  }
159  } else {
160  //Make a binary search here!
161  typedef typename Graph::edge_iterator eitr_type;
162  for(eitr_type eitr = g.edges_begin(vertex); eitr != g.edges_end(vertex); ++eitr) {
163  vertex_locator neighbor = eitr.target();
164  if(neighbor == second) {
165  (*tc_data())[vertex] = (*tc_data())[vertex] + 1;
166  }
167  }
168  }
169  return true;
170  }
171 
172  int get_state() const {
173  if(!first.is_valid()) {
174  return 0;
175  }
176  if(!second.is_valid()) {
177  return 1;
178  }
179  return 2;
180  }
181 
182  typedef typename Graph::template vertex_data<uint64_t, std::allocator<uint64_t> > vdtd_type;
183 
184  static void set_tc_data(vdtd_type* _data) { tc_data() = _data; }
185 
186  static vdtd_type*& tc_data() {
187  static vdtd_type* data;
188  return data;
189  }
190 
191  friend inline bool operator>(const triangle_count_visitor& v1, const triangle_count_visitor& v2) {
192  return v1.get_state() < v2.get_state();
193  }
194 
195  friend inline bool operator<(const triangle_count_visitor& v1, const triangle_count_visitor& v2) {
196  return v1.get_state() > v2.get_state();
197  }
198 
199  vertex_locator vertex, first, second;
200  uint32_t last_degree;
201  static Graph* m_ptr_graph;
202 };
203 
204 template<typename Graph>
206 
207 
208 template <typename TGraph>
209 uint64_t triangle_count(TGraph& g, typename TGraph::vertex_locator s) {
210  typedef TGraph graph_type;
211  typedef typename mpi::triangle_count_visitor<TGraph> visitor_type;
212  visitor_type::m_ptr_graph = &g;
214 
215  visitor_queue_type vq(&g);
216 
217  typename graph_type::template vertex_data<uint64_t, std::allocator<uint64_t> > tc_data(g);
218  visitor_type::set_tc_data(&tc_data);
219 
220  vq.init_visitor_traversal(s);
221 
222  return tc_data.global_accumulate();
223 }
224 
225 
226 
227 
228 
229 }} //end namespace havoqgt::mpi
230 
231 
232 
233 
234 #endif //HAVOQGT_MPI_TRIANGLE_COUNT_HPP_INCLUDED
hmpi::delegate_partitioned_graph< segment_manager_t > graph_type
Graph::template vertex_data< uint64_t, std::allocator< uint64_t > > vdtd_type
triangle_count_visitor(vertex_locator v, vertex_locator f, vertex_locator s, uint32_t deg)
friend bool operator>(const triangle_count_visitor &v1, const triangle_count_visitor &v2)
triangle_count_visitor(vertex_locator v, vertex_locator f, uint32_t deg)
static void set_tc_data(vdtd_type *_data)
triangle_count_visitor< Graph > my_type
uint64_t triangle_count(TGraph &g, typename TGraph::vertex_locator s)
bool visit(Graph &g, VisitorQueueHandle vis_queue) const
std::priority_queue< Visitor, std::deque< Visitor >, std::greater< Visitor > > m_data
friend bool operator<(const triangle_count_visitor &v1, const triangle_count_visitor &v2)