Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Zoltan2_OrderingSolution.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_ORDERINGSOLUTION_HPP_
51 #define _ZOLTAN2_ORDERINGSOLUTION_HPP_
52 
53 #include <Zoltan2_Standards.hpp>
54 #include <Zoltan2_Solution.hpp>
55 
56 namespace Zoltan2 {
57 
69 template <typename index_t>
70 class OrderingSolution : public Solution
71 {
72 public:
73 
76  OrderingSolution(index_t perm_size) : separatorColBlocks_(0)
77  {
78  HELLO;
79  perm_size_ = perm_size;
80  perm_ = ArrayRCP<index_t>(perm_size_);
81  invperm_ = ArrayRCP<index_t>(perm_size_);
82  separatorRange_ = ArrayRCP<index_t>(perm_size_+1);
83  separatorTree_ = ArrayRCP<index_t>(perm_size_);
84 
85  havePerm_ = false;
86  haveInverse_ = false;
87  haveSeparatorRange_ = false;
88  haveSeparatorTree_ = false;
89  }
90 
93  bool havePerm() const
94  {
95  return havePerm_;
96  }
97 
100  void setHavePerm(bool status)
101  {
102  havePerm_ = status;
103  }
104 
105 
108  bool haveInverse() const
109  {
110  return haveInverse_;
111  }
112 
115  void setHaveInverse(bool status)
116  {
117  haveInverse_ = status;
118  }
119 
122  void setHaveSeparator(bool status) {
123  this->setHavePerm(status);
124  this->setHaveInverse(status);
125  this->setHaveSeparatorRange(status);
126  this->setHaveSeparatorTree(status);
127  }
130  bool haveSeparatorRange() const
131  {
132  return haveSeparatorRange_;
133  }
134 
137  void setHaveSeparatorRange(bool status)
138  {
139  haveSeparatorRange_ = status;
140  }
141 
144  bool haveSeparatorTree() const
145  {
146  return haveSeparatorTree_;
147  }
148 
151  bool haveSeparators() const
152  {
153  return haveSeparatorRange() && haveSeparatorTree();
154  }
155 
158  void setHaveSeparatorTree(bool status)
159  {
160  haveSeparatorTree_ = status;
161  }
162 
165  void computePerm()
166  {
167  if (haveInverse_) {
168  for(size_t i=0; i<perm_size_; i++) {
169  perm_[invperm_[i]] = i;
170  }
171  havePerm_ = true;
172  }
173  else {
174  // TODO: throw exception
175  std::cerr << "No inverse!" << std::endl;
176  }
177  }
178 
182  {
183  if (havePerm_) {
184  for(size_t i=0; i<perm_size_; i++) {
185  invperm_[perm_[i]] = i;
186  }
187  havePerm_ = true;
188  }
189  else {
190  // TODO: throw exception
191  std::cerr << "No perm!" << std::endl;
192  }
193  }
194 
197  inline void setNumSeparatorBlocks(index_t nblks) {separatorColBlocks_ = nblks;}
198 
200  // Accessor functions, allowing algorithms to get ptrs to solution memory.
201  // Algorithms can then load the memory.
202  // Non-RCP versions are provided for applications to use.
203 
206  inline size_t getPermutationSize() const {return perm_size_;}
207 
210  inline index_t getNumSeparatorBlocks() const {return separatorColBlocks_;}
211 
214  // inline ArrayRCP<index_t> &getGidsRCP() {return gids_;}
215 
221  inline const ArrayRCP<index_t> &getPermutationRCP(bool inverse=false) const
222  {
223  if (inverse)
224  return invperm_;
225  else
226  return perm_;
227  }
228 
231  bool getVertexSeparator (index_t &numBlocks,
232  index_t *range,
233  index_t *tree) const {
234 
235  if (this->haveSeparators()) {
236  numBlocks = this->getNumSeparatorBlocks();
237  range = this->getSeparatorRangeView();
238  tree = this->getSeparatorTreeView();
239  return true;
240  }
241 
242  return false;
243  }
244 
247  inline const ArrayRCP<index_t> &getSeparatorRangeRCP() const
248  {
249  return separatorRange_;
250  }
251 
254  inline const ArrayRCP<index_t> &getSeparatorTreeRCP() const
255  {
256  return separatorTree_;
257  }
258 
261  // inline ArrayRCP<index_t> &getGidsRCPConst() const
262  // {
263  // return const_cast<ArrayRCP<index_t>& > (gids_);
264  // }
265 
271  inline ArrayRCP<index_t> &getPermutationRCPConst(bool inverse=false) const
272  {
273  if (inverse)
274  return const_cast<ArrayRCP<index_t>& > (invperm_);
275  else
276  return const_cast<ArrayRCP<index_t>& > (perm_);
277  }
278 
281  inline ArrayRCP<index_t> &getSeparatorRangeRCPConst() const
282  {
283  return const_cast<ArrayRCP<index_t> & > (separatorRange_);
284  }
285 
288  inline ArrayRCP<index_t> &getSeparatorTreeRCPConst() const
289  {
290  return const_cast<ArrayRCP<index_t> & > (separatorTree_);
291  }
292 
299  inline index_t *getPermutationView(bool inverse = false) const
300  {
301  if (perm_size_) {
302  if (inverse)
303  return invperm_.getRawPtr();
304  else
305  return perm_.getRawPtr();
306  }
307  else
308  return NULL;
309  }
310 
313  inline index_t *getSeparatorRangeView() const
314  {
315  // Here, don't need to check perm_size_ before calling getRawPtr.
316  // separatorRange_ always has some length, since it is allocated larger
317  // than other arrays.
318  return separatorRange_.getRawPtr();
319  }
320 
323  inline index_t *getSeparatorTreeView() const
324  {
325  if (perm_size_)
326  return separatorTree_.getRawPtr();
327  else
328  return NULL;
329  }
330 
333  inline index_t &NumSeparatorBlocks()
334  {
335  return separatorColBlocks_;
336  }
337 
341  {
342  size_t n = getPermutationSize();
343 
344  if(!havePerm_) {
345  return -1;
346  }
347 
348  std::vector<int> count(getPermutationSize());
349  for (size_t i = 0; i < n; i++) {
350  count[i] = 0;
351  }
352 
353  for (size_t i = 0; i < n; i++) {
354  if ( (perm_[i] < 0) || (perm_[i] >= static_cast<index_t>(n)) )
355  return -1;
356  else
357  count[perm_[i]]++;
358  }
359 
360  // Each index should occur exactly once (count==1)
361  for (size_t i = 0; i < n; i++) {
362  if (count[i] != 1){
363  return -2;
364  }
365  }
366 
367  return 0;
368  }
369 
370 protected:
371  // Ordering solution consists of permutation vector(s).
372  // Either perm or invperm should be computed by the algorithm.
373  size_t perm_size_;
374  bool havePerm_; // has perm_ been computed yet?
375  bool haveInverse_; // has invperm_ been computed yet?
376  bool haveSeparatorRange_; // has sepRange_ been computed yet?
377  bool haveSeparatorTree_; // has sepTree_ been computed yet?
378  ArrayRCP<index_t> perm_; // zero-based local permutation
379  ArrayRCP<index_t> invperm_; // inverse of permutation above
380  ArrayRCP<index_t> separatorRange_; // range iterator for separator tree
381  ArrayRCP<index_t> separatorTree_; // separator tree
382  index_t separatorColBlocks_; // number of column blocks in separator
383 };
384 
385 template <typename lno_t>
387 {
388 public:
389  LocalOrderingSolution(lno_t perm_size) : OrderingSolution<lno_t>(perm_size) {}
390 };
391 
392 template <typename gno_t>
394 {
395 public:
396  GlobalOrderingSolution(gno_t perm_size) : OrderingSolution<gno_t>(perm_size) {}
397 };
398 
399 }
400 
401 #endif
#define HELLO
void setHaveSeparator(bool status)
set all separator flags.
void setNumSeparatorBlocks(index_t nblks)
Set number of separator column blocks.
Defines the Solution base class.
ArrayRCP< index_t > & getPermutationRCPConst(bool inverse=false) const
Get (local) permuted GIDs by const RCP.
ArrayRCP< index_t > & getSeparatorRangeRCPConst() const
Get separator range by const RCP.
Just a placeholder for now.
bool havePerm() const
Do we have the direct permutation?
bool haveSeparatorRange() const
Do we have the separator range?
const ArrayRCP< index_t > & getSeparatorTreeRCP() const
Get (local) separator tree by RCP.
void computePerm()
Compute direct permutation from inverse.
index_t & NumSeparatorBlocks()
Get reference to separator column block.
void setHaveSeparatorTree(bool status)
Set haveSeparatorTree (intended for ordering algorithms only)
void setHaveSeparatorRange(bool status)
Set haveSeparatorRange (intended for ordering algorithms only)
size_t getPermutationSize() const
Get (local) size of permutation.
const ArrayRCP< index_t > & getPermutationRCP(bool inverse=false) const
Get (local) permuted GIDs by RCP.
index_t getNumSeparatorBlocks() const
Get number of separator column blocks.
index_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.
const ArrayRCP< index_t > & getSeparatorRangeRCP() const
Get (local) separator range by RCP.
bool getVertexSeparator(index_t &numBlocks, index_t *range, index_t *tree) const
return vertex separator variables by reference.
bool haveSeparators() const
Do we have the separators?
OrderingSolution(index_t perm_size)
Constructor allocates memory for the solution.
index_t * getSeparatorRangeView() const
Get pointer to separator range.
void setHavePerm(bool status)
Set havePerm (intended for ordering algorithms only)
int validatePerm()
returns 0 if permutation is valid, negative if invalid.
void setHaveInverse(bool status)
Set haveInverse (intended for ordering algorithms only)
tuple tree
Begin.
Definition: xml2dox.py:166
bool haveSeparatorTree() const
Do we have the separator tree?
Gathering definitions used in software development.
index_t * getSeparatorTreeView() const
Get pointer to separator tree.
The class containing ordering solutions.
void computeInverse()
Compute inverse permutation.
ArrayRCP< index_t > & getSeparatorTreeRCPConst() const
Get separator tree by const RCP.
bool haveInverse() const
Do we have the inverse permutation?