31 Monitor m(*
this,
"BuildAggregatesNonKokkos");
33 bool makeNonAdjAggs =
false;
34 bool error_on_isolated =
false;
35 if (params.isParameter(
"aggregation: error on nodes with no on-rank neighbors"))
36 error_on_isolated = params.get<
bool>(
"aggregation: error on nodes with no on-rank neighbors");
37 if (params.isParameter(
"aggregation: phase3 avoid singletons"))
38 makeNonAdjAggs = params.get<
bool>(
"aggregation: phase3 avoid singletons");
40 size_t numSingletons = 0;
43 const int myRank = graph.
GetComm()->getRank();
45 ArrayRCP<LO> vertex2AggId = aggregates.
GetVertex2AggId()->getDataNonConst(0);
46 ArrayRCP<LO> procWinner = aggregates.
GetProcWinner()->getDataNonConst(0);
50 for (LO i = 0; i < numRows; i++) {
58 bool isNewAggregate =
false;
59 bool failedToAggregate =
true;
60 for (
int j = 0; j < neighOfINode.length; j++) {
61 LO neigh = neighOfINode(j);
64 isNewAggregate =
true;
67 vertex2AggId[neigh] = numLocalAggregates;
68 procWinner[neigh] = myRank;
70 numNonAggregatedNodes--;
77 procWinner[i] = myRank;
78 numNonAggregatedNodes--;
80 vertex2AggId[i] = numLocalAggregates++;
82 failedToAggregate =
false;
89 for (; j < neighOfINode.length; j++) {
90 LO neigh = neighOfINode(j);
97 if (j < neighOfINode.length) {
99 vertex2AggId[i] = vertex2AggId[neighOfINode(j)];
100 numNonAggregatedNodes--;
101 failedToAggregate =
false;
105 if (failedToAggregate && makeNonAdjAggs) {
114 for (LO ii = 0; ii < numRows; ii++) {
115 if ((ii != i) && (aggStat[ii] !=
IGNORED)) {
116 failedToAggregate =
false;
118 procWinner[i] = myRank;
121 vertex2AggId[i] = vertex2AggId[ii];
123 vertex2AggId[i] = numLocalAggregates;
124 vertex2AggId[ii] = numLocalAggregates;
126 procWinner[ii] = myRank;
127 numNonAggregatedNodes--;
129 numLocalAggregates++;
131 numNonAggregatedNodes--;
136 if (failedToAggregate) {
137 if (error_on_isolated) {
139 std::ostringstream oss;
140 oss <<
"MueLu::AggregationPhase3Algorithm::BuildAggregatesNonKokkos: MueLu has detected a non-Dirichlet node that has no on-rank neighbors and is terminating (by user request). " << std::endl;
141 oss <<
"If this error is being generated at level 0, this is due to an initial partitioning problem in your matrix." << std::endl;
142 oss <<
"If this error is being generated at any other level, try turning on repartitioning, which may fix this problem." << std::endl;
150 vertex2AggId[i] = numLocalAggregates++;
151 numNonAggregatedNodes--;
157 procWinner[i] = myRank;
161 if (numSingletons > 0)
162 this->GetOStream(
Runtime0) <<
" WARNING Rank " << myRank <<
" singletons :" << numSingletons <<
" (phase)" << std::endl;
195 LO& numNonAggregatedNodes)
const {
199 bool error_on_isolated = params.get<
bool>(
"aggregation: error on nodes with no on-rank neighbors");
200 bool makeNonAdjAggs = params.get<
bool>(
"aggregation: phase3 avoid singletons");
203 const int myRank = graph.
GetComm()->getRank();
205 auto vertex2AggId = aggregates.
GetVertex2AggId()->getLocalViewDevice(Tpetra::Access::ReadWrite);
206 auto procWinner = aggregates.
GetProcWinner()->getLocalViewDevice(Tpetra::Access::ReadWrite);
210 auto lclLWGraph = graph;
212 Kokkos::View<LO, device_type> numAggregates(
"numAggregates");
215 Kokkos::View<unsigned*, device_type> aggStatOld(Kokkos::ViewAllocateWithoutInitializing(
"Initial aggregation status"), aggStat.extent(0));
216 Kokkos::deep_copy(aggStatOld, aggStat);
217 Kokkos::View<LO, device_type> numNonAggregated(
"numNonAggregated");
218 Kokkos::deep_copy(numNonAggregated, numNonAggregatedNodes);
219 for (
int color = 1; color < numColors + 1; ++color) {
220 Kokkos::parallel_for(
221 "Aggregation Phase 3: aggregates clean-up",
222 Kokkos::RangePolicy<execution_space>(0, numRows),
223 KOKKOS_LAMBDA(
const LO nodeIdx) {
225 if ((colors(nodeIdx) != color) ||
227 (aggStatOld(nodeIdx) ==
IGNORED)) {
232 auto neighbors = lclLWGraph.getNeighborVertices(nodeIdx);
237 bool isNewAggregate =
false;
238 for (
int neigh = 0; neigh < neighbors.length; ++neigh) {
239 neighIdx = neighbors(neigh);
241 if ((neighIdx != nodeIdx) &&
242 lclLWGraph.isLocalNeighborVertex(neighIdx) &&
243 (aggStatOld(neighIdx) ==
READY)) {
244 isNewAggregate =
true;
250 if (isNewAggregate) {
253 const LO aggId = Kokkos::atomic_fetch_add(&numAggregates(), 1);
255 procWinner(nodeIdx, 0) = myRank;
256 vertex2AggId(nodeIdx, 0) = aggId;
258 Kokkos::atomic_dec(&numNonAggregated());
259 for (
int neigh = 0; neigh < neighbors.length; ++neigh) {
260 neighIdx = neighbors(neigh);
261 if ((neighIdx != nodeIdx) &&
262 lclLWGraph.isLocalNeighborVertex(neighIdx) &&
263 (aggStatOld(neighIdx) ==
READY)) {
265 procWinner(neighIdx, 0) = myRank;
266 vertex2AggId(neighIdx, 0) = aggId;
267 Kokkos::atomic_dec(&numNonAggregated());
275 for (
int neigh = 0; neigh < neighbors.length; ++neigh) {
276 neighIdx = neighbors(neigh);
277 if (lclLWGraph.isLocalNeighborVertex(neighIdx) &&
280 procWinner(nodeIdx, 0) = myRank;
281 vertex2AggId(nodeIdx, 0) = vertex2AggId(neighIdx, 0);
282 Kokkos::atomic_dec(&numNonAggregated());
289 if (makeNonAdjAggs) {
290 for (LO otherNodeIdx = 0; otherNodeIdx < numRows; ++otherNodeIdx) {
291 if ((otherNodeIdx != nodeIdx) &&
294 procWinner(nodeIdx, 0) = myRank;
295 vertex2AggId(nodeIdx, 0) = vertex2AggId(otherNodeIdx, 0);
296 Kokkos::atomic_dec(&numNonAggregated());
304 if (!error_on_isolated) {
305 const LO aggId = Kokkos::atomic_fetch_add(&numAggregates(), 1);
307 procWinner(nodeIdx, 0) = myRank;
308 vertex2AggId(nodeIdx, 0) = aggId;
309 Kokkos::atomic_dec(&numNonAggregated());
315 Kokkos::deep_copy(aggStatOld, aggStat);
318 auto numNonAggregated_h = Kokkos::create_mirror_view(numNonAggregated);
319 Kokkos::deep_copy(numNonAggregated_h, numNonAggregated);
320 numNonAggregatedNodes = numNonAggregated_h();
321 if ((error_on_isolated) && (numNonAggregatedNodes > 0)) {
323 std::ostringstream oss;
324 oss <<
"MueLu::AggregationPhase3Algorithm::BuildAggregates: MueLu has detected a non-Dirichlet node that has no on-rank neighbors and is terminating (by user request). " << std::endl;
325 oss <<
"If this error is being generated at level 0, this is due to an initial partitioning problem in your matrix." << std::endl;
326 oss <<
"If this error is being generated at any other level, try turning on repartitioning, which may fix this problem." << std::endl;
331 auto numAggregates_h = Kokkos::create_mirror_view(numAggregates);
332 Kokkos::deep_copy(numAggregates_h, numAggregates);