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
28
29namespace Amesos2 {
30
31
32template <class Matrix, class Vector>
33Basker<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
45template <class Matrix, class Vector>
46Basker<Matrix,Vector>::~Basker( )
47{}
48
49template <class Matrix, class Vector>
50bool
52 return (this->root_ && (this->matrixA_->getComm()->getSize() == 1) && is_contiguous_);
53}
54
55template<class Matrix, class Vector>
56int
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
69template <class Matrix, class Vector>
70int
72{
73 /*No symbolic factoriztion*/
74 return(0);
75}
76
77
78template <class Matrix, class Vector>
79int
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
130template <class Matrix, class Vector>
131int
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
213template <class Matrix, class Vector>
214bool
216{
217 // The Basker can only handle square for right now
218 return( this->globalNumRows_ == this->globalNumCols_ );
219}
220
221
222template <class Matrix, class Vector>
223void
224Basker<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
239template <class Matrix, class Vector>
240Teuchos::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
259template <class Matrix, class Vector>
260bool
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
304template<class Matrix, class Vector>
305const char* Basker<Matrix,Vector>::name = "Basker";
306
307
308} // end namespace Amesos2
309
310#endif // AMESOS2_Basker_DEF_HPP
Amesos2 Basker declarations.
@ ROOTED
Definition Amesos2_TypeDecl.hpp:93
@ CONTIGUOUS_AND_ROOTED
Definition Amesos2_TypeDecl.hpp:94
@ ARBITRARY
Definition Amesos2_TypeDecl.hpp:109
Amesos2 interface to the Baker package.
Definition Amesos2_Basker_decl.hpp:40
A Matrix adapter interface for Amesos2.
Definition Amesos2_MatrixAdapter_decl.hpp:42
EPhase
Used to indicate a phase in the direct solution.
Definition Amesos2_TypeDecl.hpp:31
A templated MultiVector class adapter for Amesos2.
Definition Amesos2_MultiVecAdapter_decl.hpp:142
A generic helper class for getting a CCS representation of a Matrix.
Definition Amesos2_Util.hpp:633