Xpetra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Xpetra_TripleMatrixMultiply_def.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Xpetra: A linear algebra interface package
4 //
5 // Copyright 2012 NTESS and the Xpetra contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef PACKAGES_XPETRA_SUP_UTILS_XPETRA_TRIPLEMATRIXMULTIPLY_DEF_HPP_
11 #define PACKAGES_XPETRA_SUP_UTILS_XPETRA_TRIPLEMATRIXMULTIPLY_DEF_HPP_
12 
14 
15 namespace Xpetra {
16 
17 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
19  const Matrix& A, bool transposeA,
20  const Matrix& P, bool transposeP,
21  Matrix& Ac,
22  bool call_FillComplete_on_result,
23  bool doOptimizeStorage,
24  const std::string& label,
25  const RCP<ParameterList>& params) {
26  TEUCHOS_TEST_FOR_EXCEPTION(transposeR == false && Ac.getRowMap()->isSameAs(*R.getRowMap()) == false,
27  Exceptions::RuntimeError, "XpetraExt::TripleMatrixMultiply::MultiplyRAP: row map of Ac is not same as row map of R");
28  TEUCHOS_TEST_FOR_EXCEPTION(transposeR == true && Ac.getRowMap()->isSameAs(*R.getDomainMap()) == false,
29  Exceptions::RuntimeError, "XpetraExt::TripleMatrixMultiply::MultiplyRAP: row map of Ac is not same as domain map of R");
30 
31  TEUCHOS_TEST_FOR_EXCEPTION(!R.isFillComplete(), Exceptions::RuntimeError, "R is not fill-completed");
32  TEUCHOS_TEST_FOR_EXCEPTION(!A.isFillComplete(), Exceptions::RuntimeError, "A is not fill-completed");
33  TEUCHOS_TEST_FOR_EXCEPTION(!P.isFillComplete(), Exceptions::RuntimeError, "P is not fill-completed");
34 
35  bool haveMultiplyDoFillComplete = call_FillComplete_on_result && doOptimizeStorage;
36 
37  if (Ac.getRowMap()->lib() == Xpetra::UseEpetra) {
38  throw(Xpetra::Exceptions::RuntimeError("Xpetra::TripleMatrixMultiply::MultiplyRAP is only implemented for Tpetra"));
39  } else if (Ac.getRowMap()->lib() == Xpetra::UseTpetra) {
40 #ifdef HAVE_XPETRA_TPETRA
41  using helpers = Xpetra::Helpers<SC, LO, GO, NO>;
42  if (helpers::isTpetraCrs(R) && helpers::isTpetraCrs(A) && helpers::isTpetraCrs(P)) {
43  // All matrices are Crs
44  const Tpetra::CrsMatrix<SC, LO, GO, NO>& tpR = Xpetra::Helpers<SC, LO, GO, NO>::Op2TpetraCrs(R);
45  const Tpetra::CrsMatrix<SC, LO, GO, NO>& tpA = Xpetra::Helpers<SC, LO, GO, NO>::Op2TpetraCrs(A);
46  const Tpetra::CrsMatrix<SC, LO, GO, NO>& tpP = Xpetra::Helpers<SC, LO, GO, NO>::Op2TpetraCrs(P);
47  Tpetra::CrsMatrix<SC, LO, GO, NO>& tpAc = Xpetra::Helpers<SC, LO, GO, NO>::Op2NonConstTpetraCrs(Ac);
48 
49  // 18Feb2013 JJH I'm reenabling the code that allows the matrix matrix multiply to do the fillComplete.
50  // Previously, Tpetra's matrix matrix multiply did not support fillComplete.
51  Tpetra::TripleMatrixMultiply::MultiplyRAP(tpR, transposeR, tpA, transposeA, tpP, transposeP, tpAc, haveMultiplyDoFillComplete, label, params);
52  } else if (helpers::isTpetraBlockCrs(R) && helpers::isTpetraBlockCrs(A) && helpers::isTpetraBlockCrs(P)) {
53  // All matrices are BlockCrs (except maybe Ac)
54  // FIXME: For the moment we're just going to clobber the innards of Ac, so no reuse. Once we have a reuse kernel,
55  // we'll need to think about refactoring BlockCrs so we can do something smarter here.
56 
57  if (!A.getRowMap()->getComm()->getRank())
58  std::cout << "WARNING: Using inefficient BlockCrs Multiply Placeholder" << std::endl;
59 
60  const Tpetra::BlockCrsMatrix<SC, LO, GO, NO>& tpR = Xpetra::Helpers<SC, LO, GO, NO>::Op2TpetraBlockCrs(R);
61  const Tpetra::BlockCrsMatrix<SC, LO, GO, NO>& tpA = Xpetra::Helpers<SC, LO, GO, NO>::Op2TpetraBlockCrs(A);
62  const Tpetra::BlockCrsMatrix<SC, LO, GO, NO>& tpP = Xpetra::Helpers<SC, LO, GO, NO>::Op2TpetraBlockCrs(P);
63  // Tpetra::BlockCrsMatrix<SC,LO,GO,NO> & tpAc = Xpetra::Helpers<SC,LO,GO,NO>::Op2NonConstTpetraBlockCrs(Ac);
64 
65  using CRS = Tpetra::CrsMatrix<SC, LO, GO, NO>;
66  RCP<const CRS> Rcrs = Tpetra::convertToCrsMatrix(tpR);
67  RCP<const CRS> Acrs = Tpetra::convertToCrsMatrix(tpA);
68  RCP<const CRS> Pcrs = Tpetra::convertToCrsMatrix(tpP);
69  // RCP<CRS> Accrs = Tpetra::convertToCrsMatrix(tpAc);
70 
71  // FIXME: The lines below only works because we're assuming Ac is Point
72  RCP<CRS> Accrs = Teuchos::rcp(new CRS(Rcrs->getRowMap(), 0));
73  const bool do_fill_complete = true;
74  Tpetra::TripleMatrixMultiply::MultiplyRAP(*Rcrs, transposeR, *Acrs, transposeA, *Pcrs, transposeP, *Accrs, do_fill_complete, label, params);
75 
76  // Temporary output matrix
77  RCP<Tpetra::BlockCrsMatrix<SC, LO, GO, NO> > Ac_t = Tpetra::convertToBlockCrsMatrix(*Accrs, A.GetStorageBlockSize());
78  RCP<Xpetra::TpetraBlockCrsMatrix<SC, LO, GO, NO> > Ac_x = Teuchos::rcp(new Xpetra::TpetraBlockCrsMatrix<SC, LO, GO, NO>(Ac_t));
79  RCP<Xpetra::CrsMatrix<SC, LO, GO, NO> > Ac_p = Ac_x;
80 
81  // We can now cheat and replace the innards of Ac
82  RCP<Xpetra::CrsMatrixWrap<SC, LO, GO, NO> > Ac_w = Teuchos::rcp_dynamic_cast<Xpetra::CrsMatrixWrap<SC, LO, GO, NO> >(Teuchos::rcpFromRef(Ac));
83  Ac_w->replaceCrsMatrix(Ac_p);
84  } else {
85  // Mix and match
86  TEUCHOS_TEST_FOR_EXCEPTION(1, Exceptions::RuntimeError, "Mix-and-match Crs/BlockCrs Multiply not currently supported");
87  }
88 #else
89  throw(Xpetra::Exceptions::RuntimeError("Xpetra must be compiled with Tpetra."));
90 #endif
91  }
92 
93  if (call_FillComplete_on_result && !haveMultiplyDoFillComplete) {
94  RCP<Teuchos::ParameterList> fillParams = rcp(new Teuchos::ParameterList());
95  fillParams->set("Optimize Storage", doOptimizeStorage);
96  Ac.fillComplete((transposeP) ? P.getRangeMap() : P.getDomainMap(),
97  (transposeR) ? R.getDomainMap() : R.getRangeMap(),
98  fillParams);
99  }
100 
101  // transfer striding information
102  RCP<const Map> domainMap = Teuchos::null;
103  RCP<const Map> rangeMap = Teuchos::null;
104 
105  const std::string stridedViewLabel("stridedMaps");
106  const size_t blkSize = 1;
107  std::vector<size_t> stridingInfo(1, blkSize);
108  LocalOrdinal stridedBlockId = -1;
109 
110  if (R.IsView(stridedViewLabel)) {
111  rangeMap = transposeR ? R.getColMap(stridedViewLabel) : R.getRowMap(stridedViewLabel);
112  } else {
113  rangeMap = transposeR ? R.getDomainMap() : R.getRangeMap();
114  rangeMap = StridedMapFactory::Build(rangeMap, stridingInfo, stridedBlockId);
115  }
116 
117  if (P.IsView(stridedViewLabel)) {
118  domainMap = transposeP ? P.getRowMap(stridedViewLabel) : P.getColMap(stridedViewLabel);
119  } else {
120  domainMap = transposeP ? P.getRangeMap() : P.getDomainMap();
121  domainMap = StridedMapFactory::Build(domainMap, stridingInfo, stridedBlockId);
122  }
123  Ac.CreateView(stridedViewLabel, rangeMap, domainMap);
124 
125 } // end Multiply
126 
127 } // end namespace Xpetra
128 
129 #define XPETRA_TRIPLEMATRIXMULTIPLY_SHORT
130 
131 #endif /* PACKAGES_XPETRA_SUP_UTILS_XPETRA_TRIPLEMATRIXMULTIPLY_DEF_HPP_ */
virtual const RCP< const Map > & getColMap() const
Returns the Map that describes the column distribution in this matrix. This might be null until fillC...
Xpetra utility class containing transformation routines between Xpetra::Matrix and Epetra/Tpetra obje...
virtual const RCP< const Map > & getRowMap() const
Returns the Map that describes the row distribution in this matrix.
virtual LocalOrdinal GetStorageBlockSize() const =0
Returns the block size of the storage mechanism, which is usually 1, except for Tpetra::BlockCrsMatri...
Exception throws to report errors in the internal logical of the program.
static RCP< const Tpetra::CrsMatrix< SC, LO, GO, NO > > Op2TpetraCrs(RCP< Matrix > Op)
virtual void fillComplete(const RCP< const Map > &domainMap, const RCP< const Map > &rangeMap, const RCP< ParameterList > &params=null)=0
Signal that data entry is complete, specifying domain and range maps.
bool IsView(const viewLabel_t viewLabel) const
virtual bool isFillComplete() const =0
Returns true if fillComplete() has been called and the matrix is in compute mode. ...
void CreateView(viewLabel_t viewLabel, const RCP< const Map > &rowMap, const RCP< const Map > &colMap)
virtual const Teuchos::RCP< const map_type > getRangeMap() const =0
The Map associated with the range of this operator, which must be compatible with Y...
static RCP< Tpetra::CrsMatrix< SC, LO, GO, NO > > Op2NonConstTpetraCrs(RCP< Matrix > Op)
void replaceCrsMatrix(RCP< CrsMatrix > &M)
Expert only.
Concrete implementation of Xpetra::Matrix.
static void MultiplyRAP(const Matrix &R, bool transposeR, const Matrix &A, bool transposeA, const Matrix &P, bool transposeP, Matrix &Ac, bool call_FillComplete_on_result=true, bool doOptimizeStorage=true, const std::string &label=std::string(), const RCP< ParameterList > &params=null)
virtual const Teuchos::RCP< const map_type > getDomainMap() const =0
The Map associated with the domain of this operator, which must be compatible with X...
static RCP< const Tpetra::BlockCrsMatrix< SC, LO, GO, NO > > Op2TpetraBlockCrs(RCP< Matrix > Op)
static RCP< Xpetra::StridedMap< LocalOrdinal, GlobalOrdinal, Node > > Build(UnderlyingLib lib, global_size_t numGlobalElements, GlobalOrdinal indexBase, std::vector< size_t > &stridingInfo, const Teuchos::RCP< const Teuchos::Comm< int >> &comm, LocalOrdinal stridedBlockId=-1, GlobalOrdinal offset=0, LocalGlobal lg=Xpetra::GloballyDistributed)
Map constructor with Xpetra-defined contiguous uniform distribution.
Xpetra-specific matrix class.