Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Zoltan2_SphynxProblem.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Sphynx
4 //
5 // Copyright 2020 NTESS and the Sphynx contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef _ZOLTAN2_SPHYNXPROBLEM_HPP_
11 #define _ZOLTAN2_SPHYNXPROBLEM_HPP_
12 
13 
15 // This file contains the implementation of SphynxProblem.
16 //
17 // SphynxProblem is a subset of PartitioningProblem in Zoltan2Core. This subset
18 // only consists of the functionality and data members needed by Sphynx.
19 //
20 // SphynxProblem acts as an interface between user and the Sphynx algorithm.
21 // User creates the SphynxProblem object on her adapter and calls solve() to
22 // get a partitioning solution.
23 //
25 
27 #include "Zoltan2_Sphynx.hpp"
29 
30 namespace Zoltan2 {
31 
32 
35  static void getSphynxValidParameters(ParameterList & pl)
36  {
37 
38  RCP<Teuchos::StringValidator> sphynx_preconditionner_type_method_Validator =
39  Teuchos::rcp( new Teuchos::StringValidator(Teuchos::tuple<std::string>( "muelu", "jacobi", "polynomial")));
40 
41  pl.set("sphynx_preconditioner_type", "polynomial", "Sphynx preconditioner type", sphynx_preconditionner_type_method_Validator);
42 
43  RCP<Teuchos::StringValidator> sphynx_initial_guess_method_Validator =
44  Teuchos::rcp( new Teuchos::StringValidator(Teuchos::tuple<std::string>( "random", "constants")));
45 
46  pl.set("sphynx_initial_guess", "random", "Sphynx initial guess", sphynx_initial_guess_method_Validator);
47 
48  RCP<Teuchos::StringValidator> sphynx_eigensolver_Validator =
49  Teuchos::rcp( new Teuchos::StringValidator(Teuchos::tuple<std::string>( "LOBPCG", "randomized", "GeneralizedDavidson", "BlockDavidson", "BlockKrylovSchur")));
50 
51  pl.set("sphynx_eigensolver", "LOBPCG", "Sphynx eigensolver", sphynx_eigensolver_Validator);
52 
53  RCP<Teuchos::StringValidator> sphynx_problem_type_method_Validator =
54  Teuchos::rcp( new Teuchos::StringValidator(Teuchos::tuple<std::string>( "combinatorial", "normalized", "generalized")));
55 
56  pl.set("sphynx_problem_type", "combinatorial", "Sphynx problem type", sphynx_problem_type_method_Validator);
57 
58  RCP<Teuchos::EnhancedNumberValidator<int>> sphynx_verbosity_validator =
59  Teuchos::rcp( new Teuchos::EnhancedNumberValidator<int>(0, 1) );
60  pl.set("sphynx_verbosity", 0, "Sphynx verbosity.", sphynx_verbosity_validator);
61 
62  pl.set("sphynx_ortho_freq", 0, "Sphynx orthogonalization frequency");
63  pl.set("sphynx_res_freq", 0, "Sphynx residual frequency");
64  pl.set("sphynx_tolerance", 1e-1, "Sphynx tolerance");
65  pl.set("sphynx_max_iterations", 1000, "Sphynx max iterations");
66  pl.set("sphynx_block_size", 0, "Sphynx block size");
67  // bool parameter
68  pl.set("sphynx_skip_preprocessing", false, "Sphynx skip preprocessing.", Environment::getBoolValidator());
69  pl.set("sphynx_use_full_ortho", true, "Sphynx use full ortho.", Environment::getBoolValidator());
70  }
71 
73  const Teuchos::ParameterList &plSome, // in: user's parameters
74  const Teuchos::ParameterList &plAll, // in: validators for all params
75  Teuchos::ParameterList &plVal) // out: validators for user's params
76  {
77  ParameterList::ConstIterator next = plSome.begin();
78 
79  while (next != plSome.end()){
80 
81  const std::string &name = next->first;
82  const ParameterEntry &entrySome = plSome.getEntry(name);
83  const ParameterEntry &entryAll = plAll.getEntry(name);
84 
85  if (entrySome.isList()){
86  plVal.sublist(name); // create & get
87  // Don't set validators for sublists; sublists are for TPL's parameters
88  }
89  else{
90  plVal.setEntry(name, entryAll);
91  }
92 
93  ++next;
94  }
95  }
96 
97  template <typename Adapter>
98  class SphynxProblem : public PartitioningProblem<Adapter>
99  {
100 
101  public:
102 
103  using part_t = typename Adapter::part_t;
104  using weight_t = typename Adapter::scalar_t;
105  using scalar_t = double; // Sphynx with scalar_t=double obtains better cutsize
106  using lno_t = typename Adapter::lno_t;
107  using gno_t = typename Adapter::gno_t;
108  using node_t = typename Adapter::node_t;
109  using mvector_t = typename Tpetra::MultiVector<scalar_t, lno_t, gno_t, node_t>;
110  typedef typename Adapter::base_adapter_t base_adapter_t; // CHeck to Remove
111 
115 
116  // Constructor where Teuchos communicator is specified
117  SphynxProblem(Adapter *A,
118  Teuchos::ParameterList *p,
119  RCP<Teuchos::ParameterList> sphynxParams,
120  const RCP<const Teuchos::Comm<int> > &comm):
121  PartitioningProblem<Adapter>(A, p, comm), sphynxParams_(sphynxParams)
122  {
123  // Validation of SphynxParameter
124  ParameterList validParams;
125  try{
126  ParameterList allParameters;
127  getSphynxValidParameters(allParameters);
128 
129  setSphynxValidatorsInList(*(sphynxParams_.get()), allParameters, validParams);
130  }
132 
133  sphynxParams_->validateParametersAndSetDefaults(validParams, 0);
134 
135  int nparts = -1;
136  const Teuchos::ParameterEntry *pe = this->params_->getEntryPtr("num_global_parts");
137  if(pe)
138  nparts = pe->getValue<int>(&nparts);
139 
140  if(nparts == -1)
141  throw std::runtime_error("\nUser did not set num_global_parts"
142  "in the parameter list!n");
143  }
144 
145 #ifdef HAVE_ZOLTAN2_MPI
146  // Constructor where MPI communicator can be specified
147  SphynxProblem(Adapter *A, ParameterList *p, RCP<Teuchos::ParameterList> sphynxParams, MPI_Comm mpicomm):
148  SphynxProblem(A, p,sphynxParams,
149  rcp<const Comm<int> >(new Teuchos::MpiComm<int>(
150  Teuchos::opaqueWrapper(mpicomm))))
151  {}
152 #endif
153 
154  // Constructor where communicator is the Teuchos default.
155  SphynxProblem(Adapter *A, ParameterList *p, RCP<Teuchos::ParameterList> sphynxParams):
156  SphynxProblem(A, p,sphynxParams, Tpetra::getDefaultComm())
157  {}
158 
159  // Destructor
161 
165 
166  void createAlgorithm() override;
167  void processAlgorithmName(const std::string& algorithm, const std::string& defString, const std::string& model,
168  Environment &env, bool& removeSelfEdges, bool& isGraphType, bool& needConsecutiveGlobalIds) override;
169  RCP<mvector_t> getSphynxEigenvectors();
170  void setUserEigenvectors(const RCP<mvector_t> &userEvects);
171 
175 
176 
178  return *(this->solution_.getRawPtr());
179  };
180 
184 
185  private:
186  Teuchos::RCP<Teuchos::ParameterList> envParams_;
187  RCP<ParameterList> sphynxParams_;
188  RCP<mvector_t> eigenVectors_;
189 
190  };
191 
195 
196  template <typename Adapter>
198  const std::string &algorithm, const std::string &defString,
199  const std::string &model, Environment &env, bool &removeSelfEdges,
200  bool &isGraphType, bool &needConsecutiveGlobalIds)
201  {
202  this->algName_ = std::string("sphynx");
203  }
204 
205  template <typename Adapter>
207  {
208  // Create the algorithm
209  if (this->algName_ == std::string("sphynx")) {
210  this->algorithm_ = Teuchos::rcp(new Zoltan2::Sphynx<Adapter>(this->envConst_,
211  this->params_,
212  this->sphynxParams_,
213  this->comm_,
214  this->inputAdapter_));
215  if( this->eigenVectors_!=Teuchos::null ){
216  Teuchos::rcp_dynamic_cast<Zoltan2::Sphynx<Adapter>>(this->algorithm_)->setUserEigenvectors(eigenVectors_);
217  }
218  }
219  else {
220  throw std::logic_error("partitioning algorithm not supported");
221  }
222  }
223 
225  // Allows the user to manually set eigenvectors for the Sphynx partitioner
226  // to use rather than solving for them with Anasazi. Mainly intended
227  // for debugging purposes.
229  template <typename Adapter>
230  void SphynxProblem<Adapter>::setUserEigenvectors(const RCP<mvector_t> &userEvects)
231  {
232  eigenVectors_ = userEvects;
233  }
234 
236  // Returns an RCP containing a deep copy of the eigenvectors used by Sphynx.
238  template <typename Adapter>
239  Teuchos::RCP<Tpetra::MultiVector<double, typename Adapter::lno_t, typename Adapter::gno_t, typename Adapter::node_t> >
241  {
242  if(this->algorithm_!=Teuchos::null){
243  return Teuchos::rcp_dynamic_cast<Zoltan2::Sphynx<Adapter>>(this->algorithm_)->getSphynxEigenvectors();
244  }
245  else{
246  return Teuchos::null;
247  }
248  }
249 } // namespace Zoltan2
250 
251 #endif
Zoltan2::BaseAdapter< userTypes_t > base_adapter_t
#define Z2_FORWARD_EXCEPTIONS
Forward an exception back through call stack.
Adapter::base_adapter_t base_adapter_t
static RCP< Teuchos::BoolParameterEntryValidator > getBoolValidator()
Exists to make setting up validators less cluttered.
SphynxProblem(Adapter *A, ParameterList *p, RCP< Teuchos::ParameterList > sphynxParams)
map_t::global_ordinal_type gno_t
Definition: mapRemotes.cpp:27
typename Zoltan2::InputTraits< ztcrsmatrix_t >::node_t node_t
Defines the PartitioningSolution class.
static void setSphynxValidatorsInList(const Teuchos::ParameterList &plSome, const Teuchos::ParameterList &plAll, Teuchos::ParameterList &plVal)
void setUserEigenvectors(const RCP< mvector_t > &userEvects)
SparseMatrixAdapter_t::part_t part_t
A PartitioningSolution is a solution to a partitioning problem.
SphynxProblem(Adapter *A, Teuchos::ParameterList *p, RCP< Teuchos::ParameterList > sphynxParams, const RCP< const Teuchos::Comm< int > > &comm)
map_t::local_ordinal_type lno_t
Definition: mapRemotes.cpp:26
RCP< PartitioningSolution< Adapter > > solution_
The user parameters, debug, timing and memory profiling output objects, and error checking methods...
static void getSphynxValidParameters(ParameterList &pl)
Set up validators specific to this algorithm.
PartitioningProblem sets up partitioning problems for the user.
typename Adapter::node_t node_t
typename Tpetra::MultiVector< scalar_t, lno_t, gno_t, node_t > mvector_t
RCP< ParameterList > params_
void processAlgorithmName(const std::string &algorithm, const std::string &defString, const std::string &model, Environment &env, bool &removeSelfEdges, bool &isGraphType, bool &needConsecutiveGlobalIds) override
Defines the PartitioningProblem class.
typename Adapter::scalar_t weight_t
RCP< mvector_t > getSphynxEigenvectors()
const PartitioningSolution< Adapter > & getSolution()