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 // 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 
14 #ifndef _ZOLTAN2_ORDERINGSOLUTION_HPP_
15 #define _ZOLTAN2_ORDERINGSOLUTION_HPP_
16 
17 #include <Zoltan2_Standards.hpp>
18 #include <Zoltan2_Solution.hpp>
19 
20 namespace Zoltan2 {
21 
33 template <typename index_t>
34 class OrderingSolution : public Solution
35 {
36 public:
37 
40  OrderingSolution(index_t perm_size) : separatorColBlocks_(0)
41  {
42  HELLO;
43  perm_size_ = perm_size;
44  perm_ = ArrayRCP<index_t>(perm_size_);
45  invperm_ = ArrayRCP<index_t>(perm_size_);
46  separatorRange_ = ArrayRCP<index_t>(perm_size_+1);
47  separatorTree_ = ArrayRCP<index_t>(perm_size_);
48 
49  havePerm_ = false;
50  haveInverse_ = false;
51  haveSeparatorRange_ = false;
52  haveSeparatorTree_ = false;
53  }
54 
57  bool havePerm() const
58  {
59  return havePerm_;
60  }
61 
64  void setHavePerm(bool status)
65  {
66  havePerm_ = status;
67  }
68 
69 
72  bool haveInverse() const
73  {
74  return haveInverse_;
75  }
76 
79  void setHaveInverse(bool status)
80  {
81  haveInverse_ = status;
82  }
83 
86  void setHaveSeparator(bool status) {
87  this->setHavePerm(status);
88  this->setHaveInverse(status);
89  this->setHaveSeparatorRange(status);
90  this->setHaveSeparatorTree(status);
91  }
94  bool haveSeparatorRange() const
95  {
96  return haveSeparatorRange_;
97  }
98 
101  void setHaveSeparatorRange(bool status)
102  {
103  haveSeparatorRange_ = status;
104  }
105 
108  bool haveSeparatorTree() const
109  {
110  return haveSeparatorTree_;
111  }
112 
115  bool haveSeparators() const
116  {
117  return haveSeparatorRange() && haveSeparatorTree();
118  }
119 
122  void setHaveSeparatorTree(bool status)
123  {
124  haveSeparatorTree_ = status;
125  }
126 
129  void computePerm()
130  {
131  if (haveInverse_) {
132  for(size_t i=0; i<perm_size_; i++) {
133  perm_[invperm_[i]] = i;
134  }
135  havePerm_ = true;
136  }
137  else {
138  // TODO: throw exception
139  std::cerr << "No inverse!" << std::endl;
140  }
141  }
142 
146  {
147  if (havePerm_) {
148  for(size_t i=0; i<perm_size_; i++) {
149  invperm_[perm_[i]] = i;
150  }
151  haveInverse_ = true;
152  }
153  else {
154  // TODO: throw exception
155  std::cerr << "No perm!" << std::endl;
156  }
157  }
158 
161  inline void setNumSeparatorBlocks(index_t nblks) {separatorColBlocks_ = nblks;}
162 
164  // Accessor functions, allowing algorithms to get ptrs to solution memory.
165  // Algorithms can then load the memory.
166  // Non-RCP versions are provided for applications to use.
167 
170  inline size_t getPermutationSize() const {return perm_size_;}
171 
174  inline index_t getNumSeparatorBlocks() const {return separatorColBlocks_;}
175 
178  // inline ArrayRCP<index_t> &getGidsRCP() {return gids_;}
179 
185  inline const ArrayRCP<index_t> &getPermutationRCP(bool inverse=false) const
186  {
187  if (inverse)
188  return invperm_;
189  else
190  return perm_;
191  }
192 
195  bool getVertexSeparator (index_t &numBlocks,
196  index_t *range,
197  index_t *tree) const {
198 
199  if (this->haveSeparators()) {
200  numBlocks = this->getNumSeparatorBlocks();
201  range = this->getSeparatorRangeView();
202  tree = this->getSeparatorTreeView();
203  return true;
204  }
205 
206  return false;
207  }
208 
211  inline const ArrayRCP<index_t> &getSeparatorRangeRCP() const
212  {
213  return separatorRange_;
214  }
215 
218  inline const ArrayRCP<index_t> &getSeparatorTreeRCP() const
219  {
220  return separatorTree_;
221  }
222 
225  // inline ArrayRCP<index_t> &getGidsRCPConst() const
226  // {
227  // return const_cast<ArrayRCP<index_t>& > (gids_);
228  // }
229 
235  inline ArrayRCP<index_t> &getPermutationRCPConst(bool inverse=false) const
236  {
237  if (inverse)
238  return const_cast<ArrayRCP<index_t>& > (invperm_);
239  else
240  return const_cast<ArrayRCP<index_t>& > (perm_);
241  }
242 
245  inline ArrayRCP<index_t> &getSeparatorRangeRCPConst() const
246  {
247  return const_cast<ArrayRCP<index_t> & > (separatorRange_);
248  }
249 
252  inline ArrayRCP<index_t> &getSeparatorTreeRCPConst() const
253  {
254  return const_cast<ArrayRCP<index_t> & > (separatorTree_);
255  }
256 
263  inline index_t *getPermutationView(bool inverse = false) const
264  {
265  if (perm_size_) {
266  if (inverse)
267  return invperm_.getRawPtr();
268  else
269  return perm_.getRawPtr();
270  }
271  else
272  return NULL;
273  }
274 
277  inline index_t *getSeparatorRangeView() const
278  {
279  // Here, don't need to check perm_size_ before calling getRawPtr.
280  // separatorRange_ always has some length, since it is allocated larger
281  // than other arrays.
282  return separatorRange_.getRawPtr();
283  }
284 
287  inline index_t *getSeparatorTreeView() const
288  {
289  if (perm_size_)
290  return separatorTree_.getRawPtr();
291  else
292  return NULL;
293  }
294 
297  inline index_t &NumSeparatorBlocks()
298  {
299  return separatorColBlocks_;
300  }
301 
305  {
306  size_t n = getPermutationSize();
307 
308  if(!havePerm_) {
309  return -1;
310  }
311 
312  std::vector<int> count(getPermutationSize());
313  for (size_t i = 0; i < n; i++) {
314  count[i] = 0;
315  }
316 
317  for (size_t i = 0; i < n; i++) {
318  if ( (perm_[i] < 0) || (perm_[i] >= static_cast<index_t>(n)) )
319  return -1;
320  else
321  count[perm_[i]]++;
322  }
323 
324  // Each index should occur exactly once (count==1)
325  for (size_t i = 0; i < n; i++) {
326  if (count[i] != 1){
327  return -2;
328  }
329  }
330 
331  return 0;
332  }
333 
334 protected:
335  // Ordering solution consists of permutation vector(s).
336  // Either perm or invperm should be computed by the algorithm.
337  size_t perm_size_;
338  bool havePerm_; // has perm_ been computed yet?
339  bool haveInverse_; // has invperm_ been computed yet?
340  bool haveSeparatorRange_; // has sepRange_ been computed yet?
341  bool haveSeparatorTree_; // has sepTree_ been computed yet?
342  ArrayRCP<index_t> perm_; // zero-based local permutation
343  ArrayRCP<index_t> invperm_; // inverse of permutation above
344  ArrayRCP<index_t> separatorRange_; // range iterator for separator tree
345  ArrayRCP<index_t> separatorTree_; // separator tree
346  index_t separatorColBlocks_; // number of column blocks in separator
347 };
348 
349 template <typename lno_t>
351 {
352 public:
353  LocalOrderingSolution(lno_t perm_size) : OrderingSolution<lno_t>(perm_size) {}
354 };
355 
356 template <typename gno_t>
358 {
359 public:
361 };
362 
363 }
364 
365 #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:27
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:26
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?