51 const Matrix& B,
bool transposeB,
53 bool call_FillComplete_on_result,
54 bool doOptimizeStorage,
55 const std::string& label,
65 bool haveMultiplyDoFillComplete = call_FillComplete_on_result && doOptimizeStorage;
68#if defined(HAVE_XPETRA_EPETRA) && defined(HAVE_XPETRA_EPETRAEXT)
69 throw(
Xpetra::Exceptions::RuntimeError(
"Xpetra::MatrixMatrix::Multiply only available for GO=int or GO=long long with EpetraNode (Serial or OpenMP depending on configuration)"));
75#ifdef HAVE_XPETRA_TPETRA
77 if (helpers::isTpetraCrs(A) && helpers::isTpetraCrs(B) && helpers::isTpetraCrs(C)) {
79 const Tpetra::CrsMatrix<SC, LO, GO, NO>& tpA = helpers::Op2TpetraCrs(A);
80 const Tpetra::CrsMatrix<SC, LO, GO, NO>& tpB = helpers::Op2TpetraCrs(B);
81 Tpetra::CrsMatrix<SC, LO, GO, NO>& tpC = helpers::Op2NonConstTpetraCrs(C);
85 Tpetra::MatrixMatrix::Multiply(tpA, transposeA, tpB, transposeB, tpC, haveMultiplyDoFillComplete, label, params);
86 }
else if (helpers::isTpetraBlockCrs(A) && helpers::isTpetraBlockCrs(B)) {
91 std::cout <<
"WARNING: Using inefficient BlockCrs Multiply Placeholder" << std::endl;
95 using CRS = Tpetra::CrsMatrix<SC, LO, GO, NO>;
103 new_params->set(
"compute global constants",
true);
108 Tpetra::MatrixMatrix::Multiply(*Acrs, transposeA, *Bcrs, transposeB, *tempAc, haveMultiplyDoFillComplete, label, new_params);
117 Ac_w->replaceCrsMatrix(Ac_p);
127 if (call_FillComplete_on_result && !haveMultiplyDoFillComplete) {
129 fillParams->set(
"Optimize Storage", doOptimizeStorage);
136 RCP<Matrix> rcpA = Teuchos::rcp_const_cast<Matrix>(Teuchos::rcpFromRef(A));
137 RCP<Matrix> rcpB = Teuchos::rcp_const_cast<Matrix>(Teuchos::rcpFromRef(B));
138 C.
CreateView(
"stridedMaps", rcpA, transposeA, rcpB, transposeB);
211 bool doOptimizeStorage) {
213 "TwoMatrixMultiply for BlockedCrsMatrix not implemented for transposeA==true or transposeB==true");
224 for (
size_t i = 0; i < A.
Rows(); ++i) {
225 for (
size_t j = 0; j < B.
Cols(); ++j) {
228 for (
size_t l = 0; l < B.
Rows(); ++l) {
237 auto unwrap1 = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(crmat1);
238 auto unwrap2 = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(crmat2);
240 if (unwrap1.is_null() != unwrap2.is_null()) {
241 if (unwrap1 != Teuchos::null && unwrap1->Rows() == 1 && unwrap1->Cols() == 1)
242 crmat1 = unwrap1->getCrsMatrix();
243 if (unwrap2 != Teuchos::null && unwrap2->Rows() == 1 && unwrap2->Cols() == 1)
244 crmat2 = unwrap2->getCrsMatrix();
251 "A and B must be either both (compatible) BlockedCrsMatrix objects or both CrsMatrixWrap objects.");
255 Teuchos::rcp_const_cast<CrsGraph>(crmat1->getCrsGraph())->computeGlobalConstants();
257 Teuchos::rcp_const_cast<CrsGraph>(crmat2->getCrsGraph())->computeGlobalConstants();
260 "crmat1 does not have global constants");
262 "crmat2 does not have global constants");
264 if (crmat1->getGlobalNumEntries() == 0 || crmat2->getGlobalNumEntries() == 0)
270 if (crop1 != Teuchos::null && crop2 != Teuchos::null)
271 temp = Multiply(*crop1,
false, *crop2,
false, fos);
281 temp = TwoMatrixMultiplyBlock(*bop1, transposeA, *bop2, transposeB, fos, doFillComplete, doOptimizeStorage);
304 if (Cij->isFillComplete())
307 C->setMatrix(i, j, Cij);
309 C->setMatrix(i, j, Teuchos::null);
341 const Matrix& B,
bool transposeB,
const SC& beta,
354 if (rcpBopA == Teuchos::null && rcpBopB == Teuchos::null) {
360#ifdef HAVE_XPETRA_TPETRA
361 using tcrs_matrix_type = Tpetra::CrsMatrix<SC, LO, GO, NO>;
363 const tcrs_matrix_type& tpA = helpers::Op2TpetraCrs(A);
364 const tcrs_matrix_type& tpB = helpers::Op2TpetraCrs(B);
365 C = helpers::tpetraAdd(tpA, transposeA, alpha, tpB, transposeB, beta);
371 if (A.
IsView(
"stridedMaps")) C->CreateView(
"stridedMaps", rcpFromRef(A));
372 if (B.
IsView(
"stridedMaps")) C->CreateView(
"stridedMaps", rcpFromRef(B));
376 else if (rcpBopA == Teuchos::null && rcpBopB != Teuchos::null) {
384 for (
size_t j = 0; j < rcpBopB->Cols(); ++j) {
386 if (rcpA != Teuchos::null &&
387 rcpBopB->getMatrix(i, j) != Teuchos::null) {
389 TwoMatrixAdd(*rcpA, transposeA, alpha,
390 *(rcpBopB->getMatrix(i, j)), transposeB, beta,
391 Cij, fos, AHasFixedNnzPerRow);
392 }
else if (rcpA == Teuchos::null &&
393 rcpBopB->getMatrix(i, j) != Teuchos::null) {
394 Cij = rcpBopB->getMatrix(i, j);
395 }
else if (rcpA != Teuchos::null &&
396 rcpBopB->getMatrix(i, j) == Teuchos::null) {
397 Cij = Teuchos::rcp_const_cast<Matrix>(rcpA);
403 if (Cij->isFillComplete())
406 bC->setMatrix(i, j, Cij);
408 bC->setMatrix(i, j, Teuchos::null);
413 else if (rcpBopA != Teuchos::null && rcpBopB == Teuchos::null) {
420 for (
size_t i = 0; i < rcpBopA->Rows(); ++i) {
422 if (rcpBopA->getMatrix(i, j) != Teuchos::null &&
423 rcpB != Teuchos::null) {
425 TwoMatrixAdd(*(rcpBopA->getMatrix(i, j)), transposeA, alpha,
426 *rcpB, transposeB, beta,
427 Cij, fos, AHasFixedNnzPerRow);
428 }
else if (rcpBopA->getMatrix(i, j) == Teuchos::null &&
429 rcpB != Teuchos::null) {
430 Cij = Teuchos::rcp_const_cast<Matrix>(rcpB);
431 }
else if (rcpBopA->getMatrix(i, j) != Teuchos::null &&
432 rcpB == Teuchos::null) {
433 Cij = rcpBopA->getMatrix(i, j);
439 if (Cij->isFillComplete())
442 bC->setMatrix(i, j, Cij);
444 bC->setMatrix(i, j, Teuchos::null);
465 for (
size_t i = 0; i < rcpBopA->Rows(); ++i) {
466 for (
size_t j = 0; j < rcpBopB->Cols(); ++j) {
469 if (rcpBopA->getMatrix(i, j) != Teuchos::null &&
470 rcpBopB->getMatrix(i, j) != Teuchos::null) {
472 TwoMatrixAdd(*(rcpBopA->getMatrix(i, j)), transposeA, alpha,
473 *(rcpBopB->getMatrix(i, j)), transposeB, beta,
474 Cij, fos, AHasFixedNnzPerRow);
475 }
else if (rcpBopA->getMatrix(i, j) == Teuchos::null &&
476 rcpBopB->getMatrix(i, j) != Teuchos::null) {
477 Cij = rcpBopB->getMatrix(i, j);
478 }
else if (rcpBopA->getMatrix(i, j) != Teuchos::null &&
479 rcpBopB->getMatrix(i, j) == Teuchos::null) {
480 Cij = rcpBopA->getMatrix(i, j);
486 if (Cij->isFillComplete())
489 bC->setMatrix(i, j, Cij);
491 bC->setMatrix(i, j, Teuchos::null);