Ifpack2 Templated Preconditioning Package  Version 1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Ifpack2_Details_FastILU_Base_def.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Ifpack2: Templated Object-Oriented Algebraic Preconditioner Package
4 //
5 // Copyright 2009 NTESS and the Ifpack2 contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
11 
12 #ifndef __IFPACK2_FASTILU_BASE_DEF_HPP__
13 #define __IFPACK2_FASTILU_BASE_DEF_HPP__
14 
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 <stdexcept>
23 
24 namespace Ifpack2 {
25 namespace Details {
26 
27 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
30  : mat_(A)
31  , initFlag_(false)
32  , computedFlag_(false)
33  , nInit_(0)
34  , nComputed_(0)
35  , nApply_(0)
36  , initTime_(0.0)
37  , computeTime_(0.0)
38  , applyTime_(0.0)
39  , crsCopyTime_(0.0)
40  , params_(Params::getDefaults()) {}
41 
42 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
45  getDomainMap() const {
46  return mat_->getDomainMap();
47 }
48 
49 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
52  getRangeMap() const {
53  return mat_->getRangeMap();
54 }
55 
56 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
58  apply(const Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& X,
59  Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Y,
60  Teuchos::ETransp mode,
61  Scalar alpha,
62  Scalar beta) const {
63  const std::string timerName("Ifpack2::FastILU::apply");
65  if (timer.is_null()) {
66  timer = Teuchos::TimeMonitor::getNewCounter(timerName);
67  }
68  Teuchos::TimeMonitor timeMon(*timer);
69 
70  if (!isInitialized() || !isComputed()) {
71  throw std::runtime_error(std::string("Called ") + getName() + "::apply() without first calling initialize() and/or compute().");
72  }
73  if (X.getNumVectors() != Y.getNumVectors()) {
74  throw std::invalid_argument(getName() + "::apply: X and Y have different numbers of vectors (pass X and Y with exactly matching dimensions)");
75  }
76  if (X.getLocalLength() != Y.getLocalLength()) {
77  throw std::invalid_argument(getName() + "::apply: X and Y have different lengths (pass X and Y with exactly matching dimensions)");
78  }
79  // zero out applyTime_ now, because the calls to applyLocalPrec() will add to it
80  applyTime_ = 0;
81  int nvecs = X.getNumVectors();
82  auto nrowsX = X.getLocalLength();
83  auto nrowsY = Y.getLocalLength();
84  if (nvecs == 1) {
85  auto x2d = X.getLocalViewDevice(Tpetra::Access::ReadOnly);
86  auto y2d = Y.getLocalViewDevice(Tpetra::Access::ReadWrite);
87  ImplScalarArray x1d(const_cast<ImplScalar*>(x2d.data()), nrowsX);
88  ImplScalarArray y1d(const_cast<ImplScalar*>(y2d.data()), nrowsY);
89 
90  applyLocalPrec(x1d, y1d);
91  } else {
92  // Solve each vector one at a time (until FastILU supports multiple RHS)
93  auto x2d = X.getLocalViewDevice(Tpetra::Access::ReadOnly);
94  auto y2d = Y.getLocalViewDevice(Tpetra::Access::ReadWrite);
95  for (int i = 0; i < nvecs; i++) {
96  auto xColView1d = Kokkos::subview(x2d, Kokkos::ALL(), i);
97  auto yColView1d = Kokkos::subview(y2d, Kokkos::ALL(), i);
98  ImplScalarArray x1d(const_cast<ImplScalar*>(xColView1d.data()), nrowsX);
99  ImplScalarArray y1d(const_cast<ImplScalar*>(yColView1d.data()), nrowsY);
100 
101  applyLocalPrec(x1d, y1d);
102  }
103  }
104 }
105 
106 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
109  // Params constructor does all parameter validation, and sets default values
110  params_ = Params(List, getName());
111 }
112 
113 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
115  isBlockCrs() const {
116  return params_.blockCrs && params_.blockCrsSize > 1;
117 }
118 
119 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
122  const std::string timerName("Ifpack2::FastILU::initialize");
124  if (timer.is_null()) {
125  timer = Teuchos::TimeMonitor::getNewCounter(timerName);
126  }
127  Teuchos::TimeMonitor timeMon(*timer);
128 
129  if (mat_.is_null()) {
130  throw std::runtime_error(std::string("Called ") + getName() + "::initialize() but matrix was null (call setMatrix() with a non-null matrix first)");
131  }
132 
133  if (isBlockCrs()) {
134  auto crs_matrix = Ifpack2::Details::getCrsMatrix(this->mat_);
135 
136  if (params_.fillBlocks) {
137  // Create new TCrsMatrix with the new filled data and conver to Bcrs
138  auto crs_matrix_block_filled = Tpetra::fillLogicalBlocks(*crs_matrix, params_.blockCrsSize);
139  auto bcrs_matrix = Tpetra::convertToBlockCrsMatrix(*crs_matrix_block_filled, params_.blockCrsSize);
140  mat_ = bcrs_matrix;
141  } else {
142  // Assume input is already filled, just convert to Bcrs
143  auto bcrs_matrix = Tpetra::convertToBlockCrsMatrix(*crs_matrix, params_.blockCrsSize);
144  mat_ = bcrs_matrix;
145  }
146  }
147 
148  Kokkos::Timer copyTimer;
149  CrsArrayReader<Scalar, ImplScalar, LocalOrdinal, GlobalOrdinal, Node>::getStructure(mat_.get(), localRowPtrsHost_, localRowPtrs_, localColInds_);
150  CrsArrayReader<Scalar, ImplScalar, LocalOrdinal, GlobalOrdinal, Node>::getValues(mat_.get(), localValues_, localRowPtrsHost_);
151  crsCopyTime_ = copyTimer.seconds();
152 
153  if (params_.use_metis) {
154  assert(!params_.blockCrs);
155  const std::string timerNameMetis("Ifpack2::FastILU::Metis");
157  if (timerMetis.is_null()) {
158  timerMetis = Teuchos::TimeMonitor::getNewCounter(timerNameMetis);
159  }
160  Teuchos::TimeMonitor timeMonMetis(*timerMetis);
161 #ifdef HAVE_IFPACK2_METIS
162  idx_t nrows = localRowPtrsHost_.size() - 1;
163  if (nrows > 0) {
164  // reorder will convert both graph and perm/iperm to the internal METIS integer type
165  metis_perm_ = MetisArrayHost(Kokkos::ViewAllocateWithoutInitializing("metis_perm"), nrows);
166  metis_iperm_ = MetisArrayHost(Kokkos::ViewAllocateWithoutInitializing("metis_iperm"), nrows);
167 
168  // copy ColInds to host
169  auto localColIndsHost_ = Kokkos::create_mirror_view(localColInds_);
170  Kokkos::deep_copy(localColIndsHost_, localColInds_);
171 
172  // prepare for calling metis
173  idx_t nnz = localColIndsHost_.size();
174  MetisArrayHost metis_rowptr;
175  MetisArrayHost metis_colidx;
176 
177  bool metis_symmetrize = true;
178  if (metis_symmetrize) {
179  // symmetrize
180  using OrdinalArrayMirror = typename OrdinalArray::host_mirror_type;
181  KokkosKernels::Impl::symmetrize_graph_symbolic_hashmap<
182  OrdinalArrayHost, OrdinalArrayMirror, MetisArrayHost, MetisArrayHost, Kokkos::HostSpace::execution_space>(nrows, localRowPtrsHost_, localColIndsHost_, metis_rowptr, metis_colidx);
183 
184  // remove diagonals
185  idx_t old_nnz = nnz = 0;
186  for (idx_t i = 0; i < nrows; i++) {
187  for (LocalOrdinal k = old_nnz; k < metis_rowptr(i + 1); k++) {
188  if (metis_colidx(k) != i) {
189  metis_colidx(nnz) = metis_colidx(k);
190  nnz++;
191  }
192  }
193  old_nnz = metis_rowptr(i + 1);
194  metis_rowptr(i + 1) = nnz;
195  }
196  } else {
197  // copy and remove diagonals
198  metis_rowptr = MetisArrayHost(Kokkos::ViewAllocateWithoutInitializing("metis_rowptr"), nrows + 1);
199  metis_colidx = MetisArrayHost(Kokkos::ViewAllocateWithoutInitializing("metis_colidx"), nnz);
200  nnz = 0;
201  metis_rowptr(0) = 0;
202  for (idx_t i = 0; i < nrows; i++) {
203  for (LocalOrdinal k = localRowPtrsHost_(i); k < localRowPtrsHost_(i + 1); k++) {
204  if (localColIndsHost_(k) != i) {
205  metis_colidx(nnz) = localColIndsHost_(k);
206  nnz++;
207  }
208  }
209  metis_rowptr(i + 1) = nnz;
210  }
211  }
212 
213  // call metis
214  int info = METIS_NodeND(&nrows, metis_rowptr.data(), metis_colidx.data(),
215  NULL, NULL, metis_perm_.data(), metis_iperm_.data());
216  if (METIS_OK != info) {
217  throw std::runtime_error(std::string("METIS_NodeND returned info = " + info));
218  }
219  }
220 #else
221  throw std::runtime_error(std::string("TPL METIS is not enabled"));
222 #endif
223  }
224 
225  initLocalPrec(); // note: initLocalPrec updates initTime
226  initFlag_ = true;
227  nInit_++;
228 }
229 
230 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
232  isInitialized() const {
233  return initFlag_;
234 }
235 
236 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
239  if (!initFlag_) {
240  throw std::runtime_error(getName() + ": initialize() must be called before compute()");
241  }
242 
243  const std::string timerName("Ifpack2::FastILU::compute");
245  if (timer.is_null()) {
246  timer = Teuchos::TimeMonitor::getNewCounter(timerName);
247  }
248  Teuchos::TimeMonitor timeMon(*timer);
249 
250  // get copy of values array from matrix
251  Kokkos::Timer copyTimer;
252  CrsArrayReader<Scalar, ImplScalar, LocalOrdinal, GlobalOrdinal, Node>::getValues(mat_.get(), localValues_, localRowPtrsHost_);
253  crsCopyTime_ += copyTimer.seconds(); // add to the time spent getting rowptrs/colinds
254  computeLocalPrec(); // this updates computeTime_
255  computedFlag_ = true;
256  nComputed_++;
257 }
258 
259 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
261  isComputed() const {
262  return computedFlag_;
263 }
264 
265 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
268  getMatrix() const {
269  return mat_;
270 }
271 
272 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
275  return nInit_;
276 }
277 
278 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
280  getNumCompute() const {
281  return nComputed_;
282 }
283 
284 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
286  getNumApply() const {
287  return nApply_;
288 }
289 
290 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
293  return initTime_;
294 }
295 
296 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
299  return computeTime_;
300 }
301 
302 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
304  getApplyTime() const {
305  return applyTime_;
306 }
307 
308 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
310  getCopyTime() const {
311  return crsCopyTime_;
312 }
313 
314 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
316  checkLocalILU() const {
317  // if the underlying type of this doesn't implement checkLocalILU, it's an illegal operation
318  throw std::runtime_error(std::string("Preconditioner type Ifpack2::Details::") + getName() + " doesn't support checkLocalILU().");
319 }
320 
321 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
323  checkLocalIC() const {
324  // if the underlying type of this doesn't implement checkLocalIC, it's an illegal operation
325  throw std::runtime_error(std::string("Preconditioner type Ifpack2::Details::") + getName() + " doesn't support checkLocalIC().");
326 }
327 
328 template <typename Scalar, typename LocalOrdinal, typename GlobalOrdinal, typename Node>
330  std::ostringstream os;
331  // Output is a YAML dictionary
332  os << "\"Ifpack2::Details::" << getName() << "\": {";
333  os << "Initialized: " << (isInitialized() ? "true" : "false") << ", ";
334  os << "Computed: " << (isComputed() ? "true" : "false") << ", ";
335  os << "Sweeps: " << getSweeps() << ", ";
336  os << "Triangular solve type: " << getSpTrsvType() << ", ";
337  if (getSpTrsvType() == "Fast") {
338  os << "# of triangular solve iterations: " << getNTrisol() << ", ";
339  }
340  if (mat_.is_null()) {
341  os << "Matrix: null";
342  } else {
343  os << "Global matrix dimensions: [" << mat_->getGlobalNumRows() << ", " << mat_->getGlobalNumCols() << "]";
344  os << ", Global nnz: " << mat_->getGlobalNumEntries();
345  }
346  return os.str();
347 }
348 
349 template <typename Scalar, typename LocalOrdinal, typename GlobalOrdinal, typename Node>
352  if (A.is_null()) {
353  throw std::invalid_argument(std::string("Ifpack2::Details::") + getName() + "::setMatrix() called with a null matrix. Pass a non-null matrix.");
354  }
355  // bmk note: this modeled after RILUK::setMatrix
356  if (mat_.get() != A.get()) {
357  mat_ = A;
358  initFlag_ = false;
359  computedFlag_ = false;
360  }
361 }
362 
363 template <typename Scalar, typename LocalOrdinal, typename GlobalOrdinal, typename Node>
367  Params p;
368  p.use_metis = false;
369  p.sptrsv_algo = FastILU::SpTRSV::Fast;
370  p.nFact = 5; // # of sweeps for computing fastILU
371  p.nTrisol = 5; // # of sweeps for applying fastSpTRSV
372  p.level = 0; // level of ILU
373  p.omega = 1.0; // damping factor for fastILU
374  p.shift = 0;
375  p.guessFlag = true;
376  p.blockSizeILU = 1; // # of nonzeros / thread, for fastILU
377  p.blockSize = 1; // # of rows / thread, for SpTRSV
378  p.blockCrs = false; // whether to use block CRS for fastILU
379  p.blockCrsSize = 1; // block size for block CRS
380  p.fillBlocks = false; // whether input matrix needs to be filled
381  return p;
382 }
383 
384 template <typename Scalar, typename LocalOrdinal, typename GlobalOrdinal, typename Node>
385 FastILU_Base<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
386  Params::Params(const Teuchos::ParameterList& pL, std::string precType) {
387  *this = getDefaults();
388 // For each parameter, check that if the parameter exists, it has the right type
389 // Then get the value and sanity check it
390 // If the parameter doesn't exist, leave it as default (from Params::getDefaults())
391 //"sweeps" aka nFact
392 #define TYPE_ERROR(name, correctTypeName) \
393  { throw std::invalid_argument(precType + "::setParameters(): parameter \"" + name + "\" has the wrong type (must be " + correctTypeName + ")"); }
394 #define CHECK_VALUE(param, member, cond, msg) \
395  { \
396  if (cond) { \
397  throw std::invalid_argument(precType + "::setParameters(): parameter \"" + param + "\" has value " + std::to_string(member) + " but " + msg); \
398  } \
399  }
400 
401  // metis
402  if (pL.isParameter("metis")) {
403  if (pL.isType<bool>("metis"))
404  use_metis = pL.get<bool>("metis");
405  else
406  TYPE_ERROR("metis", "bool");
407  }
408 
409  if (pL.isParameter("sweeps")) {
410  if (pL.isType<int>("sweeps")) {
411  nFact = pL.get<int>("sweeps");
412  CHECK_VALUE("sweeps", nFact, nFact < 1, "must have a value of at least 1");
413  } else
414  TYPE_ERROR("sweeps", "int");
415  }
416  std::string sptrsv_type = "Fast";
417  if (pL.isParameter("triangular solve type")) {
418  sptrsv_type = pL.get<std::string>("triangular solve type");
419  }
420  if (sptrsv_type == "Standard Host") {
421  sptrsv_algo = FastILU::SpTRSV::StandardHost;
422  } else if (sptrsv_type == "Standard") {
423  sptrsv_algo = FastILU::SpTRSV::Standard;
424  }
425 
426  //"triangular solve iterations" aka nTrisol
427  if (pL.isParameter("triangular solve iterations")) {
428  if (pL.isType<int>("triangular solve iterations")) {
429  nTrisol = pL.get<int>("triangular solve iterations");
430  CHECK_VALUE("triangular solve iterations", nTrisol, nTrisol < 1, "must have a value of at least 1");
431  } else
432  TYPE_ERROR("triangular solve iterations", "int");
433  }
434  //"level"
435  if (pL.isParameter("level")) {
436  if (pL.isType<int>("level")) {
437  level = pL.get<int>("level");
438  } else if (pL.isType<double>("level")) {
439  // Level can be read as double (like in ILUT), but must be an exact integer
440  // Any integer used for level-of-fill can be represented exactly in double (so use exact compare)
441  double dval = pL.get<double>("level");
442  double ipart;
443  double fpart = modf(dval, &ipart);
444  level = ipart;
445  CHECK_VALUE("level", level, fpart != 0, "must be an integral value");
446  } else {
447  TYPE_ERROR("level", "int");
448  }
449  CHECK_VALUE("level", level, level < 0, "must be nonnegative");
450  }
451  if (pL.isParameter("damping factor")) {
452  if (pL.isType<double>("damping factor"))
453  omega = pL.get<double>("damping factor");
454  else
455  TYPE_ERROR("damping factor", "double");
456  }
457  if (pL.isParameter("shift")) {
458  if (pL.isType<double>("shift"))
459  shift = pL.get<double>("shift");
460  else
461  TYPE_ERROR("shift", "double");
462  }
463  //"guess" aka guessFlag
464  if (pL.isParameter("guess")) {
465  if (pL.isType<bool>("guess"))
466  guessFlag = pL.get<bool>("guess");
467  else
468  TYPE_ERROR("guess", "bool");
469  }
470  //"block size" aka blkSz
471  if (pL.isParameter("block size for ILU")) {
472  if (pL.isType<int>("block size for ILU")) {
473  blockSizeILU = pL.get<int>("block size for ILU");
474  CHECK_VALUE("block size for ILU", blockSizeILU, blockSizeILU < 1, "must have a value of at least 1");
475  } else
476  TYPE_ERROR("block size for ILU", "int");
477  }
478  //"block size" aka blkSz
479  if (pL.isParameter("block size for SpTRSV")) {
480  if (pL.isType<int>("block size for SpTRSV"))
481  blockSize = pL.get<int>("block size for SpTRSV");
482  else
483  TYPE_ERROR("block size for SpTRSV", "int");
484  }
485  //"block crs" aka blockCrs
486  if (pL.isParameter("block crs")) {
487  if (pL.isType<bool>("block crs"))
488  blockCrs = pL.get<bool>("block crs");
489  else
490  TYPE_ERROR("block crs", "bool");
491  }
492  //"block crs block size" aka blockCrsSize
493  if (pL.isParameter("block crs block size")) {
494  if (pL.isType<int>("block crs block size"))
495  blockCrsSize = pL.get<int>("block crs block size");
496  else
497  TYPE_ERROR("block crs block size", "int");
498  }
499  //"fill blocks for input" aka fillBlocks
500  if (pL.isParameter("fill blocks for input")) {
501  if (pL.isType<bool>("fill blocks for input"))
502  blockCrsSize = pL.get<bool>("fill blocks for input");
503  else
504  TYPE_ERROR("fill blocks for input", "bool");
505  }
506 
507 #undef CHECK_VALUE
508 #undef TYPE_ERROR
509 }
510 
511 #define IFPACK2_DETAILS_FASTILU_BASE_INSTANT(S, L, G, N) \
512  template class Ifpack2::Details::FastILU_Base<S, L, G, N>;
513 
514 } // namespace Details
515 } // namespace Ifpack2
516 
517 #endif
int getNumCompute() const
Get the number of times compute() was called.
Definition: Ifpack2_Details_FastILU_Base_def.hpp:280
virtual void checkLocalIC() const
Verify and print debug information about the underlying IC preconditioner.
Definition: Ifpack2_Details_FastILU_Base_def.hpp:323
double getComputeTime() const
Get the time spent in the last compute() call.
Definition: Ifpack2_Details_FastILU_Base_def.hpp:298
T & get(const std::string &name, T def_value)
static RCP< Time > getNewCounter(const std::string &name)
static RCP< Time > lookupCounter(const std::string &name)
double getCopyTime() const
Get the time spent deep copying local 3-array CRS out of the matrix.
Definition: Ifpack2_Details_FastILU_Base_def.hpp:310
T * get() const
double getInitializeTime() const
Get the time spent in the last initialize() call.
Definition: Ifpack2_Details_FastILU_Base_def.hpp:292
Teuchos::RCP< const Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > getRangeMap() const
Get the range map of the matrix.
Definition: Ifpack2_Details_FastILU_Base_def.hpp:52
double getApplyTime() const
Get the time spent in the last apply() call.
Definition: Ifpack2_Details_FastILU_Base_def.hpp:304
Teuchos::RCP< const Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > getDomainMap() const
Get the domain map of the matrix.
Definition: Ifpack2_Details_FastILU_Base_def.hpp:45
bool isParameter(const std::string &name) const
Teuchos::RCP< const TRowMatrix > getMatrix() const
Get the current matrix.
Definition: Ifpack2_Details_FastILU_Base_def.hpp:268
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:316
int getNumApply() const
Get the number of times apply() was called.
Definition: Ifpack2_Details_FastILU_Base_def.hpp:286
The base class of the Ifpack2 FastILU wrappers (Filu, Fildl and Fic)
Definition: Ifpack2_Details_FastILU_Base_decl.hpp:36
void setParameters(const Teuchos::ParameterList &List)
Validate parameters, and set defaults when parameters are not provided.
Definition: Ifpack2_Details_FastILU_Base_def.hpp:108
std::string description() const
Return a brief description of the preconditioner, in YAML format.
Definition: Ifpack2_Details_FastILU_Base_def.hpp:329
void compute()
Compute the preconditioner.
Definition: Ifpack2_Details_FastILU_Base_def.hpp:238
FastILU_Base(Teuchos::RCP< const TRowMatrix > mat_)
Constructor.
Definition: Ifpack2_Details_FastILU_Base_def.hpp:29
bool isComputed() const
Whether compute() has been called since the last time the matrix&#39;s values or structure were changed...
Definition: Ifpack2_Details_FastILU_Base_def.hpp:261
bool isInitialized() const
Whether initialize() has been called since the last time the matrix&#39;s structure was changed...
Definition: Ifpack2_Details_FastILU_Base_def.hpp:232
void initialize()
Initialize the preconditioner.
Definition: Ifpack2_Details_FastILU_Base_def.hpp:121
bool isType(const std::string &name) const
void setMatrix(const Teuchos::RCP< const TRowMatrix > &A)
Definition: Ifpack2_Details_FastILU_Base_def.hpp:351
Kokkos::View< ImplScalar *, execution_space > ImplScalarArray
Array of Scalar on device.
Definition: Ifpack2_Details_FastILU_Base_decl.hpp:59
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:58
int getNumInitialize() const
Get the number of times initialize() was called.
Definition: Ifpack2_Details_FastILU_Base_def.hpp:274
Kokkos::View< LocalOrdinal *, execution_space >::HostMirror OrdinalArrayHost
Array of LocalOrdinal on host.
Definition: Ifpack2_Details_FastILU_Base_decl.hpp:57
Provides functions for retrieving local CRS arrays (row pointers, column indices, and values) from Tp...
bool is_null() const