272 using MatrixType = Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
273 using GraphType = Xpetra::CrsGraph<LocalOrdinal, GlobalOrdinal, Node>;
274 using local_matrix_type =
typename MatrixType::local_matrix_device_type;
275 using local_graph_type =
typename GraphType::local_graph_device_type;
276 using rowptr_type =
typename local_graph_type::row_map_type::non_const_type;
277 using entries_type =
typename local_graph_type::entries_type::non_const_type;
278 using values_type =
typename local_matrix_type::values_type::non_const_type;
279 using device_type =
typename Node::device_type;
280 using memory_space =
typename device_type::memory_space;
281 using results_view_type = Kokkos::View<DecisionType*, memory_space>;
282 using magnitudeType =
typename Teuchos::ScalarTraits<Scalar>::magnitudeType;
283 using doubleMultiVector = Xpetra::MultiVector<magnitudeType, LO, GO, NO>;
285 typedef Teuchos::ScalarTraits<Scalar> STS;
286 const magnitudeType zero = Teuchos::ScalarTraits<magnitudeType>::zero();
288 auto A = Get<RCP<Matrix>>(currentLevel,
"A");
292 const ParameterList& pL = GetParameterList();
295 const magnitudeType dirichletThreshold = STS::magnitude(as<SC>(pL.get<
double>(
"aggregation: Dirichlet threshold")));
296 const magnitudeType rowSumTol = as<magnitudeType>(pL.get<
double>(
"aggregation: row sum drop tol"));
300 bool useBlocking = pL.get<
bool>(
"aggregation: use blocking");
301 std::string droppingMethod = pL.get<std::string>(
"aggregation: drop scheme");
302 std::string socUsesMatrix = pL.get<std::string>(
"aggregation: strength-of-connection: matrix");
303 std::string socUsesMeasure = pL.get<std::string>(
"aggregation: strength-of-connection: measure");
304 std::string distanceLaplacianMetric = pL.get<std::string>(
"aggregation: distance laplacian metric");
305 bool symmetrizeDroppedGraph = pL.get<
bool>(
"aggregation: symmetrize graph after dropping");
306 magnitudeType threshold;
308 if (pL.get<
bool>(
"aggregation: use ml scaling of drop tol"))
309 threshold = pL.get<
double>(
"aggregation: drop tol") / pow(2.0, currentLevel.
GetLevelID());
311 threshold = as<magnitudeType>(pL.get<
double>(
"aggregation: drop tol"));
312 bool aggregationMayCreateDirichlet = pL.get<
bool>(
"aggregation: dropping may create Dirichlet");
315 const bool reuseGraph = pL.get<
bool>(
"filtered matrix: reuse graph");
316 const bool reuseEigenvalue = pL.get<
bool>(
"filtered matrix: reuse eigenvalue");
318 const bool useRootStencil = pL.get<
bool>(
"filtered matrix: use root stencil");
319 const bool useSpreadLumping = pL.get<
bool>(
"filtered matrix: use spread lumping");
320 const std::string lumpingChoiceString = pL.get<std::string>(
"filtered matrix: lumping choice");
322 if (lumpingChoiceString ==
"diag lumping")
324 else if (lumpingChoiceString ==
"distributed lumping")
327 const magnitudeType filteringDirichletThreshold = as<magnitudeType>(pL.get<
double>(
"filtered matrix: Dirichlet threshold"));
330 bool generateColoringGraph = pL.get<
bool>(
"aggregation: coloring: use color graph");
331 const bool localizeColoringGraph = pL.get<
bool>(
"aggregation: coloring: localize color graph");
332 const bool symmetrizeColoringGraph =
true;
334#ifdef HAVE_MUELU_COALESCEDROP_ALLOW_OLD_PARAMETERS
335 translateOldAlgoParam(pL, droppingMethod, useBlocking, socUsesMatrix, socUsesMeasure, symmetrizeDroppedGraph, generateColoringGraph, threshold, lumpingChoice);
339 std::stringstream ss;
340 ss <<
"dropping scheme = \"" << droppingMethod <<
"\", strength-of-connection measure = \"" << socUsesMeasure <<
"\", strength-of-connection matrix = \"" << socUsesMatrix <<
"\", ";
341 if (socUsesMatrix ==
"distance laplacian")
342 ss <<
"distance laplacian metric = \"" << distanceLaplacianMetric <<
"\", ";
343 ss <<
"threshold = " << threshold <<
", blocksize = " << A->GetFixedBlockSize() <<
", useBlocking = " << useBlocking;
344 ss <<
", symmetrizeDroppedGraph = " << symmetrizeDroppedGraph << std::endl;
349 TEUCHOS_ASSERT(!useRootStencil);
350 TEUCHOS_ASSERT(!useSpreadLumping);
352 if (droppingMethod ==
"cut-drop")
353 TEUCHOS_TEST_FOR_EXCEPTION(threshold > 1.0,
Exceptions::RuntimeError,
"For cut-drop algorithms, \"aggregation: drop tol\" = " << threshold <<
", needs to be <= 1.0");
366 auto crsA = toCrsMatrix(A);
367 auto lclA = crsA->getLocalMatrixDevice();
387 if (rowSumTol <= 0.) {
420 auto filtered_rowptr = rowptr_type(
"filtered_rowptr", lclA.numRows() + 1);
424 auto results = results_view_type(
"results", lclA.nnz());
428 if (threshold != zero) {
429 if (socUsesMatrix ==
"A") {
430 if (socUsesMeasure ==
"unscaled") {
431 ScalarDroppingClassical<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::UnscaledMeasure>::runDroppingFunctors_on_A(*A, results, filtered_rowptr, nnz_filtered, boundaryNodes, droppingMethod, threshold,
432 aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, currentLevel, *
this);
433 }
else if (socUsesMeasure ==
"smoothed aggregation") {
434 ScalarDroppingClassical<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::SmoothedAggregationMeasure>::runDroppingFunctors_on_A(*A, results, filtered_rowptr, nnz_filtered, boundaryNodes, droppingMethod, threshold,
435 aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, currentLevel, *
this);
436 }
else if (socUsesMeasure ==
"signed ruge-stueben") {
437 ScalarDroppingClassical<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::SignedRugeStuebenMeasure>::runDroppingFunctors_on_A(*A, results, filtered_rowptr, nnz_filtered, boundaryNodes, droppingMethod, threshold,
438 aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, currentLevel, *
this);
439 }
else if (socUsesMeasure ==
"signed smoothed aggregation") {
440 ScalarDroppingClassical<Scalar, LocalOrdinal, GlobalOrdinal, Node, Misc::SignedSmoothedAggregationMeasure>::runDroppingFunctors_on_A(*A, results, filtered_rowptr, nnz_filtered, boundaryNodes, droppingMethod, threshold,
441 aggregationMayCreateDirichlet, symmetrizeDroppedGraph, useBlocking, currentLevel, *
this);
443 }
else if (socUsesMatrix ==
"distance laplacian") {
444 auto coords = Get<RCP<doubleMultiVector>>(currentLevel,
"Coordinates");
445 if (socUsesMeasure ==
"unscaled") {
446 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);
447 }
else if (socUsesMeasure ==
"smoothed aggregation") {
448 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);
449 }
else if (socUsesMeasure ==
"signed ruge-stueben") {
450 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);
451 }
else if (socUsesMeasure ==
"signed smoothed aggregation") {
452 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);
456 Kokkos::deep_copy(results,
KEEP);
458 if (symmetrizeDroppedGraph) {
460 ScalarDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, results, filtered_rowptr, nnz_filtered, useBlocking, currentLevel, *
this, drop_boundaries);
463 ScalarDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, results, filtered_rowptr, nnz_filtered, useBlocking, currentLevel, *
this, no_op);
467 if (symmetrizeDroppedGraph) {
469 ScalarDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, results, filtered_rowptr, nnz_filtered, useBlocking, currentLevel, *
this, symmetrize);
472 GO numDropped = lclA.nnz() - nnz_filtered;
474 Teuchos::reduceAll(*A->getRowMap()->getComm(), Teuchos::REDUCE_SUM, 1, &numDropped, &numGlobalDropped);
482 RCP<Matrix> filteredA;
483 RCP<LWGraph_kokkos> graph;
484 if (numGlobalDropped > 0) {
487 local_matrix_type lclFilteredA;
488 local_graph_type lclGraph;
490 filteredA = MatrixFactory::BuildCopy(A);
491 lclFilteredA = filteredA->getLocalMatrixDevice();
493 auto colidx = entries_type(
"entries", nnz_filtered);
494 lclGraph = local_graph_type(colidx, filtered_rowptr);
496 auto colidx = entries_type(
"entries", nnz_filtered);
497 auto values = values_type(
"values", nnz_filtered);
498 lclFilteredA = local_matrix_type(
"filteredA",
499 lclA.numRows(), lclA.numCols(),
501 values, filtered_rowptr, colidx);
507 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_lumped_reuse", range, fillFunctor);
511 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_lumped_noreuse", range, fillFunctor);
514 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_lumped_noreuse", range, fillFunctor);
520 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_unlumped_reuse", range, fillFunctor);
523 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_unlumped_noreuse", range, fillFunctor);
528 filteredA = MatrixFactory::Build(lclFilteredA, A->getRowMap(), A->getColMap(), A->getDomainMap(), A->getRangeMap());
529 filteredA->SetFixedBlockSize(A->GetFixedBlockSize());
531 if (reuseEigenvalue) {
536 filteredA->SetMaxEigenvalueEstimate(A->GetMaxEigenvalueEstimate());
538 filteredA->SetMaxEigenvalueEstimate(-Teuchos::ScalarTraits<SC>::one());
543 lclGraph = filteredA->getCrsGraph()->getLocalGraphDevice();
545 graph = rcp(
new LWGraph_kokkos(lclGraph, filteredA->getRowMap(), filteredA->getColMap(),
"amalgamated graph of A"));
546 graph->SetBoundaryNodeMap(boundaryNodes);
549 graph = rcp(
new LWGraph_kokkos(filteredA->getCrsGraph()->getLocalGraphDevice(), filteredA->getRowMap(), filteredA->getColMap(),
"amalgamated graph of A"));
550 graph->SetBoundaryNodeMap(boundaryNodes);
554 if (generateColoringGraph) {
555 SubFactoryMonitor mColoringGraph(*
this,
"Construct coloring graph", currentLevel);
557 filtered_rowptr = rowptr_type(
"rowptr_coloring_graph", lclA.numRows() + 1);
558 if (localizeColoringGraph) {
560 ScalarDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, results, filtered_rowptr, nnz_filtered, useBlocking, currentLevel, *
this, drop_offrank);
562 if (symmetrizeColoringGraph) {
564 ScalarDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, results, filtered_rowptr, nnz_filtered, useBlocking, currentLevel, *
this, symmetrize);
566 auto colidx = entries_type(
"entries_coloring_graph", nnz_filtered);
567 auto lclGraph = local_graph_type(colidx, filtered_rowptr);
569 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Construct_coloring_graph", range, graphConstruction);
571 auto colorGraph = rcp(
new LWGraph_kokkos(lclGraph, filteredA->getRowMap(), filteredA->getColMap(),
"coloring graph"));
572 Set(currentLevel,
"Coloring Graph", colorGraph);
575 if (pL.get<
bool>(
"filtered matrix: count negative diagonals")) {
578 GetOStream(
Runtime0) <<
"CoalesceDrop: Negative diagonals: " << neg_count << std::endl;
582 Set(currentLevel,
"DofsPerNode", dofsPerNode);
583 Set(currentLevel,
"Graph", graph);
584 Set(currentLevel,
"A", filteredA);
586 return std::make_tuple(numDropped, boundaryNodes);
594 using MatrixType = Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
595 using GraphType = Xpetra::CrsGraph<LocalOrdinal, GlobalOrdinal, Node>;
596 using local_matrix_type =
typename MatrixType::local_matrix_device_type;
597 using local_graph_type =
typename GraphType::local_graph_device_type;
598 using rowptr_type =
typename local_graph_type::row_map_type::non_const_type;
599 using entries_type =
typename local_graph_type::entries_type::non_const_type;
600 using values_type =
typename local_matrix_type::values_type::non_const_type;
601 using device_type =
typename Node::device_type;
602 using memory_space =
typename device_type::memory_space;
603 using results_view_type = Kokkos::View<DecisionType*, memory_space>;
604 using magnitudeType =
typename Teuchos::ScalarTraits<Scalar>::magnitudeType;
605 using doubleMultiVector = Xpetra::MultiVector<magnitudeType, LO, GO, NO>;
607 typedef Teuchos::ScalarTraits<Scalar> STS;
608 const magnitudeType zero = Teuchos::ScalarTraits<magnitudeType>::zero();
610 auto A = Get<RCP<Matrix>>(currentLevel,
"A");
629 TEUCHOS_TEST_FOR_EXCEPTION(A->GetFixedBlockSize() % A->GetStorageBlockSize() != 0,
Exceptions::RuntimeError,
"A->GetFixedBlockSize() needs to be a multiple of A->GetStorageBlockSize()");
630 LO blkSize = A->GetFixedBlockSize() / A->GetStorageBlockSize();
632 auto amalInfo = Get<RCP<AmalgamationInfo>>(currentLevel,
"UnAmalgamationInfo");
634 const RCP<const Map> rowMap = A->getRowMap();
635 const RCP<const Map> colMap = A->getColMap();
642 const RCP<const Map> uniqueMap = amalInfo->getNodeRowMap();
643 const RCP<const Map> nonUniqueMap = amalInfo->getNodeColMap();
644 Array<LO> rowTranslationArray = *(amalInfo->getRowTranslation());
645 Array<LO> colTranslationArray = *(amalInfo->getColTranslation());
647 Kokkos::View<LO*, Kokkos::MemoryUnmanaged>
648 rowTranslationView(rowTranslationArray.getRawPtr(), rowTranslationArray.size());
649 Kokkos::View<LO*, Kokkos::MemoryUnmanaged>
650 colTranslationView(colTranslationArray.getRawPtr(), colTranslationArray.size());
653 LO numNodes = Teuchos::as<LocalOrdinal>(uniqueMap->getLocalNumElements());
654 typedef typename Kokkos::View<LocalOrdinal*, typename Node::device_type> id_translation_type;
655 id_translation_type rowTranslation(
"dofId2nodeId", rowTranslationArray.size());
656 id_translation_type colTranslation(
"ov_dofId2nodeId", colTranslationArray.size());
657 Kokkos::deep_copy(rowTranslation, rowTranslationView);
658 Kokkos::deep_copy(colTranslation, colTranslationView);
661 blkSize = A->GetFixedBlockSize();
664 if (A->IsView(
"stridedMaps") ==
true) {
665 const RCP<const Map> myMap = A->getRowMap(
"stridedMaps");
666 const RCP<const StridedMap> strMap = Teuchos::rcp_dynamic_cast<const StridedMap>(myMap);
668 blkSize = Teuchos::as<const LocalOrdinal>(strMap->getFixedBlockSize());
669 blkId = strMap->getStridedBlockId();
671 blkPartSize = Teuchos::as<LocalOrdinal>(strMap->getStridingData()[blkId]);
674 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);
678 const ParameterList& pL = GetParameterList();
681 const magnitudeType dirichletThreshold = STS::magnitude(as<SC>(pL.get<
double>(
"aggregation: Dirichlet threshold")));
682 const magnitudeType rowSumTol = as<magnitudeType>(pL.get<
double>(
"aggregation: row sum drop tol"));
684 const bool useGreedyDirichlet = pL.get<
bool>(
"aggregation: greedy Dirichlet");
685 TEUCHOS_TEST_FOR_EXCEPTION(rowSumTol > zero,
MueLu::Exceptions::RuntimeError,
"MueLu::CoalesceDropFactory: RowSum is not implemented for vectorial problems.");
688 bool useBlocking = pL.get<
bool>(
"aggregation: use blocking");
689 std::string droppingMethod = pL.get<std::string>(
"aggregation: drop scheme");
690 std::string socUsesMatrix = pL.get<std::string>(
"aggregation: strength-of-connection: matrix");
691 std::string socUsesMeasure = pL.get<std::string>(
"aggregation: strength-of-connection: measure");
692 std::string distanceLaplacianMetric = pL.get<std::string>(
"aggregation: distance laplacian metric");
693 bool symmetrizeDroppedGraph = pL.get<
bool>(
"aggregation: symmetrize graph after dropping");
694 magnitudeType threshold;
696 if (pL.get<
bool>(
"aggregation: use ml scaling of drop tol"))
697 threshold = pL.get<
double>(
"aggregation: drop tol") / pow(2.0, currentLevel.
GetLevelID());
699 threshold = as<magnitudeType>(pL.get<
double>(
"aggregation: drop tol"));
700 bool aggregationMayCreateDirichlet = pL.get<
bool>(
"aggregation: dropping may create Dirichlet");
703 const bool reuseGraph = pL.get<
bool>(
"filtered matrix: reuse graph");
704 const bool reuseEigenvalue = pL.get<
bool>(
"filtered matrix: reuse eigenvalue");
706 const bool useRootStencil = pL.get<
bool>(
"filtered matrix: use root stencil");
707 const bool useSpreadLumping = pL.get<
bool>(
"filtered matrix: use spread lumping");
708 const std::string lumpingChoiceString = pL.get<std::string>(
"filtered matrix: lumping choice");
710 if (lumpingChoiceString ==
"diag lumping")
712 else if (lumpingChoiceString ==
"distributed lumping")
715 const magnitudeType filteringDirichletThreshold = as<magnitudeType>(pL.get<
double>(
"filtered matrix: Dirichlet threshold"));
718 bool generateColoringGraph = pL.get<
bool>(
"aggregation: coloring: use color graph");
719 const bool localizeColoringGraph = pL.get<
bool>(
"aggregation: coloring: localize color graph");
720 const bool symmetrizeColoringGraph =
true;
722#ifdef HAVE_MUELU_COALESCEDROP_ALLOW_OLD_PARAMETERS
723 translateOldAlgoParam(pL, droppingMethod, useBlocking, socUsesMatrix, socUsesMeasure, symmetrizeDroppedGraph, generateColoringGraph, threshold, lumpingChoice);
726 std::stringstream ss;
727 ss <<
"dropping scheme = \"" << droppingMethod <<
"\", strength-of-connection measure = \"" << socUsesMeasure <<
"\", strength-of-connection matrix = \"" << socUsesMatrix <<
"\", ";
728 if (socUsesMatrix ==
"distance laplacian")
729 ss <<
"distance laplacian metric = \"" << distanceLaplacianMetric <<
"\", ";
730 ss <<
"threshold = " << threshold <<
", blocksize = " << A->GetFixedBlockSize() <<
", useBlocking = " << useBlocking;
731 ss <<
", symmetrizeDroppedGraph = " << symmetrizeDroppedGraph << std::endl;
736 TEUCHOS_ASSERT(!useRootStencil);
737 TEUCHOS_ASSERT(!useSpreadLumping);
739 if (droppingMethod ==
"cut-drop")
740 TEUCHOS_TEST_FOR_EXCEPTION(threshold > 1.0,
Exceptions::RuntimeError,
"For cut-drop algorithms, \"aggregation: drop tol\" = " << threshold <<
", needs to be <= 1.0");
753 auto crsA = toCrsMatrix(A);
754 auto lclA = crsA->getLocalMatrixDevice();
769 if (useGreedyDirichlet) {
799 auto filtered_rowptr = rowptr_type(
"rowptr", lclA.numRows() + 1);
800 auto graph_rowptr = rowptr_type(
"rowptr", numNodes + 1);
802 Kokkos::pair<LocalOrdinal, LocalOrdinal> nnz = {0, 0};
805 auto results = results_view_type(
"results", lclA.nnz());
814 auto merged_rowptr = rowptr_type(
"rowptr", numNodes + 1);
818 Kokkos::parallel_scan(
"MergeCount", range, functor, nnz_merged);
820 local_graph_type lclMergedGraph;
821 auto colidx_merged = entries_type(
"entries", nnz_merged);
822 auto values_merged = values_type(
"values", nnz_merged);
824 local_matrix_type lclMergedA = local_matrix_type(
"mergedA",
825 numNodes, nonUniqueMap->getLocalNumElements(),
827 values_merged, merged_rowptr, colidx_merged);
830 Kokkos::parallel_for(
"MueLu::CoalesceDrop::MergeFill", range, fillFunctor);
832 mergedA = Xpetra::MatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(lclMergedA, uniqueMap, nonUniqueMap, uniqueMap, uniqueMap);
835 if (threshold != zero) {
836 if (socUsesMatrix ==
"A") {
837 if (socUsesMeasure ==
"unscaled") {
838 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);
839 }
else if (socUsesMeasure ==
"smoothed aggregation") {
840 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);
841 }
else if (socUsesMeasure ==
"signed ruge-stueben") {
842 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);
843 }
else if (socUsesMeasure ==
"signed smoothed aggregation") {
844 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);
846 }
else if (socUsesMatrix ==
"distance laplacian") {
847 auto coords = Get<RCP<doubleMultiVector>>(currentLevel,
"Coordinates");
849 Array<double> dlap_weights = pL.get<Array<double>>(
"aggregation: distance laplacian directional weights");
850 LocalOrdinal interleaved_blocksize = as<LocalOrdinal>(pL.get<
int>(
"aggregation: block diagonal: interleaved blocksize"));
851 if (socUsesMeasure ==
"distance laplacian") {
852 LO dim = (LO)coords->getNumVectors();
854 bool non_unity =
false;
855 for (LO i = 0; !non_unity && i < (LO)dlap_weights.size(); i++) {
856 if (dlap_weights[i] != 1.0) {
861 if ((LO)dlap_weights.size() == dim) {
862 distanceLaplacianMetric =
"weighted";
863 }
else if ((LO)dlap_weights.size() == interleaved_blocksize * dim)
864 distanceLaplacianMetric =
"block weighted";
867 "length of 'aggregation: distance laplacian directional weights' must equal the coordinate dimension OR the coordinate dimension times the blocksize");
870 GetOStream(
Statistics1) <<
"Using distance laplacian weights: " << dlap_weights << std::endl;
874 if (socUsesMeasure ==
"unscaled") {
875 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);
876 }
else if (socUsesMeasure ==
"smoothed aggregation") {
877 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);
878 }
else if (socUsesMeasure ==
"signed ruge-stueben") {
879 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);
880 }
else if (socUsesMeasure ==
"signed smoothed aggregation") {
881 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);
885 Kokkos::deep_copy(results,
KEEP);
888 VectorDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, *mergedA, blkPartSize, rowTranslation, colTranslation, results, filtered_rowptr, graph_rowptr, nnz, useBlocking, currentLevel, *
this, no_op);
891 if (symmetrizeDroppedGraph) {
893 VectorDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, *mergedA, blkPartSize, rowTranslation, colTranslation, results, filtered_rowptr, graph_rowptr, nnz, useBlocking, currentLevel, *
this, symmetrize);
898 GO numTotal = lclA.nnz();
899 GO numDropped = numTotal - nnz_filtered;
901 Teuchos::reduceAll(*A->getRowMap()->getComm(), Teuchos::REDUCE_SUM, 1, &numDropped, &numGlobalDropped);
909 RCP<Matrix> filteredA;
910 RCP<LWGraph_kokkos> graph;
911 if (numGlobalDropped > 0) {
914 local_matrix_type lclFilteredA;
916 lclFilteredA = local_matrix_type(
"filteredA", lclA.graph, lclA.numCols());
918 auto colidx = entries_type(
"entries", nnz_filtered);
919 auto values = values_type(
"values", nnz_filtered);
920 lclFilteredA = local_matrix_type(
"filteredA",
921 lclA.numRows(), lclA.numCols(),
923 values, filtered_rowptr, colidx);
926 local_graph_type lclGraph;
928 auto colidx = entries_type(
"entries", nnz_graph);
929 lclGraph = local_graph_type(colidx, graph_rowptr);
935 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_lumped_reuse", range, fillFunctor);
938 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_lumped_noreuse", range, fillFunctor);
943 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_unlumped_reuse", range, fillFunctor);
946 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Fill_unlumped_noreuse", range, fillFunctor);
950 filteredA = Xpetra::MatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(lclFilteredA, A->getRowMap(), A->getColMap(), A->getDomainMap(), A->getRangeMap());
951 filteredA->SetFixedBlockSize(blkSize);
953 if (reuseEigenvalue) {
958 filteredA->SetMaxEigenvalueEstimate(A->GetMaxEigenvalueEstimate());
960 filteredA->SetMaxEigenvalueEstimate(-Teuchos::ScalarTraits<SC>::one());
963 graph = rcp(
new LWGraph_kokkos(lclGraph, uniqueMap, nonUniqueMap,
"amalgamated graph of A"));
964 graph->SetBoundaryNodeMap(boundaryNodes);
967 graph = rcp(
new LWGraph_kokkos(mergedA->getCrsGraph()->getLocalGraphDevice(), uniqueMap, nonUniqueMap,
"amalgamated graph of A"));
968 graph->SetBoundaryNodeMap(boundaryNodes);
972 if (generateColoringGraph) {
973 SubFactoryMonitor mColoringGraph(*
this,
"Construct coloring graph", currentLevel);
975 filtered_rowptr = rowptr_type(
"rowptr_coloring_graph", lclA.numRows() + 1);
976 graph_rowptr = rowptr_type(
"rowptr", numNodes + 1);
977 if (localizeColoringGraph) {
979 VectorDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, *mergedA, blkPartSize, rowTranslation, colTranslation, results, filtered_rowptr, graph_rowptr, nnz, useBlocking, currentLevel, *
this, drop_offrank);
981 if (symmetrizeColoringGraph) {
983 VectorDroppingBase<Scalar, LocalOrdinal, GlobalOrdinal, Node>::template runDroppingFunctors<>(*A, *mergedA, blkPartSize, rowTranslation, colTranslation, results, filtered_rowptr, graph_rowptr, nnz, useBlocking, currentLevel, *
this, symmetrize);
985 auto colidx = entries_type(
"entries_coloring_graph", nnz_filtered);
986 auto lclGraph = local_graph_type(colidx, filtered_rowptr);
988 Kokkos::parallel_for(
"MueLu::CoalesceDrop::Construct_coloring_graph", range, graphConstruction);
990 auto colorGraph = rcp(
new LWGraph_kokkos(lclGraph, filteredA->getRowMap(), filteredA->getColMap(),
"coloring graph"));
991 Set(currentLevel,
"Coloring Graph", colorGraph);
994 LO dofsPerNode = blkSize;
996 Set(currentLevel,
"DofsPerNode", dofsPerNode);
997 Set(currentLevel,
"Graph", graph);
998 Set(currentLevel,
"A", filteredA);
1000 return std::make_tuple(numDropped, boundaryNodes);