From e1190ac2a355fd1e1a88c63d7fd38099d8b12b0e Mon Sep 17 00:00:00 2001 From: Luc Berger-Vergiat Date: Thu, 21 Nov 2019 16:29:57 -0700 Subject: [PATCH] MueLu: fixing the count of aggregated nodes in refactored Phase2a of aggregation, see #6325 1) A piece of logic is wrong in the algorithms that counts how many nodes have been aggregated in Phase2a of aggregation. This commit fixes that by individually counting every node that is being aggregated instead of counting all the nodes in a newly formed aggregate, at once. 2) Currently if a tentative aggregate becomes larger than maxNodesPerAggregate it is completely ignored. Now a partial aggregate will be formed instead. --- ...AggregationPhase2aAlgorithm_kokkos_def.hpp | 29 +++++++++++++------ .../interface/ParameterListInterpreter.cpp | 10 +++++++ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/packages/muelu/src/Graph/UncoupledAggregation/MueLu_AggregationPhase2aAlgorithm_kokkos_def.hpp b/packages/muelu/src/Graph/UncoupledAggregation/MueLu_AggregationPhase2aAlgorithm_kokkos_def.hpp index 7901bd4806c1..8057204f25ce 100644 --- a/packages/muelu/src/Graph/UncoupledAggregation/MueLu_AggregationPhase2aAlgorithm_kokkos_def.hpp +++ b/packages/muelu/src/Graph/UncoupledAggregation/MueLu_AggregationPhase2aAlgorithm_kokkos_def.hpp @@ -136,14 +136,20 @@ namespace MueLu { // Loop over neighbors to count how many nodes could join // the new aggregate + // Note on 2019-11-22, LBV: + // The rootCandidate is not taken into account and in fact + // not aggregatesd later on. To change that we want to + // modify: + // if(aggSize < maxNodesPerAggregate) + // to: + // if(aggSize < maxNodesPerAggregate - 1) LO numNeighbors = 0; for(int j = 0; j < neighbors.length; ++j) { LO neigh = neighbors(j); if(neigh != rootCandidate) { if(graph.isLocalNeighborVertex(neigh) && - aggStat(neigh) == READY && - aggSize < maxNodesPerAggregate) { - // aggList(aggSize) = neigh; + (aggStat(neigh) == READY) && + (aggSize < maxNodesPerAggregate)) { ++aggSize; } ++numNeighbors; @@ -152,6 +158,8 @@ namespace MueLu { // If a sufficient number of nodes can join the new aggregate // then we actually create the aggregate. + // Note on 2019-11-22, LBV: + // Same changes as described in the note above could be applied if(aggSize > minNodesPerAggregate && aggSize > factor*numNeighbors) { @@ -159,19 +167,22 @@ namespace MueLu { LO aggIndex = Kokkos:: atomic_fetch_add(&numLocalAggregates(), 1); - for(int j = 0; j < neighbors.length; ++j) { - LO neigh = neighbors(j); + LO numAggregated = 0; + for(int neighIdx = 0; neighIdx < neighbors.length; ++neighIdx) { + LO neigh = neighbors(neighIdx); if(neigh != rootCandidate) { if(graph.isLocalNeighborVertex(neigh) && - aggStat(neigh) == READY && - aggSize < maxNodesPerAggregate) { - aggStat(neigh) = AGGREGATED; + (aggStat(neigh) == READY) && + (numAggregated < aggSize)) { + aggStat(neigh) = AGGREGATED; vertex2AggId(neigh, 0) = aggIndex; procWinner(neigh, 0) = myRank; + + ++numAggregated; + --lNumNonAggregatedNodes; } } } - lNumNonAggregatedNodes -= aggSize; } } }, tmpNumNonAggregatedNodes); diff --git a/packages/muelu/test/interface/ParameterListInterpreter.cpp b/packages/muelu/test/interface/ParameterListInterpreter.cpp index e7ad61ba3ed8..05429778768a 100644 --- a/packages/muelu/test/interface/ParameterListInterpreter.cpp +++ b/packages/muelu/test/interface/ParameterListInterpreter.cpp @@ -407,6 +407,16 @@ int main_(Teuchos::CommandLineProcessor &clp, Xpetra::UnderlyingLib& lib, int ar stringToReplace = "Smoother complexity = " + floatRegex; replacementString = "Smoother complexity = "; run_sed("'s/" + stringToReplace + "/" + replacementString + "/'", baseFile); + + // Finally ignore the Chebyshev eigen value ratio which varies with aggregation + stringToReplace = "chebyshev: ratio eigenvalue = " + floatRegex; + replacementString = "chebyshev: ratio eigenvalue = "; + run_sed("'s/" + stringToReplace + "/" + replacementString + "/'", baseFile); + + // as well as the alpha paramter it sets + stringToReplace = "lambdaMax = , alpha: " + floatRegex + ", lambdaMin = ,"; + replacementString = "lambdaMax = , alpha: , lambdaMin = ,"; + run_sed("'s/" + stringToReplace + "/" + replacementString + "/'", baseFile); } // Run comparison (ignoring whitespaces)