Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Zoltan2_componentMetrics.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Zoltan2: A package of combinatorial algorithms for scientific computing
4 //
5 // Copyright 2012 NTESS and the Zoltan2 contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
17 #ifndef _ZOLTAN2_COMPONENTMETRICS_HPP_
18 #define _ZOLTAN2_COMPONENTMETRICS_HPP_
19 
20 #include <Zoltan2_Standards.hpp>
21 #include <Zoltan2_GraphModel.hpp>
22 #include <Teuchos_Comm.hpp>
23 #include <queue>
24 
25 namespace Zoltan2
26 {
27 
28 template <typename Adapter>
30 
31 public:
32  typedef typename Adapter::lno_t lno_t;
33  typedef typename Adapter::gno_t gno_t;
34  typedef typename Adapter::offset_t offset_t;
35  typedef typename Adapter::scalar_t scalar_t;
36 
37  perProcessorComponentMetrics(const Adapter &ia,
38  const Teuchos::Comm<int> &comm);
39 
40 #ifdef HAVE_ZOLTAN2_MPI
41  // Wrap MPI_Comm as a Teuchos::Comm, then call Teuchos::Comm constructor
42  // Uses delegating constructor feature of C++11.
43  perProcessorComponentMetrics(const Adapter &ia, const MPI_Comm mpicomm) :
45  Teuchos::MpiComm<int>(Teuchos::opaqueWrapper(mpicomm)))
46  {}
47 #endif
48 
50 
51  inline size_t getNumComponents() {return nComponent;}
52  inline size_t getMaxComponentSize() {return maxComponentSize;}
53  inline size_t getMinComponentSize() {return minComponentSize;}
54  inline double getAvgComponentSize() {return avgComponentSize;}
55 
56 private:
57  size_t nComponent; // number of components
58  size_t maxComponentSize; // size of largest component
59  size_t minComponentSize; // size of smalled component
60  double avgComponentSize; // average component size
61 
62  inline void markAndEnqueue(std::queue<gno_t> &q, bool *mark,
63  size_t &nUnmarkedVtx, size_t &cSize, gno_t vtx) {
64  // insert vtx into the queue
65  q.push(vtx);
66 
67  // mark vtx
68  nUnmarkedVtx--;
69  mark[vtx] = true;
70 
71  // increment component size
72  cSize++;
73  }
74 };
75 
77 template <typename Adapter>
79  const Adapter &ia, const Teuchos::Comm<int> &comm) :
80  nComponent(0), maxComponentSize(0), minComponentSize(0),
81  avgComponentSize(0.)
82 {
83  // build local graph model from input adapter
84  std::bitset<NUM_MODEL_FLAGS> graphFlags;
85  graphFlags.set(REMOVE_SELF_EDGES);
86  graphFlags.set(BUILD_LOCAL_GRAPH); // Local graph;
87  // all vertex numbering is 0 to nVtx-1
88 
89  Teuchos::RCP<const Teuchos::Comm<int> > tcomm = rcp(&comm, false);
90  Teuchos::RCP<const Zoltan2::Environment> env =
91  rcp(new Zoltan2::Environment(tcomm));
92 
93  typedef typename Adapter::base_adapter_t base_adapter_t;
94  Teuchos::RCP<const base_adapter_t> ria = rcp(&ia, false);
95  Zoltan2::GraphModel<base_adapter_t> graph(ria, env, tcomm, graphFlags);
96 
97  // get graph from model
98  const size_t nVtx = graph.getLocalNumVertices();
99  ArrayView<const gno_t> adj;
100  ArrayView<const offset_t> offset;
101  ArrayView<StridedData<lno_t, scalar_t> > wgts; // unused
102  graph.getEdgeList(adj, offset, wgts);
103 
104  // do a simple BFS on the graph;
105  // can replace later with KokkosKernels or other TPL
106  size_t nUnmarkedVtx = nVtx;
107  bool *mark = new bool[nUnmarkedVtx];
108  for (size_t i = 0; i < nUnmarkedVtx; i++) mark[i] = false;
109  size_t startVtx = 0;
110 
111  std::queue<gno_t> q;
112 
113  // until all vertices are marked...
114  while (nUnmarkedVtx > 0) {
115 
116  // Find the next component
117  size_t cSize = 0;
118  nComponent++;
119 
120  // Find an unmarked vertex; put it in the queue
121  while (mark[startVtx]) startVtx++;
122  markAndEnqueue(q, mark, nUnmarkedVtx, cSize, startVtx);
123 
124  while (!q.empty()) {
125  gno_t vtx = q.front();
126  q.pop();
127 
128  // Add neighbors of vtx to queue.
129  for (offset_t j = offset[vtx]; j < offset[vtx+1]; j++) {
130  if (!mark[adj[j]]) {
131  markAndEnqueue(q, mark, nUnmarkedVtx, cSize, adj[j]);
132  }
133  }
134  }
135 
136  // update stats
137  if (nComponent == 1) {
138  maxComponentSize = cSize;
139  minComponentSize = cSize;
140  }
141  else {
142  if (cSize > maxComponentSize) maxComponentSize = cSize;
143  if (cSize < minComponentSize) minComponentSize = cSize;
144  }
145  }
146 
147  // update stats
148  if (nComponent) avgComponentSize = double(nVtx) / double(nComponent);
149 
150  delete [] mark;
151 }
152 
153 
154 } // namespace Zoltan2
155 #endif
Zoltan2::BaseAdapter< userTypes_t > base_adapter_t
map_t::global_ordinal_type gno_t
Definition: mapRemotes.cpp:27
algorithm requires no self edges
size_t getEdgeList(ArrayView< const gno_t > &edgeIds, ArrayView< const offset_t > &offsets, ArrayView< input_t > &wgts) const
Sets pointers to this process&#39; edge (neighbor) global Ids, including off-process edges.
map_t::local_ordinal_type lno_t
Definition: mapRemotes.cpp:26
The user parameters, debug, timing and memory profiling output objects, and error checking methods...
size_t getLocalNumVertices() const
Returns the number vertices on this process.
GraphModel defines the interface required for graph models.
Gathering definitions used in software development.
Defines the GraphModel interface.
model represents graph within only one rank
perProcessorComponentMetrics(const Adapter &ia, const Teuchos::Comm< int > &comm)