Ifpack2 Templated Preconditioning Package  Version 1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Ifpack2_BlockTriDiContainer_def.hpp
1 /*@HEADER
2 // ***********************************************************************
3 //
4 // Ifpack2: Templated Object-Oriented Algebraic Preconditioner Package
5 // Copyright (2009) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 //@HEADER
41 */
42 
43 #ifndef IFPACK2_BLOCKTRIDICONTAINER_DEF_HPP
44 #define IFPACK2_BLOCKTRIDICONTAINER_DEF_HPP
45 
47 
48 #include <Tpetra_Distributor.hpp>
49 #include <Tpetra_BlockMultiVector.hpp>
50 
51 #include <Kokkos_ArithTraits.hpp>
52 #include <KokkosBatched_Util.hpp>
53 #include <KokkosBatched_Vector.hpp>
54 #include <KokkosBatched_AddRadial_Decl.hpp>
55 #include <KokkosBatched_AddRadial_Impl.hpp>
56 #include <KokkosBatched_Gemm_Decl.hpp>
57 #include <KokkosBatched_Gemm_Serial_Impl.hpp>
58 #include <KokkosBatched_Gemv_Decl.hpp>
59 #include <KokkosBatched_Gemv_Serial_Impl.hpp>
60 #include <KokkosBatched_Trsm_Decl.hpp>
61 #include <KokkosBatched_Trsm_Serial_Impl.hpp>
62 #include <KokkosBatched_Trsv_Decl.hpp>
63 #include <KokkosBatched_Trsv_Serial_Impl.hpp>
64 #include <KokkosBatched_LU_Decl.hpp>
65 #include <KokkosBatched_LU_Serial_Impl.hpp>
66 
68 #include "Ifpack2_BlockTriDiContainer_impl.hpp"
69 
70 #include <memory>
71 
72 
73 namespace Ifpack2 {
74 
78 
79  template <typename MatrixType>
80  void
81  BlockTriDiContainer<MatrixType, BlockTriDiContainerDetails::ImplSimdTag>
82  ::initInternal (const Teuchos::RCP<const row_matrix_type>& matrix,
84  const Teuchos::RCP<const import_type>& importer,
85  const bool overlapCommAndComp,
86  const bool useSeqMethod)
87  {
88  // create pointer of impl
89  impl_ = Teuchos::rcp(new BlockTriDiContainerDetails::ImplObject<MatrixType>());
90 
91  using impl_type = BlockTriDiContainerDetails::ImplType<MatrixType>;
92  using block_crs_matrix_type = typename impl_type::tpetra_block_crs_matrix_type;
93 
94  impl_->A = Teuchos::rcp_dynamic_cast<const block_crs_matrix_type>(matrix);
96  (impl_->A.is_null(), "BlockTriDiContainer currently supports Tpetra::BlockCrsMatrix only.");
97 
98  impl_->tpetra_importer = Teuchos::null;
99  impl_->async_importer = Teuchos::null;
100 
101  if (importer.is_null()) // there is no given importer, then create one
102  if (useSeqMethod)
103  impl_->tpetra_importer = BlockTriDiContainerDetails::createBlockCrsTpetraImporter<MatrixType>(impl_->A);
104  else
105  impl_->async_importer = BlockTriDiContainerDetails::createBlockCrsAsyncImporter<MatrixType>(impl_->A);
106  else
107  impl_->tpetra_importer = importer; // if there is a given importer, use it
108 
109  // as a result, there are
110  // 1) tpetra_importer is null , async_importer is null (no need for importer)
111  // 2) tpetra_importer is NOT null , async_importer is null (sequential method is used)
112  // 3) tpetra_importer is null , async_importer is NOT null (async method is used)
113 
114  // temporary disabling
115  impl_->overlap_communication_and_computation = overlapCommAndComp;
116 
117  impl_->Z = typename impl_type::tpetra_multivector_type();
118  impl_->W = typename impl_type::impl_scalar_type_1d_view();
119 
120  impl_->part_interface = BlockTriDiContainerDetails::createPartInterface<MatrixType>(impl_->A, partitions);
121  impl_->block_tridiags = BlockTriDiContainerDetails::createBlockTridiags<MatrixType>(impl_->part_interface);
122  impl_->norm_manager = BlockTriDiContainerDetails::NormManager<MatrixType>(impl_->A->getComm());
123  }
124 
125  template <typename MatrixType>
126  void
127  BlockTriDiContainer<MatrixType, BlockTriDiContainerDetails::ImplSimdTag>
128  ::clearInternal ()
129  {
130  using impl_type = BlockTriDiContainerDetails::ImplType<MatrixType>;
131  using part_interface_type = BlockTriDiContainerDetails::PartInterface<MatrixType>;
132  using block_tridiags_type = BlockTriDiContainerDetails::BlockTridiags<MatrixType>;
133  using amd_type = BlockTriDiContainerDetails::AmD<MatrixType>;
134  using norm_manager_type = BlockTriDiContainerDetails::NormManager<MatrixType>;
135 
136  impl_->A = Teuchos::null;
137  impl_->tpetra_importer = Teuchos::null;
138  impl_->async_importer = Teuchos::null;
139 
140  impl_->Z = typename impl_type::tpetra_multivector_type();
141  impl_->W = typename impl_type::impl_scalar_type_1d_view();
142 
143  impl_->part_interface = part_interface_type();
144  impl_->block_tridiags = block_tridiags_type();
145  impl_->a_minus_d = amd_type();
146  impl_->work = typename impl_type::vector_type_1d_view();
147  impl_->norm_manager = norm_manager_type();
148 
149  impl_ = Teuchos::null;
150  }
151 
152  template <typename MatrixType>
156  const Teuchos::RCP<const import_type>& importer,
157  int OverlapLevel, scalar_type DampingFactor)
158  : Container<MatrixType>(matrix, partitions, importer, OverlapLevel, DampingFactor)
159  {
160  const bool useSeqMethod = false;
161  const bool overlapCommAndComp = false;
162  initInternal(matrix, partitions, importer, overlapCommAndComp, useSeqMethod);
163  }
164 
165  template <typename MatrixType>
169  const bool overlapCommAndComp, const bool useSeqMethod)
170  : Container<MatrixType>(matrix, partitions, Teuchos::null, 0,
171  Kokkos::ArithTraits<magnitude_type>::one())
172  {
173  initInternal(matrix, partitions, Teuchos::null, overlapCommAndComp, useSeqMethod);
174  }
175 
176  template <typename MatrixType>
179  {
180  }
181 
182  template <typename MatrixType>
183  bool
186  {
187  return IsInitialized_;
188  }
189 
190  template <typename MatrixType>
191  bool
194  {
195  return IsComputed_;
196  }
197 
198  template <typename MatrixType>
199  void
202  {
203  // the solver doesn't currently take any parameters
204  }
205 
206  template <typename MatrixType>
207  void
210  {
211  IsInitialized_ = true;
212  // We assume that if you called this method, you intend to recompute
213  // everything.
214  IsComputed_ = false;
215  TEUCHOS_ASSERT(!impl_->A.is_null()); // when initInternal is called, A_ must be set
216  {
217  BlockTriDiContainerDetails::performSymbolicPhase<MatrixType>
218  (impl_->A,
219  impl_->part_interface, impl_->block_tridiags,
220  impl_->a_minus_d,
221  impl_->overlap_communication_and_computation);
222  }
223  }
224 
225  template <typename MatrixType>
226  void
229  {
230  IsComputed_ = false;
231  if (!this->isInitialized())
232  this->initialize();
233  {
234  BlockTriDiContainerDetails::performNumericPhase<MatrixType>
235  (impl_->A,
236  impl_->part_interface, impl_->block_tridiags,
237  Kokkos::ArithTraits<magnitude_type>::zero());
238  }
239  IsComputed_ = true;
240  }
241 
242  template <typename MatrixType>
243  void
246  {
247  clearInternal();
248  IsInitialized_ = false;
249  IsComputed_ = false;
250  }
251 
252  template <typename MatrixType>
253  void
255  ::applyInverseJacobi (const mv_type& X, mv_type& Y, bool zeroStartingSolution,
256  int numSweeps) const
257  {
258  const magnitude_type tol = Kokkos::ArithTraits<magnitude_type>::zero();
259  const int check_tol_every = 1;
260 
261  BlockTriDiContainerDetails::applyInverseJacobi<MatrixType>
262  (impl_->A,
263  impl_->tpetra_importer,
264  impl_->async_importer,
265  impl_->overlap_communication_and_computation,
266  X, Y, impl_->Z, impl_->W,
267  impl_->part_interface, impl_->block_tridiags, impl_->a_minus_d,
268  impl_->work,
269  impl_->norm_manager,
270  this->DampingFactor_,
271  zeroStartingSolution,
272  numSweeps,
273  tol,
274  check_tol_every);
275  }
276 
277  template <typename MatrixType>
281  {
282  return ComputeParameters();
283  }
284 
285  template <typename MatrixType>
286  void
288  ::compute (const ComputeParameters& in)
289  {
290  IsComputed_ = false;
291  if (!this->isInitialized())
292  this->initialize();
293  {
294  BlockTriDiContainerDetails::performNumericPhase<MatrixType>
295  (impl_->A,
296  impl_->part_interface, impl_->block_tridiags,
297  in.addRadiallyToDiagonal);
298  }
299  IsComputed_ = true;
300  }
301 
302  template <typename MatrixType>
306  {
307  ApplyParameters in;
308  in.dampingFactor = this->DampingFactor_;
309  return in;
310  }
311 
312  template <typename MatrixType>
313  int
315  ::applyInverseJacobi (const mv_type& X, mv_type& Y,
316  const ApplyParameters& in) const
317  {
318  int r_val = 0;
319  {
320  r_val = BlockTriDiContainerDetails::applyInverseJacobi<MatrixType>
321  (impl_->A,
322  impl_->tpetra_importer,
323  impl_->async_importer,
324  impl_->overlap_communication_and_computation,
325  X, Y, impl_->Z, impl_->W,
326  impl_->part_interface, impl_->block_tridiags, impl_->a_minus_d,
327  impl_->work,
328  impl_->norm_manager,
329  in.dampingFactor,
330  in.zeroStartingSolution,
331  in.maxNumSweeps,
332  in.tolerance,
333  in.checkToleranceEvery);
334  }
335  return r_val;
336  }
337 
338  template <typename MatrixType>
341  ::getNorms0 () const {
342  const auto p = impl_->norm_manager.getNorms0();
343  return Teuchos::arcp(p, 0, p ? 1 : 0, false);
344  }
345 
346  template <typename MatrixType>
350  const auto p = impl_->norm_manager.getNormsFinal();
351  return Teuchos::arcp(p, 0, p ? 1 : 0, false);
352  }
353 
354  template <typename MatrixType>
355  void
357  ::apply (HostView& /* X */, HostView& /* Y */, int /* blockIndex */, int /* stride */, Teuchos::ETransp /* mode */,
358  scalar_type /* alpha */, scalar_type /* beta */) const
359  {
360  TEUCHOS_TEST_FOR_EXCEPT_MSG(true, "BlockTriDiContainer::apply is not implemented. You may have reached this message "
361  << "because you want to use this container's performance-portable Jacobi iteration. In "
362  << "that case, set \"relaxation: type\" to \"MT Split Jacobi\" rather than \"Jacobi\".");
363  }
364 
365  template <typename MatrixType>
366  void
368  ::weightedApply (HostView& /* X */, HostView& /* Y */, HostView& /* D */, int /* blockIndex */, int /* stride */,
369  Teuchos::ETransp /* mode */, scalar_type /* alpha */, scalar_type /* beta */) const
370  {
371  TEUCHOS_TEST_FOR_EXCEPT_MSG(true, "BlockTriDiContainer::weightedApply is not implemented.");
372  }
373 
374  template <typename MatrixType>
375  std::ostream&
377  ::print (std::ostream& os) const
378  {
379  Teuchos::FancyOStream fos(Teuchos::rcp(&os,false));
380  fos.setOutputToRootOnly(0);
381  describe(fos);
382  return os;
383  }
384 
385  template <typename MatrixType>
386  std::string
389  {
390  std::ostringstream oss;
392  if (isInitialized()) {
393  if (isComputed()) {
394  oss << "{status = initialized, computed";
395  }
396  else {
397  oss << "{status = initialized, not computed";
398  }
399  }
400  else {
401  oss << "{status = not initialized, not computed";
402  }
403 
404  oss << "}";
405  return oss.str();
406  }
407 
408  template <typename MatrixType>
409  void
412  const Teuchos::EVerbosityLevel verbLevel) const
413  {
414  using std::endl;
415  if(verbLevel==Teuchos::VERB_NONE) return;
416  os << "================================================================================" << endl
417  << "Ifpack2::BlockTriDiContainer" << endl
418  << "Number of blocks = " << this->numBlocks_ << endl
419  << "isInitialized() = " << IsInitialized_ << endl
420  << "isComputed() = " << IsComputed_ << endl
421  << "================================================================================" << endl
422  << endl;
423  }
424 
425  template <typename MatrixType>
426  std::string
428  ::getName() { return "Ifpack2::BlockTriDiContainer::ImplSimdTag"; }
429 
430 #define IFPACK2_BLOCKTRIDICONTAINER_INSTANT(S,LO,GO,N) \
431  template class Ifpack2::BlockTriDiContainer< Tpetra::RowMatrix<S, LO, GO, N> >;
432 }
433 #endif
Ifpack2::BlockTriDiContainer class declaration.
Store and solve local block tridiagonal linear problems.
Definition: Ifpack2_BlockTriDiContainer_decl.hpp:134
void applyInverseJacobi(const mv_type &X, mv_type &Y, bool zeroStartingSolution=false, int numSweeps=1) const override
Compute Y := (1 - a) Y + a D^{-1} (X - R*Y).
Definition: Ifpack2_BlockTriDiContainer_def.hpp:255
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
#define TEUCHOS_TEST_FOR_EXCEPT_MSG(throw_exception_test, msg)
virtual std::string description() const
basic_FancyOStream & setOutputToRootOnly(const int rootRank)
BlockTriDiContainer(const Teuchos::RCP< const row_matrix_type > &matrix, const Teuchos::Array< Teuchos::Array< local_ordinal_type > > &partitions, const Teuchos::RCP< const import_type > &importer, int OverlapLevel, scalar_type DampingFactor)
Constructor.
Definition: Ifpack2_BlockTriDiContainer_def.hpp:154
Interface for creating and solving a local linear problem.
Definition: Ifpack2_Container.hpp:114
#define TEUCHOS_ASSERT(assertion_test)
bool is_null() const