Zoltan2
Loading...
Searching...
No Matches
Zoltan2_OrderingProblem.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_ORDERINGPROBLEM_HPP_
51#define _ZOLTAN2_ORDERINGPROBLEM_HPP_
52
53#include <Zoltan2_Problem.hpp>
57
59#include <string>
60#ifdef HAVE_ZOLTAN2_OVIS
61#include <ovis.h>
62#endif
63
64
65
66
67
68#include <bitset>
69
70using Teuchos::rcp_dynamic_cast;
71
72namespace Zoltan2{
73
75
94template<typename Adapter>
95class OrderingProblem : public Problem<Adapter>
96{
97public:
98
99 typedef typename Adapter::scalar_t scalar_t;
100 typedef typename Adapter::gno_t gno_t;
101 typedef typename Adapter::lno_t lno_t;
102 typedef typename Adapter::user_t user_t;
103 typedef typename Adapter::base_adapter_t base_adapter_t;
104
105#ifdef HAVE_ZOLTAN2_MPI
106 typedef Teuchos::OpaqueWrapper<MPI_Comm> mpiWrapper_t;
107#endif
108
111 virtual ~OrderingProblem() {}
112
113 OrderingProblem(Adapter *A, ParameterList *p,
114 const RCP<const Teuchos::Comm<int> > &comm) :
115 Problem<Adapter>(A, p, comm)
116 {
117 HELLO;
118 createOrderingProblem();
119 }
120
121#ifdef HAVE_ZOLTAN2_MPI
124 OrderingProblem(Adapter *A, ParameterList *p, MPI_Comm mpicomm) :
125 OrderingProblem(A, p,
126 rcp<const Comm<int> >(new Teuchos::MpiComm<int>(
127 Teuchos::opaqueWrapper(mpicomm))))
128 {}
129#endif
130
133 OrderingProblem(Adapter *A, ParameterList *p) :
134 OrderingProblem(A, p, Tpetra::getDefaultComm())
135 {}
136
139 static void getValidParameters(ParameterList & pl)
140 {
141
142#ifdef INCLUDE_ZOLTAN2_EXPERIMENTAL
144#endif
145
146 RCP<Teuchos::StringValidator> order_method_Validator =
147 Teuchos::rcp( new Teuchos::StringValidator(
148 Teuchos::tuple<std::string>( "rcm", "minimum_degree", "natural",
149 "random", "sorted_degree", "scotch", "nd" )));
150 pl.set("order_method", "rcm", "order algorithm",
151 order_method_Validator);
152
153 RCP<Teuchos::StringValidator> order_method_type_Validator =
154 Teuchos::rcp( new Teuchos::StringValidator(
155 Teuchos::tuple<std::string>( "local", "global", "both" )));
156 pl.set("order_method_type", "local", "local or global or both",
157 order_method_type_Validator);
158
159 RCP<Teuchos::StringValidator> order_package_Validator = Teuchos::rcp(
160 new Teuchos::StringValidator(
161 Teuchos::tuple<std::string>( "amd", "package2", "package3" )));
162 pl.set("order_package", "amd", "package to use in ordering",
163 order_package_Validator);
164
165 RCP<Teuchos::StringValidator> rcm_root_selection_Validator = Teuchos::rcp(
166 new Teuchos::StringValidator(
167 Teuchos::tuple<std::string>( "pseudoperipheral", "first", "smallest_degree" )));
168 pl.set("root_method", "pseudoperipheral", "method for selecting RCM root",
169 rcm_root_selection_Validator);
170 }
171
173 //
174 // \param updateInputData If true this indicates that either
175 // this is the first attempt at solution, or that we
176 // are computing a new solution and the input data has
177 // changed since the previous solution was computed.
178 // If false, this indicates that we are computing a
179 // new solution using the same input data was used for
180 // the previous solution, even though the parameters
181 // may have been changed.
182 //
183 // For the sake of performance, we ask the caller to set \c updateInputData
184 // to false if he/she is computing a new solution using the same input data,
185 // but different problem parameters, than that which was used to compute
186 // the most recent solution.
187
188 void solve(bool updateInputData=true);
189
191 //
192 // \return a reference to the solution to the most recent solve().
193
195 if(localOrderingSolution_ == Teuchos::null) {
196 throw std::logic_error( "OrderingProblem was not created with local"
197 " ordering. Set parameter order_method_type to local or both."
198 " Or use getGlobalOrderingSolution()." );
199 }
200 return setupSolution(localOrderingSolution_);
201 }
202
204 //
205 // \return a reference to the solution to the most recent solve().
206
208 if(globalOrderingSolution_ == Teuchos::null) {
209 throw std::logic_error( "OrderingProblem was not created with global"
210 " ordering. Set parameter order_method_type to global or both."
211 " Or use getLocalOrderingSolution()." );
212 }
213 return setupSolution(globalOrderingSolution_);
214 }
215
216private:
217 template<typename ordering_solution_t>
218 ordering_solution_t *setupSolution(RCP<ordering_solution_t> solution) {
219 // std::cout << "havePerm= " << solution->havePerm() << " haveInverse= "
220 // << solution->haveInverse() << std::endl;
221 // Compute Perm or InvPerm, if one is missing.
222 if (!(solution->havePerm()))
223 solution->computePerm();
224 if (!(solution->haveInverse()))
225 solution->computeInverse();
226 return solution.getRawPtr();
227 }
228
229 void createOrderingProblem();
230
231 // local or global ordering is determined by which RCP is NULL
232 RCP<LocalOrderingSolution<lno_t> > localOrderingSolution_;
233 RCP<GlobalOrderingSolution<gno_t> > globalOrderingSolution_;
234
235};
236
238template <typename Adapter>
239void OrderingProblem<Adapter>::solve(bool /* updateInputData */)
240{
241 HELLO;
242
243 size_t nVtx = this->baseModel_->getLocalNumObjects();
244
245 // TODO: Assuming one MPI process now. nVtx = ngids = nlids
246 try
247 {
248 std::string method_type = this->params_->template
249 get<std::string>("order_method_type", "local");
250
251 if(method_type == "local" || method_type == "both") {
252 localOrderingSolution_ = rcp(new LocalOrderingSolution<lno_t>(nVtx));
253 }
254 if(method_type == "global" || method_type == "both") {
255 globalOrderingSolution_ = rcp(new GlobalOrderingSolution<gno_t>(nVtx));
256 }
257 }
259
260 // Determine which algorithm to use based on defaults and parameters.
261 // TODO: Use rcm if graph model is defined, otherwise use natural.
262 // Need some exception handling here, too.
263
264 std::string method = this->params_->template
265 get<std::string>("order_method", "rcm");
266
267 // TODO: Ignore case
268 try
269 {
270
271 // could be a template... seems maybe more awkward
272 // added this to avoid duplicating local/global below
273 // so many times.
274 #define ZOLTAN2_COMPUTE_ORDERING \
275 if(localOrderingSolution_ != Teuchos::null) { \
276 alg.localOrder(localOrderingSolution_); \
277 } \
278 if(globalOrderingSolution_ != Teuchos::null) { \
279 alg.globalOrder(globalOrderingSolution_); \
280 }
281
282 if (method.compare("rcm") == 0) {
283 AlgRCM<base_adapter_t> alg(this->graphModel_, this->params_, this->comm_);
285 }
286 else if (method.compare("natural") == 0) {
287 AlgNatural<base_adapter_t> alg(this->identifierModel_, this->params_,
288 this->comm_);
290 }
291 else if (method.compare("random") == 0) {
292 AlgRandom<base_adapter_t> alg(this->identifierModel_, this->params_,
293 this->comm_);
295 }
296 else if (method.compare("sorted_degree") == 0) {
297 AlgSortedDegree<base_adapter_t> alg(this->graphModel_, this->params_,
298 this->comm_);
300 }
301 else if (method.compare("minimum_degree") == 0) {
302 std::string pkg = this->params_->template get<std::string>(
303 "order_package", "amd");
304 if (pkg.compare("amd") == 0)
305 {
306 AlgAMD<base_adapter_t> alg(this->graphModel_,
307 this->params_, this->comm_);
309 }
310 }
311 else if (method.compare("scotch") == 0) { // BDD Adding scotch ordering
312 AlgPTScotch<Adapter> alg(this->envConst_, this->comm_,
313 this->baseInputAdapter_);
315 }
316
317#ifdef INCLUDE_ZOLTAN2_EXPERIMENTAL
318 else if (method.compare("nd") == 0) {
319 AlgND<Adapter> alg(this->envConst_, this->comm_, this->graphModel_,
320 this->coordinateModel_,this->baseInputAdapter_);
322 }
323#endif
324
325 }
327}
328
330//template <typename Adapter>
331//void OrderingProblem<Adapter>::redistribute()
332//{
333// HELLO;
334//}
335
338// Method with common functionality for creating a OrderingProblem.
339// Individual constructors do appropriate conversions of input, etc.
340// This method does everything that all constructors must do.
341
342template <typename Adapter>
344{
345 HELLO;
346 using Teuchos::ParameterList;
347
348 // Determine which parameters are relevant here.
349 // For now, assume parameters similar to Zoltan:
350 // MODEL = graph, hypergraph, geometric, ids
351 // ALGORITHM = rcm, random, amd
352
353 ModelType modelType = IdentifierModelType; //default, change later
354 std::string method = this->params_->template
355 get<std::string>("order_method", "rcm");
356
357 if ((method == std::string("rcm")) ||
358 (method == std::string("sorted_degree")) ||
359 (method == std::string("minimum_degree"))) {
360 modelType = GraphModelType;
361 }
362
363#ifdef INCLUDE_ZOLTAN2_EXPERIMENTAL
364 if ((method == std::string("nd")))
365 {
366 modelType = GraphModelType;
367 }
368
369#endif
370
371 // Select Model based on parameters and InputAdapter type
372
373 std::bitset<NUM_MODEL_FLAGS> graphFlags;
374 std::bitset<NUM_MODEL_FLAGS> idFlags;
375
376
377 //MMW: need to change this to allow multiple models
378 // as I did with partitioning, use modelAvail_
379
380 switch (modelType) {
381
382 case GraphModelType:
383 graphFlags.set(REMOVE_SELF_EDGES);
384 graphFlags.set(BUILD_LOCAL_GRAPH);
385 this->graphModel_ = rcp(new GraphModel<base_adapter_t>(
386 this->baseInputAdapter_, this->envConst_, this->comm_, graphFlags));
387
388 this->baseModel_ = rcp_implicit_cast<const Model<base_adapter_t> >(
389 this->graphModel_);
390
391 break;
392
393
395 this->identifierModel_ = rcp(new IdentifierModel<base_adapter_t>(
396 this->baseInputAdapter_, this->envConst_, this->comm_, idFlags));
397
398 this->baseModel_ = rcp_implicit_cast<const Model<base_adapter_t> >(
399 this->identifierModel_);
400
401 break;
402
405 std::cout << __func__zoltan2__
406 << " Model type " << modelType << " not yet supported."
407 << std::endl;
408 break;
409
410 default:
411 std::cout << __func__zoltan2__ << " Invalid model" << modelType
412 << std::endl;
413 break;
414 }
415}
416} //namespace Zoltan2
417#endif
Defines the Zoltan2_EvaluateOrdering.hpp class.
#define Z2_FORWARD_EXCEPTIONS
Forward an exception back through call stack.
#define __func__zoltan2__
Defines the GraphModel interface.
#define ZOLTAN2_COMPUTE_ORDERING
Defines the OrderingSolution class.
Defines the Problem base class.
#define HELLO
static void getValidParameters(ParameterList &pl)
Set up validators specific to this algorithm
OrderingProblem sets up ordering problems for the user.
Adapter::base_adapter_t base_adapter_t
void solve(bool updateInputData=true)
Direct the problem to create a solution.
LocalOrderingSolution< lno_t > * getLocalOrderingSolution()
Get the local ordering solution to the problem.
OrderingProblem(Adapter *A, ParameterList *p, const RCP< const Teuchos::Comm< int > > &comm)
static void getValidParameters(ParameterList &pl)
Set up validators specific to this Problem.
OrderingProblem(Adapter *A, ParameterList *p)
Constructor that uses a default communicator.
GlobalOrderingSolution< gno_t > * getGlobalOrderingSolution()
Get the global ordering solution to the problem.
Problem base class from which other classes (PartitioningProblem, ColoringProblem,...
Created by mbenlioglu on Aug 31, 2020.
ModelType
An identifier for the general type of model.
@ IdentifierModelType
@ HypergraphModelType
@ CoordinateModelType
@ REMOVE_SELF_EDGES
algorithm requires no self edges
@ BUILD_LOCAL_GRAPH
model represents graph within only one rank