12#ifndef __IFPACK2_FASTILU_BASE_DEF_HPP__
13#define __IFPACK2_FASTILU_BASE_DEF_HPP__
16#include "Tpetra_BlockCrsMatrix.hpp"
17#include "Tpetra_BlockCrsMatrix_Helpers.hpp"
18#include "Ifpack2_Details_getCrsMatrix.hpp"
19#include <KokkosKernels_Utils.hpp>
20#include <Kokkos_Timer.hpp>
21#include <Teuchos_TimeMonitor.hpp>
22#include <Teuchos_Array.hpp>
28template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
33 , computedFlag_(
false)
37 , localCrs_(Teuchos::
null)
38 , localCrsNonConst_(Teuchos::
null)
39 , localCrsIsOwnedCopy_(
false)
44 , params_(Params::getDefaults()) {}
46template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
47Teuchos::RCP<const Tpetra::Map<LocalOrdinal, GlobalOrdinal, Node> >
50 return mat_->getDomainMap();
53template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
54Teuchos::RCP<const Tpetra::Map<LocalOrdinal, GlobalOrdinal, Node> >
57 return mat_->getRangeMap();
60template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
62 apply(
const Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& X,
63 Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Y,
67 const std::string
timerName(
"Ifpack2::FastILU::apply");
68 Teuchos::RCP<Teuchos::Time>
timer = Teuchos::TimeMonitor::lookupCounter(
timerName);
69 if (
timer.is_null()) {
74 if (!isInitialized() || !isComputed()) {
75 throw std::runtime_error(std::string(
"Called ") + getName() +
"::apply() without first calling initialize() and/or compute().");
77 if (X.getNumVectors() != Y.getNumVectors()) {
78 throw std::invalid_argument(getName() +
"::apply: X and Y have different numbers of vectors (pass X and Y with exactly matching dimensions)");
80 if (X.getLocalLength() != Y.getLocalLength()) {
81 throw std::invalid_argument(getName() +
"::apply: X and Y have different lengths (pass X and Y with exactly matching dimensions)");
85 int nvecs = X.getNumVectors();
86 auto nrowsX = X.getLocalLength();
87 auto nrowsY = Y.getLocalLength();
89 auto x2d = X.getLocalViewDevice(Tpetra::Access::ReadOnly);
90 auto y2d = Y.getLocalViewDevice(Tpetra::Access::ReadWrite);
97 auto x2d = X.getLocalViewDevice(Tpetra::Access::ReadOnly);
98 auto y2d = Y.getLocalViewDevice(Tpetra::Access::ReadWrite);
110template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
114 params_ = Params(
List, getName());
117template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
120 return params_.blockCrs && params_.blockCrsSize > 1;
123template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
126 const std::string
timerName(
"Ifpack2::FastILU::initialize");
127 Teuchos::RCP<Teuchos::Time>
timer = Teuchos::TimeMonitor::lookupCounter(
timerName);
128 if (
timer.is_null()) {
133 if (mat_.is_null()) {
134 throw std::runtime_error(std::string(
"Called ") + getName() +
"::initialize() but matrix was null (call setMatrix() with a non-null matrix first)");
138 auto crs_matrix = Ifpack2::Details::getCrsMatrix(this->mat_);
140 if (params_.fillBlocks) {
159 localCrs_ = Teuchos::null;
160 localCrsNonConst_ = Teuchos::null;
161 localCrsIsOwnedCopy_ =
false;
165 localCrs_ = Ifpack2::Details::getCrsMatrix(mat_);
167 if (localCrs_.is_null()) {
168 const LocalOrdinal numRows =
static_cast<LocalOrdinal
>(mat_->getLocalNumRows());
170 for (LocalOrdinal
i = 0;
i < numRows; ++
i) {
176 using local_inds_host_view_type =
typename TRowMatrix::nonconst_local_inds_host_view_type;
177 using values_host_view_type =
typename TRowMatrix::nonconst_values_host_view_type;
179 const size_t maxNnz = mat_->getLocalMaxNumRowEntries();
180 local_inds_host_view_type
indices(
"FastILU local CRS indices",
maxNnz);
181 values_host_view_type values(
"FastILU local CRS values",
maxNnz);
183 for (LocalOrdinal
i = 0;
i < numRows; ++
i) {
186 localCrsNonConst_->insertLocalValues(
189 reinterpret_cast<Scalar*
>(values.data()),
193 localCrsNonConst_->fillComplete(mat_->getDomainMap(), mat_->getRangeMap());
194 localCrs_ = localCrsNonConst_;
195 localCrsIsOwnedCopy_ =
true;
202 CrsArrayReader<Scalar, ImplScalar, LocalOrdinal, GlobalOrdinal, Node>::getStructure(
207 CrsArrayReader<Scalar, ImplScalar, LocalOrdinal, GlobalOrdinal, Node>::getValues(
213 if (params_.use_metis) {
214 assert(!params_.blockCrs);
221#ifdef HAVE_IFPACK2_METIS
241 KokkosKernels::Impl::symmetrize_graph_symbolic_hashmap<
263 for (LocalOrdinal
k = localRowPtrsHost_(
i);
k < localRowPtrsHost_(
i + 1);
k++) {
277 throw std::runtime_error(std::string(
"METIS_NodeND returned info = ") + std::to_string(
info));
281 throw std::runtime_error(std::string(
"TPL METIS is not enabled"));
290template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
296template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
300 throw std::runtime_error(getName() +
": initialize() must be called before compute()");
303 const std::string
timerName(
"Ifpack2::FastILU::compute");
304 Teuchos::RCP<Teuchos::Time>
timer = Teuchos::TimeMonitor::lookupCounter(
timerName);
305 if (
timer.is_null()) {
314 if (!isBlockCrs() && !localCrs_.is_null()) {
315 if (localCrsIsOwnedCopy_) {
316 localCrsNonConst_->resumeFill();
318 using local_inds_host_view_type =
typename TRowMatrix::nonconst_local_inds_host_view_type;
319 using values_host_view_type =
typename TRowMatrix::nonconst_values_host_view_type;
321 const LocalOrdinal numRows =
static_cast<LocalOrdinal
>(mat_->getLocalNumRows());
322 const size_t maxNnz = mat_->getLocalMaxNumRowEntries();
323 local_inds_host_view_type
indices(
"FastILU refresh CRS indices",
maxNnz);
324 values_host_view_type values(
"FastILU refresh CRS values",
maxNnz);
326 for (LocalOrdinal
i = 0;
i < numRows; ++
i) {
329 localCrsNonConst_->replaceLocalValues(
332 reinterpret_cast<Scalar*
>(values.data()),
336 localCrsNonConst_->fillComplete(mat_->getDomainMap(), mat_->getRangeMap());
337 localCrs_ = localCrsNonConst_;
344 CrsArrayReader<Scalar, ImplScalar, LocalOrdinal, GlobalOrdinal, Node>::getValues(
350 computedFlag_ =
true;
354template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
357 return computedFlag_;
360template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
361Teuchos::RCP<const Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
367template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
373template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
379template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
385template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
391template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
397template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
403template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
409template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
413 throw std::runtime_error(std::string(
"Preconditioner type Ifpack2::Details::") + getName() +
" doesn't support checkLocalILU().");
416template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
420 throw std::runtime_error(std::string(
"Preconditioner type Ifpack2::Details::") + getName() +
" doesn't support checkLocalIC().");
423template <
typename Scalar,
typename LocalOrdinal,
typename GlobalOrdinal,
typename Node>
425 std::ostringstream
os;
427 os <<
"\"Ifpack2::Details::" << getName() <<
"\": {";
428 os <<
"Initialized: " << (isInitialized() ?
"true" :
"false") <<
", ";
429 os <<
"Computed: " << (isComputed() ?
"true" :
"false") <<
", ";
430 os <<
"Sweeps: " << getSweeps() <<
", ";
431 os <<
"Triangular solve type: " << getSpTrsvType() <<
", ";
432 if (getSpTrsvType() ==
"Fast") {
433 os <<
"# of triangular solve iterations: " << getNTrisol() <<
", ";
435 if (mat_.is_null()) {
436 os <<
"Matrix: null";
438 os <<
"Global matrix dimensions: [" << mat_->getGlobalNumRows() <<
", " << mat_->getGlobalNumCols() <<
"]";
439 os <<
", Global nnz: " << mat_->getGlobalNumEntries();
444template <
typename Scalar,
typename LocalOrdinal,
typename GlobalOrdinal,
typename Node>
446 setMatrix(
const Teuchos::RCP<const TRowMatrix>& A) {
448 throw std::invalid_argument(std::string(
"Ifpack2::Details::") + getName() +
"::setMatrix() called with a null matrix. Pass a non-null matrix.");
451 if (mat_.get() != A.get()) {
453 localCrs_ = Teuchos::null;
454 localCrsNonConst_ = Teuchos::null;
455 localCrsIsOwnedCopy_ =
false;
457 computedFlag_ =
false;
461template <
typename Scalar,
typename LocalOrdinal,
typename GlobalOrdinal,
typename Node>
467 p.sptrsv_algo = FastILU::SpTRSV::Fast;
478 p.fillBlocks =
false;
482template <
typename Scalar,
typename LocalOrdinal,
typename GlobalOrdinal,
typename Node>
483FastILU_Base<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
484 Params::Params(
const Teuchos::ParameterList& pL, std::string precType) {
485 *
this = getDefaults();
490#define TYPE_ERROR(name, correctTypeName) \
491 { throw std::invalid_argument(precType + "::setParameters(): parameter \"" + name + "\" has the wrong type (must be " + correctTypeName + ")"); }
492#define CHECK_VALUE(param, member, cond, msg) \
495 throw std::invalid_argument(precType + "::setParameters(): parameter \"" + param + "\" has value " + std::to_string(member) + " but " + msg); \
500 if (pL.isParameter(
"metis")) {
501 if (pL.isType<
bool>(
"metis"))
502 use_metis = pL.get<
bool>(
"metis");
504 TYPE_ERROR(
"metis",
"bool");
507 if (pL.isParameter(
"sweeps")) {
508 if (pL.isType<
int>(
"sweeps")) {
509 nFact = pL.get<
int>(
"sweeps");
510 CHECK_VALUE(
"sweeps", nFact, nFact < 1,
"must have a value of at least 1");
512 TYPE_ERROR(
"sweeps",
"int");
514 std::string sptrsv_type =
"Fast";
515 if (pL.isParameter(
"triangular solve type")) {
516 sptrsv_type = pL.get<std::string>(
"triangular solve type");
518 if (sptrsv_type ==
"Standard Host") {
519 sptrsv_algo = FastILU::SpTRSV::StandardHost;
520 }
else if (sptrsv_type ==
"Standard") {
521 sptrsv_algo = FastILU::SpTRSV::Standard;
525 if (pL.isParameter(
"triangular solve iterations")) {
526 if (pL.isType<
int>(
"triangular solve iterations")) {
527 nTrisol = pL.get<
int>(
"triangular solve iterations");
528 CHECK_VALUE(
"triangular solve iterations", nTrisol, nTrisol < 1,
"must have a value of at least 1");
530 TYPE_ERROR(
"triangular solve iterations",
"int");
533 if (pL.isParameter(
"level")) {
534 if (pL.isType<
int>(
"level")) {
535 level = pL.get<
int>(
"level");
536 }
else if (pL.isType<
double>(
"level")) {
539 double dval = pL.get<
double>(
"level");
541 double fpart = modf(dval, &ipart);
543 CHECK_VALUE(
"level", level, fpart != 0,
"must be an integral value");
545 TYPE_ERROR(
"level",
"int");
547 CHECK_VALUE(
"level", level, level < 0,
"must be nonnegative");
549 if (pL.isParameter(
"damping factor")) {
550 if (pL.isType<
double>(
"damping factor"))
551 omega = pL.get<
double>(
"damping factor");
553 TYPE_ERROR(
"damping factor",
"double");
555 if (pL.isParameter(
"shift")) {
556 if (pL.isType<
double>(
"shift"))
557 shift = pL.get<
double>(
"shift");
559 TYPE_ERROR(
"shift",
"double");
562 if (pL.isParameter(
"guess")) {
563 if (pL.isType<
bool>(
"guess"))
564 guessFlag = pL.get<
bool>(
"guess");
566 TYPE_ERROR(
"guess",
"bool");
569 if (pL.isParameter(
"block size for ILU")) {
570 if (pL.isType<
int>(
"block size for ILU")) {
571 blockSizeILU = pL.get<
int>(
"block size for ILU");
572 CHECK_VALUE(
"block size for ILU", blockSizeILU, blockSizeILU < 1,
"must have a value of at least 1");
574 TYPE_ERROR(
"block size for ILU",
"int");
577 if (pL.isParameter(
"block size for SpTRSV")) {
578 if (pL.isType<
int>(
"block size for SpTRSV"))
579 blockSize = pL.get<
int>(
"block size for SpTRSV");
581 TYPE_ERROR(
"block size for SpTRSV",
"int");
584 if (pL.isParameter(
"block crs")) {
585 if (pL.isType<
bool>(
"block crs"))
586 blockCrs = pL.get<
bool>(
"block crs");
588 TYPE_ERROR(
"block crs",
"bool");
591 if (pL.isParameter(
"block crs block size")) {
592 if (pL.isType<
int>(
"block crs block size"))
593 blockCrsSize = pL.get<
int>(
"block crs block size");
595 TYPE_ERROR(
"block crs block size",
"int");
598 if (pL.isParameter(
"fill blocks for input")) {
599 if (pL.isType<
bool>(
"fill blocks for input"))
600 blockCrsSize = pL.get<
bool>(
"fill blocks for input");
602 TYPE_ERROR(
"fill blocks for input",
"bool");
609#define IFPACK2_DETAILS_FASTILU_BASE_INSTANT(S, L, G, N) \
610 template class Ifpack2::Details::FastILU_Base<S, L, G, N>;
Provides functions for retrieving local CRS arrays (row pointers, column indices, and values) from Tp...
The base class of the Ifpack2 FastILU wrappers (Filu, Fildl and Fic)
Definition Ifpack2_Details_FastILU_Base_decl.hpp:38
Tpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node >::impl_scalar_type ImplScalar
Kokkos scalar type.
Definition Ifpack2_Details_FastILU_Base_decl.hpp:45
double getInitializeTime() const
Get the time spent in the last initialize() call.
Definition Ifpack2_Details_FastILU_Base_def.hpp:387
virtual void checkLocalILU() const
Verify and print debug information about the underlying ILU preconditioner (only supported if this is...
Definition Ifpack2_Details_FastILU_Base_def.hpp:411
void setMatrix(const Teuchos::RCP< const TRowMatrix > &A)
Definition Ifpack2_Details_FastILU_Base_def.hpp:446
void compute()
Compute the preconditioner.
Definition Ifpack2_Details_FastILU_Base_def.hpp:298
double getComputeTime() const
Get the time spent in the last compute() call.
Definition Ifpack2_Details_FastILU_Base_def.hpp:393
Tpetra::CrsMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > TCrsMatrix
Tpetra CRS matrix.
Definition Ifpack2_Details_FastILU_Base_decl.hpp:49
Tpetra::RowMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > TRowMatrix
Tpetra row matrix.
Definition Ifpack2_Details_FastILU_Base_decl.hpp:47
double getCopyTime() const
Get the time spent deep copying local 3-array CRS out of the matrix.
Definition Ifpack2_Details_FastILU_Base_def.hpp:405
int getNumApply() const
Get the number of times apply() was called.
Definition Ifpack2_Details_FastILU_Base_def.hpp:381
void initialize()
Initialize the preconditioner.
Definition Ifpack2_Details_FastILU_Base_def.hpp:125
bool isInitialized() const
Whether initialize() has been called since the last time the matrix's structure was changed.
Definition Ifpack2_Details_FastILU_Base_def.hpp:292
Kokkos::View< LocalOrdinal *, execution_space >::host_mirror_type OrdinalArrayHost
Array of LocalOrdinal on host.
Definition Ifpack2_Details_FastILU_Base_decl.hpp:57
FastILU_Base(Teuchos::RCP< const TRowMatrix > mat_)
Constructor.
Definition Ifpack2_Details_FastILU_Base_def.hpp:30
void setParameters(const Teuchos::ParameterList &List)
Validate parameters, and set defaults when parameters are not provided.
Definition Ifpack2_Details_FastILU_Base_def.hpp:112
void apply(const TMultiVec &X, TMultiVec &Y, Teuchos::ETransp mode=Teuchos::NO_TRANS, Scalar alpha=Teuchos::ScalarTraits< Scalar >::one(), Scalar beta=Teuchos::ScalarTraits< Scalar >::zero()) const
Apply the preconditioner.
Definition Ifpack2_Details_FastILU_Base_def.hpp:62
double getApplyTime() const
Get the time spent in the last apply() call.
Definition Ifpack2_Details_FastILU_Base_def.hpp:399
Teuchos::RCP< const Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > getDomainMap() const
Get the domain map of the matrix.
Definition Ifpack2_Details_FastILU_Base_def.hpp:49
virtual void checkLocalIC() const
Verify and print debug information about the underlying IC preconditioner.
Definition Ifpack2_Details_FastILU_Base_def.hpp:418
int getNumInitialize() const
Get the number of times initialize() was called.
Definition Ifpack2_Details_FastILU_Base_def.hpp:369
Teuchos::RCP< const Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > getRangeMap() const
Get the range map of the matrix.
Definition Ifpack2_Details_FastILU_Base_def.hpp:56
Teuchos::RCP< const TRowMatrix > getMatrix() const
Get the current matrix.
Definition Ifpack2_Details_FastILU_Base_def.hpp:363
std::string description() const
Return a brief description of the preconditioner, in YAML format.
Definition Ifpack2_Details_FastILU_Base_def.hpp:424
Kokkos::View< ImplScalar *, execution_space > ImplScalarArray
Array of Scalar on device.
Definition Ifpack2_Details_FastILU_Base_decl.hpp:59
int getNumCompute() const
Get the number of times compute() was called.
Definition Ifpack2_Details_FastILU_Base_def.hpp:375
bool isComputed() const
Whether compute() has been called since the last time the matrix's values or structure were changed.
Definition Ifpack2_Details_FastILU_Base_def.hpp:356
Ifpack2's implementation of Trilinos::Details::LinearSolver interface.
Definition Ifpack2_Details_LinearSolver_decl.hpp:75
Ifpack2 implementation details.
Preconditioners and smoothers for Tpetra sparse matrices.
Definition Ifpack2_AdditiveSchwarz_decl.hpp:40