10#ifndef TPETRA_TRIPLEMATRIXMULTIPLY_DEF_HPP
11#define TPETRA_TRIPLEMATRIXMULTIPLY_DEF_HPP
14#include "TpetraExt_MatrixMatrix_ExtraKernels_decl.hpp"
15#include "Teuchos_VerboseObject.hpp"
16#include "Teuchos_Array.hpp"
18#include "Tpetra_ConfigDefs.hpp"
19#include "Tpetra_CrsMatrix.hpp"
21#include "Tpetra_RowMatrixTransposer.hpp"
22#include "Tpetra_ConfigDefs.hpp"
23#include "Tpetra_Map.hpp"
24#include "Tpetra_Export.hpp"
29#include "Teuchos_FancyOStream.hpp"
40#include "TpetraExt_MatrixMatrix_OpenMP.hpp"
41#include "TpetraExt_MatrixMatrix_Cuda.hpp"
42#include "TpetraExt_MatrixMatrix_HIP.hpp"
43#include "TpetraExt_MatrixMatrix_SYCL.hpp"
47namespace TripleMatrixMultiply {
55template <
class Scalar,
68 const std::string& label,
69 const Teuchos::RCP<Teuchos::ParameterList>&
params) {
83#ifdef HAVE_TPETRA_MMM_TIMINGS
84 std::string
prefix_mmm = std::string(
"TpetraExt ") + label + std::string(
": ");
85 using Teuchos::TimeMonitor;
89 const std::string
prefix =
"TpetraExt::TripleMatrixMultiply::MultiplyRAP(): ";
119 const bool newFlag = !
Ac.getGraph()->isLocallyIndexed() && !
Ac.getGraph()->isGloballyIndexed();
121 using Teuchos::ParameterList;
157 prefix <<
"ERROR, inner dimensions of op(R) and op(A) "
158 "must match for matrix-matrix product. op(R) is "
162 prefix <<
"ERROR, inner dimensions of op(A) and op(P) "
163 "must match for matrix-matrix product. op(A) is "
171 prefix <<
"ERROR, dimensions of result Ac must "
172 "match dimensions of op(R) * op(A) * op(P). Ac has "
173 <<
Ac.getGlobalNumRows()
174 <<
" rows, should have at least " <<
Rleft << std::endl);
198#ifdef HAVE_TPETRA_MMM_TIMINGS
229#ifdef HAVE_TPETRA_MMM_TIMINGS
274#ifdef HAVE_TPETRA_MMM_TIMINGS
282 "This parameter should be set to true only for MatrixMatrix operations: the optimization in Epetra that was ported to Tpetra does _not_ take into account the possibility that for any given source PID, a particular GID may not exist on the target PID: i.e. a transfer operation. A fix for this general case is in development.");
289 export_type
exporter = export_type(*
Pprime->getGraph()->getImporter());
296#ifdef HAVE_TPETRA_MMM_STATISTICS
306template <
class Scalar,
310void mult_R_A_P_newmatrix(
311 CrsMatrixStruct<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Rview,
312 CrsMatrixStruct<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Aview,
313 CrsMatrixStruct<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Pview,
314 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Ac,
315 const std::string& label,
316 const Teuchos::RCP<Teuchos::ParameterList>& params) {
317 using Teuchos::Array;
318 using Teuchos::ArrayRCP;
319 using Teuchos::ArrayView;
324 typedef LocalOrdinal LO;
325 typedef GlobalOrdinal GO;
328 typedef Import<LO, GO, NO> import_type;
329 typedef Map<LO, GO, NO> map_type;
332 typedef typename map_type::local_map_type local_map_type;
334 typedef typename KCRS::StaticCrsGraphType graph_t;
335 typedef typename graph_t::row_map_type::non_const_type lno_view_t;
336 typedef typename NO::execution_space execution_space;
337 typedef Kokkos::RangePolicy<execution_space, size_t> range_type;
338 typedef Kokkos::View<LO*, typename lno_view_t::array_layout, typename lno_view_t::device_type> lo_view_t;
340#ifdef HAVE_TPETRA_MMM_TIMINGS
341 std::string prefix_mmm = std::string(
"TpetraExt ") + label + std::string(
": ");
342 using Teuchos::TimeMonitor;
343 RCP<TimeMonitor> MM = rcp(
new TimeMonitor(*(TimeMonitor::getNewTimer(prefix_mmm + std::string(
"RAP M5 Cmap")))));
345 LO LO_INVALID = Teuchos::OrdinalTraits<LO>::invalid();
348 RCP<const import_type> Cimport;
349 RCP<const map_type> Ccolmap;
350 RCP<const import_type> Pimport = Pview.origMatrix->getGraph()->getImporter();
351 RCP<const import_type> Iimport = Pview.importMatrix.is_null() ? Teuchos::null : Pview.importMatrix->getGraph()->getImporter();
352 local_map_type Acolmap_local = Aview.colMap->getLocalMap();
353 local_map_type Prowmap_local = Pview.origMatrix->getRowMap()->getLocalMap();
354 local_map_type Irowmap_local;
355 if (!Pview.importMatrix.is_null()) Irowmap_local = Pview.importMatrix->getRowMap()->getLocalMap();
356 local_map_type Pcolmap_local = Pview.origMatrix->getColMap()->getLocalMap();
357 local_map_type Icolmap_local;
358 if (!Pview.importMatrix.is_null()) Icolmap_local = Pview.importMatrix->getColMap()->getLocalMap();
365 lo_view_t Pcol2Ccol(Kokkos::ViewAllocateWithoutInitializing(
"Pcol2Ccol"), Pview.colMap->getLocalNumElements()), Icol2Ccol;
367 if (Pview.importMatrix.is_null()) {
370 Ccolmap = Pview.colMap;
371 const LO colMapSize =
static_cast<LO
>(Pview.colMap->getLocalNumElements());
373 Kokkos::parallel_for(
374 "Tpetra::mult_R_A_P_newmatrix::Pcol2Ccol_fill",
375 Kokkos::RangePolicy<execution_space, LO>(0, colMapSize),
376 KOKKOS_LAMBDA(
const LO i) {
388 if (!Pimport.is_null() && !Iimport.is_null()) {
389 Cimport = Pimport->setUnion(*Iimport);
390 }
else if (!Pimport.is_null() && Iimport.is_null()) {
391 Cimport = Pimport->setUnion();
392 }
else if (Pimport.is_null() && !Iimport.is_null()) {
393 Cimport = Iimport->setUnion();
395 throw std::runtime_error(
"TpetraExt::RAP status of matrix importers is nonsensical");
397 Ccolmap = Cimport->getTargetMap();
402 TEUCHOS_TEST_FOR_EXCEPTION(!Cimport->getSourceMap()->isSameAs(*Pview.origMatrix->getDomainMap()),
403 std::runtime_error,
"Tpetra::RAP: Import setUnion messed with the DomainMap in an unfortunate way");
410 Kokkos::resize(Icol2Ccol, Pview.importMatrix->getColMap()->getLocalNumElements());
411 local_map_type Ccolmap_local = Ccolmap->getLocalMap();
412 Kokkos::parallel_for(
413 "Tpetra::mult_R_A_P_newmatrix::Pcol2Ccol_getGlobalElement", range_type(0, Pview.origMatrix->getColMap()->getLocalNumElements()), KOKKOS_LAMBDA(
const LO i) {
414 Pcol2Ccol(i) = Ccolmap_local.getLocalElement(Pcolmap_local.getGlobalElement(i));
416 Kokkos::parallel_for(
417 "Tpetra::mult_R_A_P_newmatrix::Icol2Ccol_getGlobalElement", range_type(0, Pview.importMatrix->getColMap()->getLocalNumElements()), KOKKOS_LAMBDA(
const LO i) {
418 Icol2Ccol(i) = Ccolmap_local.getLocalElement(Icolmap_local.getGlobalElement(i));
426 Ac.replaceColMap(Ccolmap);
444 lo_view_t targetMapToOrigRow(Kokkos::ViewAllocateWithoutInitializing(
"targetMapToOrigRow"), Aview.colMap->getLocalNumElements());
445 lo_view_t targetMapToImportRow(Kokkos::ViewAllocateWithoutInitializing(
"targetMapToImportRow"), Aview.colMap->getLocalNumElements());
446 Kokkos::parallel_for(
447 "Tpetra::mult_R_A_P_newmatrix::construct_tables", range_type(Aview.colMap->getMinLocalIndex(), Aview.colMap->getMaxLocalIndex() + 1), KOKKOS_LAMBDA(
const LO i) {
448 GO aidx = Acolmap_local.getGlobalElement(i);
449 LO P_LID = Prowmap_local.getLocalElement(aidx);
450 if (P_LID != LO_INVALID) {
451 targetMapToOrigRow(i) = P_LID;
452 targetMapToImportRow(i) = LO_INVALID;
454 LO I_LID = Irowmap_local.getLocalElement(aidx);
455 targetMapToOrigRow(i) = LO_INVALID;
456 targetMapToImportRow(i) = I_LID;
462 KernelWrappers3<Scalar, LocalOrdinal, GlobalOrdinal, Node, lo_view_t>::
463 mult_R_A_P_newmatrix_kernel_wrapper(Rview, Aview, Pview,
464 targetMapToOrigRow, targetMapToImportRow, Pcol2Ccol, Icol2Ccol,
465 Ac, Cimport, label, params);
469template <
class Scalar,
473void mult_R_A_P_reuse(
474 CrsMatrixStruct<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Rview,
475 CrsMatrixStruct<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Aview,
476 CrsMatrixStruct<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Pview,
477 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Ac,
478 const std::string& label,
479 const Teuchos::RCP<Teuchos::ParameterList>& params) {
480 using Teuchos::Array;
481 using Teuchos::ArrayRCP;
482 using Teuchos::ArrayView;
487 typedef LocalOrdinal LO;
488 typedef GlobalOrdinal GO;
491 typedef Import<LO, GO, NO> import_type;
492 typedef Map<LO, GO, NO> map_type;
495 typedef typename map_type::local_map_type local_map_type;
497 typedef typename KCRS::StaticCrsGraphType graph_t;
498 typedef typename graph_t::row_map_type::non_const_type lno_view_t;
499 typedef typename NO::execution_space execution_space;
500 typedef Kokkos::RangePolicy<execution_space, size_t> range_type;
501 typedef Kokkos::View<LO*, typename lno_view_t::array_layout, typename lno_view_t::device_type> lo_view_t;
503#ifdef HAVE_TPETRA_MMM_TIMINGS
504 std::string prefix_mmm = std::string(
"TpetraExt ") + label + std::string(
": ");
505 using Teuchos::TimeMonitor;
506 RCP<TimeMonitor> MM = rcp(
new TimeMonitor(*(TimeMonitor::getNewTimer(prefix_mmm + std::string(
"RAP M5 Cmap")))));
508 LO LO_INVALID = Teuchos::OrdinalTraits<LO>::invalid();
511 RCP<const import_type> Cimport = Ac.getGraph()->getImporter();
512 RCP<const map_type> Ccolmap = Ac.getColMap();
513 RCP<const import_type> Pimport = Pview.origMatrix->getGraph()->getImporter();
514 RCP<const import_type> Iimport = Pview.importMatrix.is_null() ? Teuchos::null : Pview.importMatrix->getGraph()->getImporter();
515 local_map_type Acolmap_local = Aview.colMap->getLocalMap();
516 local_map_type Prowmap_local = Pview.origMatrix->getRowMap()->getLocalMap();
517 local_map_type Irowmap_local;
518 if (!Pview.importMatrix.is_null()) Irowmap_local = Pview.importMatrix->getRowMap()->getLocalMap();
519 local_map_type Pcolmap_local = Pview.origMatrix->getColMap()->getLocalMap();
520 local_map_type Icolmap_local;
521 if (!Pview.importMatrix.is_null()) Icolmap_local = Pview.importMatrix->getColMap()->getLocalMap();
522 local_map_type Ccolmap_local = Ccolmap->getLocalMap();
525 lo_view_t Bcol2Ccol(Kokkos::ViewAllocateWithoutInitializing(
"Bcol2Ccol"), Pview.colMap->getLocalNumElements()), Icol2Ccol;
529 Kokkos::parallel_for(
530 range_type(0, Pview.origMatrix->getColMap()->getLocalNumElements()), KOKKOS_LAMBDA(
const LO i) {
531 Bcol2Ccol(i) = Ccolmap_local.getLocalElement(Pcolmap_local.getGlobalElement(i));
534 if (!Pview.importMatrix.is_null()) {
535 TEUCHOS_TEST_FOR_EXCEPTION(!Cimport->getSourceMap()->isSameAs(*Pview.origMatrix->getDomainMap()),
536 std::runtime_error,
"Tpetra::MMM: Import setUnion messed with the DomainMap in an unfortunate way");
538 Kokkos::resize(Icol2Ccol, Pview.importMatrix->getColMap()->getLocalNumElements());
539 Kokkos::parallel_for(
540 range_type(0, Pview.importMatrix->getColMap()->getLocalNumElements()), KOKKOS_LAMBDA(
const LO i) {
541 Icol2Ccol(i) = Ccolmap_local.getLocalElement(Icolmap_local.getGlobalElement(i));
547 lo_view_t targetMapToOrigRow(Kokkos::ViewAllocateWithoutInitializing(
"targetMapToOrigRow"), Aview.colMap->getLocalNumElements());
548 lo_view_t targetMapToImportRow(Kokkos::ViewAllocateWithoutInitializing(
"targetMapToImportRow"), Aview.colMap->getLocalNumElements());
549 Kokkos::parallel_for(
550 range_type(Aview.colMap->getMinLocalIndex(), Aview.colMap->getMaxLocalIndex() + 1), KOKKOS_LAMBDA(
const LO i) {
551 GO aidx = Acolmap_local.getGlobalElement(i);
552 LO B_LID = Prowmap_local.getLocalElement(aidx);
553 if (B_LID != LO_INVALID) {
554 targetMapToOrigRow(i) = B_LID;
555 targetMapToImportRow(i) = LO_INVALID;
557 LO I_LID = Irowmap_local.getLocalElement(aidx);
558 targetMapToOrigRow(i) = LO_INVALID;
559 targetMapToImportRow(i) = I_LID;
565 KernelWrappers3<Scalar, LocalOrdinal, GlobalOrdinal, Node, lo_view_t>::
566 mult_R_A_P_reuse_kernel_wrapper(Rview, Aview, Pview,
567 targetMapToOrigRow, targetMapToImportRow, Bcol2Ccol, Icol2Ccol,
568 Ac, Cimport, label, params);
572template <
class Scalar,
576void mult_PT_A_P_newmatrix(
577 CrsMatrixStruct<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Aview,
578 CrsMatrixStruct<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Pview,
579 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Ac,
580 const std::string& label,
581 const Teuchos::RCP<Teuchos::ParameterList>& params) {
582 using Teuchos::Array;
583 using Teuchos::ArrayRCP;
584 using Teuchos::ArrayView;
589 typedef LocalOrdinal LO;
590 typedef GlobalOrdinal GO;
593 typedef Import<LO, GO, NO> import_type;
594 typedef Map<LO, GO, NO> map_type;
597 typedef typename map_type::local_map_type local_map_type;
599 typedef typename KCRS::StaticCrsGraphType graph_t;
600 typedef typename graph_t::row_map_type::non_const_type lno_view_t;
601 typedef typename NO::execution_space execution_space;
602 typedef Kokkos::RangePolicy<execution_space, size_t> range_type;
603 typedef Kokkos::View<LO*, typename lno_view_t::array_layout, typename lno_view_t::device_type> lo_view_t;
605#ifdef HAVE_TPETRA_MMM_TIMINGS
606 std::string prefix_mmm = std::string(
"TpetraExt ") + label + std::string(
": ");
607 using Teuchos::TimeMonitor;
608 RCP<TimeMonitor> MM = rcp(
new TimeMonitor(*(TimeMonitor::getNewTimer(prefix_mmm + std::string(
"PTAP M5 Cmap")))));
610 LO LO_INVALID = Teuchos::OrdinalTraits<LO>::invalid();
613 RCP<const import_type> Cimport;
614 RCP<const map_type> Ccolmap;
615 RCP<const import_type> Pimport = Pview.origMatrix->getGraph()->getImporter();
616 RCP<const import_type> Iimport = Pview.importMatrix.is_null() ? Teuchos::null : Pview.importMatrix->getGraph()->getImporter();
617 local_map_type Acolmap_local = Aview.colMap->getLocalMap();
618 local_map_type Prowmap_local = Pview.origMatrix->getRowMap()->getLocalMap();
619 local_map_type Irowmap_local;
620 if (!Pview.importMatrix.is_null()) Irowmap_local = Pview.importMatrix->getRowMap()->getLocalMap();
621 local_map_type Pcolmap_local = Pview.origMatrix->getColMap()->getLocalMap();
622 local_map_type Icolmap_local;
623 if (!Pview.importMatrix.is_null()) Icolmap_local = Pview.importMatrix->getColMap()->getLocalMap();
630 lo_view_t Pcol2Ccol(Kokkos::ViewAllocateWithoutInitializing(
"Pcol2Ccol"), Pview.colMap->getLocalNumElements()), Icol2Ccol;
632 if (Pview.importMatrix.is_null()) {
635 Ccolmap = Pview.colMap;
636 const LO colMapSize =
static_cast<LO
>(Pview.colMap->getLocalNumElements());
638 Kokkos::parallel_for(
639 "Tpetra::mult_R_A_P_newmatrix::Pcol2Ccol_fill",
640 Kokkos::RangePolicy<execution_space, LO>(0, colMapSize),
641 KOKKOS_LAMBDA(
const LO i) {
653 if (!Pimport.is_null() && !Iimport.is_null()) {
654 Cimport = Pimport->setUnion(*Iimport);
655 }
else if (!Pimport.is_null() && Iimport.is_null()) {
656 Cimport = Pimport->setUnion();
657 }
else if (Pimport.is_null() && !Iimport.is_null()) {
658 Cimport = Iimport->setUnion();
660 throw std::runtime_error(
"TpetraExt::RAP status of matrix importers is nonsensical");
662 Ccolmap = Cimport->getTargetMap();
667 TEUCHOS_TEST_FOR_EXCEPTION(!Cimport->getSourceMap()->isSameAs(*Pview.origMatrix->getDomainMap()),
668 std::runtime_error,
"Tpetra::RAP: Import setUnion messed with the DomainMap in an unfortunate way");
675 Kokkos::resize(Icol2Ccol, Pview.importMatrix->getColMap()->getLocalNumElements());
676 local_map_type Ccolmap_local = Ccolmap->getLocalMap();
677 Kokkos::parallel_for(
678 "Tpetra::mult_R_A_P_newmatrix::Pcol2Ccol_getGlobalElement", range_type(0, Pview.origMatrix->getColMap()->getLocalNumElements()), KOKKOS_LAMBDA(
const LO i) {
679 Pcol2Ccol(i) = Ccolmap_local.getLocalElement(Pcolmap_local.getGlobalElement(i));
681 Kokkos::parallel_for(
682 "Tpetra::mult_R_A_P_newmatrix::Icol2Ccol_getGlobalElement", range_type(0, Pview.importMatrix->getColMap()->getLocalNumElements()), KOKKOS_LAMBDA(
const LO i) {
683 Icol2Ccol(i) = Ccolmap_local.getLocalElement(Icolmap_local.getGlobalElement(i));
691 Ac.replaceColMap(Ccolmap);
709 lo_view_t targetMapToOrigRow(Kokkos::ViewAllocateWithoutInitializing(
"targetMapToOrigRow"), Aview.colMap->getLocalNumElements());
710 lo_view_t targetMapToImportRow(Kokkos::ViewAllocateWithoutInitializing(
"targetMapToImportRow"), Aview.colMap->getLocalNumElements());
712 Kokkos::parallel_for(
713 "Tpetra::mult_R_A_P_newmatrix::construct_tables", range_type(Aview.colMap->getMinLocalIndex(), Aview.colMap->getMaxLocalIndex() + 1), KOKKOS_LAMBDA(
const LO i) {
714 GO aidx = Acolmap_local.getGlobalElement(i);
715 LO P_LID = Prowmap_local.getLocalElement(aidx);
716 if (P_LID != LO_INVALID) {
717 targetMapToOrigRow(i) = P_LID;
718 targetMapToImportRow(i) = LO_INVALID;
720 LO I_LID = Irowmap_local.getLocalElement(aidx);
721 targetMapToOrigRow(i) = LO_INVALID;
722 targetMapToImportRow(i) = I_LID;
728 KernelWrappers3<Scalar, LocalOrdinal, GlobalOrdinal, Node, lo_view_t>::
729 mult_PT_A_P_newmatrix_kernel_wrapper(Aview, Pview,
730 targetMapToOrigRow, targetMapToImportRow, Pcol2Ccol, Icol2Ccol,
731 Ac, Cimport, label, params);
735template <
class Scalar,
739void mult_PT_A_P_reuse(
740 CrsMatrixStruct<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Aview,
741 CrsMatrixStruct<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Pview,
742 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Ac,
743 const std::string& label,
744 const Teuchos::RCP<Teuchos::ParameterList>& params) {
745 using Teuchos::Array;
746 using Teuchos::ArrayRCP;
747 using Teuchos::ArrayView;
752 typedef LocalOrdinal LO;
753 typedef GlobalOrdinal GO;
756 typedef Import<LO, GO, NO> import_type;
757 typedef Map<LO, GO, NO> map_type;
760 typedef typename map_type::local_map_type local_map_type;
762 typedef typename KCRS::StaticCrsGraphType graph_t;
763 typedef typename graph_t::row_map_type::non_const_type lno_view_t;
764 typedef typename NO::execution_space execution_space;
765 typedef Kokkos::RangePolicy<execution_space, size_t> range_type;
766 typedef Kokkos::View<LO*, typename lno_view_t::array_layout, typename lno_view_t::device_type> lo_view_t;
768#ifdef HAVE_TPETRA_MMM_TIMINGS
769 std::string prefix_mmm = std::string(
"TpetraExt ") + label + std::string(
": ");
770 using Teuchos::TimeMonitor;
771 RCP<TimeMonitor> MM = rcp(
new TimeMonitor(*(TimeMonitor::getNewTimer(prefix_mmm + std::string(
"RAP M5 Cmap")))));
773 LO LO_INVALID = Teuchos::OrdinalTraits<LO>::invalid();
776 RCP<const import_type> Cimport = Ac.getGraph()->getImporter();
777 RCP<const map_type> Ccolmap = Ac.getColMap();
778 RCP<const import_type> Pimport = Pview.origMatrix->getGraph()->getImporter();
779 RCP<const import_type> Iimport = Pview.importMatrix.is_null() ? Teuchos::null : Pview.importMatrix->getGraph()->getImporter();
780 local_map_type Acolmap_local = Aview.colMap->getLocalMap();
781 local_map_type Prowmap_local = Pview.origMatrix->getRowMap()->getLocalMap();
782 local_map_type Irowmap_local;
783 if (!Pview.importMatrix.is_null()) Irowmap_local = Pview.importMatrix->getRowMap()->getLocalMap();
784 local_map_type Pcolmap_local = Pview.origMatrix->getColMap()->getLocalMap();
785 local_map_type Icolmap_local;
786 if (!Pview.importMatrix.is_null()) Icolmap_local = Pview.importMatrix->getColMap()->getLocalMap();
787 local_map_type Ccolmap_local = Ccolmap->getLocalMap();
790 lo_view_t Bcol2Ccol(Kokkos::ViewAllocateWithoutInitializing(
"Bcol2Ccol"), Pview.colMap->getLocalNumElements()), Icol2Ccol;
794 Kokkos::parallel_for(
795 range_type(0, Pview.origMatrix->getColMap()->getLocalNumElements()), KOKKOS_LAMBDA(
const LO i) {
796 Bcol2Ccol(i) = Ccolmap_local.getLocalElement(Pcolmap_local.getGlobalElement(i));
799 if (!Pview.importMatrix.is_null()) {
800 TEUCHOS_TEST_FOR_EXCEPTION(!Cimport->getSourceMap()->isSameAs(*Pview.origMatrix->getDomainMap()),
801 std::runtime_error,
"Tpetra::MMM: Import setUnion messed with the DomainMap in an unfortunate way");
803 Kokkos::resize(Icol2Ccol, Pview.importMatrix->getColMap()->getLocalNumElements());
804 Kokkos::parallel_for(
805 range_type(0, Pview.importMatrix->getColMap()->getLocalNumElements()), KOKKOS_LAMBDA(
const LO i) {
806 Icol2Ccol(i) = Ccolmap_local.getLocalElement(Icolmap_local.getGlobalElement(i));
812 lo_view_t targetMapToOrigRow(Kokkos::ViewAllocateWithoutInitializing(
"targetMapToOrigRow"), Aview.colMap->getLocalNumElements());
813 lo_view_t targetMapToImportRow(Kokkos::ViewAllocateWithoutInitializing(
"targetMapToImportRow"), Aview.colMap->getLocalNumElements());
814 Kokkos::parallel_for(
815 range_type(Aview.colMap->getMinLocalIndex(), Aview.colMap->getMaxLocalIndex() + 1), KOKKOS_LAMBDA(
const LO i) {
816 GO aidx = Acolmap_local.getGlobalElement(i);
817 LO B_LID = Prowmap_local.getLocalElement(aidx);
818 if (B_LID != LO_INVALID) {
819 targetMapToOrigRow(i) = B_LID;
820 targetMapToImportRow(i) = LO_INVALID;
822 LO I_LID = Irowmap_local.getLocalElement(aidx);
823 targetMapToOrigRow(i) = LO_INVALID;
824 targetMapToImportRow(i) = I_LID;
830 KernelWrappers3<Scalar, LocalOrdinal, GlobalOrdinal, Node, lo_view_t>::
831 mult_PT_A_P_reuse_kernel_wrapper(Aview, Pview,
832 targetMapToOrigRow, targetMapToImportRow, Bcol2Ccol, Icol2Ccol,
833 Ac, Cimport, label, params);
839template <
class Scalar,
843 class LocalOrdinalViewType>
844void KernelWrappers3<Scalar, LocalOrdinal, GlobalOrdinal, Node, LocalOrdinalViewType>::mult_R_A_P_newmatrix_kernel_wrapper(CrsMatrixStruct<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Rview,
845 CrsMatrixStruct<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Aview,
846 CrsMatrixStruct<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Pview,
847 const LocalOrdinalViewType& Acol2Prow_dev,
848 const LocalOrdinalViewType& Acol2PIrow_dev,
849 const LocalOrdinalViewType& Pcol2Accol_dev,
850 const LocalOrdinalViewType& PIcol2Accol_dev,
851 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Ac,
852 Teuchos::RCP<
const Import<LocalOrdinal, GlobalOrdinal, Node> > Acimport,
853 const std::string& label,
854 const Teuchos::RCP<Teuchos::ParameterList>& params) {
855#ifdef HAVE_TPETRA_MMM_TIMINGS
856 std::string prefix_mmm = std::string(
"TpetraExt ") + label + std::string(
": ");
857 using Teuchos::TimeMonitor;
858 Teuchos::RCP<Teuchos::TimeMonitor> MM = rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix_mmm + std::string(
"RAP Newmatrix SerialCore"))));
861 using Teuchos::Array;
862 using Teuchos::ArrayRCP;
863 using Teuchos::ArrayView;
869 typedef typename KCRS::StaticCrsGraphType graph_t;
870 typedef typename graph_t::row_map_type::const_type c_lno_view_t;
871 typedef typename graph_t::row_map_type::non_const_type lno_view_t;
872 typedef typename graph_t::entries_type::non_const_type lno_nnz_view_t;
873 typedef typename KCRS::values_type::non_const_type scalar_view_t;
876 typedef LocalOrdinal LO;
877 typedef GlobalOrdinal GO;
879 typedef Map<LO, GO, NO> map_type;
880 const size_t ST_INVALID = Teuchos::OrdinalTraits<LO>::invalid();
881 const LO LO_INVALID = Teuchos::OrdinalTraits<LO>::invalid();
882 const SC SC_ZERO = Teuchos::ScalarTraits<Scalar>::zero();
885 RCP<const map_type> Accolmap = Ac.getColMap();
886 size_t m = Rview.origMatrix->getLocalNumRows();
887 size_t n = Accolmap->getLocalNumElements();
888 size_t p_max_nnz_per_row = Pview.origMatrix->getLocalMaxNumRowEntries();
891 auto Acol2Prow = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(),
893 auto Acol2PIrow = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(),
895 auto Pcol2Accol = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(),
897 auto PIcol2Accol = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(),
901 const auto Amat = Aview.origMatrix->getLocalMatrixHost();
902 const auto Pmat = Pview.origMatrix->getLocalMatrixHost();
903 const auto Rmat = Rview.origMatrix->getLocalMatrixHost();
905 auto Arowptr = Amat.graph.row_map;
906 auto Prowptr = Pmat.graph.row_map;
907 auto Rrowptr = Rmat.graph.row_map;
908 const auto Acolind = Amat.graph.entries;
909 const auto Pcolind = Pmat.graph.entries;
910 const auto Rcolind = Rmat.graph.entries;
911 const auto Avals = Amat.values;
912 const auto Pvals = Pmat.values;
913 const auto Rvals = Rmat.values;
915 typename c_lno_view_t::host_mirror_type::const_type Irowptr;
916 typename lno_nnz_view_t::host_mirror_type Icolind;
917 typename scalar_view_t::host_mirror_type Ivals;
918 if (!Pview.importMatrix.is_null()) {
919 auto lclP = Pview.importMatrix->getLocalMatrixHost();
920 Irowptr = lclP.graph.row_map;
921 Icolind = lclP.graph.entries;
923 p_max_nnz_per_row = std::max(p_max_nnz_per_row, Pview.importMatrix->getLocalMaxNumRowEntries());
926#ifdef HAVE_TPETRA_MMM_TIMINGS
927 RCP<TimeMonitor> MM2 = rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix_mmm + std::string(
"RAP Newmatrix SerialCore - Compare"))));
937 size_t CSR_alloc = std::max(C_estimate_nnz(*Aview.origMatrix, *Pview.origMatrix), n);
938 typename lno_view_t::host_mirror_type Crowptr(Kokkos::ViewAllocateWithoutInitializing(
"Crowptr"), m + 1);
939 typename lno_nnz_view_t::host_mirror_type Ccolind(Kokkos::ViewAllocateWithoutInitializing(
"Ccolind"), CSR_alloc);
940 typename scalar_view_t::host_mirror_type Cvals(Kokkos::ViewAllocateWithoutInitializing(
"Cvals"), CSR_alloc);
950 const size_t INVALID = Teuchos::OrdinalTraits<size_t>::invalid();
951 Array<size_t> ac_status(n, ST_INVALID);
961 size_t nnz = 0, nnz_old = 0;
962 for (
size_t i = 0; i < m; i++) {
968 for (
size_t kk = Rrowptr[i]; kk < Rrowptr[i + 1]; kk++) {
970 const SC Rik = Rvals[kk];
974 for (
size_t ll = Arowptr[k]; ll < Arowptr[k + 1]; ll++) {
976 const SC Akl = Avals[ll];
980 if (Acol2Prow[l] != LO_INVALID) {
987 size_t Pl = Teuchos::as<size_t>(Acol2Prow[l]);
990 for (
size_t jj = Prowptr[Pl]; jj < Prowptr[Pl + 1]; jj++) {
992 LO Acj = Pcol2Accol[j];
995 if (ac_status[Acj] == INVALID || ac_status[Acj] < nnz_old) {
996#ifdef HAVE_TPETRA_DEBUG
998 TEUCHOS_TEST_FOR_EXCEPTION(nnz >= Teuchos::as<size_t>(Ccolind.size()),
1000 label <<
" ERROR, not enough memory allocated for matrix product. Allocated: " << Ccolind.extent(0) << std::endl);
1003 ac_status[Acj] = nnz;
1005 Cvals[nnz] = Rik * Akl * Plj;
1008 Cvals[ac_status[Acj]] += Rik * Akl * Plj;
1018 size_t Il = Teuchos::as<size_t>(Acol2PIrow[l]);
1019 for (
size_t jj = Irowptr[Il]; jj < Irowptr[Il + 1]; jj++) {
1021 LO Acj = PIcol2Accol[j];
1024 if (ac_status[Acj] == INVALID || ac_status[Acj] < nnz_old) {
1025#ifdef HAVE_TPETRA_DEBUG
1027 TEUCHOS_TEST_FOR_EXCEPTION(nnz >= Teuchos::as<size_t>(Ccolind.size()),
1029 label <<
" ERROR, not enough memory allocated for matrix product. Allocated: " << Ccolind.extent(0) << std::endl);
1032 ac_status[Acj] = nnz;
1034 Cvals[nnz] = Rik * Akl * Plj;
1037 Cvals[ac_status[Acj]] += Rik * Akl * Plj;
1044 if (nnz + n > CSR_alloc) {
1046 Kokkos::resize(Ccolind, CSR_alloc);
1047 Kokkos::resize(Cvals, CSR_alloc);
1055 Kokkos::resize(Ccolind, nnz);
1056 Kokkos::resize(Cvals, nnz);
1058#ifdef HAVE_TPETRA_MMM_TIMINGS
1060 MM = rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix_mmm + std::string(
"RAP Newmatrix Final Sort"))));
1062 auto Crowptr_dev = Kokkos::create_mirror_view_and_copy(
1063 typename KCRS::device_type(), Crowptr);
1064 auto Ccolind_dev = Kokkos::create_mirror_view_and_copy(
1065 typename KCRS::device_type(), Ccolind);
1066 auto Cvals_dev = Kokkos::create_mirror_view_and_copy(
1067 typename KCRS::device_type(), Cvals);
1070 if (params.is_null() || params->get(
"sort entries",
true))
1071 Import_Util::sortCrsEntries(Crowptr_dev, Ccolind_dev, Cvals_dev);
1072 Ac.setAllValues(Crowptr_dev, Ccolind_dev, Cvals_dev);
1074#ifdef HAVE_TPETRA_MMM_TIMINGS
1076 MM = rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix_mmm + std::string(
"RAP Newmatrix ESFC"))));
1087 RCP<Teuchos::ParameterList> labelList = rcp(
new Teuchos::ParameterList);
1088 labelList->set(
"Timer Label", label);
1089 if (!params.is_null()) labelList->set(
"compute global constants", params->get(
"compute global constants",
true));
1090 RCP<const Export<LO, GO, NO> > dummyExport;
1091 Ac.expertStaticFillComplete(Pview.origMatrix->getDomainMap(),
1092 Rview.origMatrix->getRangeMap(),
1101template <
class Scalar,
1103 class GlobalOrdinal,
1105 class LocalOrdinalViewType>
1106void KernelWrappers3<Scalar, LocalOrdinal, GlobalOrdinal, Node, LocalOrdinalViewType>::mult_R_A_P_reuse_kernel_wrapper(CrsMatrixStruct<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Rview,
1107 CrsMatrixStruct<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Aview,
1108 CrsMatrixStruct<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Pview,
1109 const LocalOrdinalViewType& Acol2Prow_dev,
1110 const LocalOrdinalViewType& Acol2PIrow_dev,
1111 const LocalOrdinalViewType& Pcol2Accol_dev,
1112 const LocalOrdinalViewType& PIcol2Accol_dev,
1113 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Ac,
1114 Teuchos::RCP<
const Import<LocalOrdinal, GlobalOrdinal, Node> > Acimport,
1115 const std::string& label,
1116 const Teuchos::RCP<Teuchos::ParameterList>& params) {
1117#ifdef HAVE_TPETRA_MMM_TIMINGS
1118 std::string prefix_mmm = std::string(
"TpetraExt ") + label + std::string(
": ");
1119 using Teuchos::TimeMonitor;
1120 Teuchos::RCP<Teuchos::TimeMonitor> MM = rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix_mmm + std::string(
"RAP Reuse SerialCore"))));
1123 using Teuchos::Array;
1124 using Teuchos::ArrayRCP;
1125 using Teuchos::ArrayView;
1130 typedef typename Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::local_matrix_host_type KCRS;
1131 typedef typename KCRS::StaticCrsGraphType graph_t;
1132 typedef typename graph_t::row_map_type::const_type c_lno_view_t;
1133 typedef typename graph_t::entries_type::non_const_type lno_nnz_view_t;
1134 typedef typename KCRS::values_type::non_const_type scalar_view_t;
1137 typedef LocalOrdinal LO;
1138 typedef GlobalOrdinal GO;
1140 typedef Map<LO, GO, NO> map_type;
1141 const size_t ST_INVALID = Teuchos::OrdinalTraits<LO>::invalid();
1142 const LO LO_INVALID = Teuchos::OrdinalTraits<LO>::invalid();
1143 const SC SC_ZERO = Teuchos::ScalarTraits<Scalar>::zero();
1146 RCP<const map_type> Accolmap = Ac.getColMap();
1147 size_t m = Rview.origMatrix->getLocalNumRows();
1148 size_t n = Accolmap->getLocalNumElements();
1149 size_t p_max_nnz_per_row = Pview.origMatrix->getLocalMaxNumRowEntries();
1152 auto Acol2Prow = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(),
1154 auto Acol2PIrow = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(),
1156 auto Pcol2Accol = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(),
1158 auto PIcol2Accol = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(),
1162 const KCRS Amat = Aview.origMatrix->getLocalMatrixHost();
1163 const KCRS Pmat = Pview.origMatrix->getLocalMatrixHost();
1164 const KCRS Rmat = Rview.origMatrix->getLocalMatrixHost();
1165 const KCRS Cmat = Ac.getLocalMatrixHost();
1167 c_lno_view_t Arowptr = Amat.graph.row_map, Prowptr = Pmat.graph.row_map, Rrowptr = Rmat.graph.row_map, Crowptr = Cmat.graph.row_map;
1168 const lno_nnz_view_t Acolind = Amat.graph.entries, Pcolind = Pmat.graph.entries, Rcolind = Rmat.graph.entries, Ccolind = Cmat.graph.entries;
1169 const scalar_view_t Avals = Amat.values, Pvals = Pmat.values, Rvals = Rmat.values;
1170 scalar_view_t Cvals = Cmat.values;
1172 c_lno_view_t Irowptr;
1173 lno_nnz_view_t Icolind;
1174 scalar_view_t Ivals;
1175 if (!Pview.importMatrix.is_null()) {
1176 auto lclP = Pview.importMatrix->getLocalMatrixHost();
1177 Irowptr = lclP.graph.row_map;
1178 Icolind = lclP.graph.entries;
1179 Ivals = lclP.values;
1180 p_max_nnz_per_row = std::max(p_max_nnz_per_row, Pview.importMatrix->getLocalMaxNumRowEntries());
1183#ifdef HAVE_TPETRA_MMM_TIMINGS
1184 RCP<TimeMonitor> MM2 = rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix_mmm + std::string(
"RAP Reuse SerialCore - Compare"))));
1195 Array<size_t> ac_status(n, ST_INVALID);
1209 size_t OLD_ip = 0, CSR_ip = 0;
1210 for (
size_t i = 0; i < m; i++) {
1213 OLD_ip = Crowptr[i];
1214 CSR_ip = Crowptr[i + 1];
1215 for (
size_t k = OLD_ip; k < CSR_ip; k++) {
1216 ac_status[Ccolind[k]] = k;
1223 for (
size_t kk = Rrowptr[i]; kk < Rrowptr[i + 1]; kk++) {
1225 const SC Rik = Rvals[kk];
1229 for (
size_t ll = Arowptr[k]; ll < Arowptr[k + 1]; ll++) {
1231 const SC Akl = Avals[ll];
1235 if (Acol2Prow[l] != LO_INVALID) {
1242 size_t Pl = Teuchos::as<size_t>(Acol2Prow[l]);
1245 for (
size_t jj = Prowptr[Pl]; jj < Prowptr[Pl + 1]; jj++) {
1247 LO Cij = Pcol2Accol[j];
1250 TEUCHOS_TEST_FOR_EXCEPTION(ac_status[Cij] < OLD_ip || ac_status[Cij] >= CSR_ip,
1251 std::runtime_error,
"Trying to insert a new entry (" << i <<
"," << Cij <<
") into a static graph "
1252 <<
"(c_status = " << ac_status[Cij] <<
" of [" << OLD_ip <<
"," << CSR_ip <<
"))");
1254 Cvals[ac_status[Cij]] += Rik * Akl * Plj;
1263 size_t Il = Teuchos::as<size_t>(Acol2PIrow[l]);
1264 for (
size_t jj = Irowptr[Il]; jj < Irowptr[Il + 1]; jj++) {
1266 LO Cij = PIcol2Accol[j];
1269 TEUCHOS_TEST_FOR_EXCEPTION(ac_status[Cij] < OLD_ip || ac_status[Cij] >= CSR_ip,
1270 std::runtime_error,
"Trying to insert a new entry (" << i <<
"," << Cij <<
") into a static graph "
1271 <<
"(c_status = " << ac_status[Cij] <<
" of [" << OLD_ip <<
"," << CSR_ip <<
"))");
1273 Cvals[ac_status[Cij]] += Rik * Akl * Plj;
1280#ifdef HAVE_TPETRA_MMM_TIMINGS
1281 auto MM3 = rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix_mmm + std::string(
"RAP Reuse ESFC"))));
1284 Ac.fillComplete(Ac.getDomainMap(), Ac.getRangeMap());
1290template <
class Scalar,
1292 class GlobalOrdinal,
1294 class LocalOrdinalViewType>
1295void KernelWrappers3<Scalar, LocalOrdinal, GlobalOrdinal, Node, LocalOrdinalViewType>::mult_PT_A_P_newmatrix_kernel_wrapper(CrsMatrixStruct<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Aview,
1296 CrsMatrixStruct<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Pview,
1297 const LocalOrdinalViewType& Acol2Prow,
1298 const LocalOrdinalViewType& Acol2PIrow,
1299 const LocalOrdinalViewType& Pcol2Accol,
1300 const LocalOrdinalViewType& PIcol2Accol,
1301 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Ac,
1302 Teuchos::RCP<
const Import<LocalOrdinal, GlobalOrdinal, Node> > Acimport,
1303 const std::string& label,
1304 const Teuchos::RCP<Teuchos::ParameterList>& params) {
1305#ifdef HAVE_TPETRA_MMM_TIMINGS
1306 std::string prefix_mmm = std::string(
"TpetraExt ") + label + std::string(
": ");
1307 using Teuchos::TimeMonitor;
1308 Teuchos::TimeMonitor MM(*TimeMonitor::getNewTimer(prefix_mmm + std::string(
"PTAP local transpose")));
1312 typedef RowMatrixTransposer<Scalar, LocalOrdinal, GlobalOrdinal, Node> transposer_type;
1313 transposer_type transposer(Pview.origMatrix, label + std::string(
"XP: "));
1315 using Teuchos::ParameterList;
1317 RCP<ParameterList> transposeParams(
new ParameterList);
1318 transposeParams->set(
"sort",
false);
1320 if (!params.is_null()) {
1321 transposeParams->set(
"compute global constants",
1322 params->get(
"compute global constants: temporaries",
1325 RCP<CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > Ptrans =
1326 transposer.createTransposeLocal(transposeParams);
1327 CrsMatrixStruct<Scalar, LocalOrdinal, GlobalOrdinal, Node> Rview;
1328 Rview.origMatrix = Ptrans;
1330 mult_R_A_P_newmatrix_kernel_wrapper(Rview, Aview, Pview, Acol2Prow, Acol2PIrow, Pcol2Accol, PIcol2Accol, Ac, Acimport, label, params);
1336template <
class Scalar,
1338 class GlobalOrdinal,
1340 class LocalOrdinalViewType>
1341void KernelWrappers3<Scalar, LocalOrdinal, GlobalOrdinal, Node, LocalOrdinalViewType>::mult_PT_A_P_reuse_kernel_wrapper(CrsMatrixStruct<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Aview,
1342 CrsMatrixStruct<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Pview,
1343 const LocalOrdinalViewType& Acol2Prow,
1344 const LocalOrdinalViewType& Acol2PIrow,
1345 const LocalOrdinalViewType& Pcol2Accol,
1346 const LocalOrdinalViewType& PIcol2Accol,
1347 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Ac,
1348 Teuchos::RCP<
const Import<LocalOrdinal, GlobalOrdinal, Node> > Acimport,
1349 const std::string& label,
1350 const Teuchos::RCP<Teuchos::ParameterList>& params) {
1351#ifdef HAVE_TPETRA_MMM_TIMINGS
1352 std::string prefix_mmm = std::string(
"TpetraExt ") + label + std::string(
": ");
1353 using Teuchos::TimeMonitor;
1354 Teuchos::TimeMonitor MM(*TimeMonitor::getNewTimer(prefix_mmm + std::string(
"PTAP local transpose")));
1358 typedef RowMatrixTransposer<Scalar, LocalOrdinal, GlobalOrdinal, Node> transposer_type;
1359 transposer_type transposer(Pview.origMatrix, label + std::string(
"XP: "));
1361 using Teuchos::ParameterList;
1363 RCP<ParameterList> transposeParams(
new ParameterList);
1364 transposeParams->set(
"sort",
false);
1366 if (!params.is_null()) {
1367 transposeParams->set(
"compute global constants",
1368 params->get(
"compute global constants: temporaries",
1371 RCP<CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > Ptrans =
1372 transposer.createTransposeLocal(transposeParams);
1373 CrsMatrixStruct<Scalar, LocalOrdinal, GlobalOrdinal, Node> Rview;
1374 Rview.origMatrix = Ptrans;
1376 mult_R_A_P_reuse_kernel_wrapper(Rview, Aview, Pview, Acol2Prow, Acol2PIrow, Pcol2Accol, PIcol2Accol, Ac, Acimport, label, params);
1384template <
class Scalar,
1386 class GlobalOrdinal,
1388void KernelWrappers3MMM<Scalar, LocalOrdinal, GlobalOrdinal, Node>::mult_PT_A_P_newmatrix_kernel_wrapper_2pass(CrsMatrixStruct<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Aview,
1389 CrsMatrixStruct<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Pview,
1390 const Teuchos::Array<LocalOrdinal>& Acol2PRow,
1391 const Teuchos::Array<LocalOrdinal>& Acol2PRowImport,
1392 const Teuchos::Array<LocalOrdinal>& Pcol2Accol,
1393 const Teuchos::Array<LocalOrdinal>& PIcol2Accol,
1394 CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Ac,
1395 Teuchos::RCP<
const Import<LocalOrdinal, GlobalOrdinal, Node> > Acimport,
1396 const std::string& label,
1397 const Teuchos::RCP<Teuchos::ParameterList>& params) {
1398#ifdef HAVE_TPETRA_MMM_TIMINGS
1399 std::string prefix_mmm = std::string(
"TpetraExt ") + label + std::string(
": ");
1400 using Teuchos::TimeMonitor;
1401 Teuchos::RCP<Teuchos::TimeMonitor> MM = rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix_mmm + std::string(
"PTAP Newmatrix SerialCore"))));
1404 using Teuchos::Array;
1405 using Teuchos::ArrayRCP;
1406 using Teuchos::ArrayView;
1411 typedef LocalOrdinal LO;
1412 typedef GlobalOrdinal GO;
1414 typedef RowMatrixTransposer<SC, LO, GO, NO> transposer_type;
1415 const LO LO_INVALID = Teuchos::OrdinalTraits<LO>::invalid();
1416 const SC SC_ZERO = Teuchos::ScalarTraits<Scalar>::zero();
1421 size_t n = Ac.getRowMap()->getLocalNumElements();
1422 LO maxAccol = Ac.getColMap()->getMaxLocalIndex();
1425 ArrayRCP<size_t> Acrowptr_RCP;
1426 ArrayRCP<LO> Accolind_RCP;
1427 ArrayRCP<SC> Acvals_RCP;
1434 auto Arowptr = Aview.origMatrix->getLocalRowPtrsHost();
1435 auto Acolind = Aview.origMatrix->getLocalIndicesHost();
1436 auto Avals = Aview.origMatrix->getLocalValuesHost(
1437 Tpetra::Access::ReadOnly);
1438 auto Prowptr = Pview.origMatrix->getLocalRowPtrsHost();
1439 auto Pcolind = Pview.origMatrix->getLocalIndicesHost();
1440 auto Pvals = Pview.origMatrix->getLocalValuesHost(
1441 Tpetra::Access::ReadOnly);
1442 decltype(Prowptr) Irowptr;
1443 decltype(Pcolind) Icolind;
1444 decltype(Pvals) Ivals;
1446 if (!Pview.importMatrix.is_null()) {
1447 Irowptr = Pview.importMatrix->getLocalRowPtrsHost();
1448 Icolind = Pview.importMatrix->getLocalIndicesHost();
1449 Ivals = Pview.importMatrix->getLocalValuesHost(
1450 Tpetra::Access::ReadOnly);
1458 ArrayView<size_t> Acrowptr;
1459 ArrayView<LO> Accolind;
1460 ArrayView<SC> Acvals;
1471#ifdef HAVE_TPETRA_MMM_TIMINGS
1472 MM = rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix_mmm + std::string(
"PTAP local transpose"))));
1479 transposer_type transposer(Pview.origMatrix, label + std::string(
"XP: "));
1481 using Teuchos::ParameterList;
1482 RCP<ParameterList> transposeParams(
new ParameterList);
1483 transposeParams->set(
"sort",
false);
1484 if (!params.is_null()) {
1485 transposeParams->set(
"compute global constants",
1486 params->get(
"compute global constants: temporaries",
1489 RCP<CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > Ptrans =
1490 transposer.createTransposeLocal(transposeParams);
1492 auto Rrowptr = Ptrans->getLocalRowPtrsHost();
1493 auto Rcolind = Ptrans->getLocalIndicesHost();
1494 auto Rvals = Ptrans->getLocalValuesHost(Tpetra::Access::ReadOnly);
1499#ifdef HAVE_TPETRA_MMM_TIMINGS
1500 MM = rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix_mmm + std::string(
"PTAP graph"))));
1503 const size_t ST_INVALID = Teuchos::OrdinalTraits<LO>::invalid();
1504 Array<size_t> ac_status(maxAccol + 1, ST_INVALID);
1506 size_t nnz_alloc = std::max(Ac_estimate_nnz(*Aview.origMatrix, *Pview.origMatrix), n);
1507 size_t nnzPerRowA = 100;
1508 if (Aview.origMatrix->getLocalNumEntries() > 0)
1509 nnzPerRowA = Aview.origMatrix->getLocalNumEntries() / Aview.origMatrix->getLocalNumRows();
1510 Acrowptr_RCP.resize(n + 1);
1511 Acrowptr = Acrowptr_RCP();
1512 Accolind_RCP.resize(nnz_alloc);
1513 Accolind = Accolind_RCP();
1515 size_t nnz = 0, nnz_old = 0;
1516 for (
size_t i = 0; i < n; i++) {
1522 for (
size_t kk = Rrowptr[i]; kk < Rrowptr[i + 1]; kk++) {
1525 for (
size_t ll = Arowptr[k]; ll < Arowptr[k + 1]; ll++) {
1528 if (Acol2PRow[l] != LO_INVALID) {
1535 size_t Pl = Teuchos::as<size_t>(Acol2PRow[l]);
1538 for (
size_t jj = Prowptr[Pl]; jj < Prowptr[Pl + 1]; jj++) {
1540 LO Acj = Pcol2Accol[j];
1542 if (ac_status[Acj] == ST_INVALID || ac_status[Acj] < nnz_old) {
1544 ac_status[Acj] = nnz;
1545 Accolind[nnz] = Acj;
1556 size_t Il = Teuchos::as<size_t>(Acol2PRowImport[l]);
1557 for (
size_t jj = Irowptr[Il]; jj < Irowptr[Il + 1]; jj++) {
1559 LO Acj = PIcol2Accol[j];
1561 if (ac_status[Acj] == ST_INVALID || ac_status[Acj] < nnz_old) {
1563 ac_status[Acj] = nnz;
1564 Accolind[nnz] = Acj;
1574 if (nnz + std::max(5 * nnzPerRowA, n) > nnz_alloc) {
1576 nnz_alloc = std::max(nnz_alloc, nnz + std::max(5 * nnzPerRowA, n));
1577 Accolind_RCP.resize(nnz_alloc);
1578 Accolind = Accolind_RCP();
1579 Acvals_RCP.resize(nnz_alloc);
1580 Acvals = Acvals_RCP();
1587 Accolind_RCP.resize(nnz);
1588 Accolind = Accolind_RCP();
1591 Acvals_RCP.resize(nnz, SC_ZERO);
1592 Acvals = Acvals_RCP();
1598#ifdef HAVE_TPETRA_MMM_TIMINGS
1599 MM = rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix_mmm + std::string(
"PTAP Newmatrix Fill Matrix"))));
1602 for (
size_t k = 0; k < n; k++) {
1603 for (
size_t ii = Prowptr[k]; ii < Prowptr[k + 1]; ii++) {
1605 const SC Pki = Pvals[ii];
1606 for (
size_t ll = Arowptr[k]; ll < Arowptr[k + 1]; ll++) {
1608 const SC Akl = Avals[ll];
1611 if (Acol2PRow[l] != LO_INVALID) {
1618 size_t Pl = Teuchos::as<size_t>(Acol2PRow[l]);
1619 for (
size_t jj = Prowptr[Pl]; jj < Prowptr[Pl + 1]; jj++) {
1621 LO Acj = Pcol2Accol[j];
1623 for (pp = Acrowptr[i]; pp < Acrowptr[i + 1]; pp++)
1624 if (Accolind[pp] == Acj)
1628 Acvals[pp] += Pki * Akl * Pvals[jj];
1637 size_t Il = Teuchos::as<size_t>(Acol2PRowImport[l]);
1638 for (
size_t jj = Irowptr[Il]; jj < Irowptr[Il + 1]; jj++) {
1640 LO Acj = PIcol2Accol[j];
1642 for (pp = Acrowptr[i]; pp < Acrowptr[i + 1]; pp++)
1643 if (Accolind[pp] == Acj)
1647 Acvals[pp] += Pki * Akl * Ivals[jj];
1654#ifdef HAVE_TPETRA_MMM_TIMINGS
1655 MM = rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix_mmm + std::string(
"PTAP sort"))));
1662 Import_Util::sortCrsEntries(Acrowptr_RCP(), Accolind_RCP(), Acvals_RCP());
1665 Ac.setAllValues(Acrowptr_RCP, Accolind_RCP, Acvals_RCP);
1667#ifdef HAVE_TPETRA_MMM_TIMINGS
1668 MM = rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(prefix_mmm + std::string(
"PTAP Newmatrix ESFC"))));
1679 RCP<Teuchos::ParameterList> labelList = rcp(
new Teuchos::ParameterList);
1680 labelList->set(
"Timer Label", label);
1682 if (!params.is_null()) labelList->set(
"compute global constants", params->get(
"compute global constants",
true));
1683 RCP<const Export<LO, GO, NO> > dummyExport;
1684 Ac.expertStaticFillComplete(Pview.origMatrix->getDomainMap(),
1685 Pview.origMatrix->getDomainMap(),
1687 dummyExport, labelList);
1699#define TPETRA_TRIPLEMATRIXMULTIPLY_INSTANT(SCALAR, LO, GO, NODE) \
1701 template void TripleMatrixMultiply::MultiplyRAP( \
1702 const CrsMatrix<SCALAR, LO, GO, NODE>& R, \
1704 const CrsMatrix<SCALAR, LO, GO, NODE>& A, \
1706 const CrsMatrix<SCALAR, LO, GO, NODE>& P, \
1708 CrsMatrix<SCALAR, LO, GO, NODE>& Ac, \
1709 bool call_FillComplete_on_result, \
1710 const std::string& label, \
1711 const Teuchos::RCP<Teuchos::ParameterList>& params);
Utility functions for packing and unpacking sparse matrix entries.
Internal functions and macros designed for use with Tpetra::Import and Tpetra::Export objects.
Stand-alone utility functions and macros.
KokkosSparse::CrsMatrix< impl_scalar_type, local_ordinal_type, device_type, void, typename local_graph_device_type::size_type > local_matrix_device_type
The specialization of Kokkos::CrsMatrix that represents the part of the sparse matrix on each MPI pro...
Struct that holds views of the contents of a CrsMatrix.
void MultiplyRAP(const CrsMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &R, bool transposeR, const CrsMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, bool transposeA, const CrsMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &P, bool transposeP, CrsMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &Ac, bool call_FillComplete_on_result=true, const std::string &label=std::string(), const Teuchos::RCP< Teuchos::ParameterList > ¶ms=Teuchos::null)
Sparse matrix-matrix multiply.
Namespace Tpetra contains the class and methods constituting the Tpetra library.