46 #ifndef MUELU_STRUCTUREDAGGREGATIONFACTORY_KOKKOS_DEF_HPP 47 #define MUELU_STRUCTUREDAGGREGATIONFACTORY_KOKKOS_DEF_HPP 49 #ifdef HAVE_MUELU_KOKKOS_REFACTOR 52 #include <Xpetra_Map.hpp> 53 #include <Xpetra_CrsGraph.hpp> 59 #include "MueLu_Utilities.hpp" 62 #include "MueLu_LWGraph_kokkos.hpp" 63 #include "MueLu_Aggregates_kokkos.hpp" 64 #include "MueLu_IndexManager_kokkos.hpp" 65 #include "MueLu_AggregationStructuredAlgorithm_kokkos.hpp" 71 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
72 StructuredAggregationFactory_kokkos<LocalOrdinal, GlobalOrdinal, Node>::
73 StructuredAggregationFactory_kokkos() : bDefinitionPhase_(true) { }
75 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
76 RCP<const ParameterList> StructuredAggregationFactory_kokkos<LocalOrdinal, GlobalOrdinal, Node>::
77 GetValidParameterList()
const {
78 RCP<ParameterList> validParamList = rcp(
new ParameterList());
80 #define SET_VALID_ENTRY(name) validParamList->setEntry(name, MasterList::getEntry(name)) 83 SET_VALID_ENTRY(
"aggregation: error on nodes with no on-rank neighbors");
85 #undef SET_VALID_ENTRY 88 validParamList->set<std::string> (
"aggregation: output type",
"Aggregates",
89 "Type of object holding the aggregation data: Aggregtes or CrsGraph");
90 validParamList->set<std::string> (
"aggregation: coarsening rate",
"{3}",
91 "Coarsening rate per spatial dimensions");
92 validParamList->set<
int> (
"aggregation: coarsening order", 0,
93 "The interpolation order used to construct grid transfer operators based off these aggregates.");
94 validParamList->set<RCP<const FactoryBase> >(
"Graph", Teuchos::null,
95 "Graph of the matrix after amalgamation but without dropping.");
96 validParamList->set<RCP<const FactoryBase> >(
"DofsPerNode", Teuchos::null,
97 "Number of degrees of freedom per mesh node, provided by the coalsce drop factory.");
98 validParamList->set<RCP<const FactoryBase> >(
"numDimensions", Teuchos::null,
99 "Number of spatial dimension provided by CoordinatesTransferFactory.");
100 validParamList->set<RCP<const FactoryBase> >(
"lNodesPerDim", Teuchos::null,
101 "Number of nodes per spatial dimmension provided by CoordinatesTransferFactory.");
103 return validParamList;
106 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
107 void StructuredAggregationFactory_kokkos<LocalOrdinal, GlobalOrdinal, Node>::
108 DeclareInput(Level& currentLevel)
const {
109 Input(currentLevel,
"Graph");
110 Input(currentLevel,
"DofsPerNode");
113 if(currentLevel.GetLevelID() == 0) {
114 if(currentLevel.IsAvailable(
"numDimensions", NoFactory::get())) {
115 currentLevel.DeclareInput(
"numDimensions", NoFactory::get(),
this);
117 TEUCHOS_TEST_FOR_EXCEPTION(currentLevel.IsAvailable(
"numDimensions", NoFactory::get()),
118 Exceptions::RuntimeError,
119 "numDimensions was not provided by the user on level0!");
121 if(currentLevel.IsAvailable(
"lNodesPerDim", NoFactory::get())) {
122 currentLevel.DeclareInput(
"lNodesPerDim", NoFactory::get(),
this);
124 TEUCHOS_TEST_FOR_EXCEPTION(currentLevel.IsAvailable(
"lNodesPerDim", NoFactory::get()),
125 Exceptions::RuntimeError,
126 "lNodesPerDim was not provided by the user on level0!");
129 Input(currentLevel,
"lNodesPerDim");
130 Input(currentLevel,
"numDimensions");
134 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
135 void StructuredAggregationFactory_kokkos<LocalOrdinal, GlobalOrdinal, Node>::
136 Build(Level ¤tLevel)
const {
137 FactoryMonitor m(*
this,
"Build", currentLevel);
139 RCP<Teuchos::FancyOStream> out;
140 if(
const char* dbg = std::getenv(
"MUELU_STRUCTUREDAGGREGATION_DEBUG")) {
141 out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
142 out->setShowAllFrontMatter(
false).setShowProcRank(
true);
144 out = Teuchos::getFancyOStream(rcp(
new Teuchos::oblackholestream()));
147 using device_type =
typename LWGraph_kokkos::local_graph_type::device_type;
148 using execution_space =
typename LWGraph_kokkos::local_graph_type::device_type::execution_space;
149 using memory_space =
typename LWGraph_kokkos::local_graph_type::device_type::memory_space;
151 *out <<
"Entering structured aggregation" << std::endl;
153 ParameterList pL = GetParameterList();
154 bDefinitionPhase_ =
false;
157 RCP<const LWGraph_kokkos> graph = Get<RCP<LWGraph_kokkos> >(currentLevel,
"Graph");
158 RCP<const Map> fineMap = graph->GetDomainMap();
159 const int myRank = fineMap->getComm()->getRank();
160 const LO dofsPerNode = Get<LO>(currentLevel,
"DofsPerNode");
164 const int interpolationOrder = pL.get<
int>(
"aggregation: coarsening order");
165 std::string outputType = pL.get<std::string>(
"aggregation: output type");
166 const bool outputAggregates = (outputType ==
"Aggregates" ? true :
false);
167 Array<LO> lFineNodesPerDir(3);
169 if(currentLevel.GetLevelID() == 0) {
171 lFineNodesPerDir = currentLevel.Get<Array<LO> >(
"lNodesPerDim", NoFactory::get());
172 numDimensions = currentLevel.Get<
int>(
"numDimensions", NoFactory::get());
175 lFineNodesPerDir = Get<Array<LO> >(currentLevel,
"lNodesPerDim");
176 numDimensions = Get<int>(currentLevel,
"numDimensions");
181 for(
int dim = 0; dim < 3; ++dim) {
182 if(dim >= numDimensions) {
183 lFineNodesPerDir[dim] = 1;
188 std::string coarseningRate = pL.get<std::string>(
"aggregation: coarsening rate");
189 Teuchos::Array<LO> coarseRate;
191 coarseRate = Teuchos::fromStringToArray<LO>(coarseningRate);
192 }
catch(
const Teuchos::InvalidArrayStringRepresentation& e) {
193 GetOStream(
Errors,-1) <<
" *** \"aggregation: coarsening rate\" must be a string convertible into an array! *** " 197 TEUCHOS_TEST_FOR_EXCEPTION((coarseRate.size() > 1) && (coarseRate.size() < numDimensions),
198 Exceptions::RuntimeError,
199 "\"aggregation: coarsening rate\" must have at least as many" 200 " components as the number of spatial dimensions in the problem.");
203 RCP<IndexManager_kokkos> geoData = rcp(
new IndexManager_kokkos(numDimensions,
204 interpolationOrder, myRank,
208 *out <<
"The index manager has now been built" << std::endl;
209 TEUCHOS_TEST_FOR_EXCEPTION(fineMap->getNodeNumElements()
210 !=
static_cast<size_t>(geoData->getNumLocalFineNodes()),
211 Exceptions::RuntimeError,
212 "The local number of elements in the graph's map is not equal to " 213 "the number of nodes given by: lNodesPerDim!");
217 RCP<AggregationStructuredAlgorithm_kokkos> myStructuredAlgorithm
218 = rcp(
new AggregationStructuredAlgorithm_kokkos());
220 if(interpolationOrder == 0 && outputAggregates){
221 RCP<Aggregates_kokkos> aggregates = rcp(
new Aggregates_kokkos(graph->GetDomainMap()));
222 aggregates->setObjectLabel(
"ST");
223 aggregates->SetIndexManager(geoData);
224 aggregates->AggregatesCrossProcessors(
false);
225 aggregates->SetNumAggregates(geoData->getNumCoarseNodes());
227 LO numNonAggregatedNodes = geoData->getNumLocalFineNodes();
229 Kokkos::parallel_for(
"StructuredAggregation: initialize aggStat",
231 KOKKOS_LAMBDA(
const LO nodeIdx) {aggStat(nodeIdx) =
READY;});
233 myStructuredAlgorithm->BuildAggregates(pL, *graph, *aggregates, aggStat,
234 numNonAggregatedNodes);
236 *out <<
"numNonAggregatedNodes: " << numNonAggregatedNodes << std::endl;
238 TEUCHOS_TEST_FOR_EXCEPTION(numNonAggregatedNodes, Exceptions::RuntimeError,
239 "MueLu::StructuredAggregationFactory::Build: Leftover nodes found! Error!");
240 aggregates->ComputeAggregateSizes(
true);
241 GetOStream(
Statistics1) << aggregates->description() << std::endl;
242 Set(currentLevel,
"Aggregates", aggregates);
246 RCP<CrsGraph> myGraph;
247 myStructuredAlgorithm->BuildGraph(*graph, geoData, dofsPerNode, myGraph);
248 Set(currentLevel,
"prolongatorGraph", myGraph);
251 Set(currentLevel,
"lCoarseNodesPerDim", geoData->getCoarseNodesPerDirArray());
252 Set(currentLevel,
"indexManager", geoData);
253 Set(currentLevel,
"structuredInterpolationOrder", interpolationOrder);
254 Set(currentLevel,
"numDimensions", numDimensions);
260 #endif // HAVE_MUELU_KOKKOS_REFACTOR
Namespace for MueLu classes and methods.
#define SET_VALID_ENTRY(name)