Zoltan2
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"
53 #include "Zoltan2_Environment.hpp"
55 #include <unordered_map>
56 
57 namespace Zoltan2 {
58 
62 template <typename Adapter>
63 class MappingSolution : public Solution
64 {
65 public:
66 
67 #ifndef DOXYGEN_SHOULD_SKIP_THIS
68  typedef typename Adapter::part_t part_t;
69 #endif
70 
74  const RCP<const Teuchos::Comm<int> > &comm,
75  const RCP<Algorithm<Adapter> > &algorithm_ = Teuchos::null)
76  : nParts(0), nRanks(1), myRank(comm->getRank()), maxPart(0),
77  algorithm(algorithm_) {}
78 
80 
81  typedef std::unordered_map<part_t, int> rankmap_t;
82 
87  void getMyPartsView(part_t &numParts, part_t *&parts)
88  {
89  bool useAlg = true;
90 
91  // Check first whether this algorithm answers getMyPartsView.
92  if (algorithm != Teuchos::null) {
93  try {
94  algorithm->getMyPartsView(numParts, parts);
95  }
96  catch (NotImplemented &e) {
97  // It is OK if the algorithm did not implement this method;
98  // we'll get the information from the solution below.
99  useAlg = false;
100  }
102  }
103 
104  if (!useAlg) {
105 
106  // Algorithm did not implement this method.
107 
108  // Did the algorithm register a result with the solution?
109  if ((partsForRank==Teuchos::null) && (rankForPart==Teuchos::null)) {
110  numParts = 0;
111  parts = NULL;
112  throw std::runtime_error("No mapping solution available.");
113  }
114 
115  if (partsForRank == Teuchos::null) {
116  // Need to create the array since we haven't created it before.
117  Teuchos::Array<part_t> tmp;
118 
119  part_t cnt = 0;
120  for (typename rankmap_t::iterator it = rankForPart->begin();
121  it != rankForPart->end(); it++) {
122  if (it->second == myRank) {
123  tmp.push_back(it->first);
124  cnt++;
125  }
126  }
127  if (cnt)
128  partsForRank = arcp(&tmp[0], 0, cnt, true);
129  }
130 
131  numParts = partsForRank.size();
132  if (numParts)
133  parts = partsForRank.getRawPtr();
134  else
135  parts = NULL;
136  }
137  }
138 
145  int getRankForPart(part_t part) {
146 
147  int r = -1;
148 
149  // Check first whether this algorithm answers getRankForPart.
150  // Some algorithms can compute getRankForPart implicitly, without having
151  // to store the mapping explicitly. It is more efficient for them
152  // to implement getRankForPart themselves.
153  if (algorithm != Teuchos::null) {
154  try {
155  r = algorithm->getRankForPart(part);
156  }
157  catch (NotImplemented &e) {
158  // It is OK if the algorithm did not implement this method;
159  // we'll get the information from the solution below.
160  }
162  }
163 
164  if (r == -1) { // Algorithm did not implement this method
165  if (rankForPart==Teuchos::null) {
166  throw std::runtime_error("No mapping solution available.");
167  }
168 
169  if (part < 0 || part > maxPart) {
170  throw std::runtime_error("Invalid part number input to getRankForPart");
171  }
172 
173 
174  typename rankmap_t::iterator it;
175  if ((it = rankForPart->find(part)) != rankForPart->end())
176  r = it->second;
177  else
178  throw std::runtime_error("Invalid part number input to getRankForPart");
179  }
180  return r;
181  }
182 
185  // Methods for storing mapping data in the solution.
186  // Algorithms can store their data in the solution, or implement
187  // getRankForPart and getMyPartsView themselves.
188 
189  void setMap_PartsForRank(ArrayRCP<int> &idx, ArrayRCP<part_t> &parts) {
190  nRanks = idx.size() - 1;
191  nParts = parts.size();
192 
193  // Need data stored in unordered_map; create it
194  rankForPart = rcp(new rankmap_t(idx[nRanks]));
195 
196  maxPart = 0;
197  for (int i = 0; i < nRanks; i++) {
198  for (part_t j = idx[i]; j < idx[i+1]; j++) {
199  (*rankForPart)[parts[j]] = i;
200  if (parts[j] > maxPart) maxPart = parts[j];
201  }
202  }
203 
204  // Parts for this rank are already contiguous in parts arcp.
205  // Keep a view of them.
206  partsForRank = parts->persistingView(idx[myRank],idx[myRank+1]-idx[myRank]);
207  }
208 
209  void setMap_RankForPart(ArrayRCP<part_t> &parts, ArrayRCP<int> &ranks) {
210  nParts = parts.size();
211  int maxRank = 0;
212 
213  // Need data stored in unordered_map; create it
214  rankForPart = rcp(new rankmap_t(parts.size()));
215 
216  for (size_t i = 0; i < nParts; i++) {
217  (*rankForPart)[parts[i]] = ranks[i];
218  if (parts[i] > maxPart) maxPart = parts[i];
219  if (ranks[i] > maxRank) maxRank = ranks[i];
220  }
221  nRanks = maxRank+1;
222  }
223 
224  void setMap_RankForPart(RCP<rankmap_t> &rankmap) {
225  rankForPart = rankmap;
226  nParts = rankForPart.size();
227  int maxRank = 0;
228  typename rankmap_t::iterator it;
229  for (it = rankForPart->begin(); it != rankForPart->end(); it++) {
230  if (it->first > maxPart) maxPart = it->first;
231  if (it->second > maxRank) maxRank = it->second;
232  }
233  nRanks = maxRank+1;
234  }
235  // TODO: can add other methods for setting the map, particularly if decide
236  // TODO: to store only local procs and parts info rather than global info.
237 
238 private:
239 
240  part_t nParts; // Global number of parts
241  int nRanks; // Global number of ranks
242  int myRank; // This ranks
243  part_t maxPart; // Maximum part number
244 
245  // Ways to access the answer: it can be stored in MappingSolution or
246  // provided by the Algorithm.
247  ArrayRCP<part_t> partsForRankIdx;
248  ArrayRCP<part_t> partsForRank;
249  RCP<rankmap_t> rankForPart;
250 
251  const RCP<Algorithm<Adapter> > algorithm;
252 
253 };
254 
255 } // namespace Zoltan2
256 
257 #endif
void setMap_PartsForRank(ArrayRCP< int > &idx, ArrayRCP< part_t > &parts)
#define Z2_FORWARD_EXCEPTIONS
Forward an exception back through call stack.
std::unordered_map< part_t, int > rankmap_t
PartitionMapping maps a solution or an input distribution to ranks.
Just a placeholder for now.
MappingSolution(const RCP< const Teuchos::Comm< int > > &comm, const RCP< Algorithm< Adapter > > &algorithm_=Teuchos::null)
Constructor.
void setMap_RankForPart(ArrayRCP< part_t > &parts, ArrayRCP< int > &ranks)
Exception thrown when a called base-class method is not implemented.
Algorithm defines the base class for all algorithms.
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)