48 #ifndef PACKAGES_XPETRA_SUP_UTILS_XPETRA_TRIPLEMATRIXMULTIPLY_HPP_
49 #define PACKAGES_XPETRA_SUP_UTILS_XPETRA_TRIPLEMATRIXMULTIPLY_HPP_
54 #include "Xpetra_CrsMatrixWrap.hpp"
55 #include "Xpetra_MapExtractor.hpp"
56 #include "Xpetra_Map.hpp"
59 #include "Xpetra_StridedMapFactory.hpp"
60 #include "Xpetra_StridedMap.hpp"
63 #ifdef HAVE_XPETRA_TPETRA
64 #include <TpetraExt_TripleMatrixMultiply.hpp>
65 #include <Xpetra_TpetraCrsMatrix.hpp>
66 #include <Tpetra_BlockCrsMatrix.hpp>
67 #include <Tpetra_BlockCrsMatrix_Helpers.hpp>
70 #endif // HAVE_XPETRA_TPETRA
74 template <
class Scalar,
79 #undef XPETRA_TRIPLEMATRIXMULTIPLY_SHORT
108 const Matrix& A,
bool transposeA,
109 const Matrix& P,
bool transposeP,
111 bool call_FillComplete_on_result =
true,
112 bool doOptimizeStorage =
true,
113 const std::string& label = std::string(),
114 const RCP<ParameterList>& params = null) {
115 TEUCHOS_TEST_FOR_EXCEPTION(transposeR ==
false && Ac.
getRowMap()->isSameAs(*R.
getRowMap()) ==
false,
116 Exceptions::RuntimeError,
"XpetraExt::TripleMatrixMultiply::MultiplyRAP: row map of Ac is not same as row map of R");
117 TEUCHOS_TEST_FOR_EXCEPTION(transposeR ==
true && Ac.
getRowMap()->isSameAs(*R.
getDomainMap()) ==
false,
118 Exceptions::RuntimeError,
"XpetraExt::TripleMatrixMultiply::MultiplyRAP: row map of Ac is not same as domain map of R");
124 bool haveMultiplyDoFillComplete = call_FillComplete_on_result && doOptimizeStorage;
129 #ifdef HAVE_XPETRA_TPETRA
131 if (helpers::isTpetraCrs(R) && helpers::isTpetraCrs(A) && helpers::isTpetraCrs(P)) {
140 Tpetra::TripleMatrixMultiply::MultiplyRAP(tpR, transposeR, tpA, transposeA, tpP, transposeP, tpAc, haveMultiplyDoFillComplete, label, params);
141 }
else if (helpers::isTpetraBlockCrs(R) && helpers::isTpetraBlockCrs(A) && helpers::isTpetraBlockCrs(P)) {
146 if (!A.
getRowMap()->getComm()->getRank())
147 std::cout <<
"WARNING: Using inefficient BlockCrs Multiply Placeholder" << std::endl;
154 using CRS = Tpetra::CrsMatrix<SC, LO, GO, NO>;
155 RCP<const CRS> Rcrs = Tpetra::convertToCrsMatrix(tpR);
156 RCP<const CRS> Acrs = Tpetra::convertToCrsMatrix(tpA);
157 RCP<const CRS> Pcrs = Tpetra::convertToCrsMatrix(tpP);
161 RCP<CRS> Accrs = Teuchos::rcp(
new CRS(Rcrs->getRowMap(), 0));
162 const bool do_fill_complete =
true;
163 Tpetra::TripleMatrixMultiply::MultiplyRAP(*Rcrs, transposeR, *Acrs, transposeA, *Pcrs, transposeP, *Accrs, do_fill_complete, label, params);
166 RCP<Tpetra::BlockCrsMatrix<SC, LO, GO, NO> > Ac_t = Tpetra::convertToBlockCrsMatrix(*Accrs, A.
GetStorageBlockSize());
168 RCP<Xpetra::CrsMatrix<SC, LO, GO, NO> > Ac_p = Ac_x;
175 TEUCHOS_TEST_FOR_EXCEPTION(1,
Exceptions::RuntimeError,
"Mix-and-match Crs/BlockCrs Multiply not currently supported");
182 if (call_FillComplete_on_result && !haveMultiplyDoFillComplete) {
183 RCP<Teuchos::ParameterList> fillParams = rcp(
new Teuchos::ParameterList());
184 fillParams->set(
"Optimize Storage", doOptimizeStorage);
191 RCP<const Map> domainMap = Teuchos::null;
192 RCP<const Map> rangeMap = Teuchos::null;
194 const std::string stridedViewLabel(
"stridedMaps");
195 const size_t blkSize = 1;
196 std::vector<size_t> stridingInfo(1, blkSize);
197 LocalOrdinal stridedBlockId = -1;
199 if (R.
IsView(stridedViewLabel)) {
200 rangeMap = transposeR ? R.
getColMap(stridedViewLabel) : R.
getRowMap(stridedViewLabel);
206 if (P.
IsView(stridedViewLabel)) {
207 domainMap = transposeP ? P.
getRowMap(stridedViewLabel) : P.
getColMap(stridedViewLabel);
212 Ac.
CreateView(stridedViewLabel, rangeMap, domainMap);
218 #ifdef HAVE_XPETRA_EPETRA
230 const Matrix& A,
bool transposeA,
231 const Matrix& P,
bool transposeP,
233 bool call_FillComplete_on_result =
true,
234 bool doOptimizeStorage =
true,
235 const std::string& label = std::string(),
236 const RCP<ParameterList>& params = null) {
237 TEUCHOS_TEST_FOR_EXCEPTION(transposeR ==
false && Ac.
getRowMap()->isSameAs(*R.
getRowMap()) ==
false,
238 Exceptions::RuntimeError,
"XpetraExt::TripleMatrixMultiply::MultiplyRAP: row map of Ac is not same as row map of R");
239 TEUCHOS_TEST_FOR_EXCEPTION(transposeR ==
true && Ac.
getRowMap()->isSameAs(*R.
getDomainMap()) ==
false,
240 Exceptions::RuntimeError,
"XpetraExt::TripleMatrixMultiply::MultiplyRAP: row map of Ac is not same as domain map of R");
246 bool haveMultiplyDoFillComplete = call_FillComplete_on_result && doOptimizeStorage;
251 #ifdef HAVE_XPETRA_TPETRA
252 #if ((defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_OPENMP) || !defined(HAVE_TPETRA_INST_INT_INT))) || \
253 (!defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_SERIAL) || !defined(HAVE_TPETRA_INST_INT_INT))))
257 if (helpers::isTpetraCrs(R) && helpers::isTpetraCrs(A) && helpers::isTpetraCrs(P) && helpers::isTpetraCrs(Ac)) {
266 Tpetra::TripleMatrixMultiply::MultiplyRAP(tpR, transposeR, tpA, transposeA, tpP, transposeP, tpAc, haveMultiplyDoFillComplete, label, params);
267 }
else if (helpers::isTpetraBlockCrs(R) && helpers::isTpetraBlockCrs(A) && helpers::isTpetraBlockCrs(P)) {
271 if (!A.
getRowMap()->getComm()->getRank())
272 std::cout <<
"WARNING: Using inefficient BlockCrs Multiply Placeholder" << std::endl;
279 using CRS = Tpetra::CrsMatrix<SC, LO, GO, NO>;
280 RCP<const CRS> Rcrs = Tpetra::convertToCrsMatrix(tpR);
281 RCP<const CRS> Acrs = Tpetra::convertToCrsMatrix(tpA);
282 RCP<const CRS> Pcrs = Tpetra::convertToCrsMatrix(tpP);
286 RCP<CRS> Accrs = Teuchos::rcp(
new CRS(Rcrs->getRowMap(), 0));
287 const bool do_fill_complete =
true;
288 Tpetra::TripleMatrixMultiply::MultiplyRAP(*Rcrs, transposeR, *Acrs, transposeA, *Pcrs, transposeP, *Accrs, do_fill_complete, label, params);
291 RCP<Tpetra::BlockCrsMatrix<SC, LO, GO, NO> > Ac_t = Tpetra::convertToBlockCrsMatrix(*Accrs, A.
GetStorageBlockSize());
293 RCP<Xpetra::CrsMatrix<SC, LO, GO, NO> > Ac_p = Ac_x;
301 TEUCHOS_TEST_FOR_EXCEPTION(1,
Exceptions::RuntimeError,
"Mix-and-match Crs/BlockCrs Multiply not currently supported");
307 if (call_FillComplete_on_result && !haveMultiplyDoFillComplete) {
308 RCP<Teuchos::ParameterList> fillParams = rcp(
new Teuchos::ParameterList());
309 fillParams->set(
"Optimize Storage", doOptimizeStorage);
316 RCP<const Map> domainMap = Teuchos::null;
317 RCP<const Map> rangeMap = Teuchos::null;
319 const std::string stridedViewLabel(
"stridedMaps");
320 const size_t blkSize = 1;
321 std::vector<size_t> stridingInfo(1, blkSize);
324 if (R.
IsView(stridedViewLabel)) {
325 rangeMap = transposeR ? R.
getColMap(stridedViewLabel) : R.
getRowMap(stridedViewLabel);
331 if (P.
IsView(stridedViewLabel)) {
332 domainMap = transposeP ? P.
getRowMap(stridedViewLabel) : P.
getColMap(stridedViewLabel);
337 Ac.
CreateView(stridedViewLabel, rangeMap, domainMap);
355 const Matrix& A,
bool transposeA,
356 const Matrix& P,
bool transposeP,
358 bool call_FillComplete_on_result =
true,
359 bool doOptimizeStorage =
true,
360 const std::string& label = std::string(),
361 const RCP<ParameterList>& params = null) {
362 TEUCHOS_TEST_FOR_EXCEPTION(transposeR ==
false && Ac.
getRowMap()->isSameAs(*R.
getRowMap()) ==
false,
363 Exceptions::RuntimeError,
"XpetraExt::TripleMatrixMultiply::MultiplyRAP: row map of Ac is not same as row map of R");
364 TEUCHOS_TEST_FOR_EXCEPTION(transposeR ==
true && Ac.
getRowMap()->isSameAs(*R.
getDomainMap()) ==
false,
365 Exceptions::RuntimeError,
"XpetraExt::TripleMatrixMultiply::MultiplyRAP: row map of Ac is not same as domain map of R");
371 bool haveMultiplyDoFillComplete = call_FillComplete_on_result && doOptimizeStorage;
376 #ifdef HAVE_XPETRA_TPETRA
377 #if ((defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_OPENMP) || !defined(HAVE_TPETRA_INST_INT_LONG_LONG))) || \
378 (!defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_SERIAL) || !defined(HAVE_TPETRA_INST_INT_LONG_LONG))))
382 if (helpers::isTpetraCrs(R) && helpers::isTpetraCrs(A) && helpers::isTpetraCrs(P)) {
391 Tpetra::TripleMatrixMultiply::MultiplyRAP(tpR, transposeR, tpA, transposeA, tpP, transposeP, tpAc, haveMultiplyDoFillComplete, label, params);
392 }
else if (helpers::isTpetraBlockCrs(R) && helpers::isTpetraBlockCrs(A) && helpers::isTpetraBlockCrs(P)) {
396 if (!A.
getRowMap()->getComm()->getRank())
397 std::cout <<
"WARNING: Using inefficient BlockCrs Multiply Placeholder" << std::endl;
404 using CRS = Tpetra::CrsMatrix<SC, LO, GO, NO>;
405 RCP<const CRS> Rcrs = Tpetra::convertToCrsMatrix(tpR);
406 RCP<const CRS> Acrs = Tpetra::convertToCrsMatrix(tpA);
407 RCP<const CRS> Pcrs = Tpetra::convertToCrsMatrix(tpP);
411 RCP<CRS> Accrs = Teuchos::rcp(
new CRS(Rcrs->getRowMap(), 0));
412 const bool do_fill_complete =
true;
413 Tpetra::TripleMatrixMultiply::MultiplyRAP(*Rcrs, transposeR, *Acrs, transposeA, *Pcrs, transposeP, *Accrs, do_fill_complete, label, params);
416 RCP<Tpetra::BlockCrsMatrix<SC, LO, GO, NO> > Ac_t = Tpetra::convertToBlockCrsMatrix(*Accrs, A.
GetStorageBlockSize());
418 RCP<Xpetra::CrsMatrix<SC, LO, GO, NO> > Ac_p = Ac_x;
425 TEUCHOS_TEST_FOR_EXCEPTION(1,
Exceptions::RuntimeError,
"Mix-and-match Crs/BlockCrs Multiply not currently supported");
432 if (call_FillComplete_on_result && !haveMultiplyDoFillComplete) {
433 RCP<Teuchos::ParameterList> fillParams = rcp(
new Teuchos::ParameterList());
434 fillParams->set(
"Optimize Storage", doOptimizeStorage);
441 RCP<const Map> domainMap = Teuchos::null;
442 RCP<const Map> rangeMap = Teuchos::null;
444 const std::string stridedViewLabel(
"stridedMaps");
445 const size_t blkSize = 1;
446 std::vector<size_t> stridingInfo(1, blkSize);
449 if (R.
IsView(stridedViewLabel)) {
450 rangeMap = transposeR ? R.
getColMap(stridedViewLabel) : R.
getRowMap(stridedViewLabel);
456 if (P.
IsView(stridedViewLabel)) {
457 domainMap = transposeP ? P.
getRowMap(stridedViewLabel) : P.
getColMap(stridedViewLabel);
462 Ac.
CreateView(stridedViewLabel, rangeMap, domainMap);
472 #define XPETRA_TRIPLEMATRIXMULTIPLY_SHORT
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 > ¶ms=null)
static RCP< const Tpetra::CrsMatrix< SC, LO, GO, NO > > Op2TpetraCrs(RCP< Matrix > Op)
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 > ¶ms=null)
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 > ¶ms=null)
Xpetra utility class containing transformation routines between Xpetra::Matrix and Epetra/Tpetra obje...
static RCP< Tpetra::CrsMatrix< SC, LO, GO, NO > > Op2NonConstTpetraCrs(RCP< Matrix > Op)
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.
virtual const RCP< const Map > & getColMap() const
Returns the Map that describes the column distribution in this matrix. This might be null until fillC...
virtual void fillComplete(const RCP< const Map > &domainMap, const RCP< const Map > &rangeMap, const RCP< ParameterList > ¶ms=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...
Tpetra::KokkosCompat::KokkosSerialWrapperNode EpetraNode
void replaceCrsMatrix(RCP< CrsMatrix > &M)
Expert only.
static RCP< const Tpetra::BlockCrsMatrix< SC, LO, GO, NO > > Op2TpetraBlockCrs(RCP< Matrix > Op)
Concrete implementation of Xpetra::Matrix.
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< 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.
virtual const RCP< const Map > & getRowMap() const
Returns the Map that describes the row distribution in this matrix.
Xpetra-specific matrix class.