Zoltan2
Loading...
Searching...
No Matches
Zoltan2_MappingProblem.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_MAPPINGPROBLEM_HPP_
15#define _ZOLTAN2_MAPPINGPROBLEM_HPP_
16
17#include <Zoltan2_Standards.hpp>
18
19#include <Zoltan2_Problem.hpp>
23
26#include <string>
27
28namespace Zoltan2{
29
31
45template<typename Adapter,
46 typename MachineRep = // Default MachineRep type
47 MachineRepresentation<typename Adapter::scalar_t,
48 typename Adapter::part_t> >
49class MappingProblem : public Problem<Adapter>
50{
51public:
52
53 typedef typename Adapter::scalar_t scalar_t;
54 typedef typename Adapter::gno_t gno_t;
55 typedef typename Adapter::lno_t lno_t;
56 typedef typename Adapter::user_t user_t;
57 typedef typename Adapter::part_t part_t;
58 typedef typename Adapter::base_adapter_t base_adapter_t;
59
62
65 virtual ~MappingProblem() {};
66
69 MappingProblem(Adapter *A_, Teuchos::ParameterList *p_,
70 const Teuchos::RCP<const Teuchos::Comm<int> > &ucomm_,
71 partsoln_t *partition_ = NULL,
72 MachineRep *machine_ = NULL) :
73 Problem<Adapter>(A_, p_, ucomm_)
74 {
75 HELLO;
76 createMappingProblem(partition_, machine_);
77 };
78
79#ifdef HAVE_ZOLTAN2_MPI
82 MappingProblem(Adapter *A_, Teuchos::ParameterList *p_,
83 MPI_Comm mpicomm_,
84 partsoln_t *partition_ = NULL,
85 MachineRep *machine_ = NULL) :
86 MappingProblem(A_, p_,
87 rcp<const Comm<int> >(
88 new Teuchos::MpiComm<int>(
89 Teuchos::opaqueWrapper(mpicomm_))),
90 partition_, machine_)
91 {}
92#endif
93
95 //
96 // \param updateInputData If true this indicates that either
97 // this is the first attempt at solution, or that we
98 // are computing a new solution and the input data has
99 // changed since the previous solution was computed.
100 // If false, this indicates that we are computing a
101 // new solution using the same input data was used for
102 // the previous solution, even though the parameters
103 // may have been changed.
104 //
105 // For the sake of performance, we ask the caller to set
106 // \c updateInputData
107 // to false if he/she is computing a new solution using the same
108 // input data, but different problem parameters, than that which was
109 // used to compute the most recent solution.
110
111 void solve(bool updateInputData=true);
112
115 static void getValidParameters(ParameterList & pl)
116 {
117 MachineRepresentation <typename Adapter::scalar_t,
118 typename Adapter::part_t>::getValidParameters(pl);
119 RCP<Teuchos::StringValidator> mapping_algorithm_Validator =
120 Teuchos::rcp( new Teuchos::StringValidator(
121 Teuchos::tuple<std::string>( "geometric", "default", "block" )));
122 pl.set("mapping_algorithm", "default", "mapping algorithm",
123 mapping_algorithm_Validator);
124
125
126 // bool parameter
127 pl.set("distributed_input_adapter", true,
128 "Whether the input adapter for mapping is distributed over processes or not",
130
131 // bool parameter
132 pl.set("divide_prime_first", false,
133 "When partitioning into-non power of two, whether to partition for "
134 "nonpowers of two at the beginning, or at the end",
136
137 //TODO: This should be positive integer validator.
138 pl.set("ranks_per_node", 1,
139 "The number of MPI ranks per node",
141 pl.set("reduce_best_mapping", true,
142 "If true, nodes will calculate different mappings with rotations, and best "
143 "one will be reduced. If not, the result will be the one with longest "
144 "dimension partitioning.",
146 }
147
149 //
150 // \return the solution to the most recent solve().
151
152 mapsoln_t *getSolution() { return soln.getRawPtr(); };
153 Teuchos::RCP<MachineRep> getMachine(){return machine; }
154private:
155 void createMappingProblem(partsoln_t *partition_, MachineRep *machine_);
156
157 Teuchos::RCP<mapsoln_t> soln;
158
159 Teuchos::RCP<partsoln_t> partition;
160 Teuchos::RCP<MachineRep> machine;
161};
162
164// createMappingProblem
165// Method with common functionality for creating a MappingProblem.
166// Individual constructors do appropriate conversions of input, etc.
167// This method does everything that all constructors must do.
168
169template <typename Adapter, typename MachineRep>
170void MappingProblem<Adapter, MachineRep>::createMappingProblem(
171 partsoln_t *partition_,
172 MachineRep *machine_)
173{
174 HELLO;
175
176 // Save pointer to user's partitioning solution. If not provided, create one.
177
178 if (partition_) {
179 // User provided a partitioning solution; use it.
180 partition = Teuchos::rcp(partition_, false);
181 }
182 else {
183 // User did not provide a partitioning solution;
184 // Use input adapter to create a "fake" solution with the input partition.
185
186 partition = rcp(new partsoln_t(this->env_, this->comm_,
187 this->inputAdapter_->getNumWeightsPerID()));
188 size_t nLocal = this->inputAdapter_->getLocalNumIDs();
189
190 const part_t *inputPartsView = NULL;
191 this->inputAdapter_->getPartsView(inputPartsView);
192 if (nLocal && inputPartsView == NULL) {
193 // User has not provided input parts in input adapter
194 int me = this->comm_->getRank();
195 ArrayRCP<part_t> inputParts = arcp(new part_t[nLocal], 0, nLocal, true);
196 for (size_t i = 0; i < nLocal; i++) inputParts[i] = me;
197 partition->setParts(inputParts);
198 }
199 else {
200 // User has provided input parts; use those.
201 ArrayRCP<part_t> inputParts = arcp(const_cast<part_t *>(inputPartsView),
202 0, nLocal, false);
203 partition->setParts(inputParts);
204 }
205 }
206
207 // Save pointer to user's machine. If not provided, create one.
208 if (machine_)
209 machine = Teuchos::rcp(machine_, false);
210 else {
211 try {
212 Teuchos::ParameterList pl = this->env_->getParameters();
213
214 machine = Teuchos::rcp(new MachineRep(*(this->comm_), pl));
215 }
217 }
218}
219
221template <typename Adapter, typename MachineRep>
223{
224 HELLO;
225
226
227 // Determine which algorithm to use based on defaults and parameters.
228 std::string algName("block");
229
230 Teuchos::ParameterList pl = this->env_->getParametersNonConst();
231 const Teuchos::ParameterEntry *pe = pl.getEntryPtr("mapping_algorithm");
232 if (pe) algName = pe->getValue<std::string>(&algName);
233
234 try {
235 if (algName == "default") {
236 throw(NotImplemented(__FILE__, __LINE__, __func__zoltan2__));
237#ifdef KDDKDD_NOT_READH
238 this->algorithm_ = rcp(new AlgDefaultMapping<Adapter,MachineRep>(
239 this->comm_, machine,
240 this->inputAdapter_,
241 partition, this->envConst_));
242 this->soln = rcp(new mapsoln_t(this->env_, this->comm_, this->algorithm_));
243 this->algorithm_->map(this->soln);
244#endif
245 }
246 else if (algName == "block") {
247 this->algorithm_ = rcp(new AlgBlockMapping<Adapter,MachineRep>(
248 this->comm_, machine,
249 this->inputAdapter_,
250 partition, this->envConst_));
251 this->soln = rcp(new mapsoln_t(this->env_, this->comm_, this->algorithm_));
252 this->algorithm_->map(this->soln);
253 }
254 else if (algName == "geometric") {
255
256 bool is_input_distributed = true;
257 const Teuchos::ParameterEntry *pe_input_adapter =
258 pl.getEntryPtr("distributed_input_adapter");
259 if (pe_input_adapter)
260 is_input_distributed = pe_input_adapter->getValue<bool>(&is_input_distributed);
261
262
263 int ranks_per_node = 1;
264 pe_input_adapter = pl.getEntryPtr("ranks_per_node");
265 if (pe_input_adapter)
266 ranks_per_node = pe_input_adapter->getValue<int>(&ranks_per_node);
267
268 bool divide_prime_first = false;
269 pe_input_adapter = pl.getEntryPtr("divide_prime_first");
270 if (pe_input_adapter)
271 divide_prime_first = pe_input_adapter->getValue<bool>(&divide_prime_first);
272
273 bool reduce_best_mapping = true;
274 pe_input_adapter = pl.getEntryPtr("reduce_best_mapping");
275 if (pe_input_adapter)
276 reduce_best_mapping = pe_input_adapter->getValue<bool>(&reduce_best_mapping);
277
278 this->algorithm_ =
279 rcp(new CoordinateTaskMapper<Adapter,part_t>(this->comm_,
280 machine,
281 this->inputAdapter_,
282 partition,
283 this->envConst_,
284 is_input_distributed,
285 ranks_per_node,
286 divide_prime_first,
287 reduce_best_mapping));
288
289 this->soln = rcp(new mapsoln_t(this->env_, this->comm_, this->algorithm_));
290
291 this->algorithm_->map(this->soln);
292 }
293 else {
294 // Add other mapping methods here
295 throw std::logic_error("specified mapping_algorithm not supported");
296 }
297 }
299}
300
301} //namespace Zoltan2
302
303#endif
304
305#ifdef KDDKDD
306Case 1
307MappingProblem(
308 InputAdapter
309 partitioningSolution
310 MachineRepresentation=NULL
311// KDD Don't know how to properly template MachineRepresentation. Proper types
312// KDD probably depend on how it is to be used. I imagine MJ needs
313// KDD pcoord_t to be scalar_t, right? But how does user know that at the
314// KDD time he calls this constructor?
315)
316{
317 // Create MachineRepresentation if not provided
318 // User would have called partitioning problem and provides a solution
319 // Mapping vertices are the parts from the partitioning solution
320 // Create MappingSolution that can return getRankForPart(part)
321}
322
323
324Case 2
325MappingProblem(
326 InputAdapter
327 MachineRepresentation=NULL
328)
329{
330 // Create MachineRepresentation if not provided
331 // Compute mapping vertices based on InputAdapter's partition
332 // Assuming input adapter's partition should be used.
333 // KDD would use with Exodus/Nemesis input files or PamGen meshes
334
335}
336
337
338Case 3
339MappingProblem(
340 InputAdapter
341 MachineRepresentation=NULL
342)
343{
344 // Create MachineRepresentation if not provided
345 // Call a partitioning algorithm to get mapping vertices that are the parts
346 // Mapping vertices are computed from this internal partitioning solution
347 // Maybe relevant models can be shared.
348 // Similar to what's in PartitioningProblem now and to what LibTopoMap does
349
350}
351
352
353Case 4
354MappingProblem(
355 InputAdapter
356 MachineRepresentation=NULL
357)
358{
359 // Create MachineRepresentation if not provided
360 // Call mapping with mapping vertices == IDs from the input adapter.
361 // Similar in spirit to previous case, but runs more slowly since current
362 // task mapping is done in serial.
363 // Mehmet has done experiments with Scotch, comparing case 3 with 4.
364 // Case 3 is faster; case 4 has higher quality.
365
366
367}
368
369
370// In general, the applyPartitioningSolution method should take an
371// optional MappingSolution.
372
373// Should MappingSolution provide a re-numbered communicator reflecting the new mapping?
374
375#endif
Define a simple mapping of parts to processors assuming parts.
#define Z2_FORWARD_EXCEPTIONS
Forward an exception back through call stack.
#define __func__zoltan2__
Defines the MappingSolution class.
Defines the PartitioningSolution class.
Defines the Problem base class.
Gathering definitions used in software development.
#define HELLO
static RCP< Teuchos::BoolParameterEntryValidator > getBoolValidator()
Exists to make setting up validators less cluttered.
static RCP< Teuchos::AnyNumberParameterEntryValidator > getAnyIntValidator()
Exists to make setting up validators less cluttered.
MachineRepresentation Class Base class for representing machine coordinates, networks,...
MappingProblem enables mapping of a partition (either computed or input) to MPI ranks.
MappingSolution< Adapter > mapsoln_t
Adapter::base_adapter_t base_adapter_t
static void getValidParameters(ParameterList &pl)
Set up validators specific to this Problem.
mapsoln_t * getSolution()
Get the solution to the problem.
virtual ~MappingProblem()
Destructor.
PartitioningSolution< Adapter > partsoln_t
Teuchos::RCP< MachineRep > getMachine()
MappingProblem(Adapter *A_, Teuchos::ParameterList *p_, const Teuchos::RCP< const Teuchos::Comm< int > > &ucomm_, partsoln_t *partition_=NULL, MachineRep *machine_=NULL)
Constructor that takes an Teuchos communicator.
void solve(bool updateInputData=true)
Direct the problem to create a solution.
PartitionMapping maps a solution or an input distribution to ranks.
Exception thrown when a called base-class method is not implemented.
A PartitioningSolution is a solution to a partitioning problem.
Problem base class from which other classes (PartitioningProblem, ColoringProblem,...
Created by mbenlioglu on Aug 31, 2020.
SparseMatrixAdapter_t::part_t part_t