MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MueLu_UncoupledAggregationFactory_kokkos_def.hpp
Go to the documentation of this file.
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // MueLu: A package for multigrid based preconditioning
6 // Copyright 2012 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact
39 // Jonathan Hu (jhu@sandia.gov)
40 // Andrey Prokopenko (aprokop@sandia.gov)
41 // Ray Tuminaro (rstumin@sandia.gov)
42 //
43 // ***********************************************************************
44 //
45 // @HEADER
46 #ifndef MUELU_UNCOUPLEDAGGREGATIONFACTORY_KOKKOS_DEF_HPP_
47 #define MUELU_UNCOUPLEDAGGREGATIONFACTORY_KOKKOS_DEF_HPP_
48 
49 #include <climits>
50 
51 #include <Xpetra_Map.hpp>
52 #include <Xpetra_Vector.hpp>
53 #include <Xpetra_MultiVectorFactory.hpp>
54 #include <Xpetra_VectorFactory.hpp>
55 
57 
58 #include "MueLu_OnePtAggregationAlgorithm_kokkos.hpp"
59 #include "MueLu_PreserveDirichletAggregationAlgorithm_kokkos.hpp"
60 
61 #include "MueLu_AggregationPhase1Algorithm_kokkos.hpp"
62 #include "MueLu_AggregationPhase2aAlgorithm_kokkos.hpp"
63 #include "MueLu_AggregationPhase2bAlgorithm_kokkos.hpp"
64 #include "MueLu_AggregationPhase3Algorithm_kokkos.hpp"
65 
66 #include "MueLu_Level.hpp"
67 #include "MueLu_LWGraph_kokkos.hpp"
68 #include "MueLu_Aggregates.hpp"
69 #include "MueLu_MasterList.hpp"
70 #include "MueLu_Monitor.hpp"
71 
72 #include "KokkosGraph_Distance2ColorHandle.hpp"
73 #include "KokkosGraph_Distance2Color.hpp"
74 #include "KokkosGraph_MIS2.hpp"
75 
76 namespace MueLu {
77 
78 template <class LocalOrdinal, class GlobalOrdinal, class Node>
80  : bDefinitionPhase_(true) {}
81 
82 template <class LocalOrdinal, class GlobalOrdinal, class Node>
84  RCP<ParameterList> validParamList = rcp(new ParameterList());
85 
86  // Aggregation parameters (used in aggregation algorithms)
87  // TODO introduce local member function for each aggregation algorithm such that each aggregation algorithm can define its own parameters
88 
90 #define SET_VALID_ENTRY(name) validParamList->setEntry(name, MasterList::getEntry(name))
91  SET_VALID_ENTRY("aggregation: max agg size");
92  SET_VALID_ENTRY("aggregation: min agg size");
93  SET_VALID_ENTRY("aggregation: max selected neighbors");
94  SET_VALID_ENTRY("aggregation: ordering");
95  validParamList->getEntry("aggregation: ordering").setValidator(rcp(new validatorType(Teuchos::tuple<std::string>("natural", "graph", "random"), "aggregation: ordering")));
96  SET_VALID_ENTRY("aggregation: deterministic");
97  SET_VALID_ENTRY("aggregation: coloring algorithm");
98  SET_VALID_ENTRY("aggregation: enable phase 1");
99  SET_VALID_ENTRY("aggregation: enable phase 2a");
100  SET_VALID_ENTRY("aggregation: enable phase 2b");
101  SET_VALID_ENTRY("aggregation: enable phase 3");
102  SET_VALID_ENTRY("aggregation: match ML phase1");
103  SET_VALID_ENTRY("aggregation: match ML phase2a");
104  SET_VALID_ENTRY("aggregation: match ML phase2b");
105  SET_VALID_ENTRY("aggregation: phase3 avoid singletons");
106  SET_VALID_ENTRY("aggregation: error on nodes with no on-rank neighbors");
107  SET_VALID_ENTRY("aggregation: preserve Dirichlet points");
108  SET_VALID_ENTRY("aggregation: allow user-specified singletons");
109  SET_VALID_ENTRY("aggregation: phase 1 algorithm");
110 #undef SET_VALID_ENTRY
111 
112  // general variables needed in AggregationFactory
113  validParamList->set<RCP<const FactoryBase> >("Graph", null, "Generating factory of the graph");
114  validParamList->set<RCP<const FactoryBase> >("DofsPerNode", null, "Generating factory for variable \'DofsPerNode\', usually the same as for \'Graph\'");
115 
116  // special variables necessary for OnePtAggregationAlgorithm
117  validParamList->set<std::string>("OnePt aggregate map name", "", "Name of input map for single node aggregates. (default='')");
118  validParamList->set<std::string>("OnePt aggregate map factory", "", "Generating factory of (DOF) map for single node aggregates.");
119  // validParamList->set< RCP<const FactoryBase> >("OnePt aggregate map factory", NoFactory::getRCP(), "Generating factory of (DOF) map for single node aggregates.");
120 
121  return validParamList;
122 }
123 
124 template <class LocalOrdinal, class GlobalOrdinal, class Node>
126  Input(currentLevel, "Graph");
127  Input(currentLevel, "DofsPerNode");
128 
129  const ParameterList& pL = GetParameterList();
130 
131  // request special data necessary for OnePtAggregationAlgorithm
132  std::string mapOnePtName = pL.get<std::string>("OnePt aggregate map name");
133  if (mapOnePtName.length() > 0) {
134  std::string mapOnePtFactName = pL.get<std::string>("OnePt aggregate map factory");
135  if (mapOnePtFactName == "" || mapOnePtFactName == "NoFactory") {
136  currentLevel.DeclareInput(mapOnePtName, NoFactory::get());
137  } else {
138  RCP<const FactoryBase> mapOnePtFact = GetFactory(mapOnePtFactName);
139  currentLevel.DeclareInput(mapOnePtName, mapOnePtFact.get());
140  }
141  }
142 }
143 
144 template <class LocalOrdinal, class GlobalOrdinal, class Node>
146  Build(Level& currentLevel) const {
147  using execution_space = typename LWGraph_kokkos::execution_space;
148  using memory_space = typename LWGraph_kokkos::memory_space;
149  using local_ordinal_type = typename LWGraph_kokkos::local_ordinal_type;
150  FactoryMonitor m(*this, "Build", currentLevel);
151 
152  ParameterList pL = GetParameterList();
153  bDefinitionPhase_ = false; // definition phase is finished, now all aggregation algorithm information is fixed
154 
155  if (pL.get<int>("aggregation: max agg size") == -1)
156  pL.set("aggregation: max agg size", INT_MAX);
157 
158  // define aggregation algorithms
159  RCP<const FactoryBase> graphFact = GetFactory("Graph");
160 
161  // TODO Can we keep different aggregation algorithms over more Build calls?
162  algos_.clear();
163  algos_.push_back(rcp(new PreserveDirichletAggregationAlgorithm_kokkos(graphFact)));
164  if (pL.get<bool>("aggregation: allow user-specified singletons") == true) algos_.push_back(rcp(new OnePtAggregationAlgorithm_kokkos(graphFact)));
165  if (pL.get<bool>("aggregation: enable phase 1") == true) algos_.push_back(rcp(new AggregationPhase1Algorithm_kokkos(graphFact)));
166  if (pL.get<bool>("aggregation: enable phase 2a") == true) algos_.push_back(rcp(new AggregationPhase2aAlgorithm_kokkos(graphFact)));
167  if (pL.get<bool>("aggregation: enable phase 2b") == true) algos_.push_back(rcp(new AggregationPhase2bAlgorithm_kokkos(graphFact)));
168  if (pL.get<bool>("aggregation: enable phase 3") == true) algos_.push_back(rcp(new AggregationPhase3Algorithm_kokkos(graphFact)));
169 
170  // Sanity Checking: match ML behavior is not supported in UncoupledAggregation_Kokkos in Phase 1 or Phase 2b, but is in 2a
171  TEUCHOS_TEST_FOR_EXCEPTION(pL.get<bool>("aggregation: match ML phase1"), std::invalid_argument, "Option: 'aggregation: match ML phase1' is not supported in the Kokkos version of uncoupled aggregation");
172  TEUCHOS_TEST_FOR_EXCEPTION(pL.get<bool>("aggregation: match ML phase2b"), std::invalid_argument, "Option: 'aggregation: match ML phase2b' is not supported in the Kokkos version of uncoupled aggregation");
173 
174  std::string mapOnePtName = pL.get<std::string>("OnePt aggregate map name");
175  RCP<Map> OnePtMap = Teuchos::null;
176  if (mapOnePtName.length()) {
177  std::string mapOnePtFactName = pL.get<std::string>("OnePt aggregate map factory");
178  if (mapOnePtFactName == "" || mapOnePtFactName == "NoFactory") {
179  OnePtMap = currentLevel.Get<RCP<Map> >(mapOnePtName, NoFactory::get());
180  } else {
181  RCP<const FactoryBase> mapOnePtFact = GetFactory(mapOnePtFactName);
182  OnePtMap = currentLevel.Get<RCP<Map> >(mapOnePtName, mapOnePtFact.get());
183  }
184  }
185 
186  RCP<const LWGraph_kokkos> graph = Get<RCP<LWGraph_kokkos> >(currentLevel, "Graph");
187 
188  // Build
189  RCP<Aggregates> aggregates = rcp(new Aggregates(*graph));
190  aggregates->setObjectLabel("UC");
191 
192  const LO numRows = graph->GetNodeNumVertices();
193 
194  // construct aggStat information
195  Kokkos::View<unsigned*, typename LWGraph_kokkos::device_type> aggStat(Kokkos::ViewAllocateWithoutInitializing("aggregation status"),
196  numRows);
197  Kokkos::deep_copy(aggStat, READY);
198 
199  // LBV on Sept 06 2019: re-commenting out the dirichlet boundary map
200  // even if the map is correctly extracted from the graph, aggStat is
201  // now a Kokkos::View<unsinged*, memory_space> and filling it will
202  // require a parallel_for or to copy it to the Host which is not really
203  // good from a performance point of view.
204  // If dirichletBoundaryMap was an actual Xpetra::Map, one could call
205  // getLocalMap to have a Kokkos::View on the appropriate memory_space
206  // instead of an ArrayRCP.
207  {
208  auto dirichletBoundaryMap = graph->GetBoundaryNodeMap();
209  Kokkos::parallel_for(
210  "MueLu - UncoupledAggregation: tagging boundary nodes in aggStat",
211  Kokkos::RangePolicy<local_ordinal_type, execution_space>(0, numRows),
212  KOKKOS_LAMBDA(const local_ordinal_type nodeIdx) {
213  if (dirichletBoundaryMap(nodeIdx) == true) {
214  aggStat(nodeIdx) = BOUNDARY;
215  }
216  });
217  }
218 
219  LO nDofsPerNode = Get<LO>(currentLevel, "DofsPerNode");
220  GO indexBase = graph->GetDomainMap()->getIndexBase();
221 
222  /* FIXME: This chunk of code is still executing on the host */
223  if (OnePtMap != Teuchos::null) {
224  typename Kokkos::View<unsigned*, typename LWGraph_kokkos::device_type>::HostMirror aggStatHost = Kokkos::create_mirror_view(aggStat);
225  Kokkos::deep_copy(aggStatHost, aggStat);
226 
227  for (LO i = 0; i < numRows; i++) {
228  // reconstruct global row id (FIXME only works for contiguous maps)
229  GO grid = (graph->GetDomainMap()->getGlobalElement(i) - indexBase) * nDofsPerNode + indexBase;
230 
231  for (LO kr = 0; kr < nDofsPerNode; kr++)
232  if (OnePtMap->isNodeGlobalElement(grid + kr))
233  aggStatHost(i) = ONEPT;
234  }
235 
236  Kokkos::deep_copy(aggStat, aggStatHost);
237  }
238 
239  const RCP<const Teuchos::Comm<int> > comm = graph->GetComm();
240  GO numGlobalRows = 0;
241  if (IsPrint(Statistics1))
242  MueLu_sumAll(comm, as<GO>(numRows), numGlobalRows);
243 
244  LO numNonAggregatedNodes = numRows;
245  std::string aggAlgo = pL.get<std::string>("aggregation: coloring algorithm");
246  if (aggAlgo == "mis2 coarsening" || aggAlgo == "mis2 aggregation") {
247  SubFactoryMonitor sfm(*this, "Algo \"MIS2\"", currentLevel);
248  using graph_t = typename LWGraph_kokkos::local_graph_type;
249  using device_t = typename graph_t::device_type;
250  using exec_space = typename device_t::execution_space;
251  using rowmap_t = typename graph_t::row_map_type;
252  using colinds_t = typename graph_t::entries_type;
253  using lno_t = typename colinds_t::non_const_value_type;
254  rowmap_t aRowptrs = graph->getRowPtrs();
255  colinds_t aColinds = graph->getEntries();
256  lno_t numAggs = 0;
257  typename colinds_t::non_const_type labels;
258 
259  if (aggAlgo == "mis2 coarsening") {
260  if (IsPrint(Statistics1)) GetOStream(Statistics1) << " algorithm: MIS-2 coarsening" << std::endl;
261  labels = KokkosGraph::graph_mis2_coarsen<device_t, rowmap_t, colinds_t>(aRowptrs, aColinds, numAggs);
262  } else if (aggAlgo == "mis2 aggregation") {
263  if (IsPrint(Statistics1)) GetOStream(Statistics1) << " algorithm: MIS-2 aggregation" << std::endl;
264  labels = KokkosGraph::graph_mis2_aggregate<device_t, rowmap_t, colinds_t>(aRowptrs, aColinds, numAggs);
265  }
266  auto vertex2AggId = aggregates->GetVertex2AggId()->getDeviceLocalView(Xpetra::Access::ReadWrite);
267  auto procWinner = aggregates->GetProcWinner()->getDeviceLocalView(Xpetra::Access::OverwriteAll);
268  int rank = comm->getRank();
269  Kokkos::parallel_for(
270  Kokkos::RangePolicy<exec_space>(0, numRows),
271  KOKKOS_LAMBDA(lno_t i) {
272  procWinner(i, 0) = rank;
273  if (aggStat(i) == READY) {
274  aggStat(i) = AGGREGATED;
275  vertex2AggId(i, 0) = labels(i);
276  }
277  });
278  numNonAggregatedNodes = 0;
279  aggregates->SetNumAggregates(numAggs);
280  } else {
281  {
282  SubFactoryMonitor sfm(*this, "Algo \"Graph Coloring\"", currentLevel);
283 
284  // LBV on Sept 06 2019: the note below is a little worrisome,
285  // can we guarantee that MueLu is never used on a non-symmetric
286  // graph?
287  // note: just using colinds_view in place of scalar_view_t type
288  // (it won't be used at all by symbolic SPGEMM)
289  using graph_t = typename LWGraph_kokkos::local_graph_type;
290  using KernelHandle = KokkosKernels::Experimental::
291  KokkosKernelsHandle<typename graph_t::row_map_type::value_type,
292  typename graph_t::entries_type::value_type,
293  typename graph_t::entries_type::value_type,
294  typename graph_t::device_type::execution_space,
295  typename graph_t::device_type::memory_space,
296  typename graph_t::device_type::memory_space>;
297  KernelHandle kh;
298  // leave gc algorithm choice as the default
299  kh.create_distance2_graph_coloring_handle();
300 
301  // get the distance-2 graph coloring handle
302  auto coloringHandle = kh.get_distance2_graph_coloring_handle();
303 
304  // Set the distance-2 graph coloring algorithm to use.
305  // Options:
306  // COLORING_D2_DEFAULT - Let the kernel handle pick the variation
307  // COLORING_D2_SERIAL - Use the legacy serial-only implementation
308  // COLORING_D2_VB - Use the parallel vertex based direct method
309  // COLORING_D2_VB_BIT - Same as VB but using the bitvector forbidden array
310  // COLORING_D2_VB_BIT_EF - Add experimental edge-filtering to VB_BIT
311  // COLORING_D2_NB_BIT - Net-based coloring (generally the fastest)
312  if (pL.get<bool>("aggregation: deterministic") == true) {
313  coloringHandle->set_algorithm(KokkosGraph::COLORING_D2_SERIAL);
314  if (IsPrint(Statistics1)) GetOStream(Statistics1) << " algorithm: serial" << std::endl;
315  } else if (aggAlgo == "serial") {
316  coloringHandle->set_algorithm(KokkosGraph::COLORING_D2_SERIAL);
317  if (IsPrint(Statistics1)) GetOStream(Statistics1) << " algorithm: serial" << std::endl;
318  } else if (aggAlgo == "default") {
319  coloringHandle->set_algorithm(KokkosGraph::COLORING_D2_DEFAULT);
320  if (IsPrint(Statistics1)) GetOStream(Statistics1) << " algorithm: default" << std::endl;
321  } else if (aggAlgo == "vertex based") {
322  coloringHandle->set_algorithm(KokkosGraph::COLORING_D2_VB);
323  if (IsPrint(Statistics1)) GetOStream(Statistics1) << " algorithm: vertex based" << std::endl;
324  } else if (aggAlgo == "vertex based bit set") {
325  coloringHandle->set_algorithm(KokkosGraph::COLORING_D2_VB_BIT);
326  if (IsPrint(Statistics1)) GetOStream(Statistics1) << " algorithm: vertex based bit set" << std::endl;
327  } else if (aggAlgo == "edge filtering") {
328  coloringHandle->set_algorithm(KokkosGraph::COLORING_D2_VB_BIT_EF);
329  if (IsPrint(Statistics1)) GetOStream(Statistics1) << " algorithm: edge filtering" << std::endl;
330  } else if (aggAlgo == "net based bit set") {
331  coloringHandle->set_algorithm(KokkosGraph::COLORING_D2_NB_BIT);
332  if (IsPrint(Statistics1)) GetOStream(Statistics1) << " algorithm: net based bit set" << std::endl;
333  } else {
334  TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, "Unrecognized distance 2 coloring algorithm, valid options are: serial, default, matrix squared, vertex based, vertex based bit set, edge filtering")
335  }
336 
337  // Create device views for graph rowptrs/colinds
338  typename graph_t::row_map_type aRowptrs = graph->getRowPtrs();
339  typename graph_t::entries_type aColinds = graph->getEntries();
340 
341  // run d2 graph coloring
342  // graph is symmetric so row map/entries and col map/entries are the same
343  {
344  SubFactoryMonitor sfm2(*this, "Algo \"Graph Coloring\": KokkosGraph Call", currentLevel); // CMS HACK
345  KokkosGraph::Experimental::graph_color_distance2(&kh, numRows, aRowptrs, aColinds);
346  }
347 
348  // extract the colors and store them in the aggregates
349  aggregates->SetGraphColors(coloringHandle->get_vertex_colors());
350  aggregates->SetGraphNumColors(static_cast<LO>(coloringHandle->get_num_colors()));
351 
352  // clean up coloring handle
353  kh.destroy_distance2_graph_coloring_handle();
354  }
355 
356  if (IsPrint(Statistics1)) {
357  GetOStream(Statistics1) << " num colors: " << aggregates->GetGraphNumColors() << std::endl;
358  }
359  GO numGlobalAggregatedPrev = 0, numGlobalAggsPrev = 0;
360  for (size_t a = 0; a < algos_.size(); a++) {
361  std::string phase = algos_[a]->description();
362  SubFactoryMonitor sfm2(*this, "Algo \"" + phase + "\"", currentLevel);
363 
364  int oldRank = algos_[a]->SetProcRankVerbose(this->GetProcRankVerbose());
365  algos_[a]->BuildAggregates(pL, *graph, *aggregates, aggStat, numNonAggregatedNodes);
366  algos_[a]->SetProcRankVerbose(oldRank);
367 
368  if (IsPrint(Statistics1)) {
369  GO numLocalAggregated = numRows - numNonAggregatedNodes, numGlobalAggregated = 0;
370  GO numLocalAggs = aggregates->GetNumAggregates(), numGlobalAggs = 0;
371  MueLu_sumAll(comm, numLocalAggregated, numGlobalAggregated);
372  MueLu_sumAll(comm, numLocalAggs, numGlobalAggs);
373 
374  double aggPercent = 100 * as<double>(numGlobalAggregated) / as<double>(numGlobalRows);
375  if (aggPercent > 99.99 && aggPercent < 100.00) {
376  // Due to round off (for instance, for 140465733/140466897), we could
377  // get 100.00% display even if there are some remaining nodes. This
378  // is bad from the users point of view. It is much better to change
379  // it to display 99.99%.
380  aggPercent = 99.99;
381  }
382  GetOStream(Statistics1) << " aggregated : " << (numGlobalAggregated - numGlobalAggregatedPrev) << " (phase), " << std::fixed
383  << std::setprecision(2) << numGlobalAggregated << "/" << numGlobalRows << " [" << aggPercent << "%] (total)\n"
384  << " remaining : " << numGlobalRows - numGlobalAggregated << "\n"
385  << " aggregates : " << numGlobalAggs - numGlobalAggsPrev << " (phase), " << numGlobalAggs << " (total)" << std::endl;
386  numGlobalAggregatedPrev = numGlobalAggregated;
387  numGlobalAggsPrev = numGlobalAggs;
388  }
389  }
390  }
391 
392  TEUCHOS_TEST_FOR_EXCEPTION(numNonAggregatedNodes, Exceptions::RuntimeError, "MueLu::UncoupledAggregationFactory::Build: Leftover nodes found! Error!");
393 
394  aggregates->AggregatesCrossProcessors(false);
395  aggregates->ComputeAggregateSizes(true /*forceRecompute*/);
396 
397  Set(currentLevel, "Aggregates", aggregates);
398 }
399 
400 } // namespace MueLu
401 
402 #endif /* MUELU_UNCOUPLEDAGGREGATIONFACTORY_DEF_HPP_ */
#define MueLu_sumAll(rcpComm, in, out)
T & Get(const std::string &ename, const FactoryBase *factory=NoFactory::get())
Get data without decrementing associated storage counter (i.e., read-only access). Usage: Level-&gt;Get&lt; RCP&lt;Matrix&gt; &gt;(&quot;A&quot;, factory) if factory == NULL =&gt; use default factory.
KOKKOS_INLINE_FUNCTION row_type getRowPtrs() const
Return the row pointers of the local graph.
Container class for aggregation information.
typename std::conditional< OnHost, typename local_graph_device_type::HostMirror, local_graph_device_type >::type local_graph_type
void setValidator(RCP< const ParameterEntryValidator > const &validator)
GlobalOrdinal GO
T & get(const std::string &name, T def_value)
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
Timer to be used in factories. Similar to Monitor but with additional timers.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Print more statistics.
LocalOrdinal LO
T * get() const
#define SET_VALID_ENTRY(name)
void Build(Level &currentLevel) const
Build aggregates.
KOKKOS_INLINE_FUNCTION size_type GetNodeNumVertices() const
Return number of graph vertices.
KOKKOS_INLINE_FUNCTION const boundary_nodes_type GetBoundaryNodeMap() const
Returns map with global ids of boundary nodes.
static const NoFactory * get()
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Class that holds all level-specific information.
Definition: MueLu_Level.hpp:99
Timer to be used in factories. Similar to SubMonitor but adds a timer level by level.
KOKKOS_INLINE_FUNCTION entries_type getEntries() const
Return the list entries in the local graph.
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
const RCP< const Map > GetDomainMap() const
Exception throws to report errors in the internal logical of the program.
ParameterEntry & getEntry(const std::string &name)
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()
const RCP< const Teuchos::Comm< int > > GetComm() const