Zoltan2
Loading...
Searching...
No Matches
Zoltan2_MappingSolution.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_MAPPINGSOLUTION_HPP_
51#define _ZOLTAN2_MAPPINGSOLUTION_HPP_
52#include "Teuchos_Comm.hpp"
56#include <unordered_map>
57
58namespace Zoltan2 {
59
63template <typename Adapter>
65{
66public:
67
68#ifndef DOXYGEN_SHOULD_SKIP_THIS
69 typedef typename Adapter::part_t part_t;
70 typedef typename Adapter::scalar_t t_scalar_t;
71 typedef typename Adapter::lno_t lno_t;
72 typedef typename Adapter::gno_t gno_t;
73#endif
74
78 const RCP<const Environment> &env,
79 const RCP<const Comm<int> > &comm,
80 const RCP<Algorithm<Adapter> > &algorithm = Teuchos::null)
81 :PartitioningSolution <Adapter> (
82 env, comm, 1, algorithm),
83 nParts(0), nRanks(1), myRank(comm->getRank()), maxPart(0),
84 mapping_algorithm(algorithm) {}
85
86 virtual ~MappingSolution() {}
87
88 typedef std::unordered_map<lno_t, int> rankmap_t;
89
94 void getMyPartsView(part_t &numParts, part_t *&parts)
95 {
96 bool useAlg = true;
97
98 // Check first whether this algorithm answers getMyPartsView.
99 if (mapping_algorithm != Teuchos::null) {
100 try {
101 mapping_algorithm->getMyPartsView(numParts, parts);
102 }
103 catch (NotImplemented &e) {
104 // It is OK if the algorithm did not implement this method;
105 // we'll get the information from the solution below.
106 useAlg = false;
107 }
109 }
110
111 if (!useAlg) {
112
113 // Algorithm did not implement this method.
114
115 // Did the algorithm register a result with the solution?
116 if ((partsForRank==Teuchos::null) && (rankForPart==Teuchos::null)) {
117 numParts = 0;
118 parts = NULL;
119 throw std::runtime_error("No mapping solution available.");
120 }
121
122 if (partsForRank == Teuchos::null) {
123 // Need to create the array since we haven't created it before.
124 Teuchos::Array<part_t> tmp;
125
126 part_t cnt = 0;
127 for (typename rankmap_t::iterator it = rankForPart->begin();
128 it != rankForPart->end(); it++) {
129 if (it->second == myRank) {
130 tmp.push_back(it->first);
131 cnt++;
132 }
133 }
134 if (cnt)
135 partsForRank = arcp(&tmp[0], 0, cnt, true);
136 }
137
138 numParts = partsForRank.size();
139 if (numParts)
140 parts = partsForRank.getRawPtr();
141 else
142 parts = NULL;
143 }
144 }
145
153
154 int r = -1;
155
156 // Check first whether this algorithm answers getRankForPart.
157 // Some algorithms can compute getRankForPart implicitly, without having
158 // to store the mapping explicitly. It is more efficient for them
159 // to implement getRankForPart themselves.
160 if (mapping_algorithm != Teuchos::null) {
161 try {
162 r = mapping_algorithm->getRankForPart(part);
163 }
164 catch (NotImplemented &e) {
165 // It is OK if the algorithm did not implement this method;
166 // we'll get the information from the solution below.
167 }
169 }
170
171 if (r == -1) { // Algorithm did not implement this method
172 if (rankForPart==Teuchos::null) {
173 throw std::runtime_error("No mapping solution available.");
174 }
175
176 if (part < 0 || part > maxPart) {
177 throw std::runtime_error("Invalid part number input to getRankForPart");
178 }
179
180
181 typename rankmap_t::iterator it;
182 if ((it = rankForPart->find(part)) != rankForPart->end())
183 r = it->second;
184 else
185 throw std::runtime_error("Invalid part number input to getRankForPart");
186 }
187 return r;
188 }
189
192 // Methods for storing mapping data in the solution.
193 // Algorithms can store their data in the solution, or implement
194 // getRankForPart and getMyPartsView themselves.
195
196 void setMap_PartsForRank(ArrayRCP<int> &idx, ArrayRCP<part_t> &parts) {
197 nRanks = idx.size() - 1;
198 nParts = parts.size();
199
200 // Need data stored in unordered_map; create it
201 rankForPart = rcp(new rankmap_t(idx[nRanks]));
202
203 maxPart = 0;
204 for (int i = 0; i < nRanks; i++) {
205 for (part_t j = idx[i]; j < idx[i+1]; j++) {
206 (*rankForPart)[parts[j]] = i;
207 if (parts[j] > maxPart) maxPart = parts[j];
208 }
209 }
210
211 // Parts for this rank are already contiguous in parts arcp.
212 // Keep a view of them.
213 partsForRank = parts.persistingView(idx[myRank],idx[myRank+1]-idx[myRank]);
214 }
215
223 void setMap_RankForLocalElements(ArrayRCP<int> &ranks) {
224 this->setParts(ranks);
225 }
226
227
228 void setMap_RankForPart(ArrayRCP<part_t> &parts, ArrayRCP<int> &ranks) {
229 nParts = parts.size();
230 int maxRank = 0;
231
232 // Need data stored in unordered_map; create it
233 rankForPart = rcp(new rankmap_t(parts.size()));
234
235 for (size_t i = 0; i < nParts; i++) {
236 (*rankForPart)[parts[i]] = ranks[i];
237 if (parts[i] > maxPart) maxPart = parts[i];
238 if (ranks[i] > maxRank) maxRank = ranks[i];
239 }
240 nRanks = maxRank+1;
241 }
242
243 void setMap_RankForPart(RCP<rankmap_t> &rankmap) {
244 rankForPart = rankmap;
245 nParts = rankForPart.size();
246 int maxRank = 0;
247 typename rankmap_t::iterator it;
248 for (it = rankForPart->begin(); it != rankForPart->end(); it++) {
249 if (it->first > maxPart) maxPart = it->first;
250 if (it->second > maxRank) maxRank = it->second;
251 }
252 nRanks = maxRank+1;
253 }
254 // TODO: can add other methods for setting the map, particularly if decide
255 // TODO: to store only local procs and parts info rather than global info.
256
257private:
258
259 part_t nParts; // Global number of parts
260 int nRanks; // Global number of ranks
261 int myRank; // This ranks
262 part_t maxPart; // Maximum part number
263
264 // Ways to access the answer: it can be stored in MappingSolution or
265 // provided by the Algorithm.
266 ArrayRCP<part_t> partsForRankIdx;
267 ArrayRCP<part_t> partsForRank;
268 RCP<rankmap_t> rankForPart;
269
270 const RCP<Algorithm<Adapter> > mapping_algorithm;
271
272};
273
274} // namespace Zoltan2
275
276#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
Definition: mapRemotes.cpp:17
map_t::global_ordinal_type gno_t
Definition: mapRemotes.cpp:18
Created by mbenlioglu on Aug 31, 2020.
SparseMatrixAdapter_t::part_t part_t