289 using MatrixType = Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
290 using GraphType = Xpetra::CrsGraph<LocalOrdinal, GlobalOrdinal, Node>;
291 using local_matrix_type =
typename MatrixType::local_matrix_device_type;
292 using local_graph_type =
typename GraphType::local_graph_device_type;
293 using rowptr_type =
typename local_graph_type::row_map_type::non_const_type;
294 using entries_type =
typename local_graph_type::entries_type::non_const_type;
295 using values_type =
typename local_matrix_type::values_type::non_const_type;
296 using device_type =
typename Node::device_type;
297 using memory_space =
typename device_type::memory_space;
298 using results_view_type = Kokkos::View<DecisionType*, memory_space>;
299 using magnitudeType =
typename Teuchos::ScalarTraits<Scalar>::magnitudeType;
300 using doubleMultiVector = Xpetra::MultiVector<magnitudeType, LO, GO, NO>;
302 typedef Teuchos::ScalarTraits<Scalar> STS;
303 const magnitudeType zero = Teuchos::ScalarTraits<magnitudeType>::zero();
305 auto A = Get<RCP<Matrix>>(currentLevel,
"A");
309 const ParameterList& pL = GetParameterList();
312 const magnitudeType dirichletThreshold = STS::magnitude(as<SC>(pL.get<
double>(
"aggregation: Dirichlet threshold")));
313 const magnitudeType rowSumTol = as<magnitudeType>(pL.get<
double>(
"aggregation: row sum drop tol"));
317 bool useBlocking = pL.get<
bool>(
"aggregation: use blocking");
318 std::string droppingMethod = pL.get<std::string>(
"aggregation: drop scheme");
319 std::string socUsesMatrix = pL.get<std::string>(
"aggregation: strength-of-connection: matrix");
320 std::string socUsesMeasure = pL.get<std::string>(
"aggregation: strength-of-connection: measure");
321 std::string distanceLaplacianMetric = pL.get<std::string>(
"aggregation: distance laplacian metric");
322 bool symmetrizeDroppedGraph = pL.get<
bool>(
"aggregation: symmetrize graph after dropping");
323 magnitudeType threshold;
325 if (pL.get<
bool>(
"aggregation: use ml scaling of drop tol"))
326 threshold = pL.get<
double>(
"aggregation: drop tol") / pow(2.0, currentLevel.
GetLevelID());
328 threshold = as<magnitudeType>(pL.get<
double>(
"aggregation: drop tol"));
329 bool aggregationMayCreateDirichlet = pL.get<
bool>(
"aggregation: dropping may create Dirichlet");
332 const bool reuseGraph = pL.get<
bool>(
"filtered matrix: reuse graph");
333 const bool reuseEigenvalue = pL.get<
bool>(
"filtered matrix: reuse eigenvalue");
335 const bool useRootStencil = pL.get<
bool>(
"filtered matrix: use root stencil");
336 const bool useSpreadLumping = pL.get<
bool>(
"filtered matrix: use spread lumping");
337 const std::string lumpingChoiceString = pL.get<std::string>(
"filtered matrix: lumping choice");
339 if (lumpingChoiceString ==
"diag lumping")
341 else if (lumpingChoiceString ==
"distributed lumping")
344 const magnitudeType filteringDirichletThreshold = as<magnitudeType>(pL.get<
double>(
"filtered matrix: Dirichlet threshold"));
347 bool generateColoringGraph = pL.get<
bool>(
"aggregation: coloring: use color graph");
348 const bool localizeColoringGraph = pL.get<
bool>(
"aggregation: coloring: localize color graph");
349 const bool symmetrizeColoringGraph =
true;
351#ifdef HAVE_MUELU_COALESCEDROP_ALLOW_OLD_PARAMETERS
352 translateOldAlgoParam(pL, droppingMethod, useBlocking, socUsesMatrix, socUsesMeasure, symmetrizeDroppedGraph, generateColoringGraph, threshold, lumpingChoice);
356 std::stringstream ss;
357 ss <<
"dropping scheme = \"" << droppingMethod <<
"\", strength-of-connection measure = \"" << socUsesMeasure <<
"\", strength-of-connection matrix = \"" << socUsesMatrix <<
"\", ";
358 if (socUsesMatrix ==
"distance laplacian")
359 ss <<
"distance laplacian metric = \"" << distanceLaplacianMetric <<
"\", ";
360 ss <<
"threshold = " << threshold <<
", blocksize = " << A->GetFixedBlockSize() <<
", useBlocking = " << useBlocking;
361 ss <<
", symmetrizeDroppedGraph = " << symmetrizeDroppedGraph << std::endl;
366 TEUCHOS_ASSERT(!useRootStencil);
367 TEUCHOS_ASSERT(!useSpreadLumping);
369 if (droppingMethod ==
"cut-drop")
370 TEUCHOS_TEST_FOR_EXCEPTION(threshold > 1.0,
Exceptions::RuntimeError,
"For cut-drop algorithms, \"aggregation: drop tol\" = " << threshold <<
", needs to be <= 1.0");
385 if (threshold != zero) {
386 if ((socUsesMatrix ==
"A") || (socUsesMatrix ==
"MinvA")) {
388 if (socUsesMatrix ==
"A")
390 else if (socUsesMatrix ==
"MinvA") {
391 bool storeMinvOnLevel =
false, storeMinvAOnLevel =
false;
392 if (pL.isSublist(
"project auxiliary matrices")) {
393 auto projectList = pL.sublist(
"project auxiliary matrices");
394 if (projectList.isParameter(
"Minv")) storeMinvOnLevel =
true;
395 if (projectList.isParameter(
"MinvA")) storeMinvAOnLevel =
true;
397 if (!projectList.isParameter(
"M") && !storeMinvOnLevel && !storeMinvAOnLevel) storeMinvAOnLevel =
true;
399 storeMinvAOnLevel =
true;
401 if (IsAvailable(currentLevel,
"MinvA")) {
402 A_drop = Get<RCP<Matrix>>(currentLevel,
"MinvA");
405 if (IsAvailable(currentLevel,
"Minv")) {
406 Minv = Get<RCP<Matrix>>(currentLevel,
"Minv");
413 auto M = Get<RCP<Matrix>>(currentLevel,
"M");
417 if (storeMinvOnLevel) currentLevel.
Set(
"Minv", Minv);
421 A_drop = Xpetra::MatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::BuildCopy(A);
422 auto params = Teuchos::rcp(
new Teuchos::ParameterList());
423 params->set(
"MM Throw For Non-Existent Entries",
false);
424 A_drop = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*Minv,
false, *A,
false, A_drop, GetOStream(
Statistics2),
true,
true, std::string(
"MinvA"), params);
425 if (storeMinvAOnLevel) currentLevel.
Set(
"MinvA", A_drop);
431 auto crsA = toCrsMatrix(A);
432 auto lclA = crsA->getLocalMatrixDevice();
452 if (rowSumTol <= 0.) {
485 auto filtered_rowptr = rowptr_type(
"filtered_rowptr", lclA.numRows() + 1);
489 auto results = results_view_type(
"results", lclA.nnz());
493 if (threshold != zero) {
494 if ((socUsesMatrix ==
"A") || (socUsesMatrix ==
"MinvA")) {
495 if (socUsesMeasure ==
"unscaled") {
496 ScalarDroppingClassical<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::UnscaledMeasure>::runDroppingFunctors_on_A(*A_drop, results, filtered_rowptr, nnz_filtered, boundaryNodes, droppingMethod, threshold,
497 aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, currentLevel, *
this);
498 }
else if (socUsesMeasure ==
"smoothed aggregation") {
499 ScalarDroppingClassical<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::SmoothedAggregationMeasure>::runDroppingFunctors_on_A(*A_drop, results, filtered_rowptr, nnz_filtered, boundaryNodes, droppingMethod, threshold,
500 aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, currentLevel, *
this);
501 }
else if (socUsesMeasure ==
"signed ruge-stueben") {
502 ScalarDroppingClassical<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::SignedRugeStuebenMeasure>::runDroppingFunctors_on_A(*A_drop, results, filtered_rowptr, nnz_filtered, boundaryNodes, droppingMethod, threshold,
503 aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, currentLevel, *
this);
504 }
else if (socUsesMeasure ==
"signed smoothed aggregation") {
505 ScalarDroppingClassical<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::SignedSmoothedAggregationMeasure>::runDroppingFunctors_on_A(*A_drop, results, filtered_rowptr, nnz_filtered, boundaryNodes, droppingMethod, threshold,
506 aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, currentLevel, *
this);
508 }
else if (socUsesMatrix ==
"distance laplacian") {
509 auto coords = Get<RCP<doubleMultiVector>>(currentLevel,
"Coordinates");
510 if (socUsesMeasure ==
"unscaled") {
511 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);
512 }
else if (socUsesMeasure ==
"smoothed aggregation") {
513 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);
514 }
else if (socUsesMeasure ==
"signed ruge-stueben") {
515 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);
516 }
else if (socUsesMeasure ==
"signed smoothed aggregation") {
517 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);
521 Kokkos::deep_copy(results,
KEEP);
523 if (symmetrizeDroppedGraph) {
525 ScalarDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, results, filtered_rowptr, nnz_filtered, useBlocking, currentLevel, *
this, drop_boundaries);
528 ScalarDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, results, filtered_rowptr, nnz_filtered, useBlocking, currentLevel, *
this, no_op);
532 if (symmetrizeDroppedGraph) {
534 ScalarDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, results, filtered_rowptr, nnz_filtered, useBlocking, currentLevel, *
this, symmetrize);
537 GO numDropped = lclA.nnz() - nnz_filtered;
539 Teuchos::reduceAll(*A->getRowMap()->getComm(), Teuchos::REDUCE_SUM, 1, &numDropped, &numGlobalDropped);
547 RCP<Matrix> filteredA;
548 RCP<LWGraph_kokkos> graph;
549 if (numGlobalDropped > 0) {
552 local_matrix_type lclFilteredA;
553 local_graph_type lclGraph;
555 filteredA = MatrixFactory::BuildCopy(A);
556 lclFilteredA = filteredA->getLocalMatrixDevice();
558 auto colidx = entries_type(
"entries", nnz_filtered);
559 lclGraph = local_graph_type(colidx, filtered_rowptr);
561 auto colidx = entries_type(
"entries", nnz_filtered);
562 auto values = values_type(
"values", nnz_filtered);
563 lclFilteredA = local_matrix_type(
"filteredA",
564 lclA.numRows(), lclA.numCols(),
566 values, filtered_rowptr, colidx);
572 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_lumped_reuse", range, fillFunctor);
576 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_lumped_noreuse", range, fillFunctor);
579 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_lumped_noreuse", range, fillFunctor);
585 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_unlumped_reuse", range, fillFunctor);
588 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_unlumped_noreuse", range, fillFunctor);
593 filteredA = MatrixFactory::Build(lclFilteredA, A->getRowMap(), A->getColMap(), A->getDomainMap(), A->getRangeMap());
594 filteredA->SetFixedBlockSize(A->GetFixedBlockSize());
596 if (reuseEigenvalue) {
601 filteredA->SetMaxEigenvalueEstimate(A->GetMaxEigenvalueEstimate());
603 filteredA->SetMaxEigenvalueEstimate(-Teuchos::ScalarTraits<SC>::one());
608 lclGraph = filteredA->getCrsGraph()->getLocalGraphDevice();
610 graph = rcp(
new LWGraph_kokkos(lclGraph, filteredA->getRowMap(), filteredA->getColMap(),
"amalgamated graph of A"));
611 graph->SetBoundaryNodeMap(boundaryNodes);
614 graph = rcp(
new LWGraph_kokkos(filteredA->getCrsGraph()->getLocalGraphDevice(), filteredA->getRowMap(), filteredA->getColMap(),
"amalgamated graph of A"));
615 graph->SetBoundaryNodeMap(boundaryNodes);
619 if (generateColoringGraph) {
620 SubFactoryMonitor mColoringGraph(*
this,
"Construct coloring graph", currentLevel);
622 filtered_rowptr = rowptr_type(
"rowptr_coloring_graph", lclA.numRows() + 1);
623 if (localizeColoringGraph) {
625 ScalarDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, results, filtered_rowptr, nnz_filtered, useBlocking, currentLevel, *
this, drop_offrank);
627 if (symmetrizeColoringGraph) {
629 ScalarDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, results, filtered_rowptr, nnz_filtered, useBlocking, currentLevel, *
this, symmetrize);
631 auto colidx = entries_type(
"entries_coloring_graph", nnz_filtered);
632 auto lclGraph = local_graph_type(colidx, filtered_rowptr);
634 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Construct_coloring_graph", range, graphConstruction);
636 auto colorGraph = rcp(
new LWGraph_kokkos(lclGraph, filteredA->getRowMap(), filteredA->getColMap(),
"coloring graph"));
637 Set(currentLevel,
"Coloring Graph", colorGraph);
640 if (pL.get<
bool>(
"filtered matrix: count negative diagonals")) {
643 GetOStream(
Runtime0) <<
"CoalesceDrop: Negative diagonals: " << neg_count << std::endl;
647 Set(currentLevel,
"DofsPerNode", dofsPerNode);
648 Set(currentLevel,
"Graph", graph);
649 Set(currentLevel,
"A", filteredA);
651 return std::make_tuple(numDropped, boundaryNodes);
659 using MatrixType = Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
660 using GraphType = Xpetra::CrsGraph<LocalOrdinal, GlobalOrdinal, Node>;
661 using local_matrix_type =
typename MatrixType::local_matrix_device_type;
662 using local_graph_type =
typename GraphType::local_graph_device_type;
663 using rowptr_type =
typename local_graph_type::row_map_type::non_const_type;
664 using entries_type =
typename local_graph_type::entries_type::non_const_type;
665 using values_type =
typename local_matrix_type::values_type::non_const_type;
666 using device_type =
typename Node::device_type;
667 using memory_space =
typename device_type::memory_space;
668 using results_view_type = Kokkos::View<DecisionType*, memory_space>;
669 using magnitudeType =
typename Teuchos::ScalarTraits<Scalar>::magnitudeType;
670 using doubleMultiVector = Xpetra::MultiVector<magnitudeType, LO, GO, NO>;
672 typedef Teuchos::ScalarTraits<Scalar> STS;
673 const magnitudeType zero = Teuchos::ScalarTraits<magnitudeType>::zero();
675 auto A = Get<RCP<Matrix>>(currentLevel,
"A");
694 TEUCHOS_TEST_FOR_EXCEPTION(A->GetFixedBlockSize() % A->GetStorageBlockSize() != 0,
Exceptions::RuntimeError,
"A->GetFixedBlockSize() needs to be a multiple of A->GetStorageBlockSize()");
695 LO blkSize = A->GetFixedBlockSize() / A->GetStorageBlockSize();
697 auto amalInfo = Get<RCP<AmalgamationInfo>>(currentLevel,
"UnAmalgamationInfo");
699 const RCP<const Map> rowMap = A->getRowMap();
700 const RCP<const Map> colMap = A->getColMap();
707 const RCP<const Map> uniqueMap = amalInfo->getNodeRowMap();
708 const RCP<const Map> nonUniqueMap = amalInfo->getNodeColMap();
709 Array<LO> rowTranslationArray = *(amalInfo->getRowTranslation());
710 Array<LO> colTranslationArray = *(amalInfo->getColTranslation());
712 Kokkos::View<LO*, Kokkos::MemoryUnmanaged>
713 rowTranslationView(rowTranslationArray.getRawPtr(), rowTranslationArray.size());
714 Kokkos::View<LO*, Kokkos::MemoryUnmanaged>
715 colTranslationView(colTranslationArray.getRawPtr(), colTranslationArray.size());
718 LO numNodes = Teuchos::as<LocalOrdinal>(uniqueMap->getLocalNumElements());
719 typedef typename Kokkos::View<LocalOrdinal*, typename Node::device_type> id_translation_type;
720 id_translation_type rowTranslation(
"dofId2nodeId", rowTranslationArray.size());
721 id_translation_type colTranslation(
"ov_dofId2nodeId", colTranslationArray.size());
722 Kokkos::deep_copy(rowTranslation, rowTranslationView);
723 Kokkos::deep_copy(colTranslation, colTranslationView);
726 blkSize = A->GetFixedBlockSize();
729 if (A->IsView(
"stridedMaps") ==
true) {
730 const RCP<const Map> myMap = A->getRowMap(
"stridedMaps");
731 const RCP<const StridedMap> strMap = Teuchos::rcp_dynamic_cast<const StridedMap>(myMap);
733 blkSize = Teuchos::as<const LocalOrdinal>(strMap->getFixedBlockSize());
734 blkId = strMap->getStridedBlockId();
736 blkPartSize = Teuchos::as<LocalOrdinal>(strMap->getStridingData()[blkId]);
739 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);
743 const ParameterList& pL = GetParameterList();
746 const magnitudeType dirichletThreshold = STS::magnitude(as<SC>(pL.get<
double>(
"aggregation: Dirichlet threshold")));
747 const magnitudeType rowSumTol = as<magnitudeType>(pL.get<
double>(
"aggregation: row sum drop tol"));
749 const bool useGreedyDirichlet = pL.get<
bool>(
"aggregation: greedy Dirichlet");
750 TEUCHOS_TEST_FOR_EXCEPTION(rowSumTol > zero,
MueLu::Exceptions::RuntimeError,
"MueLu::CoalesceDropFactory: RowSum is not implemented for vectorial problems.");
753 bool useBlocking = pL.get<
bool>(
"aggregation: use blocking");
754 std::string droppingMethod = pL.get<std::string>(
"aggregation: drop scheme");
755 std::string socUsesMatrix = pL.get<std::string>(
"aggregation: strength-of-connection: matrix");
756 std::string socUsesMeasure = pL.get<std::string>(
"aggregation: strength-of-connection: measure");
757 std::string distanceLaplacianMetric = pL.get<std::string>(
"aggregation: distance laplacian metric");
758 bool symmetrizeDroppedGraph = pL.get<
bool>(
"aggregation: symmetrize graph after dropping");
759 magnitudeType threshold;
761 if (pL.get<
bool>(
"aggregation: use ml scaling of drop tol"))
762 threshold = pL.get<
double>(
"aggregation: drop tol") / pow(2.0, currentLevel.
GetLevelID());
764 threshold = as<magnitudeType>(pL.get<
double>(
"aggregation: drop tol"));
765 bool aggregationMayCreateDirichlet = pL.get<
bool>(
"aggregation: dropping may create Dirichlet");
768 const bool reuseGraph = pL.get<
bool>(
"filtered matrix: reuse graph");
769 const bool reuseEigenvalue = pL.get<
bool>(
"filtered matrix: reuse eigenvalue");
771 const bool useRootStencil = pL.get<
bool>(
"filtered matrix: use root stencil");
772 const bool useSpreadLumping = pL.get<
bool>(
"filtered matrix: use spread lumping");
773 const std::string lumpingChoiceString = pL.get<std::string>(
"filtered matrix: lumping choice");
775 if (lumpingChoiceString ==
"diag lumping")
777 else if (lumpingChoiceString ==
"distributed lumping")
780 const magnitudeType filteringDirichletThreshold = as<magnitudeType>(pL.get<
double>(
"filtered matrix: Dirichlet threshold"));
783 bool generateColoringGraph = pL.get<
bool>(
"aggregation: coloring: use color graph");
784 const bool localizeColoringGraph = pL.get<
bool>(
"aggregation: coloring: localize color graph");
785 const bool symmetrizeColoringGraph =
true;
787#ifdef HAVE_MUELU_COALESCEDROP_ALLOW_OLD_PARAMETERS
788 translateOldAlgoParam(pL, droppingMethod, useBlocking, socUsesMatrix, socUsesMeasure, symmetrizeDroppedGraph, generateColoringGraph, threshold, lumpingChoice);
791 std::stringstream ss;
792 ss <<
"dropping scheme = \"" << droppingMethod <<
"\", strength-of-connection measure = \"" << socUsesMeasure <<
"\", strength-of-connection matrix = \"" << socUsesMatrix <<
"\", ";
793 if (socUsesMatrix ==
"distance laplacian")
794 ss <<
"distance laplacian metric = \"" << distanceLaplacianMetric <<
"\", ";
795 ss <<
"threshold = " << threshold <<
", blocksize = " << A->GetFixedBlockSize() <<
", useBlocking = " << useBlocking;
796 ss <<
", symmetrizeDroppedGraph = " << symmetrizeDroppedGraph << std::endl;
801 TEUCHOS_ASSERT(!useRootStencil);
802 TEUCHOS_ASSERT(!useSpreadLumping);
804 if (droppingMethod ==
"cut-drop")
805 TEUCHOS_TEST_FOR_EXCEPTION(threshold > 1.0,
Exceptions::RuntimeError,
"For cut-drop algorithms, \"aggregation: drop tol\" = " << threshold <<
", needs to be <= 1.0");
818 auto crsA = toCrsMatrix(A);
819 auto lclA = crsA->getLocalMatrixDevice();
834 if (useGreedyDirichlet) {
864 auto filtered_rowptr = rowptr_type(
"rowptr", lclA.numRows() + 1);
865 auto graph_rowptr = rowptr_type(
"rowptr", numNodes + 1);
867 Kokkos::pair<LocalOrdinal, LocalOrdinal> nnz = {0, 0};
870 auto results = results_view_type(
"results", lclA.nnz());
879 auto merged_rowptr = rowptr_type(
"rowptr", numNodes + 1);
883 Kokkos::parallel_scan(
"MergeCount", range, functor, nnz_merged);
885 local_graph_type lclMergedGraph;
886 auto colidx_merged = entries_type(
"entries", nnz_merged);
887 auto values_merged = values_type(
"values", nnz_merged);
889 local_matrix_type lclMergedA = local_matrix_type(
"mergedA",
890 numNodes, nonUniqueMap->getLocalNumElements(),
892 values_merged, merged_rowptr, colidx_merged);
895 Kokkos::parallel_for(
"MueLu::CoalesceDrop::MergeFill", range, fillFunctor);
897 mergedA = Xpetra::MatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(lclMergedA, uniqueMap, nonUniqueMap, uniqueMap, uniqueMap);
900 if (threshold != zero) {
901 if (socUsesMatrix ==
"A") {
902 if (socUsesMeasure ==
"unscaled") {
903 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);
904 }
else if (socUsesMeasure ==
"smoothed aggregation") {
905 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);
906 }
else if (socUsesMeasure ==
"signed ruge-stueben") {
907 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);
908 }
else if (socUsesMeasure ==
"signed smoothed aggregation") {
909 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);
911 }
else if (socUsesMatrix ==
"distance laplacian") {
912 auto coords = Get<RCP<doubleMultiVector>>(currentLevel,
"Coordinates");
914 Array<double> dlap_weights = pL.get<Array<double>>(
"aggregation: distance laplacian directional weights");
915 LocalOrdinal interleaved_blocksize = as<LocalOrdinal>(pL.get<
int>(
"aggregation: block diagonal: interleaved blocksize"));
916 if (socUsesMeasure ==
"distance laplacian") {
917 LO dim = (LO)coords->getNumVectors();
919 bool non_unity =
false;
920 for (LO i = 0; !non_unity && i < (LO)dlap_weights.size(); i++) {
921 if (dlap_weights[i] != 1.0) {
926 if ((LO)dlap_weights.size() == dim) {
927 distanceLaplacianMetric =
"weighted";
928 }
else if ((LO)dlap_weights.size() == interleaved_blocksize * dim)
929 distanceLaplacianMetric =
"block weighted";
932 "length of 'aggregation: distance laplacian directional weights' must equal the coordinate dimension OR the coordinate dimension times the blocksize");
935 GetOStream(
Statistics1) <<
"Using distance laplacian weights: " << dlap_weights << std::endl;
939 if (socUsesMeasure ==
"unscaled") {
940 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);
941 }
else if (socUsesMeasure ==
"smoothed aggregation") {
942 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);
943 }
else if (socUsesMeasure ==
"signed ruge-stueben") {
944 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);
945 }
else if (socUsesMeasure ==
"signed smoothed aggregation") {
946 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);
950 Kokkos::deep_copy(results,
KEEP);
953 VectorDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, *mergedA, blkPartSize, rowTranslation, colTranslation, results, filtered_rowptr, graph_rowptr, nnz, useBlocking, currentLevel, *
this, no_op);
956 if (symmetrizeDroppedGraph) {
958 VectorDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, *mergedA, blkPartSize, rowTranslation, colTranslation, results, filtered_rowptr, graph_rowptr, nnz, useBlocking, currentLevel, *
this, symmetrize);
963 GO numTotal = lclA.nnz();
964 GO numDropped = numTotal - nnz_filtered;
966 Teuchos::reduceAll(*A->getRowMap()->getComm(), Teuchos::REDUCE_SUM, 1, &numDropped, &numGlobalDropped);
974 RCP<Matrix> filteredA;
975 RCP<LWGraph_kokkos> graph;
976 if (numGlobalDropped > 0) {
979 local_matrix_type lclFilteredA;
981 lclFilteredA = local_matrix_type(
"filteredA", lclA.graph, lclA.numCols());
983 auto colidx = entries_type(
"entries", nnz_filtered);
984 auto values = values_type(
"values", nnz_filtered);
985 lclFilteredA = local_matrix_type(
"filteredA",
986 lclA.numRows(), lclA.numCols(),
988 values, filtered_rowptr, colidx);
991 local_graph_type lclGraph;
993 auto colidx = entries_type(
"entries", nnz_graph);
994 lclGraph = local_graph_type(colidx, graph_rowptr);
1000 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_lumped_reuse", range, fillFunctor);
1003 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_lumped_noreuse", range, fillFunctor);
1008 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_unlumped_reuse", range, fillFunctor);
1011 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_unlumped_noreuse", range, fillFunctor);
1015 filteredA = Xpetra::MatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(lclFilteredA, A->getRowMap(), A->getColMap(), A->getDomainMap(), A->getRangeMap());
1016 filteredA->SetFixedBlockSize(blkSize);
1018 if (reuseEigenvalue) {
1023 filteredA->SetMaxEigenvalueEstimate(A->GetMaxEigenvalueEstimate());
1025 filteredA->SetMaxEigenvalueEstimate(-Teuchos::ScalarTraits<SC>::one());
1028 graph = rcp(
new LWGraph_kokkos(lclGraph, uniqueMap, nonUniqueMap,
"amalgamated graph of A"));
1029 graph->SetBoundaryNodeMap(boundaryNodes);
1032 graph = rcp(
new LWGraph_kokkos(mergedA->getCrsGraph()->getLocalGraphDevice(), uniqueMap, nonUniqueMap,
"amalgamated graph of A"));
1033 graph->SetBoundaryNodeMap(boundaryNodes);
1037 if (generateColoringGraph) {
1038 SubFactoryMonitor mColoringGraph(*
this,
"Construct coloring graph", currentLevel);
1040 filtered_rowptr = rowptr_type(
"rowptr_coloring_graph", lclA.numRows() + 1);
1041 graph_rowptr = rowptr_type(
"rowptr", numNodes + 1);
1042 if (localizeColoringGraph) {
1044 VectorDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, *mergedA, blkPartSize, rowTranslation, colTranslation, results, filtered_rowptr, graph_rowptr, nnz, useBlocking, currentLevel, *
this, drop_offrank);
1046 if (symmetrizeColoringGraph) {
1048 VectorDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, *mergedA, blkPartSize, rowTranslation, colTranslation, results, filtered_rowptr, graph_rowptr, nnz, useBlocking, currentLevel, *
this, symmetrize);
1050 auto colidx = entries_type(
"entries_coloring_graph", nnz_filtered);
1051 auto lclGraph = local_graph_type(colidx, filtered_rowptr);
1053 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Construct_coloring_graph", range, graphConstruction);
1055 auto colorGraph = rcp(
new LWGraph_kokkos(lclGraph, filteredA->getRowMap(), filteredA->getColMap(),
"coloring graph"));
1056 Set(currentLevel,
"Coloring Graph", colorGraph);
1059 LO dofsPerNode = blkSize;
1061 Set(currentLevel,
"DofsPerNode", dofsPerNode);
1062 Set(currentLevel,
"Graph", graph);
1063 Set(currentLevel,
"A", filteredA);
1065 return std::make_tuple(numDropped, boundaryNodes);