Zoltan2
Loading...
Searching...
No Matches
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"
20#include <unordered_map>
21
22namespace Zoltan2 {
23
27template <typename Adapter>
29{
30public:
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
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
221private:
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
Defines the Environment class.
#define Z2_FORWARD_EXCEPTIONS
Forward an exception back through call stack.
Defines the PartitioningSolution class.
Algorithm defines the base class for all algorithms.
PartitionMapping maps a solution or an input distribution to ranks.
std::unordered_map< lno_t, int > rankmap_t
void setMap_RankForPart(ArrayRCP< part_t > &parts, ArrayRCP< int > &ranks)
int getRankForPart(part_t part)
Get the rank containing a part. Simplifying assumption: a part is wholy assigned to a rank; it is not...
MappingSolution(const RCP< const Environment > &env, const RCP< const Comm< int > > &comm, const RCP< Algorithm< Adapter > > &algorithm=Teuchos::null)
Constructor.
void setMap_RankForLocalElements(ArrayRCP< int > &ranks)
This is a mapping from local elements to ranks.
void setMap_PartsForRank(ArrayRCP< int > &idx, ArrayRCP< part_t > &parts)
void getMyPartsView(part_t &numParts, part_t *&parts)
Get the parts belonging to this rank.
void setMap_RankForPart(RCP< rankmap_t > &rankmap)
Exception thrown when a called base-class method is not implemented.
A PartitioningSolution is a solution to a partitioning problem.
void setParts(ArrayRCP< part_t > &partList)
The algorithm uses setParts to set the solution.
map_t::local_ordinal_type lno_t
map_t::global_ordinal_type gno_t
Created by mbenlioglu on Aug 31, 2020.
SparseMatrixAdapter_t::part_t part_t