48 #ifndef PACKAGES_XPETRA_SUP_UTILS_XPETRA_MATRIXMATRIX_HPP_ 49 #define PACKAGES_XPETRA_SUP_UTILS_XPETRA_MATRIXMATRIX_HPP_ 62 #ifdef HAVE_XPETRA_EPETRA 66 #ifdef HAVE_XPETRA_EPETRAEXT 67 #include <EpetraExt_MatrixMatrix.h> 68 #include <EpetraExt_RowMatrixOut.h> 69 #include <Epetra_RowMatrixTransposer.h> 70 #endif // HAVE_XPETRA_EPETRAEXT 72 #ifdef HAVE_XPETRA_TPETRA 73 #include <TpetraExt_MatrixMatrix.hpp> 74 #include <MatrixMarket_Tpetra.hpp> 78 #endif // HAVE_XPETRA_TPETRA 88 template <
class Scalar,
89 class LocalOrdinal = int,
90 class GlobalOrdinal = LocalOrdinal,
97 #ifdef HAVE_XPETRA_EPETRA 100 RCP<const CrsMatrixWrap> crsOp = Teuchos::rcp_dynamic_cast<
const CrsMatrixWrap>(Op);
102 "Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
104 RCP<const CrsMatrix> tmp_CrsMtx = crsOp->getCrsMatrix();
105 const RCP<const EpetraCrsMatrixT<GO,NO> > &tmp_ECrsMtx = Teuchos::rcp_dynamic_cast<
const EpetraCrsMatrixT<GO,NO> >(tmp_CrsMtx);
107 "Cast from Xpetra::CrsMatrix to Xpetra::EpetraCrsMatrix failed");
109 return tmp_ECrsMtx->getEpetra_CrsMatrix();
113 RCP<Epetra_CrsMatrix> A;
115 RCP<const CrsMatrixWrap> crsOp = Teuchos::rcp_dynamic_cast<
const CrsMatrixWrap>(Op);
117 "Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
119 RCP<const CrsMatrix> tmp_CrsMtx = crsOp->getCrsMatrix();
120 const RCP<const EpetraCrsMatrixT<GO,NO> > &tmp_ECrsMtx = Teuchos::rcp_dynamic_cast<
const EpetraCrsMatrixT<GO,NO> >(tmp_CrsMtx);
121 TEUCHOS_TEST_FOR_EXCEPTION(tmp_ECrsMtx == Teuchos::null,
Exceptions::BadCast,
"Cast from Xpetra::CrsMatrix to Xpetra::EpetraCrsMatrix failed");
123 return tmp_ECrsMtx->getEpetra_CrsMatrixNonConst();
131 const RCP<const EpetraCrsMatrixT<GO,NO> > &tmp_ECrsMtx = Teuchos::rcp_dynamic_cast<
const EpetraCrsMatrixT<GO,NO> >(tmp_CrsMtx);
133 "Cast from Xpetra::CrsMatrix to Xpetra::EpetraCrsMatrix failed");
135 return *tmp_ECrsMtx->getEpetra_CrsMatrix();
143 RCP<Epetra_CrsMatrix> A;
148 const RCP<const EpetraCrsMatrixT<GO,NO> > &tmp_ECrsMtx = Teuchos::rcp_dynamic_cast<
const EpetraCrsMatrixT<GO,NO> >(tmp_CrsMtx);
149 TEUCHOS_TEST_FOR_EXCEPTION(tmp_ECrsMtx == Teuchos::null,
Xpetra::Exceptions::BadCast,
"Cast from Xpetra::CrsMatrix to Xpetra::EpetraCrsMatrix failed");
151 return *Teuchos::rcp_const_cast<
Epetra_CrsMatrix>(tmp_ECrsMtx->getEpetra_CrsMatrix());
157 #endif // HAVE_XPETRA_EPETRA 159 #ifdef HAVE_XPETRA_TPETRA 160 static RCP<const Tpetra::CrsMatrix<SC,LO,GO,NO> >
Op2TpetraCrs(RCP<Matrix> Op) {
162 RCP<const CrsMatrixWrap> crsOp = Teuchos::rcp_dynamic_cast<
const CrsMatrixWrap>(Op);
163 TEUCHOS_TEST_FOR_EXCEPTION(crsOp == Teuchos::null,
Xpetra::Exceptions::BadCast,
"Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
165 RCP<const CrsMatrix> tmp_CrsMtx = crsOp->getCrsMatrix();
167 TEUCHOS_TEST_FOR_EXCEPTION(tmp_ECrsMtx == Teuchos::null,
Xpetra::Exceptions::BadCast,
"Cast from Xpetra::CrsMatrix to Xpetra::TpetraCrsMatrix failed");
169 return tmp_ECrsMtx->getTpetra_CrsMatrix();
174 RCP<const CrsMatrixWrap> crsOp = Teuchos::rcp_dynamic_cast<
const CrsMatrixWrap>(Op);
175 TEUCHOS_TEST_FOR_EXCEPTION(crsOp == Teuchos::null,
Xpetra::Exceptions::BadCast,
"Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
176 RCP<const CrsMatrix> tmp_CrsMtx = crsOp->getCrsMatrix();
178 TEUCHOS_TEST_FOR_EXCEPTION(tmp_ECrsMtx == Teuchos::null,
Xpetra::Exceptions::BadCast,
"Cast from Xpetra::CrsMatrix to Xpetra::TpetraCrsMatrix failed");
180 return tmp_ECrsMtx->getTpetra_CrsMatrixNonConst();
189 TEUCHOS_TEST_FOR_EXCEPTION(tmp_TCrsMtx == Teuchos::null,
Xpetra::Exceptions::BadCast,
"Cast from Xpetra::CrsMatrix to Xpetra::TpetraCrsMatrix failed");
191 return *tmp_TCrsMtx->getTpetra_CrsMatrix();
204 TEUCHOS_TEST_FOR_EXCEPTION(tmp_TCrsMtx == Teuchos::null,
Xpetra::Exceptions::BadCast,
"Cast from Xpetra::CrsMatrix to Xpetra::TpetraCrsMatrix failed");
206 return *Teuchos::rcp_const_cast<Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(tmp_TCrsMtx->getTpetra_CrsMatrix());
212 #endif // HAVE_XPETRA_TPETRA 216 template <
class Scalar,
218 class GlobalOrdinal ,
221 #undef XPETRA_MATRIXMATRIX_SHORT 251 const Matrix& B,
bool transposeB,
253 bool call_FillComplete_on_result =
true,
254 bool doOptimizeStorage =
true,
255 const std::string & label = std::string(),
256 const RCP<ParameterList>& params = null) {
258 TEUCHOS_TEST_FOR_EXCEPTION(transposeA ==
false && C.
getRowMap()->isSameAs(*A.
getRowMap()) ==
false,
260 TEUCHOS_TEST_FOR_EXCEPTION(transposeA ==
true && C.
getRowMap()->isSameAs(*A.
getDomainMap()) ==
false,
266 bool haveMultiplyDoFillComplete = call_FillComplete_on_result && doOptimizeStorage;
269 #if defined(HAVE_XPETRA_EPETRA) && defined(HAVE_XPETRA_EPETRAEXT) 270 throw(
Xpetra::Exceptions::RuntimeError(
"Xpetra::MatrixMatrix::Multiply only available for GO=int or GO=long long with EpetraNode (Serial or OpenMP depending on configuration)"));
276 #ifdef HAVE_XPETRA_TPETRA 283 Tpetra::MatrixMatrix::Multiply(tpA, transposeA, tpB, transposeB, tpC, haveMultiplyDoFillComplete, label, params);
289 if (call_FillComplete_on_result && !haveMultiplyDoFillComplete) {
290 RCP<Teuchos::ParameterList> fillParams = rcp(
new Teuchos::ParameterList());
291 fillParams->set(
"Optimize Storage", doOptimizeStorage);
298 RCP<Matrix> rcpA = Teuchos::rcp_const_cast<
Matrix>(Teuchos::rcpFromRef(A));
299 RCP<Matrix> rcpB = Teuchos::rcp_const_cast<
Matrix>(Teuchos::rcpFromRef(B));
300 C.
CreateView(
"stridedMaps", rcpA, transposeA, rcpB, transposeB);
325 static RCP<Matrix>
Multiply(
const Matrix& A,
bool transposeA,
const Matrix& B,
bool transposeB, RCP<Matrix> C_in,
326 Teuchos::FancyOStream& fos,
327 bool doFillComplete =
true,
328 bool doOptimizeStorage =
true,
329 const std::string & label = std::string(),
330 const RCP<ParameterList>& params = null) {
336 RCP<Matrix> C = C_in;
338 if (C == Teuchos::null) {
339 double nnzPerRow = Teuchos::as<double>(0);
348 nnzPerRow *= nnzPerRow;
351 if (totalNnz < minNnz)
355 fos <<
"Matrix product nnz per row estimate = " << Teuchos::as<LO>(nnzPerRow) << std::endl;
363 fos <<
"Reuse C pattern" << std::endl;
366 Multiply(A, transposeA, B, transposeB, *C, doFillComplete, doOptimizeStorage, label, params);
381 static RCP<Matrix>
Multiply(
const Matrix& A,
bool transposeA,
const Matrix& B,
bool transposeB, Teuchos::FancyOStream &fos,
382 bool callFillCompleteOnResult =
true,
bool doOptimizeStorage =
true,
const std::string& label = std::string(),
383 const RCP<ParameterList>& params = null) {
384 return Multiply(A, transposeA, B, transposeB, Teuchos::null, fos, callFillCompleteOnResult, doOptimizeStorage, label, params);
387 #ifdef HAVE_XPETRA_EPETRAEXT 391 Teuchos::FancyOStream& fos) {
392 throw(
Xpetra::Exceptions::RuntimeError(
"MLTwoMatrixMultiply only available for GO=int or GO=long long with EpetraNode (Serial or OpenMP depending on configuration)"));
393 TEUCHOS_UNREACHABLE_RETURN(Teuchos::null);
395 #endif //ifdef HAVE_XPETRA_EPETRAEXT 409 Teuchos::FancyOStream& fos,
410 bool doFillComplete =
true,
411 bool doOptimizeStorage =
true) {
413 "TwoMatrixMultiply for BlockedCrsMatrix not implemented for transposeA==true or transposeB==true");
422 RCP<BlockedCrsMatrix> C = rcp(
new BlockedCrsMatrix(rgmapextractor, domapextractor, 33 ));
424 for (
size_t i = 0; i < A.
Rows(); ++i) {
425 for (
size_t j = 0; j < B.
Cols(); ++j) {
428 for (
size_t l = 0; l < B.
Rows(); ++l) {
432 if (crmat1.is_null() || crmat2.is_null())
435 RCP<CrsMatrixWrap> crop1 = Teuchos::rcp_dynamic_cast<
CrsMatrixWrap>(crmat1);
436 RCP<CrsMatrixWrap> crop2 = Teuchos::rcp_dynamic_cast<
CrsMatrixWrap>(crmat2);
438 "A and B must be either both (compatible) BlockedCrsMatrix objects or both CrsMatrixWrap objects.");
441 if (!crop1.is_null())
442 Teuchos::rcp_const_cast<CrsGraph>(crmat1->getCrsGraph())->computeGlobalConstants();
443 if (!crop2.is_null())
444 Teuchos::rcp_const_cast<CrsGraph>(crmat2->getCrsGraph())->computeGlobalConstants();
447 "crmat1 does not have global constants");
449 "crmat2 does not have global constants");
451 if (crmat1->getGlobalNumEntries() == 0 || crmat2->getGlobalNumEntries() == 0)
455 RCP<Matrix> temp = Teuchos::null;
457 if(crop1 != Teuchos::null && crop2 != Teuchos::null)
458 temp =
Multiply (*crop1,
false, *crop2,
false, fos);
460 RCP<BlockedCrsMatrix> bop1 = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(crmat1);
461 RCP<BlockedCrsMatrix> bop2 = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(crmat2);
462 TEUCHOS_TEST_FOR_EXCEPTION(bop1.is_null()==
true,
Xpetra::Exceptions::BadCast,
"A is not a BlockedCrsMatrix. (TwoMatrixMultiplyBlock)");
463 TEUCHOS_TEST_FOR_EXCEPTION(bop2.is_null()==
true,
Xpetra::Exceptions::BadCast,
"B is not a BlockedCrsMatrix. (TwoMatrixMultiplyBlock)");
464 TEUCHOS_TEST_FOR_EXCEPTION(bop1->Cols()!=bop2->Rows(),
Xpetra::Exceptions::RuntimeError,
"A has " << bop1->Cols() <<
" columns and B has " << bop2->Rows() <<
" rows. Matrices are not compatible! (TwoMatrixMultiplyBlock)");
465 TEUCHOS_TEST_FOR_EXCEPTION(bop1->getDomainMap()->isSameAs(*(bop2->getRangeMap()))==
false,
Xpetra::Exceptions::RuntimeError,
"Domain map of A is not the same as range map of B. Matrices are not compatible! (TwoMatrixMultiplyBlock)");
468 temp =
TwoMatrixMultiplyBlock(*bop1, transposeA, *bop2, transposeB, fos, doFillComplete, doOptimizeStorage);
470 RCP<BlockedCrsMatrix> btemp = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(temp);
471 TEUCHOS_TEST_FOR_EXCEPTION(btemp->Rows()!=bop1->Rows(),
Xpetra::Exceptions::RuntimeError,
"Number of block rows of local blocked operator is " << btemp->Rows() <<
" but should be " << bop1->Rows() <<
". (TwoMatrixMultiplyBlock)");
472 TEUCHOS_TEST_FOR_EXCEPTION(btemp->Cols()!=bop2->Cols(),
Xpetra::Exceptions::RuntimeError,
"Number of block cols of local blocked operator is " << btemp->Cols() <<
" but should be " << bop2->Cols() <<
". (TwoMatrixMultiplyBlock)");
473 TEUCHOS_TEST_FOR_EXCEPTION(btemp->getRangeMapExtractor()->getFullMap()->isSameAs(*(bop1->getRangeMapExtractor()->getFullMap())) ==
false,
Xpetra::Exceptions::RuntimeError,
"Range map of local blocked operator should be same as first operator. (TwoMatrixMultiplyBlock)");
474 TEUCHOS_TEST_FOR_EXCEPTION(btemp->getDomainMapExtractor()->getFullMap()->isSameAs(*(bop2->getDomainMapExtractor()->getFullMap())) ==
false,
Xpetra::Exceptions::RuntimeError,
"Domain map of local blocked operator should be same as second operator. (TwoMatrixMultiplyBlock)");
475 TEUCHOS_TEST_FOR_EXCEPTION(btemp->getRangeMapExtractor()->getThyraMode() != bop1->getRangeMapExtractor()->getThyraMode(),
Xpetra::Exceptions::RuntimeError,
"Thyra mode of local range map extractor incompatible with range map extractor of A (TwoMatrixMultiplyBlock)");
476 TEUCHOS_TEST_FOR_EXCEPTION(btemp->getDomainMapExtractor()->getThyraMode() != bop2->getDomainMapExtractor()->getThyraMode(),
Xpetra::Exceptions::RuntimeError,
"Thyra mode of local domain map extractor incompatible with domain map extractor of B (TwoMatrixMultiplyBlock)");
481 RCP<Matrix> addRes = null;
490 if (!Cij.is_null()) {
491 if (Cij->isFillComplete())
494 C->setMatrix(i, j, Cij);
496 C->setMatrix(i, j, Teuchos::null);
524 throw Exceptions::RuntimeError(
"TwoMatrixAdd for Epetra matrices needs <double,int,int> for Scalar, LocalOrdinal and GlobalOrdinal.");
526 #ifdef HAVE_XPETRA_TPETRA 530 Tpetra::MatrixMatrix::Add(tpA, transposeA, alpha, tpB, beta);
551 const Matrix& B,
bool transposeB,
const SC& beta,
552 RCP<Matrix>& C, Teuchos::FancyOStream &fos,
bool AHasFixedNnzPerRow =
false) {
554 RCP<const Matrix> rcpA = Teuchos::rcpFromRef(A);
555 RCP<const Matrix> rcpB = Teuchos::rcpFromRef(B);
556 RCP<const BlockedCrsMatrix> rcpBopA = Teuchos::rcp_dynamic_cast<
const BlockedCrsMatrix>(rcpA);
557 RCP<const BlockedCrsMatrix> rcpBopB = Teuchos::rcp_dynamic_cast<
const BlockedCrsMatrix>(rcpB);
563 if(rcpBopA == Teuchos::null && rcpBopB == Teuchos::null) {
569 if (C == Teuchos::null) {
572 size_t numLocalRows = 0;
578 if (maxNzInA == 1 || maxNzInB == 1 || AHasFixedNnzPerRow) {
581 Teuchos::ArrayRCP<size_t> exactNnzPerRow(numLocalRows);
583 if ((maxNzInA == 1 && maxNzInB > 1) || AHasFixedNnzPerRow) {
584 for (
size_t i = 0; i < numLocalRows; ++i)
588 for (
size_t i = 0; i < numLocalRows; ++i)
592 fos <<
"MatrixMatrix::TwoMatrixAdd : special case detected (one matrix has a fixed nnz per row)" 593 <<
", using static profiling" << std::endl;
599 LO nnzToAllocate = Teuchos::as<LO>( (nnzPerRowInA + nnzPerRowInB) * 1.5) + Teuchos::as<LO>(1);
606 fos <<
"nnzPerRowInA = " << nnzPerRowInA <<
", nnzPerRowInB = " << nnzPerRowInB << std::endl;
607 fos <<
"MatrixMatrix::TwoMatrixAdd : space allocated per row = " << nnzToAllocate
608 <<
", max possible nnz per row in sum = " << maxPossible
614 fos <<
"MatrixMatrix::TwoMatrixAdd : ** WARNING ** estimate could be badly wrong because second summand is transposed" << std::endl;
620 #ifdef HAVE_XPETRA_TPETRA 625 Tpetra::MatrixMatrix::Add(tpA, transposeA, alpha, tpB, transposeB, beta, tpC);
631 if (A.
IsView(
"stridedMaps")) C->CreateView(
"stridedMaps", rcpFromRef(A));
632 if (B.
IsView(
"stridedMaps")) C->CreateView(
"stridedMaps", rcpFromRef(B));
636 else if(rcpBopA == Teuchos::null && rcpBopB != Teuchos::null) {
637 RCP<const MapExtractor> rgmapextractor = rcpBopB->getRangeMapExtractor();
638 RCP<const MapExtractor> domapextractor = rcpBopB->getDomainMapExtractor();
644 for (
size_t j = 0; j < rcpBopB->Cols(); ++j) {
645 RCP<Matrix> Cij = Teuchos::null;
646 if(rcpA != Teuchos::null &&
647 rcpBopB->getMatrix(i,j)!=Teuchos::null) {
650 *(rcpBopB->getMatrix(i,j)), transposeB, beta,
651 Cij, fos, AHasFixedNnzPerRow);
652 }
else if (rcpA == Teuchos::null &&
653 rcpBopB->getMatrix(i,j)!=Teuchos::null) {
654 Cij = rcpBopB->getMatrix(i,j);
655 }
else if (rcpA != Teuchos::null &&
656 rcpBopB->getMatrix(i,j)==Teuchos::null) {
657 Cij = Teuchos::rcp_const_cast<
Matrix>(rcpA);
662 if (!Cij.is_null()) {
663 if (Cij->isFillComplete())
666 bC->setMatrix(i, j, Cij);
668 bC->setMatrix(i, j, Teuchos::null);
673 else if(rcpBopA != Teuchos::null && rcpBopB == Teuchos::null) {
674 RCP<const MapExtractor> rgmapextractor = rcpBopA->getRangeMapExtractor();
675 RCP<const MapExtractor> domapextractor = rcpBopA->getDomainMapExtractor();
680 for (
size_t i = 0; i < rcpBopA->Rows(); ++i) {
681 RCP<Matrix> Cij = Teuchos::null;
682 if(rcpBopA->getMatrix(i,j)!=Teuchos::null &&
683 rcpB!=Teuchos::null) {
685 TwoMatrixAdd(*(rcpBopA->getMatrix(i,j)), transposeA, alpha,
686 *rcpB, transposeB, beta,
687 Cij, fos, AHasFixedNnzPerRow);
688 }
else if (rcpBopA->getMatrix(i,j) == Teuchos::null &&
689 rcpB!=Teuchos::null) {
690 Cij = Teuchos::rcp_const_cast<
Matrix>(rcpB);
691 }
else if (rcpBopA->getMatrix(i,j) != Teuchos::null &&
692 rcpB==Teuchos::null) {
693 Cij = rcpBopA->getMatrix(i,j);
698 if (!Cij.is_null()) {
699 if (Cij->isFillComplete())
702 bC->setMatrix(i, j, Cij);
704 bC->setMatrix(i, j, Teuchos::null);
714 TEUCHOS_TEST_FOR_EXCEPTION(rcpBopA->Rows()!=rcpBopB->Rows(),
Xpetra::Exceptions::RuntimeError,
"A has " << rcpBopA->Rows() <<
" rows and B has " << rcpBopA->Rows() <<
" rows. Matrices are not compatible! (TwoMatrixAdd)");
715 TEUCHOS_TEST_FOR_EXCEPTION(rcpBopA->Rows()!=rcpBopB->Rows(),
Xpetra::Exceptions::RuntimeError,
"A has " << rcpBopA->Cols() <<
" cols and B has " << rcpBopA->Cols() <<
" cols. Matrices are not compatible! (TwoMatrixAdd)");
716 TEUCHOS_TEST_FOR_EXCEPTION(rcpBopA->getRangeMap()->isSameAs(*(rcpBopB->getRangeMap()))==
false,
Xpetra::Exceptions::RuntimeError,
"Range map of A is not the same as range map of B. Matrices are not compatible! (TwoMatrixAdd)");
717 TEUCHOS_TEST_FOR_EXCEPTION(rcpBopA->getDomainMap()->isSameAs(*(rcpBopB->getDomainMap()))==
false,
Xpetra::Exceptions::RuntimeError,
"Domain map of A is not the same as domain map of B. Matrices are not compatible! (TwoMatrixAdd)");
718 TEUCHOS_TEST_FOR_EXCEPTION(rcpBopA->getRangeMapExtractor()->getThyraMode() != rcpBopB->getRangeMapExtractor()->getThyraMode(),
Xpetra::Exceptions::RuntimeError,
"Different Thyra/Xpetra style gids in RangeMapExtractor of A and B. Matrices are not compatible! (TwoMatrixAdd)");
719 TEUCHOS_TEST_FOR_EXCEPTION(rcpBopA->getDomainMapExtractor()->getThyraMode() != rcpBopB->getDomainMapExtractor()->getThyraMode(),
Xpetra::Exceptions::RuntimeError,
"Different Thyra/Xpetra style gids in DomainMapExtractor of A and B. Matrices are not compatible! (TwoMatrixAdd)");
721 RCP<const MapExtractor> rgmapextractor = rcpBopA->getRangeMapExtractor();
722 RCP<const MapExtractor> domapextractor = rcpBopB->getDomainMapExtractor();
726 for (
size_t i = 0; i < rcpBopA->Rows(); ++i) {
727 for (
size_t j = 0; j < rcpBopB->Cols(); ++j) {
729 RCP<Matrix> Cij = Teuchos::null;
730 if(rcpBopA->getMatrix(i,j)!=Teuchos::null &&
731 rcpBopB->getMatrix(i,j)!=Teuchos::null) {
733 TwoMatrixAdd(*(rcpBopA->getMatrix(i,j)), transposeA, alpha,
734 *(rcpBopB->getMatrix(i,j)), transposeB, beta,
735 Cij, fos, AHasFixedNnzPerRow);
736 }
else if (rcpBopA->getMatrix(i,j) == Teuchos::null &&
737 rcpBopB->getMatrix(i,j)!=Teuchos::null) {
738 Cij = rcpBopB->getMatrix(i,j);
739 }
else if (rcpBopA->getMatrix(i,j) != Teuchos::null &&
740 rcpBopB->getMatrix(i,j)==Teuchos::null) {
741 Cij = rcpBopA->getMatrix(i,j);
746 if (!Cij.is_null()) {
747 if (Cij->isFillComplete())
750 bC->setMatrix(i, j, Cij);
752 bC->setMatrix(i, j, Teuchos::null);
764 #ifdef HAVE_XPETRA_EPETRA 801 const Matrix& B,
bool transposeB,
803 bool call_FillComplete_on_result =
true,
804 bool doOptimizeStorage =
true,
805 const std::string & label = std::string(),
806 const RCP<ParameterList>& params = null) {
807 TEUCHOS_TEST_FOR_EXCEPTION(transposeA ==
false && C.
getRowMap()->isSameAs(*A.
getRowMap()) ==
false,
809 TEUCHOS_TEST_FOR_EXCEPTION(transposeA ==
true && C.
getRowMap()->isSameAs(*A.
getDomainMap()) ==
false,
815 bool haveMultiplyDoFillComplete = call_FillComplete_on_result && doOptimizeStorage;
818 #if defined(HAVE_XPETRA_EPETRA) && defined(HAVE_XPETRA_EPETRAEXT) 823 int i = EpetraExt::MatrixMatrix::Multiply(epA, transposeA, epB, transposeB, epC, haveMultiplyDoFillComplete);
824 if (haveMultiplyDoFillComplete) {
835 std::ostringstream buf;
837 std::string msg =
"EpetraExt::MatrixMatrix::Multiply return value of " + buf.str();
845 #ifdef HAVE_XPETRA_TPETRA 846 # if ((defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_OPENMP) || !defined(HAVE_TPETRA_INST_INT_INT))) || \ 847 (!defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_SERIAL) || !defined(HAVE_TPETRA_INST_INT_INT)))) 856 Tpetra::MatrixMatrix::Multiply(tpA, transposeA, tpB, transposeB, tpC, haveMultiplyDoFillComplete, label, params);
863 if (call_FillComplete_on_result && !haveMultiplyDoFillComplete) {
864 RCP<Teuchos::ParameterList> fillParams = rcp(
new Teuchos::ParameterList());
865 fillParams->set(
"Optimize Storage",doOptimizeStorage);
872 RCP<Matrix> rcpA = Teuchos::rcp_const_cast<
Matrix>(Teuchos::rcpFromRef(A));
873 RCP<Matrix> rcpB = Teuchos::rcp_const_cast<
Matrix>(Teuchos::rcpFromRef(B));
874 C.
CreateView(
"stridedMaps", rcpA, transposeA, rcpB, transposeB);
900 const Matrix& B,
bool transposeB,
902 Teuchos::FancyOStream& fos,
903 bool doFillComplete =
true,
904 bool doOptimizeStorage =
true,
905 const std::string & label = std::string(),
906 const RCP<ParameterList>& params = null) {
913 #if defined(HAVE_XPETRA_EPETRA) && defined(HAVE_XPETRA_EPETRAEXT) && defined(HAVE_XPETRA_ML_MMM) 919 RCP<Matrix> C = Convert_Epetra_CrsMatrix_ToXpetra_CrsMatrixWrap<SC,LO,GO,NO> (epC);
920 if (doFillComplete) {
921 RCP<Teuchos::ParameterList> fillParams = rcp(
new Teuchos::ParameterList());
922 fillParams->set(
"Optimize Storage", doOptimizeStorage);
929 C->CreateView(
"stridedMaps", rcpFromRef(A), transposeA, rcpFromRef(B), transposeB);
933 #endif // EPETRA + EPETRAEXT + ML 936 RCP<Matrix> C = C_in;
938 if (C == Teuchos::null) {
939 double nnzPerRow = Teuchos::as<double>(0);
948 nnzPerRow *= nnzPerRow;
951 if (totalNnz < minNnz)
955 fos <<
"Matrix product nnz per row estimate = " << Teuchos::as<LO>(nnzPerRow) << std::endl;
964 fos <<
"Reuse C pattern" << std::endl;
967 Multiply(A, transposeA, B, transposeB, *C, doFillComplete, doOptimizeStorage, label, params);
983 const Matrix& B,
bool transposeB,
984 Teuchos::FancyOStream &fos,
985 bool callFillCompleteOnResult =
true,
986 bool doOptimizeStorage =
true,
987 const std::string & label = std::string(),
988 const RCP<ParameterList>& params = null) {
989 return Multiply(A, transposeA, B, transposeB, Teuchos::null, fos, callFillCompleteOnResult, doOptimizeStorage, label, params);
992 #if defined(HAVE_XPETRA_EPETRA) && defined(HAVE_XPETRA_EPETRAEXT) 996 Teuchos::FancyOStream& fos) {
997 #if defined(HAVE_XPETRA_ML_MMM) // Note: this is currently not supported 999 ML_Comm_Create(&comm);
1000 fos <<
"****** USING ML's MATRIX MATRIX MULTIPLY ******" << std::endl;
1005 ML_Comm_Set_UsrComm(comm,Mcomm->
GetMpiComm());
1008 EpetraExt::CrsMatrix_SolverMap Atransform;
1009 EpetraExt::CrsMatrix_SolverMap Btransform;
1010 const Epetra_CrsMatrix& A = Atransform(const_cast<Epetra_CrsMatrix&>(epA));
1011 const Epetra_CrsMatrix& B = Btransform(const_cast<Epetra_CrsMatrix&>(epB));
1017 ML_Operator* ml_As = ML_Operator_Create(comm);
1018 ML_Operator* ml_Bs = ML_Operator_Create(comm);
1019 ML_Operator_WrapEpetraCrsMatrix(const_cast<Epetra_CrsMatrix*>(&A),ml_As);
1020 ML_Operator_WrapEpetraCrsMatrix(const_cast<Epetra_CrsMatrix*>(&B),ml_Bs);
1021 ML_Operator* ml_AtimesB = ML_Operator_Create(comm);
1023 Teuchos::TimeMonitor tm(*Teuchos::TimeMonitor::getNewTimer(
"ML_2matmult kernel"));
1024 ML_2matmult(ml_As,ml_Bs,ml_AtimesB,ML_CSR_MATRIX);
1026 ML_Operator_Destroy(&ml_As);
1027 ML_Operator_Destroy(&ml_Bs);
1032 int N_local = ml_AtimesB->invec_leng;
1033 ML_CommInfoOP* getrow_comm = ml_AtimesB->getrow->pre_comm;
1035 ML_Comm* comm_AB = ml_AtimesB->comm;
1041 for (
int i = 0; i < getrow_comm->N_neighbors; i++) {
1042 N_rcvd += (getrow_comm->neighbors)[i].N_rcv;
1043 N_send += (getrow_comm->neighbors)[i].N_send;
1044 if ( ((getrow_comm->neighbors)[i].N_rcv != 0) &&
1045 ((getrow_comm->neighbors)[i].rcv_list != NULL) ) flag = 1;
1049 std::vector<double> dtemp(N_local + N_rcvd + 1);
1050 std::vector<int> cmap (N_local + N_rcvd + 1);
1051 for (
int i = 0; i < N_local; ++i) {
1053 dtemp[i] = (double) cmap[i];
1055 ML_cheap_exchange_bdry(&dtemp[0],getrow_comm,N_local,N_send,comm_AB);
1057 int count = N_local;
1058 const int neighbors = getrow_comm->N_neighbors;
1059 for (
int i = 0; i < neighbors; i++) {
1060 const int nrcv = getrow_comm->neighbors[i].N_rcv;
1061 for (
int j = 0; j < nrcv; j++)
1062 cmap[getrow_comm->neighbors[i].rcv_list[j]] = (
int) dtemp[count++];
1065 for (
int i = 0; i < N_local+N_rcvd; ++i)
1066 cmap[i] = (
int)dtemp[i];
1084 int educatedguess = 0;
1085 for (
int i = 0; i < myrowlength; ++i) {
1087 ML_get_matrix_row(ml_AtimesB, 1, &i, &allocated, &bindx, &val, &rowlength, 0);
1088 if (rowlength>educatedguess)
1089 educatedguess = rowlength;
1095 std::vector<int> gcid(educatedguess);
1096 for (
int i = 0; i < myrowlength; ++i) {
1097 const int grid = rowmap.
GID(i);
1099 ML_get_matrix_row(ml_AtimesB, 1, &i, &allocated, &bindx, &val, &rowlength, 0);
1100 if (!rowlength)
continue;
1101 if ((
int)gcid.size() < rowlength) gcid.resize(rowlength);
1102 for (
int j = 0; j < rowlength; ++j) {
1103 gcid[j] = gcmap.GID(bindx[j]);
1107 int err = result->InsertGlobalValues(grid, rowlength, val, &gcid[0]);
1108 if (err != 0 && err != 1) {
1109 std::ostringstream errStr;
1110 errStr <<
"Epetra_CrsMatrix::InsertGlobalValues returned err=" << err;
1115 if (bindx) ML_free(bindx);
1116 if (val) ML_free(val);
1117 ML_Operator_Destroy(&ml_AtimesB);
1118 ML_Comm_Destroy(&comm);
1121 #else // no MUELU_ML 1123 "No ML multiplication available. This feature is currently not supported by Xpetra.");
1124 TEUCHOS_UNREACHABLE_RETURN(Teuchos::null);
1127 #endif //ifdef HAVE_XPETRA_EPETRAEXT 1141 Teuchos::FancyOStream& fos,
1142 bool doFillComplete =
true,
1143 bool doOptimizeStorage =
true) {
1145 "TwoMatrixMultiply for BlockedCrsMatrix not implemented for transposeA==true or transposeB==true");
1154 RCP<BlockedCrsMatrix> C = rcp(
new BlockedCrsMatrix(rgmapextractor, domapextractor, 33 ));
1156 for (
size_t i = 0; i < A.
Rows(); ++i) {
1157 for (
size_t j = 0; j < B.
Cols(); ++j) {
1160 for (
size_t l = 0; l < B.
Rows(); ++l) {
1164 if (crmat1.is_null() || crmat2.is_null())
1167 RCP<CrsMatrixWrap> crop1 = Teuchos::rcp_dynamic_cast<
CrsMatrixWrap>(crmat1);
1168 RCP<CrsMatrixWrap> crop2 = Teuchos::rcp_dynamic_cast<
CrsMatrixWrap>(crmat2);
1170 "A and B must be either both (compatible) BlockedCrsMatrix objects or both CrsMatrixWrap objects.");
1173 if (!crop1.is_null())
1174 Teuchos::rcp_const_cast<CrsGraph>(crmat1->getCrsGraph())->computeGlobalConstants();
1175 if (!crop2.is_null())
1176 Teuchos::rcp_const_cast<CrsGraph>(crmat2->getCrsGraph())->computeGlobalConstants();
1179 "crmat1 does not have global constants");
1181 "crmat2 does not have global constants");
1183 if (crmat1->getGlobalNumEntries() == 0 || crmat2->getGlobalNumEntries() == 0)
1188 RCP<Matrix> temp = Teuchos::null;
1190 if(crop1 != Teuchos::null && crop2 != Teuchos::null)
1191 temp =
Multiply (*crop1,
false, *crop2,
false, fos);
1193 RCP<BlockedCrsMatrix> bop1 = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(crmat1);
1194 RCP<BlockedCrsMatrix> bop2 = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(crmat2);
1195 TEUCHOS_TEST_FOR_EXCEPTION(bop1.is_null()==
true,
Xpetra::Exceptions::BadCast,
"A is not a BlockedCrsMatrix. (TwoMatrixMultiplyBlock)");
1196 TEUCHOS_TEST_FOR_EXCEPTION(bop2.is_null()==
true,
Xpetra::Exceptions::BadCast,
"B is not a BlockedCrsMatrix. (TwoMatrixMultiplyBlock)");
1197 TEUCHOS_TEST_FOR_EXCEPTION(bop1->Cols()!=bop2->Rows(),
Xpetra::Exceptions::RuntimeError,
"A has " << bop1->Cols() <<
" columns and B has " << bop2->Rows() <<
" rows. Matrices are not compatible! (TwoMatrixMultiplyBlock)");
1198 TEUCHOS_TEST_FOR_EXCEPTION(bop1->getDomainMap()->isSameAs(*(bop2->getRangeMap()))==
false,
Xpetra::Exceptions::RuntimeError,
"Domain map of A is not the same as range map of B. Matrices are not compatible! (TwoMatrixMultiplyBlock)");
1201 temp =
TwoMatrixMultiplyBlock(*bop1, transposeA, *bop2, transposeB, fos, doFillComplete, doOptimizeStorage);
1203 RCP<BlockedCrsMatrix> btemp = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(temp);
1204 TEUCHOS_TEST_FOR_EXCEPTION(btemp->Rows()!=bop1->Rows(),
Xpetra::Exceptions::RuntimeError,
"Number of block rows of local blocked operator is " << btemp->Rows() <<
" but should be " << bop1->Rows() <<
". (TwoMatrixMultiplyBlock)");
1205 TEUCHOS_TEST_FOR_EXCEPTION(btemp->Cols()!=bop2->Cols(),
Xpetra::Exceptions::RuntimeError,
"Number of block cols of local blocked operator is " << btemp->Cols() <<
" but should be " << bop2->Cols() <<
". (TwoMatrixMultiplyBlock)");
1206 TEUCHOS_TEST_FOR_EXCEPTION(btemp->getRangeMapExtractor()->getFullMap()->isSameAs(*(bop1->getRangeMapExtractor()->getFullMap())) ==
false,
Xpetra::Exceptions::RuntimeError,
"Range map of local blocked operator should be same as first operator. (TwoMatrixMultiplyBlock)");
1207 TEUCHOS_TEST_FOR_EXCEPTION(btemp->getDomainMapExtractor()->getFullMap()->isSameAs(*(bop2->getDomainMapExtractor()->getFullMap())) ==
false,
Xpetra::Exceptions::RuntimeError,
"Domain map of local blocked operator should be same as second operator. (TwoMatrixMultiplyBlock)");
1208 TEUCHOS_TEST_FOR_EXCEPTION(btemp->getRangeMapExtractor()->getThyraMode() != bop1->getRangeMapExtractor()->getThyraMode(),
Xpetra::Exceptions::RuntimeError,
"Thyra mode of local range map extractor incompatible with range map extractor of A (TwoMatrixMultiplyBlock)");
1209 TEUCHOS_TEST_FOR_EXCEPTION(btemp->getDomainMapExtractor()->getThyraMode() != bop2->getDomainMapExtractor()->getThyraMode(),
Xpetra::Exceptions::RuntimeError,
"Thyra mode of local domain map extractor incompatible with domain map extractor of B (TwoMatrixMultiplyBlock)");
1214 RCP<Matrix> addRes = null;
1223 if (!Cij.is_null()) {
1224 if (Cij->isFillComplete())
1227 C->setMatrix(i, j, Cij);
1229 C->setMatrix(i, j, Teuchos::null);
1254 "TwoMatrixAdd: matrix row maps are not the same.");
1257 #if defined(HAVE_XPETRA_EPETRA) && defined(HAVE_XPETRA_EPETRAEXT) 1262 int rv = EpetraExt::MatrixMatrix::Add(epA, transposeA, alpha, epB, beta);
1266 std::ostringstream buf;
1271 #ifdef HAVE_XPETRA_TPETRA 1272 # if ((defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_OPENMP) || !defined(HAVE_TPETRA_INST_INT_INT))) || \ 1273 (!defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_SERIAL) || !defined(HAVE_TPETRA_INST_INT_INT)))) 1279 Tpetra::MatrixMatrix::Add(tpA, transposeA, alpha, tpB, beta);
1301 const Matrix& B,
bool transposeB,
const SC& beta,
1302 RCP<Matrix>& C, Teuchos::FancyOStream &fos,
bool AHasFixedNnzPerRow =
false) {
1303 RCP<const Matrix> rcpA = Teuchos::rcpFromRef(A);
1304 RCP<const Matrix> rcpB = Teuchos::rcpFromRef(B);
1305 RCP<const BlockedCrsMatrix> rcpBopA = Teuchos::rcp_dynamic_cast<
const BlockedCrsMatrix>(rcpA);
1306 RCP<const BlockedCrsMatrix> rcpBopB = Teuchos::rcp_dynamic_cast<
const BlockedCrsMatrix>(rcpB);
1308 if(rcpBopA == Teuchos::null && rcpBopB == Teuchos::null) {
1314 if (C == Teuchos::null) {
1315 size_t maxNzInA = 0;
1316 size_t maxNzInB = 0;
1317 size_t numLocalRows = 0;
1325 if (maxNzInA == 1 || maxNzInB == 1 || AHasFixedNnzPerRow) {
1328 Teuchos::ArrayRCP<size_t> exactNnzPerRow(numLocalRows);
1330 if ((maxNzInA == 1 && maxNzInB > 1) || AHasFixedNnzPerRow) {
1331 for (
size_t i = 0; i < numLocalRows; ++i)
1335 for (
size_t i = 0; i < numLocalRows; ++i)
1339 fos <<
"MatrixMatrix::TwoMatrixAdd : special case detected (one matrix has a fixed nnz per row)" 1340 <<
", using static profiling" << std::endl;
1347 LO nnzToAllocate = Teuchos::as<LO>( (nnzPerRowInA + nnzPerRowInB) * 1.5) + Teuchos::as<LO>(1);
1354 fos <<
"nnzPerRowInA = " << nnzPerRowInA <<
", nnzPerRowInB = " << nnzPerRowInB << std::endl;
1355 fos <<
"MatrixMatrix::TwoMatrixAdd : space allocated per row = " << nnzToAllocate
1356 <<
", max possible nnz per row in sum = " << maxPossible
1362 fos <<
"MatrixMatrix::TwoMatrixAdd : ** WARNING ** estimate could be badly wrong because second summand is transposed" << std::endl;
1366 #if defined(HAVE_XPETRA_EPETRA) && defined(HAVE_XPETRA_EPETRAEXT) 1373 int rv = EpetraExt::MatrixMatrix::Add(epA, transposeA, alpha, epB, transposeB, beta, ref2epC);
1381 #ifdef HAVE_XPETRA_TPETRA 1382 # if ((defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_OPENMP) || !defined(HAVE_TPETRA_INST_INT_INT))) || \ 1383 (!defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_SERIAL) || !defined(HAVE_TPETRA_INST_INT_INT)))) 1390 Tpetra::MatrixMatrix::Add(tpA, transposeA, alpha, tpB, transposeB, beta, tpC);
1398 if (A.
IsView(
"stridedMaps")) C->CreateView(
"stridedMaps", rcpFromRef(A));
1399 if (B.
IsView(
"stridedMaps")) C->CreateView(
"stridedMaps", rcpFromRef(B));
1403 else if(rcpBopA == Teuchos::null && rcpBopB != Teuchos::null) {
1404 RCP<const MapExtractor> rgmapextractor = rcpBopB->getRangeMapExtractor();
1405 RCP<const MapExtractor> domapextractor = rcpBopB->getDomainMapExtractor();
1411 for (
size_t j = 0; j < rcpBopB->Cols(); ++j) {
1412 RCP<Matrix> Cij = Teuchos::null;
1413 if(rcpA != Teuchos::null &&
1414 rcpBopB->getMatrix(i,j)!=Teuchos::null) {
1417 *(rcpBopB->getMatrix(i,j)), transposeB, beta,
1418 Cij, fos, AHasFixedNnzPerRow);
1419 }
else if (rcpA == Teuchos::null &&
1420 rcpBopB->getMatrix(i,j)!=Teuchos::null) {
1421 Cij = rcpBopB->getMatrix(i,j);
1422 }
else if (rcpA != Teuchos::null &&
1423 rcpBopB->getMatrix(i,j)==Teuchos::null) {
1424 Cij = Teuchos::rcp_const_cast<
Matrix>(rcpA);
1426 Cij = Teuchos::null;
1429 if (!Cij.is_null()) {
1430 if (Cij->isFillComplete())
1432 Cij->fillComplete();
1433 bC->setMatrix(i, j, Cij);
1435 bC->setMatrix(i, j, Teuchos::null);
1440 else if(rcpBopA != Teuchos::null && rcpBopB == Teuchos::null) {
1441 RCP<const MapExtractor> rgmapextractor = rcpBopA->getRangeMapExtractor();
1442 RCP<const MapExtractor> domapextractor = rcpBopA->getDomainMapExtractor();
1448 for (
size_t i = 0; i < rcpBopA->Rows(); ++i) {
1449 RCP<Matrix> Cij = Teuchos::null;
1450 if(rcpBopA->getMatrix(i,j)!=Teuchos::null &&
1451 rcpB!=Teuchos::null) {
1453 TwoMatrixAdd(*(rcpBopA->getMatrix(i,j)), transposeA, alpha,
1454 *rcpB, transposeB, beta,
1455 Cij, fos, AHasFixedNnzPerRow);
1456 }
else if (rcpBopA->getMatrix(i,j) == Teuchos::null &&
1457 rcpB!=Teuchos::null) {
1458 Cij = Teuchos::rcp_const_cast<
Matrix>(rcpB);
1459 }
else if (rcpBopA->getMatrix(i,j) != Teuchos::null &&
1460 rcpB==Teuchos::null) {
1461 Cij = rcpBopA->getMatrix(i,j);
1463 Cij = Teuchos::null;
1466 if (!Cij.is_null()) {
1467 if (Cij->isFillComplete())
1469 Cij->fillComplete();
1470 bC->setMatrix(i, j, Cij);
1472 bC->setMatrix(i, j, Teuchos::null);
1482 TEUCHOS_TEST_FOR_EXCEPTION(rcpBopA->Rows()!=rcpBopB->Rows(),
Xpetra::Exceptions::RuntimeError,
"A has " << rcpBopA->Rows() <<
" rows and B has " << rcpBopA->Rows() <<
" rows. Matrices are not compatible! (TwoMatrixAdd)");
1483 TEUCHOS_TEST_FOR_EXCEPTION(rcpBopA->Rows()!=rcpBopB->Rows(),
Xpetra::Exceptions::RuntimeError,
"A has " << rcpBopA->Cols() <<
" cols and B has " << rcpBopA->Cols() <<
" cols. Matrices are not compatible! (TwoMatrixAdd)");
1484 TEUCHOS_TEST_FOR_EXCEPTION(rcpBopA->getRangeMap()->isSameAs(*(rcpBopB->getRangeMap()))==
false,
Xpetra::Exceptions::RuntimeError,
"Range map of A is not the same as range map of B. Matrices are not compatible! (TwoMatrixAdd)");
1485 TEUCHOS_TEST_FOR_EXCEPTION(rcpBopA->getDomainMap()->isSameAs(*(rcpBopB->getDomainMap()))==
false,
Xpetra::Exceptions::RuntimeError,
"Domain map of A is not the same as domain map of B. Matrices are not compatible! (TwoMatrixAdd)");
1486 TEUCHOS_TEST_FOR_EXCEPTION(rcpBopA->getRangeMapExtractor()->getThyraMode() != rcpBopB->getRangeMapExtractor()->getThyraMode(),
Xpetra::Exceptions::RuntimeError,
"Different Thyra/Xpetra style gids in RangeMapExtractor of A and B. Matrices are not compatible! (TwoMatrixAdd)");
1487 TEUCHOS_TEST_FOR_EXCEPTION(rcpBopA->getDomainMapExtractor()->getThyraMode() != rcpBopB->getDomainMapExtractor()->getThyraMode(),
Xpetra::Exceptions::RuntimeError,
"Different Thyra/Xpetra style gids in DomainMapExtractor of A and B. Matrices are not compatible! (TwoMatrixAdd)");
1489 RCP<const MapExtractor> rgmapextractor = rcpBopA->getRangeMapExtractor();
1490 RCP<const MapExtractor> domapextractor = rcpBopB->getDomainMapExtractor();
1495 for (
size_t i = 0; i < rcpBopA->Rows(); ++i) {
1496 for (
size_t j = 0; j < rcpBopB->Cols(); ++j) {
1498 RCP<Matrix> Cij = Teuchos::null;
1499 if(rcpBopA->getMatrix(i,j)!=Teuchos::null &&
1500 rcpBopB->getMatrix(i,j)!=Teuchos::null) {
1503 TwoMatrixAdd(*(rcpBopA->getMatrix(i,j)), transposeA, alpha,
1504 *(rcpBopB->getMatrix(i,j)), transposeB, beta,
1505 Cij, fos, AHasFixedNnzPerRow);
1506 }
else if (rcpBopA->getMatrix(i,j) == Teuchos::null &&
1507 rcpBopB->getMatrix(i,j)!=Teuchos::null) {
1508 Cij = rcpBopB->getMatrix(i,j);
1509 }
else if (rcpBopA->getMatrix(i,j) != Teuchos::null &&
1510 rcpBopB->getMatrix(i,j)==Teuchos::null) {
1511 Cij = rcpBopA->getMatrix(i,j);
1513 Cij = Teuchos::null;
1516 if (!Cij.is_null()) {
1517 if (Cij->isFillComplete())
1520 Cij->fillComplete();
1521 bC->setMatrix(i, j, Cij);
1523 bC->setMatrix(i, j, Teuchos::null);
1568 const Matrix& B,
bool transposeB,
1570 bool call_FillComplete_on_result =
true,
1571 bool doOptimizeStorage =
true,
1572 const std::string & label = std::string(),
1573 const RCP<ParameterList>& params = null) {
1574 TEUCHOS_TEST_FOR_EXCEPTION(transposeA ==
false && C.
getRowMap()->isSameAs(*A.
getRowMap()) ==
false,
1576 TEUCHOS_TEST_FOR_EXCEPTION(transposeA ==
true && C.
getRowMap()->isSameAs(*A.
getDomainMap()) ==
false,
1583 bool haveMultiplyDoFillComplete = call_FillComplete_on_result && doOptimizeStorage;
1586 #if defined(HAVE_XPETRA_EPETRA) && defined(HAVE_XPETRA_EPETRAEXT) 1591 int i = EpetraExt::MatrixMatrix::Multiply(epA, transposeA, epB, transposeB, epC, haveMultiplyDoFillComplete);
1592 if (haveMultiplyDoFillComplete) {
1603 std::ostringstream buf;
1605 std::string msg =
"EpetraExt::MatrixMatrix::Multiply return value of " + buf.str();
1613 #ifdef HAVE_XPETRA_TPETRA 1614 # if ((defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_OPENMP) || !defined(HAVE_TPETRA_INST_INT_LONG_LONG))) || \ 1615 (!defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_SERIAL) || !defined(HAVE_TPETRA_INST_INT_LONG_LONG)))) 1624 Tpetra::MatrixMatrix::Multiply(tpA, transposeA, tpB, transposeB, tpC, haveMultiplyDoFillComplete, label, params);
1631 if(call_FillComplete_on_result && !haveMultiplyDoFillComplete) {
1632 RCP<Teuchos::ParameterList> fillParams = rcp(
new Teuchos::ParameterList());
1633 fillParams->set(
"Optimize Storage",doOptimizeStorage);
1640 RCP<Matrix> rcpA = Teuchos::rcp_const_cast<
Matrix>(Teuchos::rcpFromRef(A));
1641 RCP<Matrix> rcpB = Teuchos::rcp_const_cast<
Matrix>(Teuchos::rcpFromRef(B));
1642 C.
CreateView(
"stridedMaps", rcpA, transposeA, rcpB, transposeB);
1668 const Matrix& B,
bool transposeB,
1670 Teuchos::FancyOStream& fos,
1671 bool doFillComplete =
true,
1672 bool doOptimizeStorage =
true,
1673 const std::string & label = std::string(),
1674 const RCP<ParameterList>& params = null) {
1680 RCP<Matrix> C = C_in;
1682 if (C == Teuchos::null) {
1683 double nnzPerRow = Teuchos::as<double>(0);
1692 nnzPerRow *= nnzPerRow;
1695 if (totalNnz < minNnz)
1699 fos <<
"Matrix product nnz per row estimate = " << Teuchos::as<LO>(nnzPerRow) << std::endl;
1707 fos <<
"Reuse C pattern" << std::endl;
1710 Multiply(A, transposeA, B, transposeB, *C, doFillComplete, doOptimizeStorage, label, params);
1726 const Matrix& B,
bool transposeB,
1727 Teuchos::FancyOStream &fos,
1728 bool callFillCompleteOnResult =
true,
1729 bool doOptimizeStorage =
true,
1730 const std::string & label = std::string(),
1731 const RCP<ParameterList>& params = null) {
1732 return Multiply(A, transposeA, B, transposeB, Teuchos::null, fos, callFillCompleteOnResult, doOptimizeStorage, label, params);
1735 #if defined(HAVE_XPETRA_EPETRA) && defined(HAVE_XPETRA_EPETRAEXT) 1739 Teuchos::FancyOStream& fos) {
1741 "No ML multiplication available. This feature is currently not supported by Xpetra.");
1742 TEUCHOS_UNREACHABLE_RETURN(Teuchos::null);
1744 #endif //ifdef HAVE_XPETRA_EPETRAEXT 1758 Teuchos::FancyOStream& fos,
1759 bool doFillComplete =
true,
1760 bool doOptimizeStorage =
true) {
1762 "TwoMatrixMultiply for BlockedCrsMatrix not implemented for transposeA==true or transposeB==true");
1771 RCP<BlockedCrsMatrix> C = rcp(
new BlockedCrsMatrix(rgmapextractor, domapextractor, 33 ));
1773 for (
size_t i = 0; i < A.
Rows(); ++i) {
1774 for (
size_t j = 0; j < B.
Cols(); ++j) {
1777 for (
size_t l = 0; l < B.
Rows(); ++l) {
1781 if (crmat1.is_null() || crmat2.is_null())
1784 RCP<CrsMatrixWrap> crop1 = Teuchos::rcp_dynamic_cast<
CrsMatrixWrap>(crmat1);
1785 RCP<CrsMatrixWrap> crop2 = Teuchos::rcp_dynamic_cast<
CrsMatrixWrap>(crmat2);
1787 "A and B must be either both (compatible) BlockedCrsMatrix objects or both CrsMatrixWrap objects.");
1790 if (!crop1.is_null())
1791 Teuchos::rcp_const_cast<CrsGraph>(crmat1->getCrsGraph())->computeGlobalConstants();
1792 if (!crop2.is_null())
1793 Teuchos::rcp_const_cast<CrsGraph>(crmat2->getCrsGraph())->computeGlobalConstants();
1796 "crmat1 does not have global constants");
1798 "crmat2 does not have global constants");
1800 if (crmat1->getGlobalNumEntries() == 0 || crmat2->getGlobalNumEntries() == 0)
1804 RCP<Matrix> temp = Teuchos::null;
1806 if(crop1 != Teuchos::null && crop2 != Teuchos::null)
1807 temp =
Multiply (*crop1,
false, *crop2,
false, fos);
1809 RCP<BlockedCrsMatrix> bop1 = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(crmat1);
1810 RCP<BlockedCrsMatrix> bop2 = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(crmat2);
1811 TEUCHOS_TEST_FOR_EXCEPTION(bop1.is_null()==
true,
Xpetra::Exceptions::BadCast,
"A is not a BlockedCrsMatrix. (TwoMatrixMultiplyBlock)");
1812 TEUCHOS_TEST_FOR_EXCEPTION(bop2.is_null()==
true,
Xpetra::Exceptions::BadCast,
"B is not a BlockedCrsMatrix. (TwoMatrixMultiplyBlock)");
1813 TEUCHOS_TEST_FOR_EXCEPTION(bop1->Cols()!=bop2->Rows(),
Xpetra::Exceptions::RuntimeError,
"A has " << bop1->Cols() <<
" columns and B has " << bop2->Rows() <<
" rows. Matrices are not compatible! (TwoMatrixMultiplyBlock)");
1814 TEUCHOS_TEST_FOR_EXCEPTION(bop1->getDomainMap()->isSameAs(*(bop2->getRangeMap()))==
false,
Xpetra::Exceptions::RuntimeError,
"Domain map of A is not the same as range map of B. Matrices are not compatible! (TwoMatrixMultiplyBlock)");
1817 temp =
TwoMatrixMultiplyBlock(*bop1, transposeA, *bop2, transposeB, fos, doFillComplete, doOptimizeStorage);
1819 RCP<BlockedCrsMatrix> btemp = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(temp);
1820 TEUCHOS_TEST_FOR_EXCEPTION(btemp->Rows()!=bop1->Rows(),
Xpetra::Exceptions::RuntimeError,
"Number of block rows of local blocked operator is " << btemp->Rows() <<
" but should be " << bop1->Rows() <<
". (TwoMatrixMultiplyBlock)");
1821 TEUCHOS_TEST_FOR_EXCEPTION(btemp->Cols()!=bop2->Cols(),
Xpetra::Exceptions::RuntimeError,
"Number of block cols of local blocked operator is " << btemp->Cols() <<
" but should be " << bop2->Cols() <<
". (TwoMatrixMultiplyBlock)");
1822 TEUCHOS_TEST_FOR_EXCEPTION(btemp->getRangeMapExtractor()->getFullMap()->isSameAs(*(bop1->getRangeMapExtractor()->getFullMap())) ==
false,
Xpetra::Exceptions::RuntimeError,
"Range map of local blocked operator should be same as first operator. (TwoMatrixMultiplyBlock)");
1823 TEUCHOS_TEST_FOR_EXCEPTION(btemp->getDomainMapExtractor()->getFullMap()->isSameAs(*(bop2->getDomainMapExtractor()->getFullMap())) ==
false,
Xpetra::Exceptions::RuntimeError,
"Domain map of local blocked operator should be same as second operator. (TwoMatrixMultiplyBlock)");
1824 TEUCHOS_TEST_FOR_EXCEPTION(btemp->getRangeMapExtractor()->getThyraMode() != bop1->getRangeMapExtractor()->getThyraMode(),
Xpetra::Exceptions::RuntimeError,
"Thyra mode of local range map extractor incompatible with range map extractor of A (TwoMatrixMultiplyBlock)");
1825 TEUCHOS_TEST_FOR_EXCEPTION(btemp->getDomainMapExtractor()->getThyraMode() != bop2->getDomainMapExtractor()->getThyraMode(),
Xpetra::Exceptions::RuntimeError,
"Thyra mode of local domain map extractor incompatible with domain map extractor of B (TwoMatrixMultiplyBlock)");
1830 RCP<Matrix> addRes = null;
1839 if (!Cij.is_null()) {
1840 if (Cij->isFillComplete())
1843 C->setMatrix(i, j, Cij);
1845 C->setMatrix(i, j, Teuchos::null);
1870 "TwoMatrixAdd: matrix row maps are not the same.");
1873 #if defined(HAVE_XPETRA_EPETRA) && defined(HAVE_XPETRA_EPETRAEXT) 1878 int rv = EpetraExt::MatrixMatrix::Add(epA, transposeA, alpha, epB, beta);
1882 std::ostringstream buf;
1887 #ifdef HAVE_XPETRA_TPETRA 1888 # if ((defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_OPENMP) || !defined(HAVE_TPETRA_INST_INT_LONG_LONG))) || \ 1889 (!defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_SERIAL) || !defined(HAVE_TPETRA_INST_INT_LONG_LONG)))) 1895 Tpetra::MatrixMatrix::Add(tpA, transposeA, alpha, tpB, beta);
1917 const Matrix& B,
bool transposeB,
const SC& beta,
1918 RCP<Matrix>& C, Teuchos::FancyOStream &fos,
bool AHasFixedNnzPerRow =
false) {
1919 RCP<const Matrix> rcpA = Teuchos::rcpFromRef(A);
1920 RCP<const Matrix> rcpB = Teuchos::rcpFromRef(B);
1921 RCP<const BlockedCrsMatrix> rcpBopA = Teuchos::rcp_dynamic_cast<
const BlockedCrsMatrix>(rcpA);
1922 RCP<const BlockedCrsMatrix> rcpBopB = Teuchos::rcp_dynamic_cast<
const BlockedCrsMatrix>(rcpB);
1924 if(rcpBopA == Teuchos::null && rcpBopB == Teuchos::null) {
1926 "TwoMatrixAdd: matrix row maps are not the same.");
1928 if (C == Teuchos::null) {
1929 size_t maxNzInA = 0;
1930 size_t maxNzInB = 0;
1931 size_t numLocalRows = 0;
1938 if (maxNzInA == 1 || maxNzInB == 1 || AHasFixedNnzPerRow) {
1941 Teuchos::ArrayRCP<size_t> exactNnzPerRow(numLocalRows);
1943 if ((maxNzInA == 1 && maxNzInB > 1) || AHasFixedNnzPerRow) {
1944 for (
size_t i = 0; i < numLocalRows; ++i)
1948 for (
size_t i = 0; i < numLocalRows; ++i)
1952 fos <<
"MatrixMatrix::TwoMatrixAdd : special case detected (one matrix has a fixed nnz per row)" 1953 <<
", using static profiling" << std::endl;
1960 LO nnzToAllocate = Teuchos::as<LO>( (nnzPerRowInA + nnzPerRowInB) * 1.5) + Teuchos::as<LO>(1);
1967 fos <<
"nnzPerRowInA = " << nnzPerRowInA <<
", nnzPerRowInB = " << nnzPerRowInB << std::endl;
1968 fos <<
"MatrixMatrix::TwoMatrixAdd : space allocated per row = " << nnzToAllocate
1969 <<
", max possible nnz per row in sum = " << maxPossible
1975 fos <<
"MatrixMatrix::TwoMatrixAdd : ** WARNING ** estimate could be badly wrong because second summand is transposed" << std::endl;
1979 #if defined(HAVE_XPETRA_EPETRA) && defined(HAVE_XPETRA_EPETRAEXT) 1986 int rv = EpetraExt::MatrixMatrix::Add(epA, transposeA, alpha, epB, transposeB, beta, ref2epC);
1994 #ifdef HAVE_XPETRA_TPETRA 1995 # if ((defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_OPENMP) || !defined(HAVE_TPETRA_INST_INT_LONG_LONG))) || \ 1996 (!defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_SERIAL) || !defined(HAVE_TPETRA_INST_INT_LONG_LONG)))) 2003 Tpetra::MatrixMatrix::Add(tpA, transposeA, alpha, tpB, transposeB, beta, tpC);
2011 if (A.
IsView(
"stridedMaps")) C->CreateView(
"stridedMaps", rcpFromRef(A));
2012 if (B.
IsView(
"stridedMaps")) C->CreateView(
"stridedMaps", rcpFromRef(B));
2016 else if(rcpBopA == Teuchos::null && rcpBopB != Teuchos::null) {
2017 RCP<const MapExtractor> rgmapextractor = rcpBopB->getRangeMapExtractor();
2018 RCP<const MapExtractor> domapextractor = rcpBopB->getDomainMapExtractor();
2024 for (
size_t j = 0; j < rcpBopB->Cols(); ++j) {
2025 RCP<Matrix> Cij = Teuchos::null;
2026 if(rcpA != Teuchos::null &&
2027 rcpBopB->getMatrix(i,j)!=Teuchos::null) {
2030 *(rcpBopB->getMatrix(i,j)), transposeB, beta,
2031 Cij, fos, AHasFixedNnzPerRow);
2032 }
else if (rcpA == Teuchos::null &&
2033 rcpBopB->getMatrix(i,j)!=Teuchos::null) {
2034 Cij = rcpBopB->getMatrix(i,j);
2035 }
else if (rcpA != Teuchos::null &&
2036 rcpBopB->getMatrix(i,j)==Teuchos::null) {
2037 Cij = Teuchos::rcp_const_cast<
Matrix>(rcpA);
2039 Cij = Teuchos::null;
2042 if (!Cij.is_null()) {
2043 if (Cij->isFillComplete())
2045 Cij->fillComplete();
2046 bC->setMatrix(i, j, Cij);
2048 bC->setMatrix(i, j, Teuchos::null);
2053 else if(rcpBopA != Teuchos::null && rcpBopB == Teuchos::null) {
2054 RCP<const MapExtractor> rgmapextractor = rcpBopA->getRangeMapExtractor();
2055 RCP<const MapExtractor> domapextractor = rcpBopA->getDomainMapExtractor();
2061 for (
size_t i = 0; i < rcpBopA->Rows(); ++i) {
2062 RCP<Matrix> Cij = Teuchos::null;
2063 if(rcpBopA->getMatrix(i,j)!=Teuchos::null &&
2064 rcpB!=Teuchos::null) {
2066 TwoMatrixAdd(*(rcpBopA->getMatrix(i,j)), transposeA, alpha,
2067 *rcpB, transposeB, beta,
2068 Cij, fos, AHasFixedNnzPerRow);
2069 }
else if (rcpBopA->getMatrix(i,j) == Teuchos::null &&
2070 rcpB!=Teuchos::null) {
2071 Cij = Teuchos::rcp_const_cast<
Matrix>(rcpB);
2072 }
else if (rcpBopA->getMatrix(i,j) != Teuchos::null &&
2073 rcpB==Teuchos::null) {
2074 Cij = rcpBopA->getMatrix(i,j);
2076 Cij = Teuchos::null;
2079 if (!Cij.is_null()) {
2080 if (Cij->isFillComplete())
2082 Cij->fillComplete();
2083 bC->setMatrix(i, j, Cij);
2085 bC->setMatrix(i, j, Teuchos::null);
2095 TEUCHOS_TEST_FOR_EXCEPTION(rcpBopA->Rows()!=rcpBopB->Rows(),
Xpetra::Exceptions::RuntimeError,
"A has " << rcpBopA->Rows() <<
" rows and B has " << rcpBopA->Rows() <<
" rows. Matrices are not compatible! (TwoMatrixAdd)");
2096 TEUCHOS_TEST_FOR_EXCEPTION(rcpBopA->Rows()!=rcpBopB->Rows(),
Xpetra::Exceptions::RuntimeError,
"A has " << rcpBopA->Cols() <<
" cols and B has " << rcpBopA->Cols() <<
" cols. Matrices are not compatible! (TwoMatrixAdd)");
2097 TEUCHOS_TEST_FOR_EXCEPTION(rcpBopA->getRangeMap()->isSameAs(*(rcpBopB->getRangeMap()))==
false,
Xpetra::Exceptions::RuntimeError,
"Range map of A is not the same as range map of B. Matrices are not compatible! (TwoMatrixAdd)");
2098 TEUCHOS_TEST_FOR_EXCEPTION(rcpBopA->getDomainMap()->isSameAs(*(rcpBopB->getDomainMap()))==
false,
Xpetra::Exceptions::RuntimeError,
"Domain map of A is not the same as domain map of B. Matrices are not compatible! (TwoMatrixAdd)");
2099 TEUCHOS_TEST_FOR_EXCEPTION(rcpBopA->getRangeMapExtractor()->getThyraMode() != rcpBopB->getRangeMapExtractor()->getThyraMode(),
Xpetra::Exceptions::RuntimeError,
"Different Thyra/Xpetra style gids in RangeMapExtractor of A and B. Matrices are not compatible! (TwoMatrixAdd)");
2100 TEUCHOS_TEST_FOR_EXCEPTION(rcpBopA->getDomainMapExtractor()->getThyraMode() != rcpBopB->getDomainMapExtractor()->getThyraMode(),
Xpetra::Exceptions::RuntimeError,
"Different Thyra/Xpetra style gids in DomainMapExtractor of A and B. Matrices are not compatible! (TwoMatrixAdd)");
2102 RCP<const MapExtractor> rgmapextractor = rcpBopA->getRangeMapExtractor();
2103 RCP<const MapExtractor> domapextractor = rcpBopB->getDomainMapExtractor();
2108 for (
size_t i = 0; i < rcpBopA->Rows(); ++i) {
2109 for (
size_t j = 0; j < rcpBopB->Cols(); ++j) {
2111 RCP<Matrix> Cij = Teuchos::null;
2112 if(rcpBopA->getMatrix(i,j)!=Teuchos::null &&
2113 rcpBopB->getMatrix(i,j)!=Teuchos::null) {
2116 TwoMatrixAdd(*(rcpBopA->getMatrix(i,j)), transposeA, alpha,
2117 *(rcpBopB->getMatrix(i,j)), transposeB, beta,
2118 Cij, fos, AHasFixedNnzPerRow);
2119 }
else if (rcpBopA->getMatrix(i,j) == Teuchos::null &&
2120 rcpBopB->getMatrix(i,j)!=Teuchos::null) {
2121 Cij = rcpBopB->getMatrix(i,j);
2122 }
else if (rcpBopA->getMatrix(i,j) != Teuchos::null &&
2123 rcpBopB->getMatrix(i,j)==Teuchos::null) {
2124 Cij = rcpBopA->getMatrix(i,j);
2126 Cij = Teuchos::null;
2129 if (!Cij.is_null()) {
2130 if (Cij->isFillComplete())
2133 Cij->fillComplete();
2134 bC->setMatrix(i, j, Cij);
2136 bC->setMatrix(i, j, Teuchos::null);
2145 #endif // HAVE_XPETRA_EPETRA 2149 #define XPETRA_MATRIXMATRIX_SHORT const Epetra_Map & RowMap() const
virtual size_t getNodeMaxNumRowEntries() const =0
Returns the maximum number of entries across all rows/columns on this node.
virtual size_t getNodeNumRows() const =0
Returns the number of matrix rows owned on the calling node.
std::string toString(Xpetra::UnderlyingLib lib)
Convert a Xpetra::UnderlyingLib to a std::string.
static void TwoMatrixAdd(const Matrix &A, bool transposeA, const SC &alpha, const Matrix &B, bool transposeB, const SC &beta, RCP< Matrix > &C, Teuchos::FancyOStream &fos, bool AHasFixedNnzPerRow=false)
Helper function to calculate C = alpha*A + beta*B.
virtual size_t getNodeNumEntries() const =0
Returns the local number of entries in this matrix.
static void TwoMatrixAdd(const Matrix &A, bool transposeA, const SC &alpha, const Matrix &B, bool transposeB, const SC &beta, RCP< Matrix > &C, Teuchos::FancyOStream &fos, bool AHasFixedNnzPerRow=false)
Helper function to calculate C = alpha*A + beta*B.
virtual global_size_t getGlobalNumRows() const =0
Returns the number of global rows in this matrix.
virtual const RCP< const Map > & getRowMap() const
Returns the Map that describes the row distribution in this matrix.
bool isFillComplete() const
Returns true if fillComplete() has been called and the matrix is in compute mode. ...
static RCP< Matrix > Multiply(const Matrix &A, bool transposeA, const Matrix &B, bool transposeB, RCP< Matrix > C_in, Teuchos::FancyOStream &fos, bool doFillComplete=true, bool doOptimizeStorage=true, const std::string &label=std::string(), const RCP< ParameterList > ¶ms=null)
Helper function to do matrix-matrix multiply.
static Epetra_CrsMatrix & Op2NonConstEpetraCrs(const Matrix &Op)
Xpetra utility class containing transformation routines between Xpetra::Matrix and Epetra/Tpetra obje...
virtual void resumeFill(const RCP< ParameterList > ¶ms=null)=0
Exception throws to report errors in the internal logical of the program.
static RCP< BlockedCrsMatrix > TwoMatrixMultiplyBlock(const BlockedCrsMatrix &A, bool transposeA, const BlockedCrsMatrix &B, bool transposeB, Teuchos::FancyOStream &fos, bool doFillComplete=true, bool doOptimizeStorage=true)
Helper function to do matrix-matrix multiply "in-place".
const Epetra_Comm & Comm() const
const Epetra_Map & RangeMap() const
static const Epetra_CrsMatrix & Op2EpetraCrs(const Matrix &Op)
RCP< const MapExtractor > getRangeMapExtractor() const
Returns map extractor class for range map.
Exception indicating invalid cast attempted.
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.
static void TwoMatrixAdd(const Matrix &A, bool transposeA, const SC &alpha, const Matrix &B, bool transposeB, const SC &beta, RCP< Matrix > &C, Teuchos::FancyOStream &fos, bool AHasFixedNnzPerRow=false)
Helper function to calculate C = alpha*A + beta*B.
static RCP< Matrix > Multiply(const Matrix &A, bool transposeA, const Matrix &B, bool transposeB, Teuchos::FancyOStream &fos, bool callFillCompleteOnResult=true, bool doOptimizeStorage=true, const std::string &label=std::string(), const RCP< ParameterList > ¶ms=null)
Helper function to do matrix-matrix multiply.
virtual bool isFillComplete() const =0
Returns true if fillComplete() has been called and the matrix is in compute mode. ...
int NumMyElements() const
void CreateView(viewLabel_t viewLabel, const RCP< const Map > &rowMap, const RCP< const Map > &colMap)
static void Multiply(const Matrix &A, bool transposeA, const Matrix &B, bool transposeB, Matrix &C, bool call_FillComplete_on_result=true, bool doOptimizeStorage=true, const std::string &label=std::string(), const RCP< ParameterList > ¶ms=null)
MPI_Comm GetMpiComm() const
RCP< CrsMatrix > getCrsMatrix() const
static RCP< Matrix > Multiply(const Matrix &A, bool transposeA, const Matrix &B, bool transposeB, RCP< Matrix > C_in, Teuchos::FancyOStream &fos, bool doFillComplete=true, bool doOptimizeStorage=true, const std::string &label=std::string(), const RCP< ParameterList > ¶ms=null)
Helper function to do matrix-matrix multiply.
static Tpetra::CrsMatrix< SC, LO, GO, NO > & Op2NonConstTpetraCrs(const Matrix &Op)
static RCP< Matrix > Multiply(const Matrix &A, bool transposeA, const Matrix &B, bool transposeB, RCP< Matrix > C_in, Teuchos::FancyOStream &fos, bool doFillComplete=true, bool doOptimizeStorage=true, const std::string &label=std::string(), const RCP< ParameterList > ¶ms=null)
Helper function to do matrix-matrix multiply.
virtual size_t getNumEntriesInLocalRow(LocalOrdinal localRow) const =0
Returns the current number of entries on this node in the specified local row.
const Epetra_Map & ColMap() const
static void Multiply(const Matrix &A, bool transposeA, const Matrix &B, bool transposeB, Matrix &C, bool call_FillComplete_on_result=true, bool doOptimizeStorage=true, const std::string &label=std::string(), const RCP< ParameterList > ¶ms=null)
static RCP< BlockedCrsMatrix > TwoMatrixMultiplyBlock(const BlockedCrsMatrix &A, bool transposeA, const BlockedCrsMatrix &B, bool transposeB, Teuchos::FancyOStream &fos, bool doFillComplete=true, bool doOptimizeStorage=true)
Helper function to do matrix-matrix multiply "in-place".
static void TwoMatrixAdd(const Matrix &A, bool transposeA, SC alpha, Matrix &B, SC beta)
Helper function to calculate B = alpha*A + beta*B.
static RCP< const Epetra_CrsMatrix > Op2EpetraCrs(RCP< Matrix > Op)
static void Multiply(const Matrix &A, bool transposeA, const Matrix &B, bool transposeB, Matrix &C, bool call_FillComplete_on_result=true, bool doOptimizeStorage=true, const std::string &label=std::string(), const RCP< ParameterList > ¶ms=null)
static RCP< Epetra_CrsMatrix > Op2NonConstEpetraCrs(RCP< Matrix > Op)
Exception throws to report incompatible objects (like maps).
static void TwoMatrixAdd(const Matrix &A, bool transposeA, SC alpha, Matrix &B, SC beta)
Helper function to calculate B = alpha*A + beta*B.
RCP< const Map > getRangeMap() const
Returns the Map associated with the range of this operator.
virtual global_size_t getGlobalNumEntries() const =0
Returns the global number of entries in this matrix.
Concrete implementation of Xpetra::Matrix.
Teuchos::RCP< Matrix > getMatrix(size_t r, size_t c) const
return block (r,c)
virtual Teuchos::RCP< const Map > getRangeMap() const =0
The Map associated with the range of this operator, which must be compatible with Y...
bool IsView(const viewLabel_t viewLabel) const
static RCP< Epetra_CrsMatrix > MLTwoMatrixMultiply(const Epetra_CrsMatrix &epA, const Epetra_CrsMatrix &epB, Teuchos::FancyOStream &fos)
RCP< const MapExtractor > getDomainMapExtractor() const
Returns map extractor for domain map.
static RCP< Matrix > Build(const RCP< const Map > &rowMap, size_t maxNumEntriesPerRow, Xpetra::ProfileType pftype=Xpetra::DynamicProfile)
Constructor specifying the number of non-zeros for all rows.
static RCP< BlockedCrsMatrix > TwoMatrixMultiplyBlock(const BlockedCrsMatrix &A, bool transposeA, const BlockedCrsMatrix &B, bool transposeB, Teuchos::FancyOStream &fos, bool doFillComplete=true, bool doOptimizeStorage=true)
Helper function to do matrix-matrix multiply "in-place".
virtual size_t Rows() const
number of row blocks
static RCP< Tpetra::CrsMatrix< SC, LO, GO, NO > > Op2NonConstTpetraCrs(RCP< Matrix > Op)
virtual size_t Cols() const
number of column blocks
static RCP< Matrix > Multiply(const Matrix &A, bool transposeA, const Matrix &B, bool transposeB, Teuchos::FancyOStream &fos, bool callFillCompleteOnResult=true, bool doOptimizeStorage=true, const std::string &label=std::string(), const RCP< ParameterList > ¶ms=null)
Helper function to do matrix-matrix multiply.
RCP< const Map > getDomainMap() const
Returns the Map associated with the domain of this operator.
static RCP< Epetra_CrsMatrix > MLTwoMatrixMultiply(const Epetra_CrsMatrix &epA, const Epetra_CrsMatrix &epB, Teuchos::FancyOStream &fos)
static RCP< Epetra_CrsMatrix > MLTwoMatrixMultiply(const Epetra_CrsMatrix &epA, const Epetra_CrsMatrix &epB, Teuchos::FancyOStream &fos)
static void TwoMatrixAdd(const Matrix &A, bool transposeA, SC alpha, Matrix &B, SC beta)
Helper function to calculate B = alpha*A + beta*B.
static const Tpetra::CrsMatrix< SC, LO, GO, NO > & Op2TpetraCrs(const Matrix &Op)
virtual Teuchos::RCP< const Map > getDomainMap() const =0
The Map associated with the domain of this operator, which must be compatible with X...
Xpetra-specific matrix class.
static RCP< const Tpetra::CrsMatrix< SC, LO, GO, NO > > Op2TpetraCrs(RCP< Matrix > Op)
const Epetra_Map & DomainMap() const
static RCP< Matrix > Multiply(const Matrix &A, bool transposeA, const Matrix &B, bool transposeB, Teuchos::FancyOStream &fos, bool callFillCompleteOnResult=true, bool doOptimizeStorage=true, const std::string &label=std::string(), const RCP< ParameterList > ¶ms=null)
Helper function to do matrix-matrix multiply.