Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Zoltan2_AlgBlockMapping.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 
10 #ifndef _ZOLTAN2_ALGBLOCKMAPPING_HPP_
11 #define _ZOLTAN2_ALGBLOCKMAPPING_HPP_
12 
13 #include <Zoltan2_Standards.hpp>
14 #include <Zoltan2_Algorithm.hpp>
16 #include <Zoltan2_Util.hpp>
17 #include <Tpetra_Map.hpp>
18 #include <set>
19 #include <cmath>
20 
24 // are contiguously numbered from 0 to nParts-1
25 // This use case is common; because it requires no explicit storage
26 // of the parts to ranks,
27 // we separate it from methods that do need extra storage.
29 
30 namespace Zoltan2 {
31 
32 template <typename Adapter, typename MachineRep>
33 class AlgBlockMapping : public Algorithm<Adapter>
34 {
35 
36 private:
37 
38  typedef typename Adapter::lno_t lno_t;
39  typedef typename Adapter::gno_t gno_t;
40  typedef typename Adapter::scalar_t scalar_t;
41  typedef typename Adapter::part_t part_t;
42  typedef typename Adapter::user_t user_t;
43  typedef typename Adapter::userCoord_t userCoord_t;
44 
45 public:
46 
53  const Teuchos::RCP <const Teuchos::Comm<int> > &comm_,
54  const Teuchos::RCP <const MachineRep> &machine_,
55  const Teuchos::RCP <const Adapter> &adapter_,
56  const Teuchos::RCP <const Zoltan2::PartitioningSolution<Adapter> > &psoln_,
57  const Teuchos::RCP <const Environment> &envConst):
58  nRanks(comm_->getSize()), myRank(comm_->getRank()),
59  nMyParts(0), myParts(Teuchos::null)
60  {
61  // Get set of parts from partitioning solution or adapter, if provided
62  // Otherwise, we'll assume set of parts == set of ranks
63  const part_t *partList;
64  if (psoln_ != Teuchos::null) {
65  partList = psoln_->getPartListView();
66  }
67  else {
68  adapter_->getPartsView(partList);
69  }
70 
71  // Compute maxPart, nParts
72 
73  part_t minPart, maxPart;
74 
75  if (partList == NULL) {
76  // Parts for IDs are the same as ranks
77  nParts = nRanks;
78  maxPart = nRanks-1;
79  minPart = 0;
80  }
81  else {
82  // Parts were provided by partitioning solution or input adapter
83 
84  // Find unique parts on this rank,
85  // as Tpetra::Map does not like duplicate GIDs within a rank
86 
87  size_t nLocal = adapter_->getLocalNumIDs();
88 
89  // Ideally, we'd use part_t as global ID in the map, but that won't
90  // work if Tpetra is compiled without global ID = int.
91  // typedef part_t use_this_gno_t;
92  // We'll use Tpetra's default instead
93  typedef Tpetra::Map<>::global_ordinal_type use_this_gno_t;
94 
95  std::set<use_this_gno_t> unique;
96  for (size_t i = 0; i < nLocal; i++)
97  unique.insert(partList[i]);
98 
99  size_t nUnique = unique.size();
100  Array<use_this_gno_t> uniquePartList(nUnique);
101  size_t k = 0;
102  for (typename std::set<use_this_gno_t>::iterator it = unique.begin();
103  it != unique.end(); it++)
104  uniquePartList[k++] = *it;
105 
106  // Use Tpetra::Map to find the max, min, total part.
107 
108  global_size_t nGlobalElts =
109  Teuchos::OrdinalTraits<Tpetra::global_size_t>::invalid();
110  Tpetra::Map<lno_t, use_this_gno_t> tmap(nGlobalElts, uniquePartList(),
111  0, comm_);
112 
113  nParts = Teuchos::as<part_t>(tmap.getGlobalNumElements());
114  minPart = tmap.getMinAllGlobalIndex();
115  maxPart = tmap.getMaxAllGlobalIndex();
116  }
117 
118  // Determine number of unique parts, as well as min and max part
119  // Can probably use a Tpetra Map.
120 
121  if ((minPart != 0) || (maxPart != nParts-1)) {
122  // Cannot use this mapping method
123  throw std::runtime_error("Cannot use mapping_algorithm = contiguous "
124  "unless parts are numbered from 0 to nParts-1");
125  }
126 
128  }
129 
131  // submethod of the default
132  // Assume that calling method has already confirmed assumptions
133  // about part numbering.
135  const Teuchos::RCP <const Teuchos::Comm<int> > comm_,
136  const part_t nparts) :
137  nRanks(comm_->getSize()),
138  nParts(nparts),
139  myRank(comm_->getRank()),
140  nMyParts(0),
141  myParts(Teuchos::null)
142  {
144  }
145 
147  {
148  nParts_Div_nRanks = nParts / nRanks;
149  nParts_Mod_nRanks = nParts % nRanks;
150  nMyParts = nParts_Div_nRanks + (myRank < nParts_Mod_nRanks);
151  }
152 
153  void map(const Teuchos::RCP<MappingSolution<Adapter> > &msoln) {
154  // Mapping is computed implicitly;
155  // nothing to do here since we implement
156  // getRankForPart and getMyPartsView.
157  }
158 
159  int getRankForPart(part_t p) {
160  if (p < 0 || p >= nParts)
161  throw std::runtime_error("Invalid part in getRankForPart");
162 
163  int tmp = p / nParts_Div_nRanks;
164  while (firstPart(tmp) > p) tmp--;
165  while (firstPart(tmp+1) < p) tmp++;
166  return tmp;
167  }
168 
169  void getMyPartsView(part_t &numParts, part_t *&parts)
170  {
171  // Will need to construct the arrays if this function is called.
172  // Will not work if this is a const method.
173  numParts = nMyParts;
174  if (nMyParts) {
175  if (myParts == Teuchos::null) {
176  myParts = arcp(new part_t[nMyParts], 0, nMyParts, true);
177  for (part_t i = 0; i < nMyParts; i++)
178  myParts[i] = firstPart(myRank) + i;
179  }
180  parts = myParts.getRawPtr();
181  }
182  else
183  parts = NULL;
184  }
185 
186 private:
187 
188  inline part_t firstPart(int rank) {
189  // For contiguous part assignments, the first part assigned to rank
190  return (rank * nParts_Div_nRanks + std::min(rank, nParts_Mod_nRanks));
191  }
192 
193  const int nRanks; // Global number of ranks
194  part_t nParts; // Global number of parts
195  part_t nParts_Div_nRanks; // (nParts/nRanks) precomputed for frequent use
196  part_t nParts_Mod_nRanks; // (nParts%nRanks) precomputed for frequent use
197 
198  const int myRank; // Local rank
199  part_t nMyParts; // Local number of parts
200  ArrayRCP<part_t> myParts; // Array of my parts; created only if
201  // getMyPartsView is called.
202 };
203 
204 
205 } // namespace Zoltan2
206 
207 #endif
PartitionMapping maps a solution or an input distribution to ranks.
void getMyPartsView(part_t &numParts, part_t *&parts)
In mapping, returns a view of parts assigned to the current rank.
map_t::global_ordinal_type gno_t
Definition: mapRemotes.cpp:27
Defines the PartitioningSolution class.
void map(const Teuchos::RCP< MappingSolution< Adapter > > &msoln)
SparseMatrixAdapter_t::part_t part_t
AlgBlockMapping(const Teuchos::RCP< const Teuchos::Comm< int > > &comm_, const Teuchos::RCP< const MachineRep > &machine_, const Teuchos::RCP< const Adapter > &adapter_, const Teuchos::RCP< const Zoltan2::PartitioningSolution< Adapter > > &psoln_, const Teuchos::RCP< const Environment > &envConst)
AlgBlockMapping(const Teuchos::RCP< const Teuchos::Comm< int > > comm_, const part_t nparts)
Constructor that allows this mapping method to be used as a.
A PartitioningSolution is a solution to a partitioning problem.
int getRankForPart(part_t p)
In mapping, returns the rank to which a part is assigned.
Algorithm defines the base class for all algorithms.
map_t::local_ordinal_type lno_t
Definition: mapRemotes.cpp:26
Gathering definitions used in software development.
Tpetra::global_size_t global_size_t
A gathering of useful namespace methods.
Zoltan2::BasicUserTypes< zscalar_t, zlno_t, zgno_t > user_t
Definition: Metric.cpp:39