296 using MatrixType = Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
297 using GraphType = Xpetra::CrsGraph<LocalOrdinal, GlobalOrdinal, Node>;
298 using local_matrix_type =
typename MatrixType::local_matrix_device_type;
299 using local_graph_type =
typename GraphType::local_graph_device_type;
300 using rowptr_type =
typename local_graph_type::row_map_type::non_const_type;
301 using entries_type =
typename local_graph_type::entries_type::non_const_type;
302 using values_type =
typename local_matrix_type::values_type::non_const_type;
303 using device_type =
typename Node::device_type;
304 using memory_space =
typename device_type::memory_space;
305 using results_view_type = Kokkos::View<DecisionType*, memory_space>;
306 using magnitudeType =
typename Teuchos::ScalarTraits<Scalar>::magnitudeType;
307 using doubleMultiVector = Xpetra::MultiVector<magnitudeType, LO, GO, NO>;
309 typedef Teuchos::ScalarTraits<Scalar> STS;
310 const magnitudeType zero = Teuchos::ScalarTraits<magnitudeType>::zero();
312 auto A = Get<RCP<Matrix>>(currentLevel,
"A");
314 const bool needToBuildFilteredA = currentLevel.
IsRequested(
"A",
this);
318 const ParameterList& pL = GetParameterList();
321 const magnitudeType dirichletThreshold = STS::magnitude(as<SC>(pL.get<
double>(
"aggregation: Dirichlet threshold")));
322 const magnitudeType rowSumTol = as<magnitudeType>(pL.get<
double>(
"aggregation: row sum drop tol"));
326 bool useBlocking = pL.get<
bool>(
"aggregation: use blocking");
327 std::string droppingMethod = pL.get<std::string>(
"aggregation: drop scheme");
328 std::string socUsesMatrix = pL.get<std::string>(
"aggregation: strength-of-connection: matrix");
329 std::string socUsesMeasure = pL.get<std::string>(
"aggregation: strength-of-connection: measure");
330 std::string distanceLaplacianMetric = pL.get<std::string>(
"aggregation: distance laplacian metric");
331 std::string MinvScheme = pL.get<std::string>(
"aggregation: Minv scheme");
332 bool symmetrizeDroppedGraph = pL.get<
bool>(
"aggregation: symmetrize graph after dropping");
333 magnitudeType threshold;
335 if (pL.get<
bool>(
"aggregation: use ml scaling of drop tol"))
336 threshold = pL.get<
double>(
"aggregation: drop tol") / pow(2.0, currentLevel.
GetLevelID());
338 threshold = as<magnitudeType>(pL.get<
double>(
"aggregation: drop tol"));
339 bool aggregationMayCreateDirichlet = pL.get<
bool>(
"aggregation: dropping may create Dirichlet");
342 const bool reuseGraph = pL.get<
bool>(
"filtered matrix: reuse graph") && needToBuildFilteredA;
343 const bool reuseEigenvalue = pL.get<
bool>(
"filtered matrix: reuse eigenvalue");
345 const bool useRootStencil = pL.get<
bool>(
"filtered matrix: use root stencil");
346 const bool useSpreadLumping = pL.get<
bool>(
"filtered matrix: use spread lumping");
347 const std::string lumpingChoiceString = pL.get<std::string>(
"filtered matrix: lumping choice");
349 if (needToBuildFilteredA) {
350 if (lumpingChoiceString ==
"diag lumping")
352 else if (lumpingChoiceString ==
"distributed lumping")
356 const magnitudeType filteringDirichletThreshold = as<magnitudeType>(pL.get<
double>(
"filtered matrix: Dirichlet threshold"));
359 bool generateColoringGraph = pL.get<
bool>(
"aggregation: coloring: use color graph");
360 const bool localizeColoringGraph = pL.get<
bool>(
"aggregation: coloring: localize color graph");
361 const bool symmetrizeColoringGraph =
true;
363#ifdef HAVE_MUELU_COALESCEDROP_ALLOW_OLD_PARAMETERS
364 translateOldAlgoParam(pL, droppingMethod, useBlocking, socUsesMatrix, socUsesMeasure, symmetrizeDroppedGraph, generateColoringGraph, threshold, lumpingChoice);
368 std::stringstream ss;
369 ss <<
"dropping scheme = \"" << droppingMethod <<
"\", strength-of-connection measure = \"" << socUsesMeasure <<
"\", strength-of-connection matrix = \"" << socUsesMatrix <<
"\", ";
370 if (socUsesMatrix ==
"distance laplacian")
371 ss <<
"distance laplacian metric = \"" << distanceLaplacianMetric <<
"\", ";
372 ss <<
"threshold = " << threshold <<
", blocksize = " << A->GetFixedBlockSize() <<
", useBlocking = " << useBlocking;
373 ss <<
", symmetrizeDroppedGraph = " << symmetrizeDroppedGraph << std::endl;
378 TEUCHOS_ASSERT(!useRootStencil);
379 TEUCHOS_ASSERT(!useSpreadLumping);
381 if (droppingMethod ==
"cut-drop")
382 TEUCHOS_TEST_FOR_EXCEPTION(threshold > 1.0,
Exceptions::RuntimeError,
"For cut-drop algorithms, \"aggregation: drop tol\" = " << threshold <<
", needs to be <= 1.0");
397 if (threshold != zero) {
398 if ((socUsesMatrix ==
"A") || (socUsesMatrix ==
"MinvA")) {
400 if (socUsesMatrix ==
"A")
402 else if (socUsesMatrix ==
"MinvA") {
403 bool storeMinvOnLevel =
false, storeMinvAOnLevel =
false;
404 if (pL.isSublist(
"project auxiliary matrices")) {
405 auto projectList = pL.sublist(
"project auxiliary matrices");
406 if (projectList.isParameter(
"MinvA"))
407 storeMinvAOnLevel =
true;
409 if (projectList.isParameter(
"Minv"))
410 storeMinvOnLevel =
true;
412 storeMinvAOnLevel =
true;
415 storeMinvAOnLevel =
true;
417 if (IsAvailable(currentLevel,
"MinvA")) {
418 A_drop = Get<RCP<Matrix>>(currentLevel,
"MinvA");
421 bool MueLu_Minv = IsAvailable(currentLevel,
"Minv");
423 if (MueLu_Minv || User_Minv) {
425 Minv = Get<RCP<Matrix>>(currentLevel,
"Minv");
434 M = Get<RCP<Matrix>>(currentLevel,
"M");
437#ifdef moreExperimentsToSeeIfHelpful
441 for (
size_t iii = 0; iii < A->getLocalNumRows(); iii++)
442 if (boundaryNodes[iii]) nAbc++;
445 for (
size_t iii = 0; iii < M->getLocalNumRows(); iii++)
446 if (MbcBefore[iii]) nMbcBefore++;
447 GetOStream(
Statistics1) <<
"MueLu_CoalesceDropFactory_kokkos_def: # A bcs = " << nAbc <<
", # M bcs before MueLu enforcement = " << nMbcBefore;
453 for (
size_t iii = 0; iii < M->getLocalNumRows(); iii++)
454 if (MbcAfter[iii]) nMbcAfter++;
455 GetOStream(
Statistics1) <<
", # M bcs after MueLu enforcement = " << nMbcAfter << std::endl;
463 if (storeMinvOnLevel) currentLevel.
Set(
"Minv", Minv);
467 A_drop = Xpetra::MatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::BuildCopy(A);
468 auto params = Teuchos::rcp(
new Teuchos::ParameterList());
469 params->set(
"MM Throw For Non-Existent Entries",
false);
470 A_drop = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Minv,
false, *A,
false, A_drop, GetOStream(
Statistics2),
true,
true, std::string(
"MinvA"), params);
478 if (storeMinvAOnLevel) currentLevel.
Set(
"MinvA", A_drop);
484 auto crsA = toCrsMatrix(A);
485 auto lclA = crsA->getLocalMatrixDevice();
505 if (rowSumTol <= 0.) {
538 auto filtered_rowptr = rowptr_type(
"filtered_rowptr", lclA.numRows() + 1);
542 auto results = results_view_type(
"results", lclA.nnz());
546 if (threshold != zero) {
547 if ((socUsesMatrix ==
"A") || (socUsesMatrix ==
"MinvA")) {
548 if (socUsesMeasure ==
"unscaled") {
549 ScalarDroppingClassical<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::UnscaledMeasure>::runDroppingFunctors_on_A(*A_drop, results, filtered_rowptr, nnz_filtered, boundaryNodes, droppingMethod, threshold,
550 aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, currentLevel, *
this);
551 }
else if (socUsesMeasure ==
"smoothed aggregation") {
552 ScalarDroppingClassical<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::SmoothedAggregationMeasure>::runDroppingFunctors_on_A(*A_drop, results, filtered_rowptr, nnz_filtered, boundaryNodes, droppingMethod, threshold,
553 aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, currentLevel, *
this);
554 }
else if (socUsesMeasure ==
"signed ruge-stueben") {
555 ScalarDroppingClassical<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::SignedRugeStuebenMeasure>::runDroppingFunctors_on_A(*A_drop, results, filtered_rowptr, nnz_filtered, boundaryNodes, droppingMethod, threshold,
556 aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, currentLevel, *
this);
557 }
else if (socUsesMeasure ==
"signed smoothed aggregation") {
558 ScalarDroppingClassical<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::SignedSmoothedAggregationMeasure>::runDroppingFunctors_on_A(*A_drop, results, filtered_rowptr, nnz_filtered, boundaryNodes, droppingMethod, threshold,
559 aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, currentLevel, *
this);
561 }
else if (socUsesMatrix ==
"distance laplacian") {
562 auto coords = Get<RCP<doubleMultiVector>>(currentLevel,
"Coordinates");
563 if (socUsesMeasure ==
"unscaled") {
564 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);
565 }
else if (socUsesMeasure ==
"smoothed aggregation") {
566 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);
567 }
else if (socUsesMeasure ==
"signed ruge-stueben") {
568 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);
569 }
else if (socUsesMeasure ==
"signed smoothed aggregation") {
570 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);
574 Kokkos::deep_copy(results,
KEEP);
576 if (symmetrizeDroppedGraph) {
578 ScalarDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, results, filtered_rowptr, nnz_filtered, useBlocking, currentLevel, *
this, drop_boundaries);
581 ScalarDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, results, filtered_rowptr, nnz_filtered, useBlocking, currentLevel, *
this, no_op);
585 if (symmetrizeDroppedGraph) {
587 ScalarDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, results, filtered_rowptr, nnz_filtered, useBlocking, currentLevel, *
this, symmetrize);
590 GO numDropped = lclA.nnz() - nnz_filtered;
592 Teuchos::reduceAll(*A->getRowMap()->getComm(), Teuchos::REDUCE_SUM, 1, &numDropped, &numGlobalDropped);
600 RCP<LWGraph_kokkos> graph;
601 RCP<Matrix> filteredA;
602 if (numGlobalDropped > 0) {
605 local_graph_type lclGraph;
606 local_matrix_type lclFilteredA;
607 auto colidx = entries_type(
"entries", nnz_filtered);
608 lclGraph = local_graph_type(colidx, filtered_rowptr);
611 filteredA = MatrixFactory::BuildCopy(A);
612 lclFilteredA = filteredA->getLocalMatrixDevice();
613 }
else if (needToBuildFilteredA) {
614 auto values = values_type(
"values", nnz_filtered);
615 lclFilteredA = local_matrix_type(
"filteredA", lclGraph, lclA.numCols());
621 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_lumped_reuse", range, fillFunctor);
625 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_lumped_noreuse", range, fillFunctor);
628 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_lumped_noreuse", range, fillFunctor);
634 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_unlumped_reuse", range, fillFunctor);
636 if (needToBuildFilteredA) {
638 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_unlumped_noreuse", range, fillFunctor);
641 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_unlumped_noreuse", range, fillFunctor);
646 if (needToBuildFilteredA) {
648 filteredA = MatrixFactory::Build(lclFilteredA, A->getRowMap(), A->getColMap(), A->getDomainMap(), A->getRangeMap());
649 filteredA->SetFixedBlockSize(A->GetFixedBlockSize());
651 if (reuseEigenvalue) {
656 filteredA->SetMaxEigenvalueEstimate(A->GetMaxEigenvalueEstimate());
658 filteredA->SetMaxEigenvalueEstimate(-Teuchos::ScalarTraits<SC>::one());
662 graph = rcp(
new LWGraph_kokkos(lclGraph, A->getRowMap(), A->getColMap(),
"amalgamated graph of A"));
663 graph->SetBoundaryNodeMap(boundaryNodes);
665 if (needToBuildFilteredA)
667 graph = rcp(
new LWGraph_kokkos(A->getCrsGraph()->getLocalGraphDevice(), A->getRowMap(), A->getColMap(),
"amalgamated graph of A"));
668 graph->SetBoundaryNodeMap(boundaryNodes);
672 if (generateColoringGraph) {
673 SubFactoryMonitor mColoringGraph(*
this,
"Construct coloring graph", currentLevel);
675 filtered_rowptr = rowptr_type(
"rowptr_coloring_graph", lclA.numRows() + 1);
676 if (localizeColoringGraph) {
678 ScalarDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, results, filtered_rowptr, nnz_filtered, useBlocking, currentLevel, *
this, drop_offrank);
680 if (symmetrizeColoringGraph) {
682 ScalarDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, results, filtered_rowptr, nnz_filtered, useBlocking, currentLevel, *
this, symmetrize);
684 auto colidx = entries_type(
"entries_coloring_graph", nnz_filtered);
685 auto lclGraph = local_graph_type(colidx, filtered_rowptr);
687 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Construct_coloring_graph", range, graphConstruction);
689 auto colorGraph = rcp(
new LWGraph_kokkos(lclGraph, A->getRowMap(), A->getColMap(),
"coloring graph"));
690 Set(currentLevel,
"Coloring Graph", colorGraph);
693 if (needToBuildFilteredA && pL.get<
bool>(
"filtered matrix: count negative diagonals")) {
696 GetOStream(
Runtime0) <<
"CoalesceDrop: Negative diagonals: " << neg_count << std::endl;
700 Set(currentLevel,
"DofsPerNode", dofsPerNode);
701 Set(currentLevel,
"Graph", graph);
702 if (needToBuildFilteredA)
703 Set(currentLevel,
"A", filteredA);
705 return std::make_tuple(numDropped, (
GlobalOrdinal)nnz_filtered, boundaryNodes);
713 using MatrixType = Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
714 using GraphType = Xpetra::CrsGraph<LocalOrdinal, GlobalOrdinal, Node>;
715 using local_matrix_type =
typename MatrixType::local_matrix_device_type;
716 using local_graph_type =
typename GraphType::local_graph_device_type;
717 using rowptr_type =
typename local_graph_type::row_map_type::non_const_type;
718 using entries_type =
typename local_graph_type::entries_type::non_const_type;
719 using values_type =
typename local_matrix_type::values_type::non_const_type;
720 using device_type =
typename Node::device_type;
721 using memory_space =
typename device_type::memory_space;
722 using results_view_type = Kokkos::View<DecisionType*, memory_space>;
723 using magnitudeType =
typename Teuchos::ScalarTraits<Scalar>::magnitudeType;
724 using doubleMultiVector = Xpetra::MultiVector<magnitudeType, LO, GO, NO>;
726 typedef Teuchos::ScalarTraits<Scalar> STS;
727 const magnitudeType zero = Teuchos::ScalarTraits<magnitudeType>::zero();
729 auto A = Get<RCP<Matrix>>(currentLevel,
"A");
731 const bool needToBuildFilteredA = currentLevel.
IsRequested(
"A",
this);
750 TEUCHOS_TEST_FOR_EXCEPTION(A->GetFixedBlockSize() % A->GetStorageBlockSize() != 0,
Exceptions::RuntimeError,
"A->GetFixedBlockSize() needs to be a multiple of A->GetStorageBlockSize()");
751 LO blkSize = A->GetFixedBlockSize() / A->GetStorageBlockSize();
753 auto amalInfo = Get<RCP<AmalgamationInfo>>(currentLevel,
"UnAmalgamationInfo");
755 const RCP<const Map> rowMap = A->getRowMap();
756 const RCP<const Map> colMap = A->getColMap();
763 const RCP<const Map> uniqueMap = amalInfo->getNodeRowMap();
764 const RCP<const Map> nonUniqueMap = amalInfo->getNodeColMap();
765 Array<LO> rowTranslationArray = *(amalInfo->getRowTranslation());
766 Array<LO> colTranslationArray = *(amalInfo->getColTranslation());
768 Kokkos::View<LO*, Kokkos::MemoryUnmanaged>
769 rowTranslationView(rowTranslationArray.getRawPtr(), rowTranslationArray.size());
770 Kokkos::View<LO*, Kokkos::MemoryUnmanaged>
771 colTranslationView(colTranslationArray.getRawPtr(), colTranslationArray.size());
774 LO numNodes = Teuchos::as<LocalOrdinal>(uniqueMap->getLocalNumElements());
775 typedef typename Kokkos::View<LocalOrdinal*, typename Node::device_type> id_translation_type;
776 id_translation_type rowTranslation(
"dofId2nodeId", rowTranslationArray.size());
777 id_translation_type colTranslation(
"ov_dofId2nodeId", colTranslationArray.size());
778 Kokkos::deep_copy(rowTranslation, rowTranslationView);
779 Kokkos::deep_copy(colTranslation, colTranslationView);
782 blkSize = A->GetFixedBlockSize();
785 if (A->IsView(
"stridedMaps") ==
true) {
786 const RCP<const Map> myMap = A->getRowMap(
"stridedMaps");
787 const RCP<const StridedMap> strMap = Teuchos::rcp_dynamic_cast<const StridedMap>(myMap);
789 blkSize = Teuchos::as<const LocalOrdinal>(strMap->getFixedBlockSize());
790 blkId = strMap->getStridedBlockId();
792 blkPartSize = Teuchos::as<LocalOrdinal>(strMap->getStridingData()[blkId]);
795 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);
799 const ParameterList& pL = GetParameterList();
802 const magnitudeType dirichletThreshold = STS::magnitude(as<SC>(pL.get<
double>(
"aggregation: Dirichlet threshold")));
803 const magnitudeType rowSumTol = as<magnitudeType>(pL.get<
double>(
"aggregation: row sum drop tol"));
805 const bool useGreedyDirichlet = pL.get<
bool>(
"aggregation: greedy Dirichlet");
806 TEUCHOS_TEST_FOR_EXCEPTION(rowSumTol > zero,
MueLu::Exceptions::RuntimeError,
"MueLu::CoalesceDropFactory: RowSum is not implemented for vectorial problems.");
809 bool useBlocking = pL.get<
bool>(
"aggregation: use blocking");
810 std::string droppingMethod = pL.get<std::string>(
"aggregation: drop scheme");
811 std::string socUsesMatrix = pL.get<std::string>(
"aggregation: strength-of-connection: matrix");
812 std::string socUsesMeasure = pL.get<std::string>(
"aggregation: strength-of-connection: measure");
813 std::string distanceLaplacianMetric = pL.get<std::string>(
"aggregation: distance laplacian metric");
814 bool symmetrizeDroppedGraph = pL.get<
bool>(
"aggregation: symmetrize graph after dropping");
815 magnitudeType threshold;
817 if (pL.get<
bool>(
"aggregation: use ml scaling of drop tol"))
818 threshold = pL.get<
double>(
"aggregation: drop tol") / pow(2.0, currentLevel.
GetLevelID());
820 threshold = as<magnitudeType>(pL.get<
double>(
"aggregation: drop tol"));
821 bool aggregationMayCreateDirichlet = pL.get<
bool>(
"aggregation: dropping may create Dirichlet");
824 const bool reuseGraph = pL.get<
bool>(
"filtered matrix: reuse graph") && needToBuildFilteredA;
825 const bool reuseEigenvalue = pL.get<
bool>(
"filtered matrix: reuse eigenvalue");
827 const bool useRootStencil = pL.get<
bool>(
"filtered matrix: use root stencil");
828 const bool useSpreadLumping = pL.get<
bool>(
"filtered matrix: use spread lumping");
829 const std::string lumpingChoiceString = pL.get<std::string>(
"filtered matrix: lumping choice");
831 if (needToBuildFilteredA) {
832 if (lumpingChoiceString ==
"diag lumping")
834 else if (lumpingChoiceString ==
"distributed lumping")
838 const magnitudeType filteringDirichletThreshold = as<magnitudeType>(pL.get<
double>(
"filtered matrix: Dirichlet threshold"));
841 bool generateColoringGraph = pL.get<
bool>(
"aggregation: coloring: use color graph");
842 const bool localizeColoringGraph = pL.get<
bool>(
"aggregation: coloring: localize color graph");
843 const bool symmetrizeColoringGraph =
true;
845#ifdef HAVE_MUELU_COALESCEDROP_ALLOW_OLD_PARAMETERS
846 translateOldAlgoParam(pL, droppingMethod, useBlocking, socUsesMatrix, socUsesMeasure, symmetrizeDroppedGraph, generateColoringGraph, threshold, lumpingChoice);
849 std::stringstream ss;
850 ss <<
"dropping scheme = \"" << droppingMethod <<
"\", strength-of-connection measure = \"" << socUsesMeasure <<
"\", strength-of-connection matrix = \"" << socUsesMatrix <<
"\", ";
851 if (socUsesMatrix ==
"distance laplacian")
852 ss <<
"distance laplacian metric = \"" << distanceLaplacianMetric <<
"\", ";
853 ss <<
"threshold = " << threshold <<
", blocksize = " << A->GetFixedBlockSize() <<
", useBlocking = " << useBlocking;
854 ss <<
", symmetrizeDroppedGraph = " << symmetrizeDroppedGraph << std::endl;
859 TEUCHOS_ASSERT(!useRootStencil);
860 TEUCHOS_ASSERT(!useSpreadLumping);
862 if (droppingMethod ==
"cut-drop")
863 TEUCHOS_TEST_FOR_EXCEPTION(threshold > 1.0,
Exceptions::RuntimeError,
"For cut-drop algorithms, \"aggregation: drop tol\" = " << threshold <<
", needs to be <= 1.0");
876 auto crsA = toCrsMatrix(A);
877 auto lclA = crsA->getLocalMatrixDevice();
892 if (useGreedyDirichlet) {
922 auto filtered_rowptr = rowptr_type(
"rowptr", lclA.numRows() + 1);
923 auto graph_rowptr = rowptr_type(
"rowptr", numNodes + 1);
925 Kokkos::pair<LocalOrdinal, LocalOrdinal> nnz = {0, 0};
928 auto results = results_view_type(
"results", lclA.nnz());
937 auto merged_rowptr = rowptr_type(
"rowptr", numNodes + 1);
941 Kokkos::parallel_scan(
"MergeCount", range, functor, nnz_merged);
943 local_graph_type lclMergedGraph;
944 auto colidx_merged = entries_type(
"entries", nnz_merged);
945 auto values_merged = values_type(
"values", nnz_merged);
947 local_matrix_type lclMergedA = local_matrix_type(
"mergedA",
948 numNodes, nonUniqueMap->getLocalNumElements(),
950 values_merged, merged_rowptr, colidx_merged);
953 Kokkos::parallel_for(
"MueLu::CoalesceDrop::MergeFill", range, fillFunctor);
955 mergedA = Xpetra::MatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(lclMergedA, uniqueMap, nonUniqueMap, uniqueMap, uniqueMap);
958 if (threshold != zero) {
959 if (socUsesMatrix ==
"A") {
960 if (socUsesMeasure ==
"unscaled") {
961 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);
962 }
else if (socUsesMeasure ==
"smoothed aggregation") {
963 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);
964 }
else if (socUsesMeasure ==
"signed ruge-stueben") {
965 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);
966 }
else if (socUsesMeasure ==
"signed smoothed aggregation") {
967 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);
969 }
else if (socUsesMatrix ==
"distance laplacian") {
970 auto coords = Get<RCP<doubleMultiVector>>(currentLevel,
"Coordinates");
972 Array<double> dlap_weights = pL.get<Array<double>>(
"aggregation: distance laplacian directional weights");
973 LocalOrdinal interleaved_blocksize = as<LocalOrdinal>(pL.get<
int>(
"aggregation: block diagonal: interleaved blocksize"));
974 if (socUsesMeasure ==
"distance laplacian") {
975 LO dim = (LO)coords->getNumVectors();
977 bool non_unity =
false;
978 for (LO i = 0; !non_unity && i < (LO)dlap_weights.size(); i++) {
979 if (dlap_weights[i] != 1.0) {
984 if ((LO)dlap_weights.size() == dim) {
985 distanceLaplacianMetric =
"weighted";
986 }
else if ((LO)dlap_weights.size() == interleaved_blocksize * dim)
987 distanceLaplacianMetric =
"block weighted";
990 "length of 'aggregation: distance laplacian directional weights' must equal the coordinate dimension OR the coordinate dimension times the blocksize");
993 GetOStream(
Statistics1) <<
"Using distance laplacian weights: " << dlap_weights << std::endl;
997 if (socUsesMeasure ==
"unscaled") {
998 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);
999 }
else if (socUsesMeasure ==
"smoothed aggregation") {
1000 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);
1001 }
else if (socUsesMeasure ==
"signed ruge-stueben") {
1002 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);
1003 }
else if (socUsesMeasure ==
"signed smoothed aggregation") {
1004 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);
1008 Kokkos::deep_copy(results,
KEEP);
1011 VectorDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, *mergedA, blkPartSize, rowTranslation, colTranslation, results, filtered_rowptr, graph_rowptr, nnz, useBlocking, currentLevel, *
this, no_op);
1014 if (symmetrizeDroppedGraph) {
1016 VectorDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, *mergedA, blkPartSize, rowTranslation, colTranslation, results, filtered_rowptr, graph_rowptr, nnz, useBlocking, currentLevel, *
this, symmetrize);
1021 GO numTotal = mergedA->getLocalNumEntries();
1022 GO numDropped = numTotal - nnz_graph;
1023 GO numGlobalDropped;
1024 Teuchos::reduceAll(*A->getRowMap()->getComm(), Teuchos::REDUCE_SUM, 1, &numDropped, &numGlobalDropped);
1032 RCP<LWGraph_kokkos> graph;
1033 RCP<Matrix> filteredA;
1034 if (numGlobalDropped > 0) {
1037 local_graph_type lclGraph;
1039 auto colidx = entries_type(
"entries", nnz_graph);
1040 lclGraph = local_graph_type(colidx, graph_rowptr);
1043 local_matrix_type lclFilteredA;
1046 lclFilteredA = local_matrix_type(
"filteredA", lclA.graph, lclA.numCols());
1047 }
else if (needToBuildFilteredA) {
1048 auto colidx = entries_type(
"entries", nnz_filtered);
1049 auto values = values_type(
"values", nnz_filtered);
1050 lclFilteredA = local_matrix_type(
"filteredA",
1051 lclA.numRows(), lclA.numCols(),
1053 values, filtered_rowptr, colidx);
1059 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_lumped_reuse", range, fillFunctor);
1062 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_lumped_noreuse", range, fillFunctor);
1067 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_unlumped_reuse", range, fillFunctor);
1069 if (needToBuildFilteredA) {
1071 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_unlumped_noreuse", range, fillFunctor);
1073 auto fillFunctor =
MatrixConstruction::VectorFillFunctor<local_matrix_type,
false,
false,
false>(lclA, blkSize, colTranslation, results, lclFilteredA, lclGraph, filteringDirichletThreshold);
1074 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_unlumped_noreuse", range, fillFunctor);
1079 if (needToBuildFilteredA) {
1080 filteredA = Xpetra::MatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(lclFilteredA, A->getRowMap(), A->getColMap(), A->getDomainMap(), A->getRangeMap());
1081 filteredA->SetFixedBlockSize(blkSize);
1083 if (reuseEigenvalue) {
1088 filteredA->SetMaxEigenvalueEstimate(A->GetMaxEigenvalueEstimate());
1090 filteredA->SetMaxEigenvalueEstimate(-Teuchos::ScalarTraits<SC>::one());
1094 graph = rcp(
new LWGraph_kokkos(lclGraph, uniqueMap, nonUniqueMap,
"amalgamated graph of A"));
1095 graph->SetBoundaryNodeMap(boundaryNodes);
1097 if (needToBuildFilteredA)
1099 graph = rcp(
new LWGraph_kokkos(mergedA->getCrsGraph()->getLocalGraphDevice(), uniqueMap, nonUniqueMap,
"amalgamated graph of A"));
1100 graph->SetBoundaryNodeMap(boundaryNodes);
1104 if (generateColoringGraph) {
1105 SubFactoryMonitor mColoringGraph(*
this,
"Construct coloring graph", currentLevel);
1107 filtered_rowptr = rowptr_type(
"rowptr_coloring_graph", lclA.numRows() + 1);
1108 graph_rowptr = rowptr_type(
"rowptr", numNodes + 1);
1109 if (localizeColoringGraph) {
1111 VectorDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, *mergedA, blkPartSize, rowTranslation, colTranslation, results, filtered_rowptr, graph_rowptr, nnz, useBlocking, currentLevel, *
this, drop_offrank);
1113 if (symmetrizeColoringGraph) {
1115 VectorDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, *mergedA, blkPartSize, rowTranslation, colTranslation, results, filtered_rowptr, graph_rowptr, nnz, useBlocking, currentLevel, *
this, symmetrize);
1117 auto colidx = entries_type(
"entries_coloring_graph", nnz_filtered);
1118 auto lclGraph = local_graph_type(colidx, filtered_rowptr);
1120 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Construct_coloring_graph", range, graphConstruction);
1122 auto colorGraph = rcp(
new LWGraph_kokkos(lclGraph, A->getRowMap(), A->getColMap(),
"coloring graph"));
1123 Set(currentLevel,
"Coloring Graph", colorGraph);
1126 LO dofsPerNode = blkSize;
1128 Set(currentLevel,
"DofsPerNode", dofsPerNode);
1129 Set(currentLevel,
"Graph", graph);
1130 if (needToBuildFilteredA)
1131 Set(currentLevel,
"A", filteredA);
1133 return std::make_tuple(numDropped, (
GlobalOrdinal)nnz_graph, boundaryNodes);