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  haveInverse_ = 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:
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.
tuple tree
Definition: validXML.py:22
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.
map_t::global_ordinal_type gno_t
Definition: mapRemotes.cpp:18
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.
map_t::local_ordinal_type lno_t
Definition: mapRemotes.cpp:17
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)
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?