Zoltan2
Zoltan2_EvaluateOrdering.hpp
Go to the documentation of this file.
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // Zoltan2: A package of combinatorial algorithms for scientific computing
6 // Copyright 2012 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Karen Devine (kddevin@sandia.gov)
39 // Erik Boman (egboman@sandia.gov)
40 // Siva Rajamanickam (srajama@sandia.gov)
41 //
42 // ***********************************************************************
43 //
44 // @HEADER
45 
50 #ifndef ZOLTAN2_EVALUATEORDERING_HPP
51 #define ZOLTAN2_EVALUATEORDERING_HPP
52 
55 
56 namespace Zoltan2{
57 
61 template <typename Adapter>
62 class EvaluateOrdering : public EvaluateBaseClass<Adapter> {
63 
64 private:
65  typedef typename Adapter::lno_t lno_t;
66  typedef typename Adapter::gno_t gno_t;
67  typedef typename Adapter::part_t part_t;
68  typedef typename Adapter::scalar_t scalar_t;
69  typedef typename Adapter::base_adapter_t base_adapter_t;
70 
71  // To do - this is only appropriate for the local ordering
72  // Need to decide how to organize these classes
73  // Do we potentially want local + global in this class
74  // Do we want to eliminate the EvaluateLocalOrdering and EvaluateGlobalOrdering
75  // derived classes? Or perhaps make them completely independent of each other
76  lno_t bandwidth;
77  lno_t envelope;
78  lno_t separatorSize;
79 
80  void sharedConstructor(const Adapter *ia,
81  ParameterList *p,
82  const RCP<const Comm<int> > &problemComm,
83  const LocalOrderingSolution<lno_t> *localSoln,
84  const GlobalOrderingSolution<gno_t> *globalSoln);
85 public:
86 
96  const Adapter *ia,
97  ParameterList *p,
98  const LocalOrderingSolution<lno_t> *localSoln,
99  const GlobalOrderingSolution<gno_t> *globalSoln)
100  {
101  RCP<const Comm<int> > problemComm = DefaultComm<int>::getComm();
102  sharedConstructor(ia, p, problemComm, localSoln, globalSoln);
103  }
104 
115  const Adapter *ia,
116  ParameterList *p,
117  const RCP<const Comm<int> > &problemComm,
118  const LocalOrderingSolution<lno_t> *localSoln,
119  const GlobalOrderingSolution<gno_t> *globalSoln)
120  {
121  sharedConstructor(ia, p, problemComm, localSoln, globalSoln);
122  }
123 
124 #ifdef HAVE_ZOLTAN2_MPI
125 
135  const Adapter *ia,
136  ParameterList *p,
137  MPI_Comm comm,
138  const LocalOrderingSolution<lno_t> *localSoln,
139  const GlobalOrderingSolution<gno_t> *globalSoln)
140  {
141  RCP<Teuchos::OpaqueWrapper<MPI_Comm> > wrapper =
142  Teuchos::opaqueWrapper(comm);
143  RCP<const Comm<int> > problemComm =
144  rcp<const Comm<int> >(new Teuchos::MpiComm<int>(wrapper));
145  sharedConstructor(ia, p, problemComm, localSoln, globalSoln);
146  }
147 #endif
148 
149  lno_t getBandwidth() const { return bandwidth; }
150  lno_t getEnvelope() const { return envelope; }
151  lno_t getSeparatorSize() const { return separatorSize; }
152 
156  virtual void printMetrics(std::ostream &os) const {
157 
158  // To Do - complete this formatting
159  os << "Ordering Metrics" << std::endl;
160  os << std::setw(20) << " " << std::setw(11) << "ordered" << std::endl;
161  os << std::setw(20) << "envelope" << std::setw(11) << std::setprecision(4)
162  << envelope << std::endl;
163  os << std::setw(20) << "bandwidth" << std::setw(11) << std::setprecision(4)
164  << bandwidth << std::endl;
165  }
166 
168  const RCP<const Environment> &env,
169  const RCP<const Comm<int> > &comm,
170  const Adapter *ia,
172  {
173  env->debug(DETAILED_STATUS, "Entering orderingMetrics"); // begin
174 
175  typedef StridedData<lno_t, scalar_t> input_t;
176 
177  // get graph
178  std::bitset<NUM_MODEL_FLAGS> modelFlags;
179  RCP<GraphModel<base_adapter_t> > graph;
180  const RCP<const base_adapter_t> bia =
181  rcp(dynamic_cast<const base_adapter_t *>(ia), false);
182  graph = rcp(new GraphModel<base_adapter_t>(bia,env,comm,modelFlags));
183  ArrayView<const gno_t> Ids;
184  ArrayView<input_t> vwgts;
185  ArrayView<const gno_t> edgeIds;
186  ArrayView<const lno_t> offsets;
187  ArrayView<input_t> wgts;
188  ArrayView<input_t> vtx;
189  graph->getEdgeList(edgeIds, offsets, wgts);
190  lno_t numVertex = graph->getVertexList(Ids, vwgts);
191 
192  lno_t * perm = localSoln->getPermutationView();
193 
194  // print as matrix - this was debugging code which can be deleted later
195  #define MDM
196  #ifdef MDM
197  for( int checkRank = 0; checkRank < comm->getSize(); ++checkRank ) {
198  comm->barrier();
199  if( checkRank == comm->getRank() ) {
200  std::cout << "-----------------------------------------" << std::endl;
201  std::cout << "Inspect rank: " << checkRank << std::endl;
202  std::cout << std::endl;
203  if(numVertex < 30) { // don't spam if it's too many...
204  Array<lno_t> oldMatrix(numVertex*numVertex);
205  Array<lno_t> newMatrix(numVertex*numVertex);
206 
207  // print the solution permutation
208  std::cout << std::endl << "perm: ";
209  for(lno_t n = 0; n < numVertex; ++n) {
210  std::cout << " " << perm[n] << " ";
211  }
212 
213  lno_t * iperm = localSoln->getPermutationView(true);
214  std::cout << std::endl << "iperm: ";
215  for(lno_t n = 0; n < numVertex; ++n) {
216  std::cout << " " << iperm[n] << " ";
217  }
218  std::cout << std::endl;
219  // write 1's to old matrix (original form) and new matrix (using solution)
220  for (lno_t y = 0; y < numVertex; y++) {
221  for (lno_t n = offsets[y]; n < offsets[y+1]; ++n) {
222  lno_t x = static_cast<lno_t>(edgeIds[n]); // to resolve
223  if (x < numVertex && y < numVertex) { // to develop - for MPI this may not be local
224  oldMatrix[x + y*numVertex] = 1;
225  newMatrix[perm[x] + perm[y]*numVertex] = 1;
226  }
227  }
228  }
229 
230  // print oldMatrix
231  std::cout << std::endl << "original graph in matrix form:" << std::endl;
232  for(lno_t y = 0; y < numVertex; ++y) {
233  for(lno_t x = 0; x < numVertex; ++x) {
234  std::cout << " " << oldMatrix[x + y*numVertex];
235  }
236  std::cout << std::endl;
237  }
238 
239  // print newMatrix
240  std::cout << std::endl << "reordered graph in matrix form:" << std::endl;
241  for(lno_t y = 0; y < numVertex; ++y) {
242  for(lno_t x = 0; x < numVertex; ++x) {
243  std::cout << " " << newMatrix[x + y*numVertex];
244  }
245  std::cout << std::endl;
246  }
247  std::cout << std::endl;
248  }
249  }
250 
251  comm->barrier();
252  }
253  #endif // Ends temporary logging which can be deleted later
254 
255  // calculate bandwidth and envelope for unsolved and solved case
256  lno_t bw_right = 0;
257  lno_t bw_left = 0;
258  envelope = 0;
259 
260  for (lno_t j = 0; j < numVertex; j++) {
261  lno_t y = Ids[j];
262  for (auto n = offsets[j]; n < offsets[j+1]; ++n) {
263  lno_t x = static_cast<lno_t>(edgeIds[n]); // to resolve
264  if(x < numVertex) {
265  lno_t x2 = perm[x];
266  lno_t y2 = perm[y];
267 
268  // solved bandwidth calculation
269  lno_t delta_right = y2 - x2;
270  if (delta_right > bw_right) {
271  bw_right = delta_right;
272  }
273  lno_t delta_left = y2 - x2;
274  if (delta_left > bw_left) {
275  bw_left = delta_left;
276  }
277 
278  // solved envelope calculation
279  if(delta_right > 0) {
280  envelope += delta_right;
281  }
282  if(delta_left > 0) {
283  envelope += delta_left;
284  }
285  envelope += 1; // need to check this - do we count center?
286  }
287  }
288  }
289 
290  bandwidth = (bw_left + bw_right + 1);
291 
292  // TO DO - No implementation yet for this metric
293  separatorSize = 0;
294 
295  env->debug(DETAILED_STATUS, "Exiting orderingMetrics"); // end
296  }
297 };
298 
299 // sharedConstructor
300 template <typename Adapter>
302  const Adapter *ia,
303  ParameterList *p,
304  const RCP<const Comm<int> > &comm,
305  const LocalOrderingSolution<lno_t> *localSoln,
306  const GlobalOrderingSolution<gno_t> *globalSoln)
307 {
308  RCP<const Comm<int> > problemComm = (comm == Teuchos::null) ?
309  DefaultComm<int>::getComm() : comm;
310 
311  RCP<Environment> env;
312  try{
313  env = rcp(new Environment(*p, problemComm));
314  }
316 
317  env->debug(DETAILED_STATUS, std::string("Entering EvaluateOrdering"));
318  env->timerStart(MACRO_TIMERS, "Computing ordering metrics");
319 
320  try{
321  // May want to move these into the specific derived classes
322  // But it depends on whether we eventually may have both types and perhaps
323  // want to combine the metrics
324  if(localSoln) {
325  localOrderingMetrics(env, problemComm, ia, localSoln);
326  }
327 
328  if(globalSoln) {
329  throw std::logic_error("EvaluateOrdering not set up for global ordering.");
330  }
331  }
333  env->timerStop(MACRO_TIMERS, "Computing ordering metrics");
334 
335  env->debug(DETAILED_STATUS, std::string("Exiting EvaluateOrdering"));
336 }
337 
338 template <typename Adapter>
339 class EvaluateLocalOrdering : public EvaluateOrdering<Adapter> {
340 private:
341  typedef typename Adapter::lno_t lno_t;
342 
343 public:
352  const Adapter *ia,
353  ParameterList *p,
354  const LocalOrderingSolution<lno_t> *localSoln) :
355  EvaluateOrdering<Adapter>(ia, p, localSoln, nullptr) {}
356 
366  const Adapter *ia,
367  ParameterList *p,
368  const RCP<const Comm<int> > &problemComm,
369  const LocalOrderingSolution<lno_t> *localSoln) :
370  EvaluateOrdering<Adapter>(ia, p, problemComm, localSoln, nullptr) {}
371 
372 #ifdef HAVE_ZOLTAN2_MPI
373 
383  const Adapter *ia,
384  ParameterList *p,
385  MPI_Comm comm,
386  const LocalOrderingSolution<lno_t> *localSoln) :
387  EvaluateOrdering<Adapter>(ia, p, comm, localSoln, nullptr) {}
388 #endif
389 };
390 
391 template <typename Adapter>
392 class EvaluateGlobalOrdering : public EvaluateOrdering<Adapter> {
393 private:
394  typedef typename Adapter::gno_t gno_t;
395 
396 public:
405  const Adapter *ia,
406  ParameterList *p,
407  const GlobalOrderingSolution<gno_t> *globalSoln) :
408  EvaluateOrdering<Adapter>(ia, p, nullptr, globalSoln) {}
409 
419  const Adapter *ia,
420  ParameterList *p,
421  const RCP<const Comm<int> > &problemComm,
422  const GlobalOrderingSolution<gno_t> *globalSoln) :
423  EvaluateOrdering<Adapter>(ia, p, problemComm, nullptr, globalSoln) {}
424 
425 #ifdef HAVE_ZOLTAN2_MPI
426 
436  const Adapter *ia,
437  ParameterList *p,
438  MPI_Comm comm,
439  const GlobalOrderingSolution<gno_t> *globalSoln) :
440  EvaluateOrdering<Adapter>(ia, p, comm, nullptr, globalSoln) {}
441 #endif
442 };
443 
444 } // namespace Zoltan2
445 
446 #endif
Zoltan2::BaseAdapter< userTypes_t > base_adapter_t
Time an algorithm (or other entity) as a whole.
EvaluateGlobalOrdering(const Adapter *ia, ParameterList *p, const RCP< const Comm< int > > &problemComm, const GlobalOrderingSolution< gno_t > *globalSoln)
Constructor where Teuchos communicator is specified.
#define Z2_FORWARD_EXCEPTIONS
Forward an exception back through call stack.
EvaluateOrdering(const Adapter *ia, ParameterList *p, const LocalOrderingSolution< lno_t > *localSoln, const GlobalOrderingSolution< gno_t > *globalSoln)
Constructor where communicator is Teuchos default.
EvaluateOrdering(const Adapter *ia, ParameterList *p, const RCP< const Comm< int > > &problemComm, const LocalOrderingSolution< lno_t > *localSoln, const GlobalOrderingSolution< gno_t > *globalSoln)
Constructor where Teuchos communicator is specified.
Defines the OrderingSolution class.
A class that computes and returns quality metrics. base class for the local and global ordering vers...
sub-steps, each method&#39;s entry and exit
EvaluateLocalOrdering(const Adapter *ia, ParameterList *p, const LocalOrderingSolution< lno_t > *localSoln)
Constructor where communicator is Teuchos default.
SparseMatrixAdapter_t::part_t part_t
The StridedData class manages lists of weights or coordinates.
void localOrderingMetrics(const RCP< const Environment > &env, const RCP< const Comm< int > > &comm, const Adapter *ia, const LocalOrderingSolution< typename Adapter::lno_t > *localSoln)
The user parameters, debug, timing and memory profiling output objects, and error checking methods...
Base class for the EvaluatePartition and EvaluateOrdering classes.
GraphModel defines the interface required for graph models.
virtual void printMetrics(std::ostream &os) const
Print all metrics of type metricType based on the metric object type Note that parent class currently...
lno_t * getPermutationView(bool inverse=false) const
Get pointer to permutation. If inverse = true, return inverse permutation. By default, perm[i] is where new index i can be found in the old ordering. When inverse==true, perm[i] is where old index i can be found in the new ordering.
EvaluateGlobalOrdering(const Adapter *ia, ParameterList *p, const GlobalOrderingSolution< gno_t > *globalSoln)
Constructor where communicator is Teuchos default.
EvaluateLocalOrdering(const Adapter *ia, ParameterList *p, const RCP< const Comm< int > > &problemComm, const LocalOrderingSolution< lno_t > *localSoln)
Constructor where Teuchos communicator is specified.