NeoPZ
TPZBoostGraph.cpp
Go to the documentation of this file.
1 
6 #include "TPZBoostGraph.h"
7 #include <fstream>
8 #include "pzmanvector.h"
9 
10 #ifdef USING_BOOST
11 
12 #include <boost/graph/properties.hpp>
13 #include <boost/graph/compressed_sparse_row_graph.hpp>
14 #include "pzlog.h"
15 //#include <sys/time.h>
16 #include <stdio.h>
17 
18 #ifdef LOG4CXX
19 static LoggerPtr logger(Logger::getLogger("pz.external.boostgraph"));
20 #endif
21 
22 using namespace boost;
23 using namespace std;
24 
25 TPZBoostGraph::TPZBoostGraph(int64_t NElements, int64_t NNodes) : TPZRenumbering(NElements,NNodes),fGType(Sloan)//,fGType(KMCExpensive)
26 {
27  m_Graph.clear();
28 }
29 
30 
31 TPZBoostGraph::~TPZBoostGraph()
32 {
33  //Performe termination tasks
34 }
35 
36 
37 void TPZBoostGraph::ClearDataStructures()
38 {
39  m_Edges.clear();
41 }
42 
43 void TPZBoostGraph::CompressedResequence(TPZVec<int64_t> &perm, TPZVec<int64_t> &inverseperm)
44 {
45 
46 
47  /* if the graph is empty, trivial */
48  if (this->fNNodes == 0)
49  {
50  perm.resize(0);
51  inverseperm.resize(0);
52  return;
53  }
54  /* define type graph */
55  typedef boost::compressed_sparse_row_graph<boost::directedS> BoostGraph;
56 
57  /* this code is a copy modified from the method ConvertGraph. Used here to create a Compressed Sparse Row Graph Boost */
58  int64_t nod,el;
59  TPZVec<int64_t> nodtoelgraphindex;
60  TPZVec<int64_t> nodtoelgraph;
61 
62  NodeToElGraph(fElementGraph,fElementGraphIndex,nodtoelgraph,nodtoelgraphindex);
63 
64  std::vector<std::pair<std::size_t, std::size_t> > edges;
65 
66  size_t maxsize = 100000;
67  int resize_times = 1;
68  edges.reserve(1000000);
69 
70  for(nod=0; nod<fNNodes; nod++)
71  {
72  int64_t firstel = nodtoelgraphindex[nod];
73  int64_t lastel = nodtoelgraphindex[nod+1];
74  std::set<int64_t> nodecon;
75  for(el=firstel; el<lastel; el++)
76  {
77  int64_t gel = nodtoelgraph[el];
78  int64_t firstelnode = fElementGraphIndex[gel];
79  int64_t lastelnode = fElementGraphIndex[gel+1];
80  nodecon.insert(&fElementGraph[firstelnode],&fElementGraph[(lastelnode-1)]+1);
81  }
82  nodecon.erase(nod);
83 
84  std::set<int64_t>::iterator it;
85  for(it = nodecon.begin(); it!= nodecon.end(); it++)
86  {
87  edges.push_back(std::make_pair(nod, *it));
88  edges.push_back(std::make_pair(*it, nod));
89  if (edges.size() > (edges.size()+maxsize*resize_times)) {
90  edges.reserve(edges.size()+maxsize*(++resize_times));
91  }
92  }
93  }
94 
95  BoostGraph G(boost::edges_are_unsorted_multi_pass, edges.begin(), edges.end(), fNNodes);
96 
97  boost::property_map<BoostGraph, boost::vertex_index_t>::type boost_index_map;
98  boost_index_map = get(boost::vertex_index, G);
99 
100  // Compute graph re-ordering
101  std::vector<std::size_t> inv_perm(fNNodes);
102 
103  boost::cuthill_mckee_ordering(G, inv_perm.begin());
104 
105  perm.Resize(fNNodes);
106  inverseperm.Resize(fNNodes);
107 
108  for (std::size_t i = 0; i < fNNodes; ++i)
109  {
110  perm[inv_perm[i]] = i;
111  inverseperm[i]=inv_perm[i];
112  }
113 
114 }
115 void TPZBoostGraph::Resequence(TPZVec<int64_t> &perm, TPZVec<int64_t> &inverseperm)
116 {
117 #ifdef LOG4CXX
118  if (logger->isDebugEnabled())
119  {
120  std::stringstream sout;
121  sout << "TPZBoostGraph::Resequence started \n";
122  Print(fElementGraph,fElementGraphIndex,"Element graph when entering Resequence",sout);
123  LOG4CXX_DEBUG(logger,sout.str());
124  }
125 #endif
126  if (this->fNNodes == 0) {
127  perm.resize(0);
128  inverseperm.resize(0);
129  return;
130  }
131  Graph G;
132  size_type i;
133  size_type elgraphsize = fElementGraphIndex.NElements()-1;
134  TPZManVector<int64_t> nconnects(fNNodes,0);
135 
136  for(i=0; i < elgraphsize; i++)
137  {
138  int64_t first, second;
139  first = fElementGraphIndex[i];
140  second = fElementGraphIndex[i+1];
141  int64_t j,k;
142  for(j=first; j< second; j++)
143  {
144  for(k=j+1; k<second; k++)
145  {
146  add_edge(fElementGraph[j],fElementGraph[k],G);
147  nconnects[fElementGraph[j]]++;
148  }
149  }
150  }
151 
152  for(i=0; i< (size_type)nconnects.size(); i++)
153  {
154  if(!nconnects[i])
155  {
156  add_edge(i,i,G);
157  }
158  }
159 
160  graph_traits<Graph>::vertex_iterator ui, ui_end;
161 
162  property_map<Graph,vertex_degree_t>::type deg = get(vertex_degree, G);
163  for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui)
164  deg[*ui] = degree(*ui, G);
165 
166 #ifdef LOG4CXX
167  if (logger->isDebugEnabled())
168  {
169  std::stringstream sout;
170  sout << "NNodes " << fNNodes << std::endl;
171  sout << "NElements " << fNElements << std::endl;
172 
173  sout << "Original Bandwidth: " << bandwidth(G) << std::endl;
174  sout << " Original profile: "
175  << profile(G)
176  << std::endl;
177  LOGPZ_DEBUG(logger, sout.str())
178  }
179 #endif
180  /* std::cout << " Original max_wavefront: "
181  << max_wavefront(G)
182  << std::endl;
183  std::cout << " Original aver_wavefront: "
184  << aver_wavefront(G)
185  << std::endl;
186  std::cout << " Original rms_wavefront: "
187  << rms_wavefront(G)
188  << std::endl;*/
189  // std::cout << "Number of Vertices " << num_vertices(G) << std::endl;
190  // std::cout << "Number of Edges " << num_edges(G) << std::endl;
191  int64_t nVertices = num_vertices(G);
192  // std::cout << "Number of Vertices " << nVertices << std::endl;
193  TPZVec<Vertex> inv_perm(nVertices);
194  TPZVec<size_type> l_perm(nVertices);
195  for(size_type i = 0; i < (size_type)l_perm.size(); i++) l_perm[i]=-1;
196  for(size_type i = 0; i < (size_type)l_perm.size(); i++) inv_perm[i]=0;
197  perm.Resize(fNNodes,-1);
198 
199  switch(fGType)
200  {
201  case KMC:
202 
203  {
204  Vertex s = vertex(0, G);
205  //reverse cuthill_mckee_ordering
206  cuthill_mckee_ordering(G, s, inv_perm.begin(), get(vertex_color, G),
207  get(vertex_degree, G));
208 #ifdef LOG4CXX
209  if(logger->isDebugEnabled())
210  {
211  LOGPZ_DEBUG(logger,"Reverse Cuthill-McKee ordering:")
212  }
213 #endif
214 
215  }
216  break;
217 
218  case KMCExpensive:
219  {
220  cuthill_mckee_ordering(G, inv_perm.begin(), get(vertex_color, G),
221  get(vertex_degree, G));
222 #ifdef LOG4CXX
223  if (logger->isDebugEnabled()) {
224  LOGPZ_DEBUG(logger, "Reverse Expensive Cuthill-McKee ordering:")
225  }
226 #endif
227 
228  }
229  break;
230  case Sloan:
231  {
232 #ifdef LOG4CXX
233  if (logger->isDebugEnabled()) {
234  LOGPZ_DEBUG(logger, "Sloan ordering:")
235  }
236 #endif
237 
238  //Setting the start node
239  Vertex s = vertex(0, G);
240  int ecc; //defining a variable for the pseudoperipheral radius
241 
242  //Calculating the pseudoeperipheral node and radius
243  Vertex e = pseudo_peripheral_pair(G, s, ecc, get(vertex_color, G), get(vertex_degree, G) );
244 #ifdef LOG4CXX
245  if (logger->isDebugEnabled())
246  {
247  std::stringstream sout;
248  sout << "Sloan Starting vertex: " << s << endl;
249  sout << "Sloan Pseudoperipheral vertex: " << e << endl;
250  sout << "Sloan Pseudoperipheral radius: " << ecc << endl << endl;
251  LOGPZ_DEBUG(logger, sout.str())
252  }
253 #endif
254  //Sloan ordering
255  sloan_ordering(G, s, e, inv_perm.begin(), get(vertex_color, G),
256  get(vertex_degree, G), get(vertex_priority, G));
257  }
258  break;
259 
260  }
261 
262  for (size_type c = 0; c != (size_type)inv_perm.size(); ++c)
263  {
264  l_perm[inv_perm[c]] = c;
265  }
266 
267  /*
268  std::cout << "l_perm = ";
269  for (size_type i = 0; i < l_perm.size(); ++i)
270  {
271  std::cout << i << "/" << l_perm[i] << " ";
272  }
273  std::cout << std::endl;
274  */
275  // property_map<Graph, vertex_index_t>::type
276  // index_map = get(vertex_index, G);
277 
278  /* std::cout << " bandwidth: "
279  << bandwidth(G, make_iterator_property_map(&l_perm[0], index_map, l_perm[0]))
280  << std::endl;
281  std::cout << " profile: "
282  << profile(G, make_iterator_property_map(&l_perm[0], index_map, l_perm[0]))
283  << std::endl;
284  std::cout << " max_wavefront: "
285  << max_wavefront(G, make_iterator_property_map(&l_perm[0], index_map, l_perm[0]))
286  << std::endl;
287  std::cout << " aver_wavefront: "
288  << aver_wavefront(G, make_iterator_property_map(&l_perm[0], index_map, l_perm[0]))
289  << std::endl;
290  std::cout << " rms_wavefront: "
291  << rms_wavefront(G, make_iterator_property_map(&l_perm[0], index_map, l_perm[0]))
292  << std::endl;
293  std::cout << " inverse map bandwidth: "
294  << bandwidth(G, make_iterator_property_map(&inv_perm[0], index_map, inv_perm[0]))
295  << std::endl;
296  std::cout << " inverse map profile: "
297  << profile(G, make_iterator_property_map(&inv_perm[0], index_map, inv_perm[0]))
298  << std::endl;
299  std::cout << " inverse map max_wavefront: "
300  << max_wavefront(G, make_iterator_property_map(&inv_perm[0], index_map, inv_perm[0]))
301  << std::endl;
302  std::cout << " inverse map aver_wavefront: "
303  << aver_wavefront(G, make_iterator_property_map(&inv_perm[0], index_map, inv_perm[0]))
304  << std::endl;
305  std::cout << " inverse map rms_wavefront: "
306  << rms_wavefront(G, make_iterator_property_map(&inv_perm[0], index_map, inv_perm[0]))
307  << std::endl;*/
308  perm.Resize(l_perm.size());
309  inverseperm.Resize(inv_perm.size());
310  for(i=0; i<(size_type)l_perm.size(); i++)
311  {
312  perm[i] = l_perm[i];
313  inverseperm[i] = inv_perm[i];
314  }
315 #ifdef LOG4CXX
316  if (logger->isDebugEnabled()) {
317  LOGPZ_DEBUG(logger, "TPZBoostGraph::Resequence finished")
318  }
319 #endif
320 
321 }
322 /*
323 
324  std::cout << "l_perm[index_map[inv_perm[c]]] " <<
325  l_perm[index_map[inv_perm[c]]] << " index_map[inv_perm[c]] " <<
326  index_map[inv_perm[c]] <<
327  " Inv_Perm[c] " << inv_perm[c] << "\n";
328 
329 
330  void TPZBoostGraph::Resequence(TPZVec<int> &permuta, TPZVec<int> &inverseperm)
331  {
332  //Creating a graph and adding the edges from above into it
333  Graph G;//(10);
334  for (int i = 0; i < m_Edges.size(); ++i)
335  add_edge(m_Edges[i].first, m_Edges[i].second, G);
336 
337  //Creating two iterators over the vertices
338  graph_traits<Graph>::vertex_iterator ui, ui_end;
339 
340  //Creating a property_map with the degrees of the degrees of each vertex
341  property_map<Graph,vertex_degree_t>::type deg = get(vertex_degree, G);
342  for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui)
343  deg[*ui] = degree(*ui, G);
344 
345  //Creating a property_map for the indices of a vertex
346  property_map<Graph, vertex_index_t>::type index_map = get(vertex_index, G);
347 
348  std::cout << "original bandwidth: " << bandwidth(G) << std::endl;
349  std::cout << "original profile: " << profile(G) << std::endl;
350  std::cout << "original max_wavefront: " << max_wavefront(G) << std::endl;
351  std::cout << "original aver_wavefront: " << aver_wavefront(G) << std::endl;
352  std::cout << "original rms_wavefront: " << rms_wavefront(G) << std::endl;
353 
354 
355  //Creating a vector of vertices
356  std::vector<Vertex> sloan_order(num_vertices(G));
357  //Creating a vector of size_type
358  std::vector<size_type> perm(num_vertices(G));
359  permuta.Resize(perm.size());
360  {
361  //sloan_ordering
362  sloan_ordering(G, sloan_order.begin(),
363  get(vertex_color, G),
364  make_degree_map(G),
365  get(vertex_priority, G) );
366 
367  cout << endl << "Sloan ordering without a start-vertex:" << endl;
368  cout << " ";
369  for (std::vector<Vertex>::const_iterator i=sloan_order.begin();
370  i != sloan_order.end(); ++i)
371  {
372  cout << index_map[*i] << " ";
373  permuta[*i]=index_map[*i];
374  }
375  cout << endl;
376 
377  for (size_type c = 0; c != sloan_order.size(); ++c)
378  perm[index_map[sloan_order[c]]] = c;
379  std::cout << " bandwidth: "
380  << bandwidth(G, make_iterator_property_map(&perm[0], index_map, perm[0]))
381  << std::endl;
382  std::cout << " profile: "
383  << profile(G, make_iterator_property_map(&perm[0], index_map, perm[0]))
384  << std::endl;
385  std::cout << " max_wavefront: "
386  << max_wavefront(G, make_iterator_property_map(&perm[0], index_map, perm[0]))
387  << std::endl;
388  std::cout << " aver_wavefront: "
389  << aver_wavefront(G, make_iterator_property_map(&perm[0], index_map, perm[0]))
390  << std::endl;
391  std::cout << " rms_wavefront: "
392  << rms_wavefront(G, make_iterator_property_map(&perm[0], index_map, perm[0]))
393  << std::endl;
394  }
395 
396  {
397 
398  //Setting the start node
399  Vertex s = vertex(0, G);
400  int ecc; //defining a variable for the pseudoperipheral radius
401 
402  //Calculating the pseudoeperipheral node and radius
403  Vertex e = pseudo_peripheral_pair(G, s, ecc, get(vertex_color, G), get(vertex_degree, G) );
404 
405  cout << endl;
406  cout << "Starting vertex: " << s << endl;
407  cout << "Pseudoperipheral vertex: " << e << endl;
408  cout << "Pseudoperipheral radius: " << ecc << endl << endl;
409 
410 
411 
412  //Sloan ordering
413  sloan_ordering(G, s, e, sloan_order.begin(), get(vertex_color, G),
414  get(vertex_degree, G), get(vertex_priority, G));
415 
416  cout << "Sloan ordering starting at: " << s << endl;
417  cout << " ";
418 
419  for (std::vector<Vertex>::const_iterator i = sloan_order.begin();
420  i != sloan_order.end(); ++i)
421  {
422  cout << index_map[*i] << " ";
423  permuta[*i]=index_map[*i];
424  }
425  cout << endl;
426 
427  for (size_type c = 0; c != sloan_order.size(); ++c)
428  perm[index_map[sloan_order[c]]] = c;
429  std::cout << " bandwidth: "
430  << bandwidth(G, make_iterator_property_map(&perm[0], index_map, perm[0]))
431  << std::endl;
432  std::cout << " profile: "
433  << profile(G, make_iterator_property_map(&perm[0], index_map, perm[0]))
434  << std::endl;
435  std::cout << " max_wavefront: "
436  << max_wavefront(G, make_iterator_property_map(&perm[0], index_map, perm[0]))
437  << std::endl;
438  std::cout << " aver_wavefront: "
439  << aver_wavefront(G, make_iterator_property_map(&perm[0], index_map, perm[0]))
440  << std::endl;
441  std::cout << " rms_wavefront: "
442  << rms_wavefront(G, make_iterator_property_map(&perm[0], index_map, perm[0]))
443  << std::endl;
444  }
445 
446  }
447  */
448 /*
449  {
450  //perm.Resize(fNNodes+1);
451  Graph G;
452  for (int i = 0; i < m_Edges.size(); ++i)
453  add_edge(m_Edges[i].first, m_Edges[i].second, G);
454 
455  graph_traits<Graph>::vertex_iterator ui, ui_end;
456 
457  property_map<Graph,vertex_degree_t>::type deg = get(vertex_degree, G);
458  for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui)
459  deg[*ui] = degree(*ui, G);
460 
461  property_map<Graph, vertex_index_t>::type
462  index_map = get(vertex_index, G);
463 
464  std::cout << "original bandwidth: " << bandwidth(G) << std::endl;
465  std::cout << "Number of Vertices " << num_vertices(G) << std::endl;
466  std::cout << "Number of Edges " << num_edges(G) << std::endl;
467 
468  std::vector<Vertex> inv_perm(num_vertices(G));
469  std::vector<size_type> l_perm(num_vertices(G));
470 
471  {
472  //reverse cuthill_mckee_ordering
473  // cuthill_mckee_ordering(G, inv_perm.rbegin(), get(vertex_color, G),
474  // make_degree_map(G));
475  cuthill_mckee_ordering(G, inv_perm.begin(), get(vertex_color, G),
476  make_degree_map(G));
477  cout << "Reverse Cuthill-McKee ordering:" << endl;
478  cout << " ";
479  perm.Resize(l_perm.size(),0);
480  int orignode = 0;
481  for (std::vector<Vertex>::const_iterator i=inv_perm.begin();i != inv_perm.end();++i)
482  {
483  cout << *i << ": " << index_map[*i] << " ";
484  perm[orignode] = index_map[*i];
485  orignode++;
486  }
487  cout << endl;
488 
489  for (size_type c = 0; c != inv_perm.size(); ++c)
490  {
491  l_perm[index_map[inv_perm[c]]] = c;
492  std::cout << "l_perm[index_map[inv_perm[c]]] " <<
493  l_perm[index_map[inv_perm[c]]] << " index_map[inv_perm[c]] " <<
494  index_map[inv_perm[c]] <<
495  " Inv_Perm[c] " << inv_perm[c] << "\n";
496  }
497  std::cout << " bandwidth: "
498  << bandwidth(G, make_iterator_property_map(&l_perm[0], index_map, l_perm[0]))
499  << std::endl;
500  }
501 
502 
503 
504  }
505  */
506 
507 /*
508  std::vector<Vertex> inv_perm(num_vertices(m_Graph));
509  std::vector<size_type> l_perm(num_vertices(m_Graph));
510  {
511  Vertex s = vertex(0, m_Graph);
512  //reverse cuthill_mckee_ordering
513  cuthill_mckee_ordering(m_Graph, s, inv_perm.rbegin(), get(vertex_color, m_Graph),
514  get(vertex_degree, m_Graph));
515  for (std::vector<Vertex>::const_iterator i=inv_perm.begin();
516  i != inv_perm.end(); ++i)
517  cout << m_Index_map[*i] << " ";
518  cout << endl;
519 
520  for (size_type c = 0; c != inv_perm.size(); ++c)
521  l_perm[m_Index_map[inv_perm[c]]] = c;
522  std::cout << " bandwidth: "
523  << bandwidth(m_Graph, make_iterator_property_map(&l_perm[0], m_Index_map, l_perm[0]))
524  << std::endl;
525  }
526  int i;
527  int nVertex = l_perm.size();
528  perm.Resize(nVertex);
529  inverseperm.Resize(nVertex);
530  for(i = 0; i < nVertex; i++)
531  {
532  perm[i]=l_perm[i];
533  inverseperm[i]=inv_perm[i];
534  }
535 
536  */
537 #endif
Contains definitions to LOGPZ_DEBUG, LOGPZ_INFO, LOGPZ_WARN, LOGPZ_ERROR and LOGPZ_FATAL, and the implementation of the inline InitializePZLOG(string) function using log4cxx library or not. It must to be called out of "#ifdef LOG4CXX" scope.
virtual void resize(const int64_t newsize)
Definition: pzvec.h:213
void degree(int root, int adj_num, int adj_row[], int adj[], int mask[], int deg[], int *iccsze, int ls[], int node_num)
Definition: rcm.cpp:875
void profile(double *ara, double *arb, double *arc, unsigned sz, unsigned num_threads, void *(*fun)(void *), ElapsedTimeRunStat &et, RunStatsTable &rst)
Definition: gflopstest.cpp:237
virtual void Resize(const int64_t newsize, const T &object)
Resizes the vector object reallocating the necessary storage, copying the existing objects to the new...
Definition: pzvec.h:373
Contains the TPZBoostGraph class which implements an interface to the BGL for graph operations...
This abstract class which defines the behavior which derived classes need to implement for implement...
#define LOGPZ_DEBUG(A, B)
Define log for debug info.
Definition: pzlog.h:87
Free store vector implementation.
virtual void ClearDataStructures()
This will reset all datastructures the object may contain.