10 #ifndef BELOS_PSEUDO_BLOCK_CG_SOLMGR_HPP
11 #define BELOS_PSEUDO_BLOCK_CG_SOLMGR_HPP
32 #ifdef BELOS_TEUCHOS_TIME_MONITOR
73 template<
class ScalarType,
class MV,
class OP,
74 const bool supportsScalarType =
78 Belos::Details::LapackSupportsScalar<ScalarType>::value>
80 static const bool scalarTypeIsSupported =
99 template<
class ScalarType,
class MV,
class OP>
170 return Teuchos::tuple(timerSolve_);
258 std::string description()
const override;
266 ScalarType & lambda_min,
267 ScalarType & lambda_max,
268 ScalarType & ConditionNumber );
294 static constexpr
int maxIters_default_ = 1000;
295 static constexpr
bool assertPositiveDefiniteness_default_ =
true;
296 static constexpr
bool showMaxResNormOnly_default_ =
false;
299 static constexpr
int outputFreq_default_ = -1;
300 static constexpr
int defQuorum_default_ = 1;
301 static constexpr
bool foldConvergenceDetectionIntoAllreduce_default_ =
false;
302 static constexpr
const char * resScale_default_ =
"Norm of Initial Residual";
303 static constexpr
const char * label_default_ =
"Belos";
304 static constexpr
bool genCondEst_default_ =
false;
307 MagnitudeType convtol_,achievedTol_;
308 int maxIters_, numIters_;
309 int verbosity_, outputStyle_, outputFreq_, defQuorum_;
310 bool assertPositiveDefiniteness_, showMaxResNormOnly_;
311 bool foldConvergenceDetectionIntoAllreduce_;
312 std::string resScale_;
314 ScalarType condEstimate_;
329 template<
class ScalarType,
class MV,
class OP>
331 outputStream_(Teuchos::rcpFromRef(std::cout)),
333 maxIters_(maxIters_default_),
335 verbosity_(verbosity_default_),
336 outputStyle_(outputStyle_default_),
337 outputFreq_(outputFreq_default_),
338 defQuorum_(defQuorum_default_),
339 assertPositiveDefiniteness_(assertPositiveDefiniteness_default_),
340 showMaxResNormOnly_(showMaxResNormOnly_default_),
341 foldConvergenceDetectionIntoAllreduce_(foldConvergenceDetectionIntoAllreduce_default_),
342 resScale_(resScale_default_),
343 genCondEst_(genCondEst_default_),
344 condEstimate_(-Teuchos::ScalarTraits<ScalarType>::one()),
345 label_(label_default_),
350 template<
class ScalarType,
class MV,
class OP>
355 outputStream_(Teuchos::rcpFromRef(std::cout)),
357 maxIters_(maxIters_default_),
359 verbosity_(verbosity_default_),
360 outputStyle_(outputStyle_default_),
361 outputFreq_(outputFreq_default_),
362 defQuorum_(defQuorum_default_),
363 assertPositiveDefiniteness_(assertPositiveDefiniteness_default_),
364 showMaxResNormOnly_(showMaxResNormOnly_default_),
365 foldConvergenceDetectionIntoAllreduce_(foldConvergenceDetectionIntoAllreduce_default_),
366 resScale_(resScale_default_),
367 genCondEst_(genCondEst_default_),
368 condEstimate_(-Teuchos::ScalarTraits<ScalarType>::one()),
369 label_(label_default_),
373 problem_.is_null (), std::invalid_argument,
374 "Belos::PseudoBlockCGSolMgr two-argument constructor: "
375 "'problem' is null. You must supply a non-null Belos::LinearProblem "
376 "instance when calling this constructor.");
384 template<
class ScalarType,
class MV,
class OP>
390 using Teuchos::parameterList;
394 RCP<const ParameterList> defaultParams = this->getValidParameters ();
413 if (params_.is_null ()) {
415 params_ = parameterList (defaultParams->name ());
422 maxIters_ = params->
get (
"Maximum Iterations", maxIters_default_);
425 params_->set (
"Maximum Iterations", maxIters_);
426 if (! maxIterTest_.is_null ()) {
427 maxIterTest_->setMaxIters (maxIters_);
432 if (params->
isParameter (
"Assert Positive Definiteness")) {
433 assertPositiveDefiniteness_ =
434 params->
get (
"Assert Positive Definiteness",
435 assertPositiveDefiniteness_default_);
438 params_->set (
"Assert Positive Definiteness", assertPositiveDefiniteness_);
441 if (params->
isParameter(
"Fold Convergence Detection Into Allreduce")) {
442 foldConvergenceDetectionIntoAllreduce_ = params->
get(
"Fold Convergence Detection Into Allreduce",
443 foldConvergenceDetectionIntoAllreduce_default_);
448 const std::string tempLabel = params->
get (
"Timer Label", label_default_);
451 if (tempLabel != label_) {
453 params_->set (
"Timer Label", label_);
454 const std::string solveLabel =
455 label_ +
": PseudoBlockCGSolMgr total solve time";
456 #ifdef BELOS_TEUCHOS_TIME_MONITOR
464 if (Teuchos::isParameterType<int> (*params,
"Verbosity")) {
465 verbosity_ = params->
get (
"Verbosity", verbosity_default_);
467 verbosity_ = (int) Teuchos::getParameter<Belos::MsgType> (*params,
"Verbosity");
471 params_->set (
"Verbosity", verbosity_);
472 if (! printer_.is_null ()) {
473 printer_->setVerbosity (verbosity_);
479 if (Teuchos::isParameterType<int> (*params,
"Output Style")) {
480 outputStyle_ = params->
get (
"Output Style", outputStyle_default_);
483 outputStyle_ = (int) Teuchos::getParameter<Belos::OutputType> (*params,
"Output Style");
488 params_->set (
"Output Style", outputStyle_);
489 outputTest_ = Teuchos::null;
494 outputStream_ = params->
get<RCP<std::ostream> > (
"Output Stream");
497 params_->set (
"Output Stream", outputStream_);
498 if (! printer_.is_null ()) {
499 printer_->setOStream (outputStream_);
506 outputFreq_ = params->
get (
"Output Frequency", outputFreq_default_);
510 params_->set (
"Output Frequency", outputFreq_);
511 if (! outputTest_.is_null ()) {
512 outputTest_->setOutputFrequency (outputFreq_);
517 if (params->
isParameter (
"Estimate Condition Number")) {
518 genCondEst_ = params->
get (
"Estimate Condition Number", genCondEst_default_);
522 if (printer_.is_null ()) {
531 if (params->
isParameter (
"Convergence Tolerance")) {
532 if (params->
isType<MagnitudeType> (
"Convergence Tolerance")) {
533 convtol_ = params->
get (
"Convergence Tolerance",
541 params_->set (
"Convergence Tolerance", convtol_);
542 if (! convTest_.is_null ()) {
543 convTest_->setTolerance (convtol_);
547 if (params->
isParameter (
"Show Maximum Residual Norm Only")) {
548 showMaxResNormOnly_ = params->
get<
bool> (
"Show Maximum Residual Norm Only");
551 params_->set (
"Show Maximum Residual Norm Only", showMaxResNormOnly_);
552 if (! convTest_.is_null ()) {
553 convTest_->setShowMaxResNormOnly (showMaxResNormOnly_);
558 bool newResTest =
false;
563 std::string tempResScale = resScale_;
564 bool implicitResidualScalingName =
false;
566 tempResScale = params->
get<std::string> (
"Residual Scaling");
568 else if (params->
isParameter (
"Implicit Residual Scaling")) {
569 tempResScale = params->
get<std::string> (
"Implicit Residual Scaling");
570 implicitResidualScalingName =
true;
574 if (resScale_ != tempResScale) {
577 resScale_ = tempResScale;
581 if (implicitResidualScalingName) {
582 params_->set (
"Implicit Residual Scaling", resScale_);
585 params_->set (
"Residual Scaling", resScale_);
588 if (! convTest_.is_null ()) {
592 catch (std::exception& e) {
602 defQuorum_ = params->
get (
"Deflation Quorum", defQuorum_);
603 params_->set (
"Deflation Quorum", defQuorum_);
604 if (! convTest_.is_null ()) {
605 convTest_->setQuorum( defQuorum_ );
612 if (maxIterTest_.is_null ()) {
617 if (convTest_.is_null () || newResTest) {
618 convTest_ =
rcp (
new StatusTestResNorm_t (convtol_, defQuorum_, showMaxResNormOnly_));
622 if (sTest_.is_null () || newResTest) {
623 sTest_ =
rcp (
new StatusTestCombo_t (StatusTestCombo_t::OR, maxIterTest_, convTest_));
626 if (outputTest_.is_null () || newResTest) {
630 outputTest_ = stoFactory.
create (printer_, sTest_, outputFreq_,
634 const std::string solverDesc =
" Pseudo Block CG ";
635 outputTest_->setSolverDesc (solverDesc);
639 if (timerSolve_.is_null ()) {
640 const std::string solveLabel =
641 label_ +
": PseudoBlockCGSolMgr total solve time";
642 #ifdef BELOS_TEUCHOS_TIME_MONITOR
652 template<
class ScalarType,
class MV,
class OP>
657 using Teuchos::parameterList;
660 if (validParams_.is_null()) {
662 RCP<ParameterList> pl = parameterList ();
664 "The relative residual tolerance that needs to be achieved by the\n"
665 "iterative solver in order for the linear system to be declared converged.");
666 pl->set(
"Maximum Iterations", static_cast<int>(maxIters_default_),
667 "The maximum number of block iterations allowed for each\n"
668 "set of RHS solved.");
669 pl->set(
"Assert Positive Definiteness", static_cast<bool>(assertPositiveDefiniteness_default_),
670 "Whether or not to assert that the linear operator\n"
671 "and the preconditioner are indeed positive definite.");
672 pl->set(
"Verbosity", static_cast<int>(verbosity_default_),
673 "What type(s) of solver information should be outputted\n"
674 "to the output stream.");
675 pl->set(
"Output Style", static_cast<int>(outputStyle_default_),
676 "What style is used for the solver information outputted\n"
677 "to the output stream.");
678 pl->set(
"Output Frequency", static_cast<int>(outputFreq_default_),
679 "How often convergence information should be outputted\n"
680 "to the output stream.");
681 pl->set(
"Deflation Quorum", static_cast<int>(defQuorum_default_),
682 "The number of linear systems that need to converge before\n"
683 "they are deflated. This number should be <= block size.");
684 pl->set(
"Output Stream", Teuchos::rcpFromRef(std::cout),
685 "A reference-counted pointer to the output stream where all\n"
686 "solver output is sent.");
687 pl->set(
"Show Maximum Residual Norm Only", static_cast<bool>(showMaxResNormOnly_default_),
688 "When convergence information is printed, only show the maximum\n"
689 "relative residual norm when the block size is greater than one.");
690 pl->set(
"Implicit Residual Scaling", resScale_default_,
691 "The type of scaling used in the residual convergence test.");
692 pl->set(
"Estimate Condition Number", static_cast<bool>(genCondEst_default_),
693 "Whether or not to estimate the condition number of the preconditioned system.");
699 pl->set(
"Residual Scaling", resScale_default_,
700 "The type of scaling used in the residual convergence test. This "
701 "name is deprecated; the new name is \"Implicit Residual Scaling\".");
702 pl->set(
"Timer Label", static_cast<const char *>(label_default_),
703 "The string to use as a prefix for the timer labels.");
704 pl->set(
"Fold Convergence Detection Into Allreduce",static_cast<bool>(foldConvergenceDetectionIntoAllreduce_default_),
705 "Merge the allreduce for convergence detection with the one for CG.\n"
706 "This saves one all-reduce, but incurs more computation.");
714 template<
class ScalarType,
class MV,
class OP>
717 const char prefix[] =
"Belos::PseudoBlockCGSolMgr::solve: ";
722 if (!isSet_) { setParameters( params_ ); }
726 prefix <<
"The linear problem to solve is not ready. You must call "
727 "setProblem() on the Belos::LinearProblem instance before telling the "
728 "Belos solver to solve it.");
732 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
733 int numCurrRHS = numRHS2Solve;
735 std::vector<int> currIdx( numRHS2Solve ), currIdx2( numRHS2Solve );
736 for (
int i=0; i<numRHS2Solve; ++i) {
737 currIdx[i] = startPtr+i;
742 problem_->setLSIndex( currIdx );
748 plist.
set(
"Assert Positive Definiteness",assertPositiveDefiniteness_);
749 if(genCondEst_) plist.
set(
"Max Size For Condest",maxIters_);
752 outputTest_->reset();
755 bool isConverged =
true;
760 if (numRHS2Solve == 1) {
761 plist.
set(
"Fold Convergence Detection Into Allreduce",
762 foldConvergenceDetectionIntoAllreduce_);
775 block_cg_iter->setDoCondEst(genCondEst_);
776 bool condEstPerf =
false;
780 #ifdef BELOS_TEUCHOS_TIME_MONITOR
784 while ( numRHS2Solve > 0 ) {
787 std::vector<int> convRHSIdx;
788 std::vector<int> currRHSIdx( currIdx );
789 currRHSIdx.resize(numCurrRHS);
792 block_cg_iter->resetNumIters();
795 outputTest_->resetNumCalls();
798 Teuchos::RCP<MV> R_0 = MVT::CloneViewNonConst( *(Teuchos::rcp_const_cast<MV>(problem_->getInitResVec())), currIdx );
801 block_cg_iter->initializeCG(state_, R_0);
808 block_cg_iter->iterate();
815 if ( convTest_->getStatus() ==
Passed ) {
822 if (convIdx.size() == currRHSIdx.size())
826 problem_->setCurrLS();
830 for (
unsigned int i=0; i<currRHSIdx.size(); ++i) {
832 for (
unsigned int j=0; j<convIdx.size(); ++j) {
833 if (currRHSIdx[i] == convIdx[j]) {
839 currIdx2[have] = currIdx2[i];
840 currRHSIdx[have++] = currRHSIdx[i];
843 currRHSIdx.resize(have);
844 currIdx2.resize(have);
847 if (currRHSIdx[0] != 0 && genCondEst_ && !condEstPerf)
850 ScalarType l_min, l_max;
853 compute_condnum_tridiag_sym(diag,offdiag,eigenEstimates_,l_min,l_max,condEstimate_);
856 block_cg_iter->setDoCondEst(
false);
861 problem_->setLSIndex( currRHSIdx );
864 std::vector<MagnitudeType> norms;
865 R_0 = MVT::CloneCopy( *(block_cg_iter->getNativeResiduals(&norms)),currIdx2 );
866 for (
int i=0; i<have; ++i) { currIdx2[i] = i; }
869 block_cg_iter->initializeCG(state_, R_0);
877 else if ( maxIterTest_->getStatus() ==
Passed ) {
892 "Belos::PseudoBlockCGSolMgr::solve(): Invalid return from PseudoBlockCGIter::iterate().");
897 achievedTol_ = MT::one();
899 MVT::MvInit( *X, SCT::zero() );
900 printer_->stream(
Warnings) <<
"Belos::PseudoBlockCGSolMgr::solve(): Warning! NaN has been detected!"
904 catch (
const std::exception &e) {
905 printer_->stream(
Errors) <<
"Error! Caught std::exception in PseudoBlockCGIter::iterate() at iteration "
906 << block_cg_iter->getNumIters() << std::endl
907 << e.what() << std::endl;
913 problem_->setCurrLS();
916 startPtr += numCurrRHS;
917 numRHS2Solve -= numCurrRHS;
919 if ( numRHS2Solve > 0 ) {
921 numCurrRHS = numRHS2Solve;
922 currIdx.resize( numCurrRHS );
923 currIdx2.resize( numCurrRHS );
924 for (
int i=0; i<numCurrRHS; ++i)
925 { currIdx[i] = startPtr+i; currIdx2[i] = i; }
928 problem_->setLSIndex( currIdx );
931 currIdx.resize( numRHS2Solve );
942 #ifdef BELOS_TEUCHOS_TIME_MONITOR
951 numIters_ = maxIterTest_->getNumIters();
955 const std::vector<MagnitudeType>* pTestValues = convTest_->getTestValue();
956 if (pTestValues != NULL && pTestValues->size () > 0) {
957 achievedTol_ = *std::max_element (pTestValues->begin(), pTestValues->end());
961 if (genCondEst_ && !condEstPerf) {
962 ScalarType l_min, l_max;
965 compute_condnum_tridiag_sym(diag,offdiag,eigenEstimates_,l_min,l_max,condEstimate_);
976 template<
class ScalarType,
class MV,
class OP>
979 std::ostringstream oss;
987 template<
class ScalarType,
class MV,
class OP>
993 ScalarType & lambda_min,
994 ScalarType & lambda_max,
995 ScalarType & ConditionNumber )
1006 const int N = diag.
size ();
1007 ScalarType scalar_dummy;
1008 std::vector<MagnitudeType> mag_dummy(4*N);
1013 lambda_min = STS::one ();
1014 lambda_max = STS::one ();
1017 &scalar_dummy, 1, &mag_dummy[0], &info);
1019 (info < 0, std::logic_error,
"Belos::PseudoBlockCGSolMgr::"
1020 "compute_condnum_tridiag_sym: LAPACK's _PTEQR failed with info = "
1021 << info <<
" < 0. This suggests there might be a bug in the way Belos "
1022 "is calling LAPACK. Please report this to the Belos developers.");
1023 for (
int k = 0; k < N; k++) {
1024 lambdas[k] = diag[N - 1 - k];
1026 lambda_min = Teuchos::as<ScalarType> (diag[N-1]);
1027 lambda_max = Teuchos::as<ScalarType> (diag[0]);
1034 if (STS::real (lambda_max) < STS::real (lambda_min)) {
1035 ConditionNumber = STS::one ();
1039 ConditionNumber = lambda_max / lambda_min;
ScaleType convertStringToScaleType(const std::string &scaleType)
Convert the given string to its ScaleType enum value.
Collection of types and exceptions used within the Belos solvers.
Belos's basic output manager for sending information of select verbosity levels to the appropriate ou...
Class which manages the output and verbosity of the Belos solvers.
bool is_null(const boost::shared_ptr< T > &p)
ScaleType
The type of scaling to use on the residual norm value.
PseudoBlockCGSolMgr(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &problem, const Teuchos::RCP< Teuchos::ParameterList > &pl)
This class implements the preconditioned Conjugate Gradient (CG) iteration.
Pure virtual base class which augments the basic interface for a conjugate gradient linear solver ite...
T & get(const std::string &name, T def_value)
Belos concrete class for performing the conjugate-gradient (CG) iteration.
bool is_null(const std::shared_ptr< T > &p)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
A factory class for generating StatusTestOutput objects.
PseudoBlockCGSolMgrLinearProblemFailure is thrown when the linear problem is not setup (i...
An implementation of StatusTestResNorm using a family of residual norms.
ScalarType getConditionEstimate() const
Gets the estimated condition number.
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
void PTEQR(const char &COMPZ, const OrdinalType &n, MagnitudeType *D, MagnitudeType *E, ScalarType *Z, const OrdinalType &ldz, MagnitudeType *WORK, OrdinalType *info) const
static const double convTol
Default convergence tolerance.
Belos::StatusTest class for specifying a maximum number of iterations.
static std::string name()
Teuchos::RCP< const Teuchos::ParameterList > getCurrentParameters() const override
Get a parameter list containing the current parameters for this object.
A factory class for generating StatusTestOutput objects.
const LinearProblem< ScalarType, MV, OP > & getProblem() const override
Return a reference to the linear problem being solved by this solver manager.
Traits class which defines basic operations on multivectors.
The Belos::PseudoBlockCGSolMgr provides a powerful and fully-featured solver manager over the pseudo-...
Belos::StatusTest for logically combining several status tests.
void resize(const size_type n, const T &val=T())
bool isParameter(const std::string &name) const
This class implements the pseudo-block CG iteration, where the basic CG algorithm is performed on all...
A Belos::StatusTest class for specifying a maximum number of iterations.
Structure to contain pointers to PseudoBlockCGIteration state variables.
ResetType
How to reset the solver.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Pure virtual base class which describes the basic interface for a solver manager. ...
static void summarize(Ptr< const Comm< int > > comm, std::ostream &out=std::cout, const bool alwaysWriteLocal=false, const bool writeGlobalStats=true, const bool writeZeroTimers=true, const ECounterSetOp setOp=Intersection, const std::string &filter="", const bool ignoreZeroTimers=false)
Teuchos::ArrayRCP< MagnitudeType > getEigenEstimates() const
Teuchos::RCP< StatusTestGenResNorm< ScalarType, MV, OP > > getResidualStatusTest() const
Return the residual status test.
A linear system to solve, and its associated information.
Teuchos::Array< Teuchos::RCP< Teuchos::Time > > getTimers() const
Return the timers for this object.
Class which describes the linear problem to be solved by the iterative solver.
bool isLOADetected() const override
Return whether a loss of accuracy was detected by this solver during the most current solve...
Teuchos::RCP< SolverManager< ScalarType, MV, OP > > clone() const override
clone for Inverted Injection (DII)
int getNumIters() const override
Get the iteration count for the most recent call to solve().
Type traits class that says whether Teuchos::LAPACK has a valid implementation for the given ScalarTy...
void setProblem(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &problem) override
Set the linear problem that needs to be solved.
ReturnType
Whether the Belos solve converged for all linear systems.
void validateParameters(ParameterList const &validParamList, int const depth=1000, EValidateUsed const validateUsed=VALIDATE_USED_ENABLED, EValidateDefaults const validateDefaults=VALIDATE_DEFAULTS_ENABLED) const
Teuchos::RCP< StatusTestOutput< ScalarType, MV, OP > > create(const Teuchos::RCP< OutputManager< ScalarType > > &printer, Teuchos::RCP< StatusTest< ScalarType, MV, OP > > test, int mod, int printStates)
Create the StatusTestOutput object specified by the outputStyle.
PseudoBlockCGSolMgrLinearProblemFailure(const std::string &what_arg)
Structure to contain pointers to CGIteration state variables.
Belos::StatusTestResNorm for specifying general residual norm stopping criteria.
void reset(const ResetType type) override
Performs a reset of the solver manager specified by the ResetType. This informs the solver manager th...
bool isType(const std::string &name) const
A class for extending the status testing capabilities of Belos via logical combinations.
virtual ~PseudoBlockCGSolMgr()=default
Class which defines basic traits for the operator type.
Belos concrete class for performing the pseudo-block CG iteration.
Parent class to all Belos exceptions.
Default parameters common to most Belos solvers.
Base class for Belos::SolverManager subclasses which normally can only compile with ScalarType types ...
Belos header file which uses auto-configuration information to include necessary C++ headers...
MagnitudeType achievedTol() const override
Tolerance achieved by the last solve() invocation.
Teuchos::RCP< StatusTestGenResNorm< ScalarType, MV, OP > > getResidualStatusTest() const