Amesos2 - Direct Sparse Solver Interfaces Version of the Day
Amesos2_SolverCore_def.hpp
Go to the documentation of this file.
1// @HEADER
2//
3// ***********************************************************************
4//
5// Amesos2: Templated Direct Sparse Solver Package
6// Copyright 2011 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 Michael A. Heroux (maherou@sandia.gov)
39//
40// ***********************************************************************
41//
42// @HEADER
43
52
53#ifndef AMESOS2_SOLVERCORE_DEF_HPP
54#define AMESOS2_SOLVERCORE_DEF_HPP
55
56#include "Kokkos_ArithTraits.hpp"
57
58#include "Amesos2_MatrixAdapter_def.hpp"
59#include "Amesos2_MultiVecAdapter_def.hpp"
60
61#include "Amesos2_Util.hpp"
62
63#include "KokkosSparse_spmv.hpp"
64#include "KokkosBlas.hpp"
65
66namespace Amesos2 {
67
68
69template <template <class,class> class ConcreteSolver, class Matrix, class Vector >
71 Teuchos::RCP<const Matrix> A,
72 Teuchos::RCP<Vector> X,
73 Teuchos::RCP<const Vector> B )
74 : matrixA_(createConstMatrixAdapter<Matrix>(A))
75 , multiVecX_(X) // may be null
76 , multiVecB_(B) // may be null
77 , globalNumRows_(matrixA_->getGlobalNumRows())
78 , globalNumCols_(matrixA_->getGlobalNumCols())
79 , globalNumNonZeros_(matrixA_->getGlobalNNZ())
80 , rowIndexBase_(matrixA_->getRowIndexBase())
81 , columnIndexBase_(matrixA_->getColumnIndexBase())
82 , rank_(Teuchos::rank(*this->getComm()))
83 , root_(rank_ == 0)
84 , nprocs_(Teuchos::size(*this->getComm()))
85{
86 TEUCHOS_TEST_FOR_EXCEPTION(
88 std::invalid_argument,
89 "Matrix shape inappropriate for this solver");
90}
91
92
94template <template <class,class> class ConcreteSolver, class Matrix, class Vector >
99
100
101template <template <class,class> class ConcreteSolver, class Matrix, class Vector >
104{
105#ifdef HAVE_AMESOS2_TIMERS
106 Teuchos::TimeMonitor LocalTimer1(timers_.totalTime_);
107#endif
108
109 loadA(PREORDERING);
110
111 int error_code = static_cast<solver_type*>(this)->preOrdering_impl();
112 if (error_code == EXIT_SUCCESS){
113 ++status_.numPreOrder_;
114 status_.last_phase_ = PREORDERING;
115 }
116
117 return *this;
118}
119
120
121template <template <class,class> class ConcreteSolver, class Matrix, class Vector >
124{
125#ifdef HAVE_AMESOS2_TIMERS
126 Teuchos::TimeMonitor LocalTimer1(timers_.totalTime_);
127#endif
128
129 if( !status_.preOrderingDone() ){
130 preOrdering();
131 if( !matrix_loaded_ ) loadA(SYMBFACT);
132 } else {
133 loadA(SYMBFACT);
134 }
135
136 int error_code = static_cast<solver_type*>(this)->symbolicFactorization_impl();
137 if (error_code == EXIT_SUCCESS){
138 ++status_.numSymbolicFact_;
139 status_.last_phase_ = SYMBFACT;
140 }
141
142 return *this;
143}
144
145
146template <template <class,class> class ConcreteSolver, class Matrix, class Vector >
149{
150#ifdef HAVE_AMESOS2_TIMERS
151 Teuchos::TimeMonitor LocalTimer1(timers_.totalTime_);
152#endif
153
154 if( !status_.symbolicFactorizationDone() ){
156 if( !matrix_loaded_ ) loadA(NUMFACT);
157 } else {
158 loadA(NUMFACT);
159 }
160
161 int error_code = static_cast<solver_type*>(this)->numericFactorization_impl();
162 if (error_code == EXIT_SUCCESS){
163 ++status_.numNumericFact_;
164 status_.last_phase_ = NUMFACT;
165 }
166
167 return *this;
168}
169
170
171template <template <class,class> class ConcreteSolver, class Matrix, class Vector >
172void
177
178template <template <class,class> class ConcreteSolver, class Matrix, class Vector >
179void
181 const Teuchos::Ptr<const Vector> B) const
182{
183#ifdef HAVE_AMESOS2_TIMERS
184 Teuchos::TimeMonitor LocalTimer1(timers_.totalTime_);
185#endif
186
187 X.assert_not_null();
188 B.assert_not_null();
189
190 if (control_.useIterRefine_) {
191 solve_ir(X, B, control_.maxNumIterRefines_, control_.verboseIterRefine_);
192 return;
193 }
194
195 const Teuchos::RCP<MultiVecAdapter<Vector> > x =
196 createMultiVecAdapter<Vector>(Teuchos::rcpFromPtr(X));
197 const Teuchos::RCP<const MultiVecAdapter<Vector> > b =
198 createConstMultiVecAdapter<Vector>(Teuchos::rcpFromPtr(B));
199
200#ifdef HAVE_AMESOS2_DEBUG
201 // Check some required properties of X and B
202 TEUCHOS_TEST_FOR_EXCEPTION
203 (x->getGlobalLength() != matrixA_->getGlobalNumCols(),
204 std::invalid_argument,
205 "MultiVector X must have length equal to the number of "
206 "global columns in A. X->getGlobalLength() = "
207 << x->getGlobalLength() << " != A->getGlobalNumCols() = "
208 << matrixA_->getGlobalNumCols() << ".");
209
210 TEUCHOS_TEST_FOR_EXCEPTION(b->getGlobalLength() != matrixA_->getGlobalNumRows(),
211 std::invalid_argument,
212 "MultiVector B must have length equal to the number of "
213 "global rows in A");
214
215 TEUCHOS_TEST_FOR_EXCEPTION(x->getGlobalNumVectors() != b->getGlobalNumVectors(),
216 std::invalid_argument,
217 "X and B MultiVectors must have the same number of vectors");
218#endif // HAVE_AMESOS2_DEBUG
219
220 if( !status_.numericFactorizationDone() ){
221 // This casting-away of constness is probably OK because this
222 // function is meant to be "logically const"
223 const_cast<type&>(*this).numericFactorization();
224 }
225
226 int error_code = static_cast<const solver_type*>(this)->solve_impl(Teuchos::outArg(*x), Teuchos::ptrInArg(*b));
227 if (error_code == EXIT_SUCCESS){
228 ++status_.numSolve_;
229 status_.last_phase_ = SOLVE;
230 }
231}
232
233template <template <class,class> class ConcreteSolver, class Matrix, class Vector >
234void
235SolverCore<ConcreteSolver,Matrix,Vector>::solve(Vector* X, const Vector* B) const
236{
237 solve(Teuchos::ptr(X), Teuchos::ptr(B));
238}
239
240
241template <template <class,class> class ConcreteSolver, class Matrix, class Vector >
242int
243SolverCore<ConcreteSolver,Matrix,Vector>::solve_ir(const int maxNumIters, const bool verbose)
244{
245 return solve_ir(multiVecX_.ptr(), multiVecB_.ptr(), maxNumIters, verbose);
246}
247
248template <template <class,class> class ConcreteSolver, class Matrix, class Vector >
249int
250SolverCore<ConcreteSolver,Matrix,Vector>::solve_ir(Vector* X, const Vector* B, const int maxNumIters, const bool verbose) const
251{
252 return solve_ir(Teuchos::ptr(X), Teuchos::ptr(B), maxNumIters, verbose);
253}
254
255template <template <class,class> class ConcreteSolver, class Matrix, class Vector >
256int
257SolverCore<ConcreteSolver,Matrix,Vector>::solve_ir(const Teuchos::Ptr< Vector> x,
258 const Teuchos::Ptr<const Vector> b,
259 const int maxNumIters,
260 const bool verbose) const
261{
262 using KAT = Kokkos::ArithTraits<scalar_type>;
263 using impl_scalar_type = typename KAT::val_type;
264 using magni_type = typename KAT::mag_type;
265 using host_execution_space = Kokkos::DefaultHostExecutionSpace;
266 using host_crsmat_t = KokkosSparse::CrsMatrix<impl_scalar_type, int, host_execution_space, void, int>;
267 using host_graph_t = typename host_crsmat_t::StaticCrsGraphType;
268 using host_values_t = typename host_crsmat_t::values_type::non_const_type;
269 using host_row_map_t = typename host_graph_t::row_map_type::non_const_type;
270 using host_colinds_t = typename host_graph_t::entries_type::non_const_type;
271 using host_mvector_t = Kokkos::View<impl_scalar_type **, Kokkos::LayoutLeft, host_execution_space>;
272 using host_vector_t = Kokkos::View<impl_scalar_type *, Kokkos::LayoutLeft, host_execution_space>;
273 using host_magni_view = Kokkos::View<magni_type *, Kokkos::LayoutLeft, host_execution_space>;
274
275 const impl_scalar_type one(1.0);
276 const impl_scalar_type mone = impl_scalar_type(-one);
277 const magni_type eps = KAT::eps ();
278
279 // get data needed for IR
280 using MVAdapter = MultiVecAdapter<Vector>;
281 Teuchos::RCP< MVAdapter> X = createMultiVecAdapter<Vector>(Teuchos::rcpFromPtr(x));
282 Teuchos::RCP<const MVAdapter> B = createConstMultiVecAdapter<Vector>(Teuchos::rcpFromPtr(b));
283
284 auto r_ = B->clone();
285 auto e_ = X->clone();
286 auto r = r_.ptr();
287 auto e = e_.ptr();
288 Teuchos::RCP< MVAdapter> R = createMultiVecAdapter<Vector>(Teuchos::rcpFromPtr(r));
289 Teuchos::RCP< MVAdapter> E = createMultiVecAdapter<Vector>(Teuchos::rcpFromPtr(e));
290
291 const size_t nrhs = X->getGlobalNumVectors();
292 const int nnz = this->matrixA_->getGlobalNNZ();
293 const int nrows = this->matrixA_->getGlobalNumRows();
294
295 // get local matriix
296 host_crsmat_t crsmat;
297 host_graph_t static_graph;
298 host_row_map_t rowmap_view;
299 host_colinds_t colind_view;
300 host_values_t values_view;
301 if (this->root_) {
302 Kokkos::resize(rowmap_view, 1+nrows);
303 Kokkos::resize(colind_view, nnz);
304 Kokkos::resize(values_view, nnz);
305 } else {
306 Kokkos::resize(rowmap_view, 1);
307 Kokkos::resize(colind_view, 0);
308 Kokkos::resize(values_view, 0);
309 }
310
311 int nnz_ret = 0;
313 MatrixAdapter<Matrix>, host_values_t, host_colinds_t, host_row_map_t>::do_get(
314 this->matrixA_.ptr(),
315 values_view, colind_view, rowmap_view,
316 nnz_ret, ROOTED, ARBITRARY, this->rowIndexBase_);
317
318 if (this->root_) {
319 static_graph = host_graph_t(colind_view, rowmap_view);
320 crsmat = host_crsmat_t("CrsMatrix", nrows, values_view, static_graph);
321 }
322
323 //
324 // ** First Solve **
325 static_cast<const solver_type*>(this)->solve_impl(Teuchos::outArg(*X), Teuchos::ptrInArg(*B));
326
327
328 // auxiliary scalar Kokkos views
329 const int ldx = (this->root_ ? X->getGlobalLength() : 0);
330 const int ldb = (this->root_ ? B->getGlobalLength() : 0);
331 const int ldr = (this->root_ ? R->getGlobalLength() : 0);
332 const int lde = (this->root_ ? E->getGlobalLength() : 0);
333 const bool initialize_data = true;
334 const bool not_initialize_data = true;
335 host_mvector_t X_view;
336 host_mvector_t B_view;
337 host_mvector_t R_view;
338 host_mvector_t E_view;
339
340 global_size_type rowIndexBase = this->rowIndexBase_;
341 auto Xptr = Teuchos::Ptr< MVAdapter>(X.ptr());
342 auto Bptr = Teuchos::Ptr<const MVAdapter>(B.ptr());
343 auto Rptr = Teuchos::Ptr< MVAdapter>(R.ptr());
344 auto Eptr = Teuchos::Ptr< MVAdapter>(E.ptr());
345 Util::get_1d_copy_helper_kokkos_view<MVAdapter, host_mvector_t>::
346 do_get( initialize_data, Xptr, X_view, ldx, CONTIGUOUS_AND_ROOTED, rowIndexBase);
347 Util::get_1d_copy_helper_kokkos_view<MVAdapter, host_mvector_t>::
348 do_get( initialize_data, Bptr, B_view, ldb, CONTIGUOUS_AND_ROOTED, rowIndexBase);
349 Util::get_1d_copy_helper_kokkos_view<MVAdapter, host_mvector_t>::
350 do_get(not_initialize_data, Rptr, R_view, ldr, CONTIGUOUS_AND_ROOTED, rowIndexBase);
351 Util::get_1d_copy_helper_kokkos_view<MVAdapter, host_mvector_t>::
352 do_get(not_initialize_data, Eptr, E_view, lde, CONTIGUOUS_AND_ROOTED, rowIndexBase);
353
354
355 host_magni_view x0norms("x0norms", nrhs);
356 host_magni_view bnorms("bnorms", nrhs);
357 host_magni_view enorms("enorms", nrhs);
358 if (this->root_) {
359 // compute initial solution norms (used for stopping criteria)
360 for (size_t j = 0; j < nrhs; j++) {
361 auto x_subview = Kokkos::subview(X_view, Kokkos::ALL(), j);
362 host_vector_t x_1d (const_cast<impl_scalar_type*>(x_subview.data()), x_subview.extent(0));
363 x0norms(j) = KokkosBlas::nrm2(x_1d);
364 }
365 if (verbose) {
366 std::cout << std::endl
367 << " SolverCore :: solve_ir (maxNumIters = " << maxNumIters
368 << ", tol = " << x0norms(0) << " * " << eps << " = " << x0norms(0)*eps
369 << ")" << std::endl;
370 }
371
372 // compute residual norm
373 if (verbose) {
374 std::cout << " bnorm = ";
375 for (size_t j = 0; j < nrhs; j++) {
376 auto b_subview = Kokkos::subview(B_view, Kokkos::ALL(), j);
377 host_vector_t b_1d (const_cast<impl_scalar_type*>(b_subview.data()), b_subview.extent(0));
378 bnorms(j) = KokkosBlas::nrm2(b_1d);
379 std::cout << bnorms(j) << ", ";
380 }
381 std::cout << std::endl;
382 }
383 }
384
385
386 //
387 // ** Iterative Refinement **
388 int numIters = 0;
389 int converged = 0; // 0 = has not converged, 1 = converged
390 for (numIters = 0; numIters < maxNumIters && converged == 0; ++numIters) {
391 // r = b - Ax (on rank-0)
392 if (this->root_) {
393 Kokkos::deep_copy(R_view, B_view);
394 KokkosSparse::spmv("N", mone, crsmat, X_view, one, R_view);
395 Kokkos::fence();
396
397 if (verbose) {
398 // compute residual norm
399 std::cout << " > " << numIters << " : norm(r,x,e) = ";
400 for (size_t j = 0; j < nrhs; j++) {
401 auto r_subview = Kokkos::subview(R_view, Kokkos::ALL(), j);
402 auto x_subview = Kokkos::subview(X_view, Kokkos::ALL(), j);
403 host_vector_t r_1d (const_cast<impl_scalar_type*>(r_subview.data()), r_subview.extent(0));
404 host_vector_t x_1d (const_cast<impl_scalar_type*>(x_subview.data()), x_subview.extent(0));
405 impl_scalar_type rnorm = KokkosBlas::nrm2(r_1d);
406 impl_scalar_type xnorm = KokkosBlas::nrm2(x_1d);
407 std::cout << rnorm << " -> " << rnorm/bnorms(j) << " " << xnorm << " " << enorms(j) << ", ";
408 }
409 std::cout << std::endl;
410 }
411 }
412
413 // e = A^{-1} r
414 Util::put_1d_data_helper_kokkos_view<MVAdapter, host_mvector_t>::
415 do_put(Rptr, R_view, ldr, CONTIGUOUS_AND_ROOTED, rowIndexBase);
416 static_cast<const solver_type*>(this)->solve_impl(Teuchos::outArg(*E), Teuchos::ptrInArg(*R));
417 Util::get_1d_copy_helper_kokkos_view<MVAdapter, host_mvector_t>::
418 do_get(initialize_data, Eptr, E_view, lde, CONTIGUOUS_AND_ROOTED, rowIndexBase);
419
420 // x = x + e (on rank-0)
421 if (this->root_) {
422 KokkosBlas::axpy(one, E_view, X_view);
423
424 if (numIters < maxNumIters-1) {
425 // compute norm of corrections for "convergence" check
426 converged = 1;
427 for (size_t j = 0; j < nrhs; j++) {
428 auto e_subview = Kokkos::subview(E_view, Kokkos::ALL(), j);
429 host_vector_t e_1d (const_cast<impl_scalar_type*>(e_subview.data()), e_subview.extent(0));
430 enorms(j) = KokkosBlas::nrm2(e_1d);
431 if (enorms(j) > eps * x0norms(j)) {
432 converged = 0;
433 }
434 }
435 if (verbose && converged) {
436 std::cout << " converged " << std::endl;
437 }
438 }
439 }
440
441 // broadcast "converged"
442 Teuchos::broadcast(*(this->matrixA_->getComm()), 0, &converged);
443 } // end of for-loop for IR iteration
444
445 if (verbose && this->root_) {
446 // r = b - Ax
447 Kokkos::deep_copy(R_view, B_view);
448 KokkosSparse::spmv("N", mone, crsmat, X_view, one, R_view);
449 Kokkos::fence();
450 std::cout << " > final residual norm = ";
451 for (size_t j = 0; j < nrhs; j++) {
452 auto r_subview = Kokkos::subview(R_view, Kokkos::ALL(), j);
453 host_vector_t r_1d (const_cast<impl_scalar_type*>(r_subview.data()), r_subview.extent(0));
454 scalar_type rnorm = KokkosBlas::nrm2(r_1d);
455 std::cout << rnorm << " -> " << rnorm/bnorms(j) << ", ";
456 }
457 std::cout << std::endl << std::endl;
458 }
459
460 // put X for output
461 Util::put_1d_data_helper_kokkos_view<MVAdapter, host_mvector_t>::
462 do_put(Xptr, X_view, ldx, CONTIGUOUS_AND_ROOTED, rowIndexBase);
463
464 return numIters;
465}
466
467template <template <class,class> class ConcreteSolver, class Matrix, class Vector >
468bool
470{
471#ifdef HAVE_AMESOS2_TIMERS
472 Teuchos::TimeMonitor LocalTimer1(timers_.totalTime_);
473#endif
474
475 return( static_cast<solver_type*>(this)->matrixShapeOK_impl() );
476}
477
478 // The RCP should probably be to a const Matrix, but that throws a
479 // wrench in some of the traits mechanisms that aren't expecting
480 // const types
481template <template <class,class> class ConcreteSolver, class Matrix, class Vector >
482void
483SolverCore<ConcreteSolver,Matrix,Vector>::setA( const Teuchos::RCP<const Matrix> a,
484 EPhase keep_phase )
485{
486 matrixA_ = createConstMatrixAdapter(a);
487
488#ifdef HAVE_AMESOS2_DEBUG
489 TEUCHOS_TEST_FOR_EXCEPTION( (keep_phase != CLEAN) &&
490 (globalNumRows_ != matrixA_->getGlobalNumRows() ||
491 globalNumCols_ != matrixA_->getGlobalNumCols()),
492 std::invalid_argument,
493 "Dimensions of new matrix be the same as the old matrix if "
494 "keeping any solver phase" );
495#endif
496
497 status_.last_phase_ = keep_phase;
498
499 // Reset phase counters
500 switch( status_.last_phase_ ){
501 case CLEAN:
502 status_.numPreOrder_ = 0;
503 // Intentional fallthrough.
504 case PREORDERING:
505 status_.numSymbolicFact_ = 0;
506 // Intentional fallthrough.
507 case SYMBFACT:
508 status_.numNumericFact_ = 0;
509 // Intentional fallthrough.
510 case NUMFACT: // probably won't ever happen by itself
511 status_.numSolve_ = 0;
512 // Intentional fallthrough.
513 case SOLVE: // probably won't ever happen
514 break;
515 }
516
517 // Re-get the matrix dimensions in case they have changed
518 globalNumNonZeros_ = matrixA_->getGlobalNNZ();
519 globalNumCols_ = matrixA_->getGlobalNumCols();
520 globalNumRows_ = matrixA_->getGlobalNumRows();
521}
522
523
524template <template <class,class> class ConcreteSolver, class Matrix, class Vector >
527 const Teuchos::RCP<Teuchos::ParameterList> & parameterList )
528{
529#ifdef HAVE_AMESOS2_TIMERS
530 Teuchos::TimeMonitor LocalTimer1(timers_.totalTime_);
531#endif
532
533 if( parameterList->name() == "Amesos2" ){
534 // First, validate the parameterList
535 Teuchos::RCP<const Teuchos::ParameterList> valid_params = getValidParameters();
536 parameterList->validateParameters(*valid_params);
537
538 // Do everything here that is for generic status and control parameters
539 control_.setControlParameters(parameterList);
540
541 // Finally, hook to the implementation's parameter list parser
542 // First check if there is a dedicated sublist for this solver and use that if there is
543 if( parameterList->isSublist(name()) ){
544 // Have control look through the solver's parameter list to see if
545 // there is anything it recognizes (mostly the "Transpose" parameter)
546 control_.setControlParameters(Teuchos::sublist(parameterList, name()));
547
548 static_cast<solver_type*>(this)->setParameters_impl(Teuchos::sublist(parameterList, name()));
549 }
550 }
551
552 return *this;
553}
554
555
556template <template <class,class> class ConcreteSolver, class Matrix, class Vector >
557Teuchos::RCP<const Teuchos::ParameterList>
559{
560#ifdef HAVE_AMESOS2_TIMERS
561 Teuchos::TimeMonitor LocalTimer1( timers_.totalTime_ );
562#endif
563
564 using Teuchos::ParameterList;
565 using Teuchos::RCP;
566 using Teuchos::rcp;
567
568 //RCP<ParameterList> control_params = rcp(new ParameterList("Amesos2 Control"));
569 RCP<ParameterList> control_params = rcp(new ParameterList("Amesos2"));
570 control_params->set("Transpose", false, "Whether to solve with the matrix transpose");
571 control_params->set("Iterative refinement", false, "Whether to solve with iterative refinement");
572 control_params->set("Number of iterative refinements", 2, "Number of iterative refinements");
573 control_params->set("Verboes for iterative refinement", false, "Verbosity for iterative refinements");
574 // control_params->set("AddToDiag", "");
575 // control_params->set("AddZeroToDiag", false);
576 // control_params->set("MatrixProperty", "general");
577 // control_params->set("Reindex", false);
578
579 RCP<const ParameterList>
580 solver_params = static_cast<const solver_type*>(this)->getValidParameters_impl();
581 // inject the "Transpose" parameter into the solver's valid parameters
582 Teuchos::rcp_const_cast<ParameterList>(solver_params)->set("Transpose", false,
583 "Whether to solve with the "
584 "matrix transpose");
585
586 RCP<ParameterList> amesos2_params = rcp(new ParameterList("Amesos2"));
587 amesos2_params->setParameters(*control_params);
588 amesos2_params->set(name(), *solver_params);
589
590 return amesos2_params;
591}
592
593
594template <template <class,class> class ConcreteSolver, class Matrix, class Vector >
595std::string
597{
598 std::ostringstream oss;
599 oss << name() << " solver interface";
600 return oss.str();
601}
602
603
604template <template <class,class> class ConcreteSolver, class Matrix, class Vector >
605void
607 Teuchos::FancyOStream &out,
608 const Teuchos::EVerbosityLevel verbLevel) const
609{
610 if( matrixA_.is_null() || (rank_ != 0) ){ return; }
611 using std::endl;
612 using std::setw;
613 using Teuchos::VERB_DEFAULT;
614 using Teuchos::VERB_NONE;
615 using Teuchos::VERB_LOW;
616 using Teuchos::VERB_MEDIUM;
617 using Teuchos::VERB_HIGH;
618 using Teuchos::VERB_EXTREME;
619 Teuchos::EVerbosityLevel vl = verbLevel;
620 if (vl == VERB_DEFAULT) vl = VERB_LOW;
621 Teuchos::RCP<const Teuchos::Comm<int> > comm = this->getComm();
622 size_t width = 1;
623 for( size_t dec = 10; dec < globalNumRows_; dec *= 10 ) {
624 ++width;
625 }
626 width = std::max<size_t>(width,size_t(11)) + 2;
627 Teuchos::OSTab tab(out);
628 // none: print nothing
629 // low: print O(1) info from node 0
630 // medium: print O(P) info, num entries per node
631 // high: print O(N) info, num entries per row
632 // extreme: print O(NNZ) info: print indices and values
633 //
634 // for medium and higher, print constituent objects at specified verbLevel
635 if( vl != VERB_NONE ) {
636 std::string p = name();
637 Util::printLine(out);
638 out << this->description() << std::endl << std::endl;
639
640 out << p << "Matrix has " << globalNumRows_ << " rows"
641 << " and " << globalNumNonZeros_ << " nonzeros"
642 << std::endl;
643 if( vl == VERB_MEDIUM || vl == VERB_HIGH || vl == VERB_EXTREME ){
644 out << p << "Nonzero elements per row = "
646 << std::endl;
647 out << p << "Percentage of nonzero elements = "
649 << std::endl;
650 }
651 if( vl == VERB_HIGH || vl == VERB_EXTREME ){
652 out << p << "Use transpose = " << control_.useTranspose_
653 << std::endl;
654 out << p << "Use iterative refinement = " << control_.useIterRefine_
655 << std::endl;
656 }
657 if ( vl == VERB_EXTREME ){
658 printTiming(out,vl);
659 }
660 Util::printLine(out);
661 }
662}
663
664
665template <template <class,class> class ConcreteSolver, class Matrix, class Vector >
666void
668 Teuchos::FancyOStream &out,
669 const Teuchos::EVerbosityLevel verbLevel) const
670{
671 if( matrixA_.is_null() || (rank_ != 0) ){ return; }
672
673 double preTime = timers_.preOrderTime_.totalElapsedTime();
674 double symTime = timers_.symFactTime_.totalElapsedTime();
675 double numTime = timers_.numFactTime_.totalElapsedTime();
676 double solTime = timers_.solveTime_.totalElapsedTime();
677 double totTime = timers_.totalTime_.totalElapsedTime();
678 double overhead = totTime - (preTime + symTime + numTime + solTime);
679
680 std::string p = name() + " : ";
681 Util::printLine(out);
682
683 if(verbLevel != Teuchos::VERB_NONE)
684 {
685 out << p << "Time to convert matrix to implementation format = "
686 << timers_.mtxConvTime_.totalElapsedTime() << " (s)"
687 << std::endl;
688 out << p << "Time to redistribute matrix = "
689 << timers_.mtxRedistTime_.totalElapsedTime() << " (s)"
690 << std::endl;
691
692 out << p << "Time to convert vectors to implementation format = "
693 << timers_.vecConvTime_.totalElapsedTime() << " (s)"
694 << std::endl;
695 out << p << "Time to redistribute vectors = "
696 << timers_.vecRedistTime_.totalElapsedTime() << " (s)"
697 << std::endl;
698
699 out << p << "Number of pre-orderings = "
700 << status_.getNumPreOrder()
701 << std::endl;
702 out << p << "Time for pre-ordering = "
703 << preTime << " (s), avg = "
704 << preTime / status_.getNumPreOrder() << " (s)"
705 << std::endl;
706
707 out << p << "Number of symbolic factorizations = "
708 << status_.getNumSymbolicFact()
709 << std::endl;
710 out << p << "Time for sym fact = "
711 << symTime << " (s), avg = "
712 << symTime / status_.getNumSymbolicFact() << " (s)"
713 << std::endl;
714
715 out << p << "Number of numeric factorizations = "
716 << status_.getNumNumericFact()
717 << std::endl;
718 out << p << "Time for num fact = "
719 << numTime << " (s), avg = "
720 << numTime / status_.getNumNumericFact() << " (s)"
721 << std::endl;
722
723 out << p << "Number of solve phases = "
724 << status_.getNumSolve()
725 << std::endl;
726 out << p << "Time for solve = "
727 << solTime << " (s), avg = "
728 << solTime / status_.getNumSolve() << " (s)"
729 << std::endl;
730
731 out << p << "Total time spent in Amesos2 = "
732 << totTime << " (s)"
733 << std::endl;
734 out << p << "Total time spent in the Amesos2 interface = "
735 << overhead << " (s)"
736 << std::endl;
737 out << p << " (the above time does not include solver time)"
738 << std::endl;
739 out << p << "Amesos2 interface time / total time = "
740 << overhead / totTime
741 << std::endl;
742 Util::printLine(out);
743 }
744}
745
746
747template <template <class,class> class ConcreteSolver, class Matrix, class Vector >
748void
750 Teuchos::ParameterList& timingParameterList) const
751{
752 Teuchos::ParameterList temp;
753 timingParameterList = temp.setName("NULL");
754}
755
756
757template <template <class,class> class ConcreteSolver, class Matrix, class Vector >
758std::string
760{
761 std::string solverName = solver_type::name;
762 return solverName;
763}
764
765template <template <class,class> class ConcreteSolver, class Matrix, class Vector >
766void
768{
769 matrix_loaded_ = static_cast<solver_type*>(this)->loadA_impl(current_phase);
770}
771
772
773} // end namespace Amesos2
774
775#endif // AMESOS2_SOLVERCORE_DEF_HPP
@ ROOTED
Definition Amesos2_TypeDecl.hpp:127
@ CONTIGUOUS_AND_ROOTED
Definition Amesos2_TypeDecl.hpp:128
@ ARBITRARY
Definition Amesos2_TypeDecl.hpp:143
Utility functions for Amesos2.
A Matrix adapter interface for Amesos2.
Definition Amesos2_MatrixAdapter_decl.hpp:76
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Definition Amesos2_SolverCore_def.hpp:606
int nprocs_
Number of process images in the matrix communicator.
Definition Amesos2_SolverCore_decl.hpp:509
super_type & numericFactorization()
Performs numeric factorization on the matrix A.
Definition Amesos2_SolverCore_def.hpp:148
void printTiming(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
Prints timing information about the current solver.
Definition Amesos2_SolverCore_def.hpp:667
Teuchos::RCP< const MatrixAdapter< Matrix > > matrixA_
The LHS operator.
Definition Amesos2_SolverCore_decl.hpp:455
std::string description() const
Returns a short description of this Solver.
Definition Amesos2_SolverCore_def.hpp:596
int rank_
The MPI rank of this image.
Definition Amesos2_SolverCore_decl.hpp:503
bool root_
If true, then this is the root processor.
Definition Amesos2_SolverCore_decl.hpp:506
SolverCore(Teuchos::RCP< const Matrix > A, Teuchos::RCP< Vector > X, Teuchos::RCP< const Vector > B)
Initialize a Solver instance.
Definition Amesos2_SolverCore_def.hpp:70
super_type & setParameters(const Teuchos::RCP< Teuchos::ParameterList > &parameterList)
Set/update internal variables and solver options.
Definition Amesos2_SolverCore_def.hpp:526
void getTiming(Teuchos::ParameterList &timingParameterList) const
Extracts timing information from the current solver.
Definition Amesos2_SolverCore_def.hpp:749
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Return a const parameter list of all of the valid parameters that this->setParameterList(....
Definition Amesos2_SolverCore_def.hpp:558
global_size_type rowIndexBase_
Index base of rowmap of matrixA_.
Definition Amesos2_SolverCore_decl.hpp:485
std::string name() const
Return the name of this solver.
Definition Amesos2_SolverCore_def.hpp:759
global_size_type globalNumCols_
Number of global columns in matrixA_.
Definition Amesos2_SolverCore_decl.hpp:479
void setA(const Teuchos::RCP< const Matrix > a, EPhase keep_phase=CLEAN)
Sets the matrix A of this solver.
Definition Amesos2_SolverCore_def.hpp:483
void loadA(EPhase current_phase)
Refresh this solver's internal data about A.
Definition Amesos2_SolverCore_def.hpp:767
bool matrix_loaded_
Definition Amesos2_SolverCore_decl.hpp:462
global_size_type columnIndexBase_
Index base of column map of matrixA_.
Definition Amesos2_SolverCore_decl.hpp:488
Timers timers_
Various timing statistics.
Definition Amesos2_SolverCore_decl.hpp:497
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Returns a pointer to the Teuchos::Comm communicator with this operator.
Definition Amesos2_SolverCore_decl.hpp:363
global_size_type globalNumNonZeros_
Number of global non-zero values in matrixA_.
Definition Amesos2_SolverCore_decl.hpp:482
global_size_type globalNumRows_
Number of global rows in matrixA_.
Definition Amesos2_SolverCore_decl.hpp:476
Status status_
Holds status information about a solver.
Definition Amesos2_SolverCore_decl.hpp:491
~SolverCore()
Destructor.
Definition Amesos2_SolverCore_def.hpp:95
Teuchos::RCP< const Vector > multiVecB_
The RHS vector/multi-vector.
Definition Amesos2_SolverCore_decl.hpp:473
void solve()
Solves (or ).
Definition Amesos2_SolverCore_def.hpp:173
Control control_
Parameters for solving.
Definition Amesos2_SolverCore_decl.hpp:494
bool matrixShapeOK()
Returns true if the solver can handle this matrix shape.
Definition Amesos2_SolverCore_def.hpp:469
super_type & symbolicFactorization()
Performs symbolic factorization on the matrix A.
Definition Amesos2_SolverCore_def.hpp:123
Teuchos::RCP< Vector > multiVecX_
The LHS vector/multi-vector.
Definition Amesos2_SolverCore_decl.hpp:466
super_type & preOrdering()
Pre-orders the matrix A for minimal fill-in.
Definition Amesos2_SolverCore_def.hpp:103
Interface to Amesos2 solver objects.
Definition Amesos2_Solver_decl.hpp:78
EPhase
Used to indicate a phase in the direct solution.
Definition Amesos2_TypeDecl.hpp:65
A templated MultiVector class adapter for Amesos2.
Definition Amesos2_MultiVecAdapter_decl.hpp:176
Teuchos::RCP< MultiVecAdapter< MV > > createMultiVecAdapter(Teuchos::RCP< MV > mv)
Factory creation method for MultiVecAdapters.
Definition Amesos2_MultiVecAdapter_decl.hpp:188
Similar to get_ccs_helper , but used to get a CRS representation of the given matrix.
Definition Amesos2_Util.hpp:663