Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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 
61 #include <Zoltan2_TaskMapping.hpp>
62 #include <string>
63 
64 namespace Zoltan2{
65 
67 
81 template<typename Adapter,
82  typename MachineRep = // Default MachineRep type
83  MachineRepresentation<typename Adapter::scalar_t,
84  typename Adapter::part_t> >
85 class MappingProblem : public Problem<Adapter>
86 {
87 public:
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;
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
116 
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,
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; }
190 private:
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 
205 template <typename Adapter, typename MachineRep>
206 void 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 
257 template <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
342 Case 1
343 MappingProblem(
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 
360 Case 2
361 MappingProblem(
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 
374 Case 3
375 MappingProblem(
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 
389 Case 4
390 MappingProblem(
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 HELLO
Zoltan2::BaseAdapter< userTypes_t > base_adapter_t
#define Z2_FORWARD_EXCEPTIONS
Forward an exception back through call stack.
PartitionMapping maps a solution or an input distribution to ranks.
static RCP< Teuchos::BoolParameterEntryValidator > getBoolValidator()
Exists to make setting up validators less cluttered.
Adapter::base_adapter_t base_adapter_t
map_t::global_ordinal_type gno_t
Definition: mapRemotes.cpp:18
void solve(bool updateInputData=true)
Direct the problem to create a solution.
Defines the PartitioningSolution class.
Define a simple mapping of parts to processors assuming parts.
mapsoln_t * getSolution()
Get the solution to the problem.
SparseMatrixAdapter_t::part_t part_t
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.
A PartitioningSolution is a solution to a partitioning problem.
Exception thrown when a called base-class method is not implemented.
static void getValidParameters(ParameterList &pl)
Set up validators specific to this Problem.
Problem base class from which other classes (PartitioningProblem, ColoringProblem, OrderingProblem, MatchingProblem, etc.) derive.
Defines the Problem base class.
map_t::local_ordinal_type lno_t
Definition: mapRemotes.cpp:17
static RCP< Teuchos::AnyNumberParameterEntryValidator > getAnyIntValidator()
Exists to make setting up validators less cluttered.
MachineRepresentation Class Base class for representing machine coordinates, networks, etc.
MappingSolution< Adapter > mapsoln_t
Defines the MappingSolution class.
Gathering definitions used in software development.
PartitioningSolution< Adapter > partsoln_t
MappingProblem enables mapping of a partition (either computed or input) to MPI ranks.
Teuchos::RCP< MachineRep > getMachine()
virtual ~MappingProblem()
Destructor.
#define __func__zoltan2__
Zoltan2::BasicUserTypes< zscalar_t, zlno_t, zgno_t > user_t
Definition: Metric.cpp:74