Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Zoltan2_MappingSolution.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_MAPPINGSOLUTION_HPP_
15 #define _ZOLTAN2_MAPPINGSOLUTION_HPP_
16 #include "Teuchos_Comm.hpp"
17 #include "Zoltan2_Environment.hpp"
20 #include <unordered_map>
21 
22 namespace Zoltan2 {
23 
27 template <typename Adapter>
28 class MappingSolution : public PartitioningSolution<Adapter>
29 {
30 public:
31 
32 #ifndef DOXYGEN_SHOULD_SKIP_THIS
33  typedef typename Adapter::part_t part_t;
34  typedef typename Adapter::scalar_t t_scalar_t;
35  typedef typename Adapter::lno_t lno_t;
36  typedef typename Adapter::gno_t gno_t;
37 #endif
38 
42  const RCP<const Environment> &env,
43  const RCP<const Comm<int> > &comm,
44  const RCP<Algorithm<Adapter> > &algorithm = Teuchos::null)
45  :PartitioningSolution <Adapter> (
46  env, comm, 1, algorithm),
47  nParts(0), nRanks(1), myRank(comm->getRank()), maxPart(0),
48  mapping_algorithm(algorithm) {}
49 
50  virtual ~MappingSolution() {}
51 
52  typedef std::unordered_map<lno_t, int> rankmap_t;
53 
58  void getMyPartsView(part_t &numParts, part_t *&parts)
59  {
60  bool useAlg = true;
61 
62  // Check first whether this algorithm answers getMyPartsView.
63  if (mapping_algorithm != Teuchos::null) {
64  try {
65  mapping_algorithm->getMyPartsView(numParts, parts);
66  }
67  catch (NotImplemented &e) {
68  // It is OK if the algorithm did not implement this method;
69  // we'll get the information from the solution below.
70  useAlg = false;
71  }
73  }
74 
75  if (!useAlg) {
76 
77  // Algorithm did not implement this method.
78 
79  // Did the algorithm register a result with the solution?
80  if ((partsForRank==Teuchos::null) && (rankForPart==Teuchos::null)) {
81  numParts = 0;
82  parts = NULL;
83  throw std::runtime_error("No mapping solution available.");
84  }
85 
86  if (partsForRank == Teuchos::null) {
87  // Need to create the array since we haven't created it before.
88  Teuchos::Array<part_t> tmp;
89 
90  part_t cnt = 0;
91  for (typename rankmap_t::iterator it = rankForPart->begin();
92  it != rankForPart->end(); it++) {
93  if (it->second == myRank) {
94  tmp.push_back(it->first);
95  cnt++;
96  }
97  }
98  if (cnt)
99  partsForRank = arcp(&tmp[0], 0, cnt, true);
100  }
101 
102  numParts = partsForRank.size();
103  if (numParts)
104  parts = partsForRank.getRawPtr();
105  else
106  parts = NULL;
107  }
108  }
109 
116  int getRankForPart(part_t part) {
117 
118  int r = -1;
119 
120  // Check first whether this algorithm answers getRankForPart.
121  // Some algorithms can compute getRankForPart implicitly, without having
122  // to store the mapping explicitly. It is more efficient for them
123  // to implement getRankForPart themselves.
124  if (mapping_algorithm != Teuchos::null) {
125  try {
126  r = mapping_algorithm->getRankForPart(part);
127  }
128  catch (NotImplemented &e) {
129  // It is OK if the algorithm did not implement this method;
130  // we'll get the information from the solution below.
131  }
133  }
134 
135  if (r == -1) { // Algorithm did not implement this method
136  if (rankForPart==Teuchos::null) {
137  throw std::runtime_error("No mapping solution available.");
138  }
139 
140  if (part < 0 || part > maxPart) {
141  throw std::runtime_error("Invalid part number input to getRankForPart");
142  }
143 
144 
145  typename rankmap_t::iterator it;
146  if ((it = rankForPart->find(part)) != rankForPart->end())
147  r = it->second;
148  else
149  throw std::runtime_error("Invalid part number input to getRankForPart");
150  }
151  return r;
152  }
153 
156  // Methods for storing mapping data in the solution.
157  // Algorithms can store their data in the solution, or implement
158  // getRankForPart and getMyPartsView themselves.
159 
160  void setMap_PartsForRank(ArrayRCP<int> &idx, ArrayRCP<part_t> &parts) {
161  nRanks = idx.size() - 1;
162  nParts = parts.size();
163 
164  // Need data stored in unordered_map; create it
165  rankForPart = rcp(new rankmap_t(idx[nRanks]));
166 
167  maxPart = 0;
168  for (int i = 0; i < nRanks; i++) {
169  for (part_t j = idx[i]; j < idx[i+1]; j++) {
170  (*rankForPart)[parts[j]] = i;
171  if (parts[j] > maxPart) maxPart = parts[j];
172  }
173  }
174 
175  // Parts for this rank are already contiguous in parts arcp.
176  // Keep a view of them.
177  partsForRank = parts.persistingView(idx[myRank],idx[myRank+1]-idx[myRank]);
178  }
179 
187  void setMap_RankForLocalElements(ArrayRCP<int> &ranks) {
188  this->setParts(ranks);
189  }
190 
191 
192  void setMap_RankForPart(ArrayRCP<part_t> &parts, ArrayRCP<int> &ranks) {
193  nParts = parts.size();
194  int maxRank = 0;
195 
196  // Need data stored in unordered_map; create it
197  rankForPart = rcp(new rankmap_t(parts.size()));
198 
199  for (size_t i = 0; i < nParts; i++) {
200  (*rankForPart)[parts[i]] = ranks[i];
201  if (parts[i] > maxPart) maxPart = parts[i];
202  if (ranks[i] > maxRank) maxRank = ranks[i];
203  }
204  nRanks = maxRank+1;
205  }
206 
207  void setMap_RankForPart(RCP<rankmap_t> &rankmap) {
208  rankForPart = rankmap;
209  nParts = rankForPart.size();
210  int maxRank = 0;
211  typename rankmap_t::iterator it;
212  for (it = rankForPart->begin(); it != rankForPart->end(); it++) {
213  if (it->first > maxPart) maxPart = it->first;
214  if (it->second > maxRank) maxRank = it->second;
215  }
216  nRanks = maxRank+1;
217  }
218  // TODO: can add other methods for setting the map, particularly if decide
219  // TODO: to store only local procs and parts info rather than global info.
220 
221 private:
222 
223  part_t nParts; // Global number of parts
224  int nRanks; // Global number of ranks
225  int myRank; // This ranks
226  part_t maxPart; // Maximum part number
227 
228  // Ways to access the answer: it can be stored in MappingSolution or
229  // provided by the Algorithm.
230  ArrayRCP<part_t> partsForRankIdx;
231  ArrayRCP<part_t> partsForRank;
232  RCP<rankmap_t> rankForPart;
233 
234  const RCP<Algorithm<Adapter> > mapping_algorithm;
235 
236 };
237 
238 } // namespace Zoltan2
239 
240 #endif
void setMap_PartsForRank(ArrayRCP< int > &idx, ArrayRCP< part_t > &parts)
#define Z2_FORWARD_EXCEPTIONS
Forward an exception back through call stack.
PartitionMapping maps a solution or an input distribution to ranks.
void setMap_RankForLocalElements(ArrayRCP< int > &ranks)
This is a mapping from local elements to ranks.
std::unordered_map< lno_t, int > rankmap_t
MappingSolution(const RCP< const Environment > &env, const RCP< const Comm< int > > &comm, const RCP< Algorithm< Adapter > > &algorithm=Teuchos::null)
Constructor.
map_t::global_ordinal_type gno_t
Definition: mapRemotes.cpp:27
Defines the PartitioningSolution class.
void setMap_RankForPart(ArrayRCP< part_t > &parts, ArrayRCP< int > &ranks)
SparseMatrixAdapter_t::part_t part_t
A PartitioningSolution is a solution to a partitioning problem.
Exception thrown when a called base-class method is not implemented.
Algorithm defines the base class for all algorithms.
map_t::local_ordinal_type lno_t
Definition: mapRemotes.cpp:26
void setParts(ArrayRCP< part_t > &partList)
The algorithm uses setParts to set the solution.
int getRankForPart(part_t part)
Get the rank containing a part. Simplifying assumption: a part is wholy assigned to a rank; it is not...
void getMyPartsView(part_t &numParts, part_t *&parts)
Get the parts belonging to this rank.
Defines the Environment class.
void setMap_RankForPart(RCP< rankmap_t > &rankmap)