Amesos2 - Direct Sparse Solver Interfaces  Version of the Day
Amesos2_Basker_def.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Amesos2: Templated Direct Sparse Solver Package
4 //
5 // Copyright 2011 NTESS and the Amesos2 contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
19 #ifndef AMESOS2_BASKER_DEF_HPP
20 #define AMESOS2_BASKER_DEF_HPP
21 
22 #include <Teuchos_Tuple.hpp>
23 #include <Teuchos_ParameterList.hpp>
24 #include <Teuchos_StandardParameterEntryValidators.hpp>
25 
27 #include "Amesos2_Basker_decl.hpp"
28 
29 namespace Amesos2 {
30 
31 
32 template <class Matrix, class Vector>
33 Basker<Matrix,Vector>::Basker(
34  Teuchos::RCP<const Matrix> A,
35  Teuchos::RCP<Vector> X,
36  Teuchos::RCP<const Vector> B )
37  : SolverCore<Amesos2::Basker,Matrix,Vector>(A, X, B)
38  , is_contiguous_(true)
39 // , basker()
40 {
41  //Nothing
42 }
43 
44 
45 template <class Matrix, class Vector>
46 Basker<Matrix,Vector>::~Basker( )
47 {}
48 
49 template <class Matrix, class Vector>
50 bool
52  return (this->root_ && (this->matrixA_->getComm()->getSize() == 1) && is_contiguous_);
53 }
54 
55 template<class Matrix, class Vector>
56 int
58 {
59  /* TODO: Define what it means for Basker
60  */
61 #ifdef HAVE_AMESOS2_TIMERS
62  Teuchos::TimeMonitor preOrderTimer(this->timers_.preOrderTime_);
63 #endif
64 
65  return(0);
66 }
67 
68 
69 template <class Matrix, class Vector>
70 int
72 {
73  /*No symbolic factoriztion*/
74  return(0);
75 }
76 
77 
78 template <class Matrix, class Vector>
79 int
81 {
82  using Teuchos::as;
83 
84  int info = 0;
85  if ( this->root_ ){
86  { // Do factorization
87  #ifdef HAVE_AMESOS2_TIMERS
88  Teuchos::TimeMonitor numFactTimer(this->timers_.numFactTime_);
89  #endif
90 
91  #ifdef HAVE_AMESOS2_VERBOSE_DEBUG
92  std::cout << "Basker:: Before numeric factorization" << std::endl;
93  std::cout << "nzvals_ : " << nzvals_.toString() << std::endl;
94  std::cout << "rowind_ : " << rowind_.toString() << std::endl;
95  std::cout << "colptr_ : " << colptr_.toString() << std::endl;
96  #endif
97 
98  basker_dtype * pBaskerValues = function_map::convert_scalar(host_nzvals_view_.data());
99  info = basker.factor(this->globalNumRows_, this->globalNumCols_, this->globalNumNonZeros_, host_col_ptr_view_.data(), host_rows_view_.data(), pBaskerValues);
100 
101  // This is set after numeric factorization complete as pivoting can be used;
102  // In this case, a discrepancy between symbolic and numeric nnz total can occur.
103  this->setNnzLU( as<size_t>(basker.get_NnzLU() ) ) ;
104  }
105 
106  }
107 
108  /* All processes should have the same error code */
109  Teuchos::broadcast(*(this->matrixA_->getComm()), 0, &info);
110 
111  //global_size_type info_st = as<global_size_type>(info);
112  /* TODO : Proper error messages*/
113  TEUCHOS_TEST_FOR_EXCEPTION( (info == -1) ,
114  std::runtime_error,
115  "Basker: Could not alloc space for L and U");
116  TEUCHOS_TEST_FOR_EXCEPTION( (info == -2),
117  std::runtime_error,
118  "Basker: Could not alloc needed work space");
119  TEUCHOS_TEST_FOR_EXCEPTION( (info == -3) ,
120  std::runtime_error,
121  "Basker: Could not alloc additional memory needed for L and U");
122  TEUCHOS_TEST_FOR_EXCEPTION( (info > 0) ,
123  std::runtime_error,
124  "Basker: Zero pivot found at: " << info );
125 
126  return(info);
127 }
128 
129 
130 template <class Matrix, class Vector>
131 int
133  const Teuchos::Ptr<MultiVecAdapter<Vector> > X,
134  const Teuchos::Ptr<const MultiVecAdapter<Vector> > B) const
135 {
136  int ierr = 0; // returned error code
137 
138  using Teuchos::as;
139 
140  const global_size_type ld_rhs = this->root_ ? X->getGlobalLength() : 0;
141  const size_t nrhs = X->getGlobalNumVectors();
142 
143  bool bDidAssignX;
144  { // Get values from RHS B
145 #ifdef HAVE_AMESOS2_TIMERS
146  Teuchos::TimeMonitor mvConvTimer(this->timers_.vecConvTime_);
147  Teuchos::TimeMonitor redistTimer( this->timers_.vecRedistTime_ );
148 #endif
149 
150  const bool initialize_data = true;
151  const bool do_not_initialize_data = false;
152  if ( single_proc_optimization() && nrhs == 1 ) {
153  // no msp creation
154  Util::get_1d_copy_helper_kokkos_view<MultiVecAdapter<Vector>,
155  host_solve_array_t>::do_get(initialize_data, B, bValues_, as<size_t>(ld_rhs));
156 
157  bDidAssignX = Util::get_1d_copy_helper_kokkos_view<MultiVecAdapter<Vector>,
158  host_solve_array_t>::do_get(do_not_initialize_data, X, xValues_, as<size_t>(ld_rhs));
159  }
160  else {
161  Util::get_1d_copy_helper_kokkos_view<MultiVecAdapter<Vector>,
162  host_solve_array_t>::do_get(initialize_data, B, bValues_,
163  as<size_t>(ld_rhs),
164  (is_contiguous_ == true) ? ROOTED : CONTIGUOUS_AND_ROOTED,
165  this->rowIndexBase_);
166 
167  // See Amesos2_Tacho_def.hpp for notes on why we 'get' x here.
168  bDidAssignX = Util::get_1d_copy_helper_kokkos_view<MultiVecAdapter<Vector>,
169  host_solve_array_t>::do_get(do_not_initialize_data, X, xValues_,
170  as<size_t>(ld_rhs),
171  (is_contiguous_ == true) ? ROOTED : CONTIGUOUS_AND_ROOTED,
172  this->rowIndexBase_);
173  }
174  }
175 
176  if ( this->root_ ) { // do solve
177 #ifdef HAVE_AMESOS2_TIMERS
178  Teuchos::TimeMonitor solveTimer(this->timers_.solveTime_);
179 #endif
180 
181  basker_dtype * pxBaskerValues = function_map::convert_scalar(xValues_.data());
182  basker_dtype * pbBaskerValues = function_map::convert_scalar(bValues_.data());
183  ierr = basker.solveMultiple(nrhs, pbBaskerValues, pxBaskerValues);
184  }
185 
186  /* All processes should have the same error code */
187  Teuchos::broadcast(*(this->getComm()), 0, &ierr);
188 
189  TEUCHOS_TEST_FOR_EXCEPTION( ierr > 0,
190  std::runtime_error,
191  "Encountered zero diag element at: " << ierr);
192  TEUCHOS_TEST_FOR_EXCEPTION( ierr == -1,
193  std::runtime_error,
194  "Could not alloc needed working memory for solve" );
195 
196  // if bDidAssignX, then we solved straight to the adapter's X memory space without
197  // requiring additional memory allocation, so the x data is already in place.
198  if(!bDidAssignX) {
199 #ifdef HAVE_AMESOS2_TIMERS
200  Teuchos::TimeMonitor redistTimer(this->timers_.vecRedistTime_);
201 #endif
202 
203  Util::put_1d_data_helper_kokkos_view<MultiVecAdapter<Vector>,
204  host_solve_array_t>::do_put(X, xValues_,
205  as<size_t>(ld_rhs),
206  (is_contiguous_ == true) ? ROOTED : CONTIGUOUS_AND_ROOTED);
207  }
208 
209  return(ierr);
210 }
211 
212 
213 template <class Matrix, class Vector>
214 bool
216 {
217  // The Basker can only handle square for right now
218  return( this->globalNumRows_ == this->globalNumCols_ );
219 }
220 
221 
222 template <class Matrix, class Vector>
223 void
224 Basker<Matrix,Vector>::setParameters_impl(const Teuchos::RCP<Teuchos::ParameterList> & parameterList )
225 {
226  using Teuchos::RCP;
227  using Teuchos::getIntegralValue;
228  using Teuchos::ParameterEntryValidator;
229 
230  RCP<const Teuchos::ParameterList> valid_params = getValidParameters_impl();
231 
232  if(parameterList->isParameter("IsContiguous"))
233  {
234  is_contiguous_ = parameterList->get<bool>("IsContiguous");
235  }
236 
237 }
238 
239 template <class Matrix, class Vector>
240 Teuchos::RCP<const Teuchos::ParameterList>
242 {
243  using Teuchos::ParameterList;
244 
245  static Teuchos::RCP<const Teuchos::ParameterList> valid_params;
246 
247  if( is_null(valid_params) ){
248  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
249 
250  pl->set("IsContiguous", true, "Are GIDs contiguous");
251  pl->set("alnnz", 2, "Approx number of nonzeros in L, default is 2*nnz(A)");
252  pl->set("aunnx", 2, "Approx number of nonzeros in I, default is 2*nnz(U)");
253  valid_params = pl;
254  }
255  return valid_params;
256 }
257 
258 
259 template <class Matrix, class Vector>
260 bool
262 {
263  using Teuchos::as;
264  if(current_phase == SOLVE) return (false);
265 
266  #ifdef HAVE_AMESOS2_TIMERS
267  Teuchos::TimeMonitor convTimer(this->timers_.mtxConvTime_);
268  #endif
269 
270  // Only the root image needs storage allocated
271  if( this->root_ ){
272  host_nzvals_view_ = host_value_type_array(
273  Kokkos::ViewAllocateWithoutInitializing("host_nzvals_view_"), this->globalNumNonZeros_);
274  host_rows_view_ = host_ordinal_type_array(
275  Kokkos::ViewAllocateWithoutInitializing("host_rows_view_"), this->globalNumNonZeros_);
276  host_col_ptr_view_ = host_ordinal_type_array(
277  Kokkos::ViewAllocateWithoutInitializing("host_col_ptr_view_"), this->globalNumRows_ + 1);
278  }
279 
280  local_ordinal_type nnz_ret = 0;
281  {
282  #ifdef HAVE_AMESOS2_TIMERS
283  Teuchos::TimeMonitor mtxRedistTimer( this->timers_.mtxRedistTime_ );
284  #endif
285 
287  MatrixAdapter<Matrix>,host_value_type_array,host_ordinal_type_array,host_ordinal_type_array>
288  ::do_get(this->matrixA_.ptr(),
289  host_nzvals_view_, host_rows_view_, host_col_ptr_view_, nnz_ret,
290  (is_contiguous_ == true) ? ROOTED : CONTIGUOUS_AND_ROOTED,
291  ARBITRARY,
292  this->rowIndexBase_);
293  }
294 
295  if( this->root_ ){
296  TEUCHOS_TEST_FOR_EXCEPTION( nnz_ret != as<local_ordinal_type>(this->globalNumNonZeros_),
297  std::runtime_error,
298  "Amesos2_Basker loadA_impl: Did not get the expected number of non-zero vals");
299  }
300  return true;
301 }
302 
303 
304 template<class Matrix, class Vector>
305 const char* Basker<Matrix,Vector>::name = "Basker";
306 
307 
308 } // end namespace Amesos2
309 
310 #endif // AMESOS2_Basker_DEF_HPP
A generic helper class for getting a CCS representation of a Matrix.
Definition: Amesos2_Util.hpp:614
EPhase
Used to indicate a phase in the direct solution.
Definition: Amesos2_TypeDecl.hpp:31
bool loadA_impl(EPhase current_phase)
Reads matrix data into internal structures.
Definition: Amesos2_Basker_def.hpp:261
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters_impl() const
Definition: Amesos2_Basker_def.hpp:241
Amesos2 interface to the Baker package.
Definition: Amesos2_Basker_decl.hpp:39
Amesos2 Basker declarations.
bool single_proc_optimization() const
can we optimize size_type and ordinal_type for straight pass through,
Definition: Amesos2_Basker_def.hpp:51
A Matrix adapter interface for Amesos2.
Definition: Amesos2_MatrixAdapter_decl.hpp:42
bool matrixShapeOK_impl() const
Determines whether the shape of the matrix is OK for this solver.
Definition: Amesos2_Basker_def.hpp:215
int preOrdering_impl()
Performs pre-ordering on the matrix to increase efficiency.
Definition: Amesos2_Basker_def.hpp:57
int numericFactorization_impl()
Basker specific numeric factorization.
Definition: Amesos2_Basker_def.hpp:80
A templated MultiVector class adapter for Amesos2.
Definition: Amesos2_MultiVecAdapter_decl.hpp:142
int solve_impl(const Teuchos::Ptr< MultiVecAdapter< Vector > > X, const Teuchos::Ptr< const MultiVecAdapter< Vector > > B) const
Basker specific solve.
Definition: Amesos2_Basker_def.hpp:132