Zoltan2
Loading...
Searching...
No Matches
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
30namespace Zoltan2 {
31
32template <typename Adapter, typename MachineRep>
33class AlgBlockMapping : public Algorithm<Adapter>
34{
35
36private:
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
45public:
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
186private:
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
Defines the PartitioningSolution class.
Gathering definitions used in software development.
A gathering of useful namespace methods.
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.
void map(const Teuchos::RCP< MappingSolution< Adapter > > &msoln)
void getMyPartsView(part_t &numParts, part_t *&parts)
In mapping, returns a view of parts assigned to the current rank.
int getRankForPart(part_t p)
In mapping, returns the rank to which a part is assigned.
Algorithm defines the base class for all algorithms.
PartitionMapping maps a solution or an input distribution to ranks.
A PartitioningSolution is a solution to a partitioning problem.
Created by mbenlioglu on Aug 31, 2020.
Tpetra::global_size_t global_size_t
SparseMatrixAdapter_t::part_t part_t