Zoltan2
Loading...
Searching...
No Matches
Zoltan2_MappingProblem.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_MAPPINGPROBLEM_HPP_
51#define _ZOLTAN2_MAPPINGPROBLEM_HPP_
52
53#include <Zoltan2_Standards.hpp>
54
55#include <Zoltan2_Problem.hpp>
59
62#include <string>
63
64namespace Zoltan2{
65
67
81template<typename Adapter,
82 typename MachineRep = // Default MachineRep type
83 MachineRepresentation<typename Adapter::scalar_t,
84 typename Adapter::part_t> >
85class MappingProblem : public Problem<Adapter>
86{
87public:
88
89 typedef typename Adapter::scalar_t scalar_t;
90 typedef typename Adapter::gno_t gno_t;
91 typedef typename Adapter::lno_t lno_t;
92 typedef typename Adapter::user_t user_t;
93 typedef typename Adapter::part_t part_t;
94 typedef typename Adapter::base_adapter_t base_adapter_t;
95
98
101 virtual ~MappingProblem() {};
102
105 MappingProblem(Adapter *A_, Teuchos::ParameterList *p_,
106 const Teuchos::RCP<const Teuchos::Comm<int> > &ucomm_,
107 partsoln_t *partition_ = NULL,
108 MachineRep *machine_ = NULL) :
109 Problem<Adapter>(A_, p_, ucomm_)
110 {
111 HELLO;
112 createMappingProblem(partition_, machine_);
113 };
114
115#ifdef HAVE_ZOLTAN2_MPI
118 MappingProblem(Adapter *A_, Teuchos::ParameterList *p_,
119 MPI_Comm mpicomm_,
120 partsoln_t *partition_ = NULL,
121 MachineRep *machine_ = NULL) :
122 MappingProblem(A_, p_,
123 rcp<const Comm<int> >(
124 new Teuchos::MpiComm<int>(
125 Teuchos::opaqueWrapper(mpicomm_))),
126 partition_, machine_)
127 {}
128#endif
129
131 //
132 // \param updateInputData If true this indicates that either
133 // this is the first attempt at solution, or that we
134 // are computing a new solution and the input data has
135 // changed since the previous solution was computed.
136 // If false, this indicates that we are computing a
137 // new solution using the same input data was used for
138 // the previous solution, even though the parameters
139 // may have been changed.
140 //
141 // For the sake of performance, we ask the caller to set
142 // \c updateInputData
143 // to false if he/she is computing a new solution using the same
144 // input data, but different problem parameters, than that which was
145 // used to compute the most recent solution.
146
147 void solve(bool updateInputData=true);
148
151 static void getValidParameters(ParameterList & pl)
152 {
153 MachineRepresentation <typename Adapter::scalar_t,
154 typename Adapter::part_t>::getValidParameters(pl);
155 RCP<Teuchos::StringValidator> mapping_algorithm_Validator =
156 Teuchos::rcp( new Teuchos::StringValidator(
157 Teuchos::tuple<std::string>( "geometric", "default", "block" )));
158 pl.set("mapping_algorithm", "default", "mapping algorithm",
159 mapping_algorithm_Validator);
160
161
162 // bool parameter
163 pl.set("distributed_input_adapter", true,
164 "Whether the input adapter for mapping is distributed over processes or not",
166
167 // bool parameter
168 pl.set("divide_prime_first", false,
169 "When partitioning into-non power of two, whether to partition for "
170 "nonpowers of two at the beginning, or at the end",
172
173 //TODO: This should be positive integer validator.
174 pl.set("ranks_per_node", 1,
175 "The number of MPI ranks per node",
177 pl.set("reduce_best_mapping", true,
178 "If true, nodes will calculate different mappings with rotations, and best "
179 "one will be reduced. If not, the result will be the one with longest "
180 "dimension partitioning.",
182 }
183
185 //
186 // \return the solution to the most recent solve().
187
188 mapsoln_t *getSolution() { return soln.getRawPtr(); };
189 Teuchos::RCP<MachineRep> getMachine(){return machine; }
190private:
191 void createMappingProblem(partsoln_t *partition_, MachineRep *machine_);
192
193 Teuchos::RCP<mapsoln_t> soln;
194
195 Teuchos::RCP<partsoln_t> partition;
196 Teuchos::RCP<MachineRep> machine;
197};
198
200// createMappingProblem
201// Method with common functionality for creating a MappingProblem.
202// Individual constructors do appropriate conversions of input, etc.
203// This method does everything that all constructors must do.
204
205template <typename Adapter, typename MachineRep>
206void MappingProblem<Adapter, MachineRep>::createMappingProblem(
207 partsoln_t *partition_,
208 MachineRep *machine_)
209{
210 HELLO;
211
212 // Save pointer to user's partitioning solution. If not provided, create one.
213
214 if (partition_) {
215 // User provided a partitioning solution; use it.
216 partition = Teuchos::rcp(partition_, false);
217 }
218 else {
219 // User did not provide a partitioning solution;
220 // Use input adapter to create a "fake" solution with the input partition.
221
222 partition = rcp(new partsoln_t(this->env_, this->comm_,
223 this->inputAdapter_->getNumWeightsPerID()));
224 size_t nLocal = this->inputAdapter_->getLocalNumIDs();
225
226 const part_t *inputPartsView = NULL;
227 this->inputAdapter_->getPartsView(inputPartsView);
228 if (nLocal && inputPartsView == NULL) {
229 // User has not provided input parts in input adapter
230 int me = this->comm_->getRank();
231 ArrayRCP<part_t> inputParts = arcp(new part_t[nLocal], 0, nLocal, true);
232 for (size_t i = 0; i < nLocal; i++) inputParts[i] = me;
233 partition->setParts(inputParts);
234 }
235 else {
236 // User has provided input parts; use those.
237 ArrayRCP<part_t> inputParts = arcp(const_cast<part_t *>(inputPartsView),
238 0, nLocal, false);
239 partition->setParts(inputParts);
240 }
241 }
242
243 // Save pointer to user's machine. If not provided, create one.
244 if (machine_)
245 machine = Teuchos::rcp(machine_, false);
246 else {
247 try {
248 Teuchos::ParameterList pl = this->env_->getParameters();
249
250 machine = Teuchos::rcp(new MachineRep(*(this->comm_), pl));
251 }
253 }
254}
255
257template <typename Adapter, typename MachineRep>
259{
260 HELLO;
261
262
263 // Determine which algorithm to use based on defaults and parameters.
264 std::string algName("block");
265
266 Teuchos::ParameterList pl = this->env_->getParametersNonConst();
267 const Teuchos::ParameterEntry *pe = pl.getEntryPtr("mapping_algorithm");
268 if (pe) algName = pe->getValue<std::string>(&algName);
269
270 try {
271 if (algName == "default") {
272 throw(NotImplemented(__FILE__, __LINE__, __func__zoltan2__));
273#ifdef KDDKDD_NOT_READH
274 this->algorithm_ = rcp(new AlgDefaultMapping<Adapter,MachineRep>(
275 this->comm_, machine,
276 this->inputAdapter_,
277 partition, this->envConst_));
278 this->soln = rcp(new mapsoln_t(this->env_, this->comm_, this->algorithm_));
279 this->algorithm_->map(this->soln);
280#endif
281 }
282 else if (algName == "block") {
283 this->algorithm_ = rcp(new AlgBlockMapping<Adapter,MachineRep>(
284 this->comm_, machine,
285 this->inputAdapter_,
286 partition, this->envConst_));
287 this->soln = rcp(new mapsoln_t(this->env_, this->comm_, this->algorithm_));
288 this->algorithm_->map(this->soln);
289 }
290 else if (algName == "geometric") {
291
292 bool is_input_distributed = true;
293 const Teuchos::ParameterEntry *pe_input_adapter =
294 pl.getEntryPtr("distributed_input_adapter");
295 if (pe_input_adapter)
296 is_input_distributed = pe_input_adapter->getValue<bool>(&is_input_distributed);
297
298
299 int ranks_per_node = 1;
300 pe_input_adapter = pl.getEntryPtr("ranks_per_node");
301 if (pe_input_adapter)
302 ranks_per_node = pe_input_adapter->getValue<int>(&ranks_per_node);
303
304 bool divide_prime_first = false;
305 pe_input_adapter = pl.getEntryPtr("divide_prime_first");
306 if (pe_input_adapter)
307 divide_prime_first = pe_input_adapter->getValue<bool>(&divide_prime_first);
308
309 bool reduce_best_mapping = true;
310 pe_input_adapter = pl.getEntryPtr("reduce_best_mapping");
311 if (pe_input_adapter)
312 reduce_best_mapping = pe_input_adapter->getValue<bool>(&reduce_best_mapping);
313
314 this->algorithm_ =
315 rcp(new CoordinateTaskMapper<Adapter,part_t>(this->comm_,
316 machine,
317 this->inputAdapter_,
318 partition,
319 this->envConst_,
320 is_input_distributed,
321 ranks_per_node,
322 divide_prime_first,
323 reduce_best_mapping));
324
325 this->soln = rcp(new mapsoln_t(this->env_, this->comm_, this->algorithm_));
326
327 this->algorithm_->map(this->soln);
328 }
329 else {
330 // Add other mapping methods here
331 throw std::logic_error("specified mapping_algorithm not supported");
332 }
333 }
335}
336
337} //namespace Zoltan2
338
339#endif
340
341#ifdef KDDKDD
342Case 1
343MappingProblem(
344 InputAdapter
345 partitioningSolution
346 MachineRepresentation=NULL
347// KDD Don't know how to properly template MachineRepresentation. Proper types
348// KDD probably depend on how it is to be used. I imagine MJ needs
349// KDD pcoord_t to be scalar_t, right? But how does user know that at the
350// KDD time he calls this constructor?
351)
352{
353 // Create MachineRepresentation if not provided
354 // User would have called partitioning problem and provides a solution
355 // Mapping vertices are the parts from the partitioning solution
356 // Create MappingSolution that can return getRankForPart(part)
357}
358
359
360Case 2
361MappingProblem(
362 InputAdapter
363 MachineRepresentation=NULL
364)
365{
366 // Create MachineRepresentation if not provided
367 // Compute mapping vertices based on InputAdapter's partition
368 // Assuming input adapter's partition should be used.
369 // KDD would use with Exodus/Nemesis input files or PamGen meshes
370
371}
372
373
374Case 3
375MappingProblem(
376 InputAdapter
377 MachineRepresentation=NULL
378)
379{
380 // Create MachineRepresentation if not provided
381 // Call a partitioning algorithm to get mapping vertices that are the parts
382 // Mapping vertices are computed from this internal partitioning solution
383 // Maybe relevant models can be shared.
384 // Similar to what's in PartitioningProblem now and to what LibTopoMap does
385
386}
387
388
389Case 4
390MappingProblem(
391 InputAdapter
392 MachineRepresentation=NULL
393)
394{
395 // Create MachineRepresentation if not provided
396 // Call mapping with mapping vertices == IDs from the input adapter.
397 // Similar in spirit to previous case, but runs more slowly since current
398 // task mapping is done in serial.
399 // Mehmet has done experiments with Scotch, comparing case 3 with 4.
400 // Case 3 is faster; case 4 has higher quality.
401
402
403}
404
405
406// In general, the applyPartitioningSolution method should take an
407// optional MappingSolution.
408
409// Should MappingSolution provide a re-numbered communicator reflecting the new mapping?
410
411#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