278 using MatrixType = Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
279 using GraphType = Xpetra::CrsGraph<LocalOrdinal, GlobalOrdinal, Node>;
280 using local_matrix_type =
typename MatrixType::local_matrix_device_type;
281 using local_graph_type =
typename GraphType::local_graph_device_type;
282 using rowptr_type =
typename local_graph_type::row_map_type::non_const_type;
283 using entries_type =
typename local_graph_type::entries_type::non_const_type;
284 using values_type =
typename local_matrix_type::values_type::non_const_type;
285 using device_type =
typename Node::device_type;
286 using memory_space =
typename device_type::memory_space;
287 using results_view_type = Kokkos::View<DecisionType*, memory_space>;
288 using magnitudeType =
typename Teuchos::ScalarTraits<Scalar>::magnitudeType;
289 using doubleMultiVector = Xpetra::MultiVector<magnitudeType, LO, GO, NO>;
291 typedef Teuchos::ScalarTraits<Scalar> STS;
292 const magnitudeType zero = Teuchos::ScalarTraits<magnitudeType>::zero();
294 auto A = Get<RCP<Matrix>>(currentLevel,
"A");
298 const ParameterList& pL = GetParameterList();
301 const magnitudeType dirichletThreshold = STS::magnitude(as<SC>(pL.get<
double>(
"aggregation: Dirichlet threshold")));
302 const magnitudeType rowSumTol = as<magnitudeType>(pL.get<
double>(
"aggregation: row sum drop tol"));
306 bool useBlocking = pL.get<
bool>(
"aggregation: use blocking");
307 std::string droppingMethod = pL.get<std::string>(
"aggregation: drop scheme");
308 std::string socUsesMatrix = pL.get<std::string>(
"aggregation: strength-of-connection: matrix");
309 std::string socUsesMeasure = pL.get<std::string>(
"aggregation: strength-of-connection: measure");
310 std::string distanceLaplacianMetric = pL.get<std::string>(
"aggregation: distance laplacian metric");
311 bool symmetrizeDroppedGraph = pL.get<
bool>(
"aggregation: symmetrize graph after dropping");
312 magnitudeType threshold;
314 if (pL.get<
bool>(
"aggregation: use ml scaling of drop tol"))
315 threshold = pL.get<
double>(
"aggregation: drop tol") / pow(2.0, currentLevel.
GetLevelID());
317 threshold = as<magnitudeType>(pL.get<
double>(
"aggregation: drop tol"));
318 bool aggregationMayCreateDirichlet = pL.get<
bool>(
"aggregation: dropping may create Dirichlet");
321 const bool reuseGraph = pL.get<
bool>(
"filtered matrix: reuse graph");
322 const bool reuseEigenvalue = pL.get<
bool>(
"filtered matrix: reuse eigenvalue");
324 const bool useRootStencil = pL.get<
bool>(
"filtered matrix: use root stencil");
325 const bool useSpreadLumping = pL.get<
bool>(
"filtered matrix: use spread lumping");
326 const std::string lumpingChoiceString = pL.get<std::string>(
"filtered matrix: lumping choice");
328 if (lumpingChoiceString ==
"diag lumping")
330 else if (lumpingChoiceString ==
"distributed lumping")
333 const magnitudeType filteringDirichletThreshold = as<magnitudeType>(pL.get<
double>(
"filtered matrix: Dirichlet threshold"));
336 bool generateColoringGraph = pL.get<
bool>(
"aggregation: coloring: use color graph");
337 const bool localizeColoringGraph = pL.get<
bool>(
"aggregation: coloring: localize color graph");
338 const bool symmetrizeColoringGraph =
true;
340#ifdef HAVE_MUELU_COALESCEDROP_ALLOW_OLD_PARAMETERS
341 translateOldAlgoParam(pL, droppingMethod, useBlocking, socUsesMatrix, socUsesMeasure, symmetrizeDroppedGraph, generateColoringGraph, threshold, lumpingChoice);
345 std::stringstream ss;
346 ss <<
"dropping scheme = \"" << droppingMethod <<
"\", strength-of-connection measure = \"" << socUsesMeasure <<
"\", strength-of-connection matrix = \"" << socUsesMatrix <<
"\", ";
347 if (socUsesMatrix ==
"distance laplacian")
348 ss <<
"distance laplacian metric = \"" << distanceLaplacianMetric <<
"\", ";
349 ss <<
"threshold = " << threshold <<
", blocksize = " << A->GetFixedBlockSize() <<
", useBlocking = " << useBlocking;
350 ss <<
", symmetrizeDroppedGraph = " << symmetrizeDroppedGraph << std::endl;
355 TEUCHOS_ASSERT(!useRootStencil);
356 TEUCHOS_ASSERT(!useSpreadLumping);
358 if (droppingMethod ==
"cut-drop")
359 TEUCHOS_TEST_FOR_EXCEPTION(threshold > 1.0,
Exceptions::RuntimeError,
"For cut-drop algorithms, \"aggregation: drop tol\" = " << threshold <<
", needs to be <= 1.0");
374 if (threshold != zero) {
375 if ((socUsesMatrix ==
"A") || (socUsesMatrix ==
"MinvA")) {
377 if (socUsesMatrix ==
"A")
379 else if (socUsesMatrix ==
"MinvA") {
385 Minv = Get<RCP<Matrix>>(currentLevel,
"Minv");
387 auto M = Get<RCP<Matrix>>(currentLevel,
"M");
393 A_drop = Xpetra::MatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::BuildCopy(A);
394 auto params = Teuchos::rcp(
new Teuchos::ParameterList());
395 params->set(
"MM Throw For Non-Existent Entries",
false);
396 A_drop = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Minv,
false, *A,
false, A_drop, GetOStream(
Statistics2),
true,
true, std::string(
"MinvA"), params);
398#ifdef JustUsingDiagMforInverse
405 A_drop = MatrixFactory::BuildCopy(A);
407 A_drop->leftScale(*MinvDiag);
415 auto crsA = toCrsMatrix(A);
416 auto lclA = crsA->getLocalMatrixDevice();
436 if (rowSumTol <= 0.) {
469 auto filtered_rowptr = rowptr_type(
"filtered_rowptr", lclA.numRows() + 1);
473 auto results = results_view_type(
"results", lclA.nnz());
477 if (threshold != zero) {
478 if ((socUsesMatrix ==
"A") || (socUsesMatrix ==
"MinvA")) {
479 if (socUsesMeasure ==
"unscaled") {
480 ScalarDroppingClassical<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::UnscaledMeasure>::runDroppingFunctors_on_A(*A_drop, results, filtered_rowptr, nnz_filtered, boundaryNodes, droppingMethod, threshold,
481 aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, currentLevel, *
this);
482 }
else if (socUsesMeasure ==
"smoothed aggregation") {
483 ScalarDroppingClassical<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::SmoothedAggregationMeasure>::runDroppingFunctors_on_A(*A_drop, results, filtered_rowptr, nnz_filtered, boundaryNodes, droppingMethod, threshold,
484 aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, currentLevel, *
this);
485 }
else if (socUsesMeasure ==
"signed ruge-stueben") {
486 ScalarDroppingClassical<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::SignedRugeStuebenMeasure>::runDroppingFunctors_on_A(*A_drop, results, filtered_rowptr, nnz_filtered, boundaryNodes, droppingMethod, threshold,
487 aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, currentLevel, *
this);
488 }
else if (socUsesMeasure ==
"signed smoothed aggregation") {
489 ScalarDroppingClassical<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::SignedSmoothedAggregationMeasure>::runDroppingFunctors_on_A(*A_drop, results, filtered_rowptr, nnz_filtered, boundaryNodes, droppingMethod, threshold,
490 aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, currentLevel, *
this);
492 }
else if (socUsesMatrix ==
"distance laplacian") {
493 auto coords = Get<RCP<doubleMultiVector>>(currentLevel,
"Coordinates");
494 if (socUsesMeasure ==
"unscaled") {
495 ScalarDroppingDistanceLaplacian<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::UnscaledMeasure>::runDroppingFunctors_on_dlap(*A, results, filtered_rowptr, nnz_filtered, boundaryNodes, droppingMethod, threshold, aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, distanceLaplacianMetric, currentLevel, *
this);
496 }
else if (socUsesMeasure ==
"smoothed aggregation") {
497 ScalarDroppingDistanceLaplacian<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::SmoothedAggregationMeasure>::runDroppingFunctors_on_dlap(*A, results, filtered_rowptr, nnz_filtered, boundaryNodes, droppingMethod, threshold, aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, distanceLaplacianMetric, currentLevel, *
this);
498 }
else if (socUsesMeasure ==
"signed ruge-stueben") {
499 ScalarDroppingDistanceLaplacian<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::SignedRugeStuebenMeasure>::runDroppingFunctors_on_dlap(*A, results, filtered_rowptr, nnz_filtered, boundaryNodes, droppingMethod, threshold, aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, distanceLaplacianMetric, currentLevel, *
this);
500 }
else if (socUsesMeasure ==
"signed smoothed aggregation") {
501 ScalarDroppingDistanceLaplacian<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::SignedSmoothedAggregationMeasure>::runDroppingFunctors_on_dlap(*A, results, filtered_rowptr, nnz_filtered, boundaryNodes, droppingMethod, threshold, aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, distanceLaplacianMetric, currentLevel, *
this);
505 Kokkos::deep_copy(results,
KEEP);
507 if (symmetrizeDroppedGraph) {
509 ScalarDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, results, filtered_rowptr, nnz_filtered, useBlocking, currentLevel, *
this, drop_boundaries);
512 ScalarDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, results, filtered_rowptr, nnz_filtered, useBlocking, currentLevel, *
this, no_op);
516 if (symmetrizeDroppedGraph) {
518 ScalarDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, results, filtered_rowptr, nnz_filtered, useBlocking, currentLevel, *
this, symmetrize);
521 GO numDropped = lclA.nnz() - nnz_filtered;
523 Teuchos::reduceAll(*A->getRowMap()->getComm(), Teuchos::REDUCE_SUM, 1, &numDropped, &numGlobalDropped);
531 RCP<Matrix> filteredA;
532 RCP<LWGraph_kokkos> graph;
533 if (numGlobalDropped > 0) {
536 local_matrix_type lclFilteredA;
537 local_graph_type lclGraph;
539 filteredA = MatrixFactory::BuildCopy(A);
540 lclFilteredA = filteredA->getLocalMatrixDevice();
542 auto colidx = entries_type(
"entries", nnz_filtered);
543 lclGraph = local_graph_type(colidx, filtered_rowptr);
545 auto colidx = entries_type(
"entries", nnz_filtered);
546 auto values = values_type(
"values", nnz_filtered);
547 lclFilteredA = local_matrix_type(
"filteredA",
548 lclA.numRows(), lclA.numCols(),
550 values, filtered_rowptr, colidx);
556 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_lumped_reuse", range, fillFunctor);
560 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_lumped_noreuse", range, fillFunctor);
563 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_lumped_noreuse", range, fillFunctor);
569 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_unlumped_reuse", range, fillFunctor);
572 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_unlumped_noreuse", range, fillFunctor);
577 filteredA = MatrixFactory::Build(lclFilteredA, A->getRowMap(), A->getColMap(), A->getDomainMap(), A->getRangeMap());
578 filteredA->SetFixedBlockSize(A->GetFixedBlockSize());
580 if (reuseEigenvalue) {
585 filteredA->SetMaxEigenvalueEstimate(A->GetMaxEigenvalueEstimate());
587 filteredA->SetMaxEigenvalueEstimate(-Teuchos::ScalarTraits<SC>::one());
592 lclGraph = filteredA->getCrsGraph()->getLocalGraphDevice();
594 graph = rcp(
new LWGraph_kokkos(lclGraph, filteredA->getRowMap(), filteredA->getColMap(),
"amalgamated graph of A"));
595 graph->SetBoundaryNodeMap(boundaryNodes);
598 graph = rcp(
new LWGraph_kokkos(filteredA->getCrsGraph()->getLocalGraphDevice(), filteredA->getRowMap(), filteredA->getColMap(),
"amalgamated graph of A"));
599 graph->SetBoundaryNodeMap(boundaryNodes);
603 if (generateColoringGraph) {
604 SubFactoryMonitor mColoringGraph(*
this,
"Construct coloring graph", currentLevel);
606 filtered_rowptr = rowptr_type(
"rowptr_coloring_graph", lclA.numRows() + 1);
607 if (localizeColoringGraph) {
609 ScalarDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, results, filtered_rowptr, nnz_filtered, useBlocking, currentLevel, *
this, drop_offrank);
611 if (symmetrizeColoringGraph) {
613 ScalarDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, results, filtered_rowptr, nnz_filtered, useBlocking, currentLevel, *
this, symmetrize);
615 auto colidx = entries_type(
"entries_coloring_graph", nnz_filtered);
616 auto lclGraph = local_graph_type(colidx, filtered_rowptr);
618 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Construct_coloring_graph", range, graphConstruction);
620 auto colorGraph = rcp(
new LWGraph_kokkos(lclGraph, filteredA->getRowMap(), filteredA->getColMap(),
"coloring graph"));
621 Set(currentLevel,
"Coloring Graph", colorGraph);
624 if (pL.get<
bool>(
"filtered matrix: count negative diagonals")) {
627 GetOStream(
Runtime0) <<
"CoalesceDrop: Negative diagonals: " << neg_count << std::endl;
631 Set(currentLevel,
"DofsPerNode", dofsPerNode);
632 Set(currentLevel,
"Graph", graph);
633 Set(currentLevel,
"A", filteredA);
635 return std::make_tuple(numDropped, boundaryNodes);
643 using MatrixType = Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
644 using GraphType = Xpetra::CrsGraph<LocalOrdinal, GlobalOrdinal, Node>;
645 using local_matrix_type =
typename MatrixType::local_matrix_device_type;
646 using local_graph_type =
typename GraphType::local_graph_device_type;
647 using rowptr_type =
typename local_graph_type::row_map_type::non_const_type;
648 using entries_type =
typename local_graph_type::entries_type::non_const_type;
649 using values_type =
typename local_matrix_type::values_type::non_const_type;
650 using device_type =
typename Node::device_type;
651 using memory_space =
typename device_type::memory_space;
652 using results_view_type = Kokkos::View<DecisionType*, memory_space>;
653 using magnitudeType =
typename Teuchos::ScalarTraits<Scalar>::magnitudeType;
654 using doubleMultiVector = Xpetra::MultiVector<magnitudeType, LO, GO, NO>;
656 typedef Teuchos::ScalarTraits<Scalar> STS;
657 const magnitudeType zero = Teuchos::ScalarTraits<magnitudeType>::zero();
659 auto A = Get<RCP<Matrix>>(currentLevel,
"A");
678 TEUCHOS_TEST_FOR_EXCEPTION(A->GetFixedBlockSize() % A->GetStorageBlockSize() != 0,
Exceptions::RuntimeError,
"A->GetFixedBlockSize() needs to be a multiple of A->GetStorageBlockSize()");
679 LO blkSize = A->GetFixedBlockSize() / A->GetStorageBlockSize();
681 auto amalInfo = Get<RCP<AmalgamationInfo>>(currentLevel,
"UnAmalgamationInfo");
683 const RCP<const Map> rowMap = A->getRowMap();
684 const RCP<const Map> colMap = A->getColMap();
691 const RCP<const Map> uniqueMap = amalInfo->getNodeRowMap();
692 const RCP<const Map> nonUniqueMap = amalInfo->getNodeColMap();
693 Array<LO> rowTranslationArray = *(amalInfo->getRowTranslation());
694 Array<LO> colTranslationArray = *(amalInfo->getColTranslation());
696 Kokkos::View<LO*, Kokkos::MemoryUnmanaged>
697 rowTranslationView(rowTranslationArray.getRawPtr(), rowTranslationArray.size());
698 Kokkos::View<LO*, Kokkos::MemoryUnmanaged>
699 colTranslationView(colTranslationArray.getRawPtr(), colTranslationArray.size());
702 LO numNodes = Teuchos::as<LocalOrdinal>(uniqueMap->getLocalNumElements());
703 typedef typename Kokkos::View<LocalOrdinal*, typename Node::device_type> id_translation_type;
704 id_translation_type rowTranslation(
"dofId2nodeId", rowTranslationArray.size());
705 id_translation_type colTranslation(
"ov_dofId2nodeId", colTranslationArray.size());
706 Kokkos::deep_copy(rowTranslation, rowTranslationView);
707 Kokkos::deep_copy(colTranslation, colTranslationView);
710 blkSize = A->GetFixedBlockSize();
713 if (A->IsView(
"stridedMaps") ==
true) {
714 const RCP<const Map> myMap = A->getRowMap(
"stridedMaps");
715 const RCP<const StridedMap> strMap = Teuchos::rcp_dynamic_cast<const StridedMap>(myMap);
717 blkSize = Teuchos::as<const LocalOrdinal>(strMap->getFixedBlockSize());
718 blkId = strMap->getStridedBlockId();
720 blkPartSize = Teuchos::as<LocalOrdinal>(strMap->getStridingData()[blkId]);
723 TEUCHOS_TEST_FOR_EXCEPTION(A->getRowMap()->getLocalNumElements() % blkPartSize != 0,
MueLu::Exceptions::RuntimeError,
"MueLu::CoalesceDropFactory: Number of local elements is " << A->getRowMap()->getLocalNumElements() <<
" but should be a multiple of " << blkPartSize);
727 const ParameterList& pL = GetParameterList();
730 const magnitudeType dirichletThreshold = STS::magnitude(as<SC>(pL.get<
double>(
"aggregation: Dirichlet threshold")));
731 const magnitudeType rowSumTol = as<magnitudeType>(pL.get<
double>(
"aggregation: row sum drop tol"));
733 const bool useGreedyDirichlet = pL.get<
bool>(
"aggregation: greedy Dirichlet");
734 TEUCHOS_TEST_FOR_EXCEPTION(rowSumTol > zero,
MueLu::Exceptions::RuntimeError,
"MueLu::CoalesceDropFactory: RowSum is not implemented for vectorial problems.");
737 bool useBlocking = pL.get<
bool>(
"aggregation: use blocking");
738 std::string droppingMethod = pL.get<std::string>(
"aggregation: drop scheme");
739 std::string socUsesMatrix = pL.get<std::string>(
"aggregation: strength-of-connection: matrix");
740 std::string socUsesMeasure = pL.get<std::string>(
"aggregation: strength-of-connection: measure");
741 std::string distanceLaplacianMetric = pL.get<std::string>(
"aggregation: distance laplacian metric");
742 bool symmetrizeDroppedGraph = pL.get<
bool>(
"aggregation: symmetrize graph after dropping");
743 magnitudeType threshold;
745 if (pL.get<
bool>(
"aggregation: use ml scaling of drop tol"))
746 threshold = pL.get<
double>(
"aggregation: drop tol") / pow(2.0, currentLevel.
GetLevelID());
748 threshold = as<magnitudeType>(pL.get<
double>(
"aggregation: drop tol"));
749 bool aggregationMayCreateDirichlet = pL.get<
bool>(
"aggregation: dropping may create Dirichlet");
752 const bool reuseGraph = pL.get<
bool>(
"filtered matrix: reuse graph");
753 const bool reuseEigenvalue = pL.get<
bool>(
"filtered matrix: reuse eigenvalue");
755 const bool useRootStencil = pL.get<
bool>(
"filtered matrix: use root stencil");
756 const bool useSpreadLumping = pL.get<
bool>(
"filtered matrix: use spread lumping");
757 const std::string lumpingChoiceString = pL.get<std::string>(
"filtered matrix: lumping choice");
759 if (lumpingChoiceString ==
"diag lumping")
761 else if (lumpingChoiceString ==
"distributed lumping")
764 const magnitudeType filteringDirichletThreshold = as<magnitudeType>(pL.get<
double>(
"filtered matrix: Dirichlet threshold"));
767 bool generateColoringGraph = pL.get<
bool>(
"aggregation: coloring: use color graph");
768 const bool localizeColoringGraph = pL.get<
bool>(
"aggregation: coloring: localize color graph");
769 const bool symmetrizeColoringGraph =
true;
771#ifdef HAVE_MUELU_COALESCEDROP_ALLOW_OLD_PARAMETERS
772 translateOldAlgoParam(pL, droppingMethod, useBlocking, socUsesMatrix, socUsesMeasure, symmetrizeDroppedGraph, generateColoringGraph, threshold, lumpingChoice);
775 std::stringstream ss;
776 ss <<
"dropping scheme = \"" << droppingMethod <<
"\", strength-of-connection measure = \"" << socUsesMeasure <<
"\", strength-of-connection matrix = \"" << socUsesMatrix <<
"\", ";
777 if (socUsesMatrix ==
"distance laplacian")
778 ss <<
"distance laplacian metric = \"" << distanceLaplacianMetric <<
"\", ";
779 ss <<
"threshold = " << threshold <<
", blocksize = " << A->GetFixedBlockSize() <<
", useBlocking = " << useBlocking;
780 ss <<
", symmetrizeDroppedGraph = " << symmetrizeDroppedGraph << std::endl;
785 TEUCHOS_ASSERT(!useRootStencil);
786 TEUCHOS_ASSERT(!useSpreadLumping);
788 if (droppingMethod ==
"cut-drop")
789 TEUCHOS_TEST_FOR_EXCEPTION(threshold > 1.0,
Exceptions::RuntimeError,
"For cut-drop algorithms, \"aggregation: drop tol\" = " << threshold <<
", needs to be <= 1.0");
802 auto crsA = toCrsMatrix(A);
803 auto lclA = crsA->getLocalMatrixDevice();
818 if (useGreedyDirichlet) {
848 auto filtered_rowptr = rowptr_type(
"rowptr", lclA.numRows() + 1);
849 auto graph_rowptr = rowptr_type(
"rowptr", numNodes + 1);
851 Kokkos::pair<LocalOrdinal, LocalOrdinal> nnz = {0, 0};
854 auto results = results_view_type(
"results", lclA.nnz());
863 auto merged_rowptr = rowptr_type(
"rowptr", numNodes + 1);
867 Kokkos::parallel_scan(
"MergeCount", range, functor, nnz_merged);
869 local_graph_type lclMergedGraph;
870 auto colidx_merged = entries_type(
"entries", nnz_merged);
871 auto values_merged = values_type(
"values", nnz_merged);
873 local_matrix_type lclMergedA = local_matrix_type(
"mergedA",
874 numNodes, nonUniqueMap->getLocalNumElements(),
876 values_merged, merged_rowptr, colidx_merged);
879 Kokkos::parallel_for(
"MueLu::CoalesceDrop::MergeFill", range, fillFunctor);
881 mergedA = Xpetra::MatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(lclMergedA, uniqueMap, nonUniqueMap, uniqueMap, uniqueMap);
884 if (threshold != zero) {
885 if (socUsesMatrix ==
"A") {
886 if (socUsesMeasure ==
"unscaled") {
887 VectorDroppingClassical<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::UnscaledMeasure>::runDroppingFunctors_on_A(*A, *mergedA, blkPartSize, rowTranslation, colTranslation, results, filtered_rowptr, graph_rowptr, nnz, boundaryNodes, droppingMethod, threshold, aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, currentLevel, *
this);
888 }
else if (socUsesMeasure ==
"smoothed aggregation") {
889 VectorDroppingClassical<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::SmoothedAggregationMeasure>::runDroppingFunctors_on_A(*A, *mergedA, blkPartSize, rowTranslation, colTranslation, results, filtered_rowptr, graph_rowptr, nnz, boundaryNodes, droppingMethod, threshold, aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, currentLevel, *
this);
890 }
else if (socUsesMeasure ==
"signed ruge-stueben") {
891 VectorDroppingClassical<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::SignedRugeStuebenMeasure>::runDroppingFunctors_on_A(*A, *mergedA, blkPartSize, rowTranslation, colTranslation, results, filtered_rowptr, graph_rowptr, nnz, boundaryNodes, droppingMethod, threshold, aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, currentLevel, *
this);
892 }
else if (socUsesMeasure ==
"signed smoothed aggregation") {
893 VectorDroppingClassical<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::SignedSmoothedAggregationMeasure>::runDroppingFunctors_on_A(*A, *mergedA, blkPartSize, rowTranslation, colTranslation, results, filtered_rowptr, graph_rowptr, nnz, boundaryNodes, droppingMethod, threshold, aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, currentLevel, *
this);
895 }
else if (socUsesMatrix ==
"distance laplacian") {
896 auto coords = Get<RCP<doubleMultiVector>>(currentLevel,
"Coordinates");
898 Array<double> dlap_weights = pL.get<Array<double>>(
"aggregation: distance laplacian directional weights");
899 LocalOrdinal interleaved_blocksize = as<LocalOrdinal>(pL.get<
int>(
"aggregation: block diagonal: interleaved blocksize"));
900 if (socUsesMeasure ==
"distance laplacian") {
901 LO dim = (LO)coords->getNumVectors();
903 bool non_unity =
false;
904 for (LO i = 0; !non_unity && i < (LO)dlap_weights.size(); i++) {
905 if (dlap_weights[i] != 1.0) {
910 if ((LO)dlap_weights.size() == dim) {
911 distanceLaplacianMetric =
"weighted";
912 }
else if ((LO)dlap_weights.size() == interleaved_blocksize * dim)
913 distanceLaplacianMetric =
"block weighted";
916 "length of 'aggregation: distance laplacian directional weights' must equal the coordinate dimension OR the coordinate dimension times the blocksize");
919 GetOStream(
Statistics1) <<
"Using distance laplacian weights: " << dlap_weights << std::endl;
923 if (socUsesMeasure ==
"unscaled") {
924 VectorDroppingDistanceLaplacian<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::UnscaledMeasure>::runDroppingFunctors_on_dlap(*A, *mergedA, blkPartSize, rowTranslation, colTranslation, results, filtered_rowptr, graph_rowptr, nnz, boundaryNodes, droppingMethod, threshold, aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, distanceLaplacianMetric, dlap_weights, interleaved_blocksize, currentLevel, *
this);
925 }
else if (socUsesMeasure ==
"smoothed aggregation") {
926 VectorDroppingDistanceLaplacian<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::SmoothedAggregationMeasure>::runDroppingFunctors_on_dlap(*A, *mergedA, blkPartSize, rowTranslation, colTranslation, results, filtered_rowptr, graph_rowptr, nnz, boundaryNodes, droppingMethod, threshold, aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, distanceLaplacianMetric, dlap_weights, interleaved_blocksize, currentLevel, *
this);
927 }
else if (socUsesMeasure ==
"signed ruge-stueben") {
928 VectorDroppingDistanceLaplacian<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::SignedRugeStuebenMeasure>::runDroppingFunctors_on_dlap(*A, *mergedA, blkPartSize, rowTranslation, colTranslation, results, filtered_rowptr, graph_rowptr, nnz, boundaryNodes, droppingMethod, threshold, aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, distanceLaplacianMetric, dlap_weights, interleaved_blocksize, currentLevel, *
this);
929 }
else if (socUsesMeasure ==
"signed smoothed aggregation") {
930 VectorDroppingDistanceLaplacian<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::SignedSmoothedAggregationMeasure>::runDroppingFunctors_on_dlap(*A, *mergedA, blkPartSize, rowTranslation, colTranslation, results, filtered_rowptr, graph_rowptr, nnz, boundaryNodes, droppingMethod, threshold, aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, distanceLaplacianMetric, dlap_weights, interleaved_blocksize, currentLevel, *
this);
934 Kokkos::deep_copy(results,
KEEP);
937 VectorDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, *mergedA, blkPartSize, rowTranslation, colTranslation, results, filtered_rowptr, graph_rowptr, nnz, useBlocking, currentLevel, *
this, no_op);
940 if (symmetrizeDroppedGraph) {
942 VectorDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, *mergedA, blkPartSize, rowTranslation, colTranslation, results, filtered_rowptr, graph_rowptr, nnz, useBlocking, currentLevel, *
this, symmetrize);
947 GO numTotal = lclA.nnz();
948 GO numDropped = numTotal - nnz_filtered;
950 Teuchos::reduceAll(*A->getRowMap()->getComm(), Teuchos::REDUCE_SUM, 1, &numDropped, &numGlobalDropped);
958 RCP<Matrix> filteredA;
959 RCP<LWGraph_kokkos> graph;
960 if (numGlobalDropped > 0) {
963 local_matrix_type lclFilteredA;
965 lclFilteredA = local_matrix_type(
"filteredA", lclA.graph, lclA.numCols());
967 auto colidx = entries_type(
"entries", nnz_filtered);
968 auto values = values_type(
"values", nnz_filtered);
969 lclFilteredA = local_matrix_type(
"filteredA",
970 lclA.numRows(), lclA.numCols(),
972 values, filtered_rowptr, colidx);
975 local_graph_type lclGraph;
977 auto colidx = entries_type(
"entries", nnz_graph);
978 lclGraph = local_graph_type(colidx, graph_rowptr);
984 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_lumped_reuse", range, fillFunctor);
987 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_lumped_noreuse", range, fillFunctor);
992 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_unlumped_reuse", range, fillFunctor);
995 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_unlumped_noreuse", range, fillFunctor);
999 filteredA = Xpetra::MatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(lclFilteredA, A->getRowMap(), A->getColMap(), A->getDomainMap(), A->getRangeMap());
1000 filteredA->SetFixedBlockSize(blkSize);
1002 if (reuseEigenvalue) {
1007 filteredA->SetMaxEigenvalueEstimate(A->GetMaxEigenvalueEstimate());
1009 filteredA->SetMaxEigenvalueEstimate(-Teuchos::ScalarTraits<SC>::one());
1012 graph = rcp(
new LWGraph_kokkos(lclGraph, uniqueMap, nonUniqueMap,
"amalgamated graph of A"));
1013 graph->SetBoundaryNodeMap(boundaryNodes);
1016 graph = rcp(
new LWGraph_kokkos(mergedA->getCrsGraph()->getLocalGraphDevice(), uniqueMap, nonUniqueMap,
"amalgamated graph of A"));
1017 graph->SetBoundaryNodeMap(boundaryNodes);
1021 if (generateColoringGraph) {
1022 SubFactoryMonitor mColoringGraph(*
this,
"Construct coloring graph", currentLevel);
1024 filtered_rowptr = rowptr_type(
"rowptr_coloring_graph", lclA.numRows() + 1);
1025 graph_rowptr = rowptr_type(
"rowptr", numNodes + 1);
1026 if (localizeColoringGraph) {
1028 VectorDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, *mergedA, blkPartSize, rowTranslation, colTranslation, results, filtered_rowptr, graph_rowptr, nnz, useBlocking, currentLevel, *
this, drop_offrank);
1030 if (symmetrizeColoringGraph) {
1032 VectorDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, *mergedA, blkPartSize, rowTranslation, colTranslation, results, filtered_rowptr, graph_rowptr, nnz, useBlocking, currentLevel, *
this, symmetrize);
1034 auto colidx = entries_type(
"entries_coloring_graph", nnz_filtered);
1035 auto lclGraph = local_graph_type(colidx, filtered_rowptr);
1037 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Construct_coloring_graph", range, graphConstruction);
1039 auto colorGraph = rcp(
new LWGraph_kokkos(lclGraph, filteredA->getRowMap(), filteredA->getColMap(),
"coloring graph"));
1040 Set(currentLevel,
"Coloring Graph", colorGraph);
1043 LO dofsPerNode = blkSize;
1045 Set(currentLevel,
"DofsPerNode", dofsPerNode);
1046 Set(currentLevel,
"Graph", graph);
1047 Set(currentLevel,
"A", filteredA);
1049 return std::make_tuple(numDropped, boundaryNodes);