Zoltan2
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 
80 template<typename Adapter,
81  typename MachineRep = // Default MachineRep type
82  MachineRepresentation<typename Adapter::scalar_t,
83  typename Adapter::part_t> >
84 class MappingProblem : public Problem<Adapter>
85 {
86 public:
87 
88  typedef typename Adapter::scalar_t scalar_t;
89  typedef typename Adapter::gno_t gno_t;
90  typedef typename Adapter::lno_t lno_t;
91  typedef typename Adapter::user_t user_t;
92  typedef typename Adapter::part_t part_t;
94 
97 
100  virtual ~MappingProblem() {};
101 
104  MappingProblem(Adapter *A_, Teuchos::ParameterList *p_,
105  const Teuchos::RCP<const Teuchos::Comm<int> > &ucomm_,
106  partsoln_t *partition_ = NULL, MachineRep *machine_ = NULL) :
107  Problem<Adapter>(A_, p_, ucomm_)
108  {
109  HELLO;
110  createMappingProblem(partition_, machine_);
111  };
112 
113 #ifdef HAVE_ZOLTAN2_MPI
114 
116  MappingProblem(Adapter *A_, Teuchos::ParameterList *p_,
117  MPI_Comm ucomm_,
118  partsoln_t *partition_ = NULL, MachineRep *machine_ = NULL) :
119  Problem<Adapter>(A_, p_, ucomm_)
120  {
121  HELLO;
122  createMappingProblem(partition_, machine_);
123  };
124 #endif
125 
127  //
128  // \param updateInputData If true this indicates that either
129  // this is the first attempt at solution, or that we
130  // are computing a new solution and the input data has
131  // changed since the previous solution was computed.
132  // If false, this indicates that we are computing a
133  // new solution using the same input data was used for
134  // the previous solution, even though the parameters
135  // may have been changed.
136  //
137  // For the sake of performance, we ask the caller to set \c updateInputData
138  // to false if he/she is computing a new solution using the same input data,
139  // but different problem parameters, than that which was used to compute
140  // the most recent solution.
141 
142  void solve(bool updateInputData=true);
143 
146  static void getValidParameters(ParameterList & pl)
147  {
148  RCP<Teuchos::StringValidator> mapping_algorithm_Validator =
149  Teuchos::rcp( new Teuchos::StringValidator(
150  Teuchos::tuple<std::string>( "geometric", "default", "block" )));
151  pl.set("mapping_algorithm", "default", "mapping algorithm",
152  mapping_algorithm_Validator);
153  }
154 
156  //
157  // \return the solution to the most recent solve().
158 
159  mapsoln_t *getSolution() { return soln.getRawPtr(); };
160 
161 private:
162  void createMappingProblem(partsoln_t *partition_, MachineRep *machine_);
163 
164  Teuchos::RCP<mapsoln_t> soln;
165 
166  Teuchos::RCP<partsoln_t> partition;
167  Teuchos::RCP<MachineRep> machine;
168 };
169 
171 // createMappingProblem
172 // Method with common functionality for creating a MappingProblem.
173 // Individual constructors do appropriate conversions of input, etc.
174 // This method does everything that all constructors must do.
175 
176 template <typename Adapter, typename MachineRep>
177 void MappingProblem<Adapter, MachineRep>::createMappingProblem(
178  partsoln_t *partition_,
179  MachineRep *machine_)
180 {
181  HELLO;
182 
183  // Save pointer to user's partitioning solution. If not provided, create one.
184 
185  if (partition_) {
186  // User provided a partitioning solution; use it.
187  partition = Teuchos::rcp(partition_, false);
188  }
189  else {
190  // User did not provide a partitioning solution;
191  // Use input adapter to create a "fake" solution with the input partition.
192 
193  partition = rcp(new partsoln_t(this->env_, this->comm_,
194  this->inputAdapter_->getNumWeightsPerID()));
195  size_t nLocal = this->inputAdapter_->getLocalNumIDs();
196 
197  const part_t *inputPartsView = NULL;
198  this->inputAdapter_->getPartsView(inputPartsView);
199  if (nLocal && inputPartsView == NULL) {
200  // User has not provided input parts in input adapter
201  int me = this->comm_->getRank();
202  ArrayRCP<part_t> inputParts = arcp(new part_t[nLocal], 0, nLocal, true);
203  for (size_t i = 0; i < nLocal; i++) inputParts[i] = me;
204  partition->setParts(inputParts);
205  }
206  else {
207  // User has provided input parts; use those.
208  ArrayRCP<part_t> inputParts = arcp(const_cast<part_t *>(inputPartsView),
209  0, nLocal, false);
210  partition->setParts(inputParts);
211  }
212  }
213 
214  // Save pointer to user's machine. If not provided, create one.
215  if (machine_)
216  machine = Teuchos::rcp(machine_, false);
217  else {
218  try {
219  machine = Teuchos::rcp(new MachineRep(*(this->comm_)));
220  }
222  }
223 }
224 
226 template <typename Adapter, typename MachineRep>
228 {
229  HELLO;
230 
231 
232  // Determine which algorithm to use based on defaults and parameters.
233  std::string algName("block");
234 
235  Teuchos::ParameterList pl = this->env_->getParametersNonConst();
236  const Teuchos::ParameterEntry *pe = pl.getEntryPtr("mapping_algorithm");
237  if (pe) algName = pe->getValue<std::string>(&algName);
238 
239  try {
240  if (algName == "default") {
241  throw(NotImplemented(__FILE__, __LINE__, __func__zoltan2__));
242 #ifdef KDDKDD_NOT_READH
243  this->algorithm_ = rcp(new AlgDefaultMapping<Adapter,MachineRep>(
244  this->comm_, machine,
245  this->inputAdapter_,
246  partition, this->envConst_));
247  this->soln = rcp(new mapsoln_t(this->comm_, this->algorithm_));
248  this->algorithm_->map(this->soln);
249 #endif
250  }
251  else if (algName == "block") {
252  this->algorithm_ = rcp(new AlgBlockMapping<Adapter,MachineRep>(
253  this->comm_, machine,
254  this->inputAdapter_,
255  partition, this->envConst_));
256  this->soln = rcp(new mapsoln_t(this->comm_, this->algorithm_));
257  this->algorithm_->map(this->soln);
258  }
259 #ifdef KDDNOTREADY_NEEDTOMAKE_CTM_ANALGORITHM
260  else if (algName == "geometric") {
261  this->algorithm_ =
262  rcp(new CoordinateTaskMapper<Adapter,part_t>(this->comm_,
263  machine,
264  this->inputAdapter_,
265  partition,
266  this->envConst_));
267  this->soln = rcp(new mapsoln_t(this->comm_, this->algorithm_));
268  this->algorithm_->map(this->soln);
269  }
270 #endif
271  else {
272  // Add other mapping methods here
273  throw std::logic_error("specified mapping_algorithm not supported");
274  }
275  }
277 }
278 
279 } //namespace Zoltan2
280 
281 #endif
282 
283 #ifdef KDDKDD
284 Case 1
285 MappingProblem(
286  InputAdapter
287  partitioningSolution
288  MachineRepresentation=NULL
289 // KDD Don't know how to properly template MachineRepresentation. Proper types
290 // KDD probably depend on how it is to be used. I imagine MJ needs
291 // KDD pcoord_t to be scalar_t, right? But how does user know that at the
292 // KDD time he calls this constructor?
293 )
294 {
295  // Create MachineRepresentation if not provided
296  // User would have called partitioning problem and provides a solution
297  // Mapping vertices are the parts from the partitioning solution
298  // Create MappingSolution that can return getRankForPart(part)
299 }
300 
301 
302 Case 2
303 MappingProblem(
304  InputAdapter
305  MachineRepresentation=NULL
306 )
307 {
308  // Create MachineRepresentation if not provided
309  // Compute mapping vertices based on InputAdapter's partition
310  // Assuming input adapter's partition should be used.
311  // KDD would use with Exodus/Nemesis input files or PamGen meshes
312 
313 }
314 
315 
316 Case 3
317 MappingProblem(
318  InputAdapter
319  MachineRepresentation=NULL
320 )
321 {
322  // Create MachineRepresentation if not provided
323  // Call a partitioning algorithm to get mapping vertices that are the parts
324  // Mapping vertices are computed from this internal partitioning solution
325  // Maybe relevant models can be shared.
326  // Similar to what's in PartitioningProblem now and to what LibTopoMap does
327 
328 }
329 
330 
331 Case 4
332 MappingProblem(
333  InputAdapter
334  MachineRepresentation=NULL
335 )
336 {
337  // Create MachineRepresentation if not provided
338  // Call mapping with mapping vertices == IDs from the input adapter.
339  // Similar in spirit to previous case, but runs more slowly since current
340  // task mapping is done in serial.
341  // Mehmet has done experiments with Scotch, comparing case 3 with 4.
342  // Case 3 is faster; case 4 has higher quality.
343 
344 
345 }
346 
347 
348 In general, the applyPartitioningSolution method should take an
349 optional MappingSolution.
350 
351 Should MappingSolution provide a re-numbered communicator reflecting the new mapping?
352 
353 #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.
Adapter::base_adapter_t base_adapter_t
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.
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.
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.
virtual ~MappingProblem()
Destructor.
#define __func__zoltan2__