46 #ifndef MUELU_AGGREGATIONPHASE3ALGORITHM_KOKKOS_DEF_HPP
47 #define MUELU_AGGREGATIONPHASE3ALGORITHM_KOKKOS_DEF_HPP
49 #ifdef HAVE_MUELU_KOKKOS_REFACTOR
51 #include <Teuchos_Comm.hpp>
52 #include <Teuchos_CommHelpers.hpp>
54 #include <Xpetra_Vector.hpp>
58 #include "MueLu_Aggregates_kokkos.hpp"
60 #include "MueLu_LWGraph_kokkos.hpp"
69 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
70 void AggregationPhase3Algorithm_kokkos<LocalOrdinal, GlobalOrdinal, Node>::
71 BuildAggregates(
const ParameterList& params,
72 const LWGraph_kokkos& graph,
73 Aggregates_kokkos& aggregates,
75 LO& numNonAggregatedNodes)
const {
78 if(params.get<
bool>(
"aggregation: deterministic")) {
79 Monitor m(*
this,
"BuildAggregatesDeterministic");
80 BuildAggregatesRandom(params, graph, aggregates, aggStat, numNonAggregatedNodes);
82 Monitor m(*
this,
"BuildAggregatesRandom");
83 BuildAggregatesRandom(params, graph, aggregates, aggStat, numNonAggregatedNodes);
90 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
91 void AggregationPhase3Algorithm_kokkos<LocalOrdinal, GlobalOrdinal, Node>::
92 BuildAggregatesRandom(
const ParameterList& params,
93 const LWGraph_kokkos& graph,
94 Aggregates_kokkos& aggregates,
96 LO& numNonAggregatedNodes)
const {
98 bool error_on_isolated = params.get<
bool>(
"aggregation: error on nodes with no on-rank neighbors");
99 bool makeNonAdjAggs = params.get<
bool>(
"aggregation: phase3 avoid singletons");
101 const LO numRows = graph.GetNodeNumVertices();
102 const int myRank = graph.GetComm()->getRank();
104 auto vertex2AggId = aggregates.GetVertex2AggId()->template getLocalView<memory_space>();
105 auto procWinner = aggregates.GetProcWinner() ->template getLocalView<memory_space>();
106 auto colors = aggregates.GetGraphColors();
107 const LO numColors = aggregates.GetGraphNumColors();
116 for(
int color = 1; color < numColors + 1; ++color) {
119 KOKKOS_LAMBDA(
const LO nodeIdx) {
121 if( (colors(nodeIdx) != color) ||
123 (aggStatOld(nodeIdx) ==
IGNORED) ){
return; }
126 auto neighbors = graph.getNeighborVertices(nodeIdx);
131 bool isNewAggregate =
false;
132 for(
int neigh = 0; neigh < neighbors.length; ++neigh) {
133 neighIdx = neighbors(neigh);
135 if((neighIdx != nodeIdx) &&
136 graph.isLocalNeighborVertex(neighIdx) &&
137 (aggStatOld(neighIdx) ==
READY)) {
138 isNewAggregate =
true;
147 const LO aggId = Kokkos::atomic_fetch_add(&numAggregates(), 1);
149 procWinner(nodeIdx, 0) = myRank;
150 vertex2AggId(nodeIdx, 0) = aggId;
152 Kokkos::atomic_decrement(&numNonAggregated());
153 for(
int neigh = 0; neigh < neighbors.length; ++neigh) {
154 neighIdx = neighbors(neigh);
155 if((neighIdx != nodeIdx) &&
156 graph.isLocalNeighborVertex(neighIdx) &&
157 (aggStatOld(neighIdx) ==
READY)) {
159 procWinner(neighIdx, 0) = myRank;
160 vertex2AggId(neighIdx, 0) = aggId;
161 Kokkos::atomic_decrement(&numNonAggregated());
169 for(
int neigh = 0; neigh < neighbors.length; ++neigh) {
170 neighIdx = neighbors(neigh);
171 if (graph.isLocalNeighborVertex(neighIdx) &&
174 procWinner(nodeIdx, 0) = myRank;
175 vertex2AggId(nodeIdx, 0) = vertex2AggId(neighIdx, 0);
176 Kokkos::atomic_decrement(&numNonAggregated());
184 for(LO otherNodeIdx = 0; otherNodeIdx < numRows; ++otherNodeIdx) {
185 if((otherNodeIdx != nodeIdx) &&
188 procWinner(nodeIdx, 0) = myRank;
189 vertex2AggId(nodeIdx, 0) = vertex2AggId(otherNodeIdx, 0);
190 Kokkos::atomic_decrement(&numNonAggregated());
198 if(!error_on_isolated) {
199 const LO aggId = Kokkos::atomic_fetch_add(&numAggregates(), 1);
201 procWinner(nodeIdx, 0) = myRank;
202 vertex2AggId(nodeIdx, 0) = aggId;
203 Kokkos::atomic_decrement(&numNonAggregated());
212 auto numNonAggregated_h = Kokkos::create_mirror_view(numNonAggregated);
214 numNonAggregatedNodes = numNonAggregated_h();
215 if( (error_on_isolated) && (numNonAggregatedNodes > 0) ) {
217 std::ostringstream oss;
218 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;
219 oss<<
"If this error is being generated at level 0, this is due to an initial partitioning problem in your matrix."<<std::endl;
220 oss<<
"If this error is being generated at any other level, try turning on repartitioning, which may fix this problem."<<std::endl;
221 throw Exceptions::RuntimeError(oss.str());
225 auto numAggregates_h = Kokkos::create_mirror_view(numAggregates);
227 aggregates.SetNumAggregates(numAggregates_h());
232 #endif // HAVE_MUELU_KOKKOS_REFACTOR
233 #endif // MUELU_AGGREGATIONPHASE3ALGORITHM_KOKKOS_DEF_HPP
void deep_copy(const View< DT, DP...> &dst, typename ViewTraits< DT, DP...>::const_value_type &value, typename std::enable_if< std::is_same< typename ViewTraits< DT, DP...>::specialize, void >::value >::type *=nullptr)
KOKKOS_INLINE_FUNCTION constexpr std::enable_if< std::is_integral< iType >::value, size_t >::type extent(const iType &r) const noexcept
void parallel_for(const ExecPolicy &policy, const FunctorType &functor, const std::string &str="", typename std::enable_if< Kokkos::Impl::is_execution_policy< ExecPolicy >::value >::type *=nullptr)