MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MueLu_ClassicalMapFactory_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 
47 #ifndef MUELU_CLASSICALMAPFACTORY_DEF_HPP_
48 #define MUELU_CLASSICALMAPFACTORY_DEF_HPP_
49 
50 #include <Teuchos_Array.hpp>
51 #include <Teuchos_ArrayRCP.hpp>
52 
53 #ifdef HAVE_MPI
55 #endif
56 
57 #include <Xpetra_Vector.hpp>
58 #include <Xpetra_StridedMapFactory.hpp>
59 #include <Xpetra_VectorFactory.hpp>
60 #include <Xpetra_Import.hpp>
61 #include <Xpetra_IO.hpp>
62 
64 #include "MueLu_Level.hpp"
65 #include "MueLu_LWGraph.hpp"
66 #include "MueLu_MasterList.hpp"
67 #include "MueLu_Monitor.hpp"
68 
69 #include "MueLu_LWGraph.hpp"
70 
71 #ifdef HAVE_MUELU_ZOLTAN2
73 #include <Zoltan2_XpetraCrsGraphAdapter.hpp>
74 #include <Zoltan2_ColoringProblem.hpp>
75 #include <Zoltan2_ColoringSolution.hpp>
76 
77 #endif
78 
79 #include "MueLu_LWGraph_kokkos.hpp"
80 #include <KokkosGraph_Distance1ColorHandle.hpp>
81 #include <KokkosGraph_Distance1Color.hpp>
82 
83 namespace MueLu {
84 
85 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
87  RCP<ParameterList> validParamList = rcp(new ParameterList());
88 #define SET_VALID_ENTRY(name) validParamList->setEntry(name, MasterList::getEntry(name))
89  SET_VALID_ENTRY("aggregation: deterministic");
90  SET_VALID_ENTRY("aggregation: coloring algorithm");
91  SET_VALID_ENTRY("aggregation: coloring: use color graph");
92 #undef SET_VALID_ENTRY
93  validParamList->set<RCP<const FactoryBase> >("A", Teuchos::null, "Generating factory of the matrix A");
94  validParamList->set<RCP<const FactoryBase> >("UnAmalgamationInfo", Teuchos::null, "Generating factory of UnAmalgamationInfo");
95  validParamList->set<RCP<const FactoryBase> >("Graph", null, "Generating factory of the graph");
96  validParamList->set<RCP<const FactoryBase> >("Coloring Graph", null, "Generating factory of the graph");
97  validParamList->set<RCP<const FactoryBase> >("DofsPerNode", null, "Generating factory for variable \'DofsPerNode\', usually the same as for \'Graph\'");
98 
99  return validParamList;
100 }
101 
102 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
104  Input(currentLevel, "A");
105  Input(currentLevel, "UnAmalgamationInfo");
106  Input(currentLevel, "Graph");
107 
108  const ParameterList& pL = GetParameterList();
109  bool use_color_graph = pL.get<bool>("aggregation: coloring: use color graph");
110  if (use_color_graph)
111  Input(currentLevel, "Coloring Graph");
112 }
113 
114 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
116  FactoryMonitor m(*this, "Build", currentLevel);
117  const ParameterList& pL = GetParameterList();
118  RCP<const Matrix> A = Get<RCP<Matrix> >(currentLevel, "A");
119 
120  RCP<const LWGraph> graph;
121  bool use_color_graph = pL.get<bool>("aggregation: coloring: use color graph");
122  if (use_color_graph)
123  graph = Get<RCP<LWGraph> >(currentLevel, "Coloring Graph");
124  else
125  graph = Get<RCP<LWGraph> >(currentLevel, "Graph");
126 
127  /* ============================================================= */
128  /* Phase 1 : Compute an initial MIS */
129  /* ============================================================= */
130  ArrayRCP<LO> myColors;
131  LO numColors = 0;
132 
133  RCP<LocalOrdinalVector> fc_splitting;
134  std::string coloringAlgo = pL.get<std::string>("aggregation: coloring algorithm");
135 
136  // Switch to Zoltan2 if we're parallel and Tpetra (and not file)
137 #ifdef HAVE_MUELU_ZOLTAN2
138  int numProcs = A->getRowMap()->getComm()->getSize();
139  if (coloringAlgo != "file" && numProcs > 1 && graph->GetDomainMap()->lib() == Xpetra::UseTpetra)
140  coloringAlgo = "Zoltan2";
141 #endif
142 
143  //#define CMS_DUMP
144 #ifdef CMS_DUMP
145  {
146  int rank = graph->GetDomainMap()->getComm()->getRank();
147 
148  printf("[%d,%d] graph local size = %dx%d\n", rank, currentLevel.GetLevelID(), (int)graph->GetDomainMap()->getLocalNumElements(), (int)graph->GetImportMap()->getLocalNumElements());
149 
150  std::ofstream ofs(std::string("m_dropped_graph_") + std::to_string(currentLevel.GetLevelID()) + std::string("_") + std::to_string(rank) + std::string(".dat"), std::ofstream::out);
151  RCP<Teuchos::FancyOStream> fancy = Teuchos::fancyOStream(Teuchos::rcpFromRef(ofs));
152  graph->print(*fancy, Debug);
153  }
154  {
155  A->getRowMap()->getComm()->barrier();
156  }
157 
158 #endif
159 
160  // Switch to MIS if we're in Epetra (and not file)
161  if (coloringAlgo != "file" && graph->GetDomainMap()->lib() == Xpetra::UseEpetra)
162  coloringAlgo = "MIS";
163 
164  if (coloringAlgo == "file") {
165  // Read the CF splitting from disk
166  // NOTE: For interoperability reasons, this is dependent on the point_type enum not changing
167  std::string map_file = std::string("map_fcsplitting_") + std::to_string(currentLevel.GetLevelID()) + std::string(".m");
168  std::string color_file = std::string("fcsplitting_") + std::to_string(currentLevel.GetLevelID()) + std::string(".m");
169 
170  FILE* mapfile = fopen(map_file.c_str(), "r");
171  using real_type = typename Teuchos::ScalarTraits<SC>::magnitudeType;
172  using RealValuedMultiVector = typename Xpetra::MultiVector<real_type, LO, GO, NO>;
174 
175  GetOStream(Statistics1) << "Reading FC splitting from " << color_file << ", using map file " << map_file << ". On rank " << A->getRowMap()->getComm()->getRank() << " local size is " << A->getRowMap()->getLocalNumElements() << std::endl;
176  if (mapfile) {
177  fclose(mapfile);
178  RCP<const Map> colorMap = Xpetra::IO<Scalar, LocalOrdinal, GlobalOrdinal, Node>::ReadMap(map_file, A->getRowMap()->lib(), A->getRowMap()->getComm());
179  TEUCHOS_TEST_FOR_EXCEPTION(!colorMap->isCompatible(*A->getRowMap()), std::invalid_argument, "Coloring on disk has incompatible map with A");
180 
182  } else {
183  // Use A's rowmap and hope it matches
185  }
186  TEUCHOS_TEST_FOR_EXCEPTION(mv.is_null(), std::invalid_argument, "Coloring on disk cannot be read");
187  fc_splitting = LocalOrdinalVectorFactory::Build(A->getRowMap());
188  TEUCHOS_TEST_FOR_EXCEPTION(mv->getLocalLength() != fc_splitting->getLocalLength(), std::invalid_argument, "Coloring map mismatch");
189 
190  // Overlay the Dirichlet Points (and copy out the rest)
191  auto boundaryNodes = graph->GetBoundaryNodeMap();
192  ArrayRCP<const real_type> mv_data = mv->getData(0);
193  ArrayRCP<LO> fc_data = fc_splitting->getDataNonConst(0);
194  for (LO i = 0; i < (LO)fc_data.size(); i++) {
195  if (boundaryNodes[i])
196  fc_data[i] = DIRICHLET_PT;
197  else
198  fc_data[i] = Teuchos::as<LO>(mv_data[i]);
199  }
200  }
201 #ifdef HAVE_MUELU_ZOLTAN2
202  else if (coloringAlgo.find("Zoltan2") != std::string::npos && graph->GetDomainMap()->lib() == Xpetra::UseTpetra) {
203  SubFactoryMonitor sfm(*this, "DistributedGraphColoring", currentLevel);
204  DoDistributedGraphColoring(graph, myColors, numColors);
205  }
206 #endif
207  else if (coloringAlgo == "MIS" || graph->GetDomainMap()->lib() == Xpetra::UseTpetra) {
208  SubFactoryMonitor sfm(*this, "MIS", currentLevel);
209  TEUCHOS_TEST_FOR_EXCEPTION(A->getRowMap()->getComm()->getSize() != 1, std::invalid_argument, "MIS on more than 1 MPI rank is not supported");
210  DoMISNaive(*graph, myColors, numColors);
211  } else {
212  SubFactoryMonitor sfm(*this, "GraphColoring", currentLevel);
213  TEUCHOS_TEST_FOR_EXCEPTION(A->getRowMap()->getComm()->getSize() != 1, std::invalid_argument, "KokkosKernels graph coloring on more than 1 MPI rank is not supported");
214  DoGraphColoring(*graph, myColors, numColors);
215  }
216 
217 #ifdef CMS_DUMP
218  {
219  int rank = graph->GetDomainMap()->getComm()->getRank();
220 
221  printf("[%d,%d] num colors %d\n", rank, currentLevel.GetLevelID(), numColors);
222 
223  std::ofstream ofs(std::string("m_colors_") + std::to_string(currentLevel.GetLevelID()) + std::string("_") + std::to_string(rank) + std::string(".dat"), std::ofstream::out);
224  RCP<Teuchos::FancyOStream> fancy = Teuchos::fancyOStream(Teuchos::rcpFromRef(ofs));
225  *fancy << myColors();
226  }
227  {
228  A->getRowMap()->getComm()->barrier();
229  }
230 
231 #endif
232 
233  /* ============================================================= */
234  /* Phase 2 : Mark the C-Points */
235  /* ============================================================= */
236  LO num_c_points = 0, num_d_points = 0, num_f_points = 0;
237  if (fc_splitting.is_null()) {
238  // We just have a coloring, so we need to generate a splitting
239  auto boundaryNodes = graph->GetBoundaryNodeMap();
240  fc_splitting = LocalOrdinalVectorFactory::Build(A->getRowMap());
241  ArrayRCP<LO> myPointType = fc_splitting->getDataNonConst(0);
242  for (LO i = 0; i < (LO)myColors.size(); i++) {
243  if (boundaryNodes[i]) {
244  myPointType[i] = DIRICHLET_PT;
245  num_d_points++;
246  } else if ((LO)myColors[i] == 1) {
247  myPointType[i] = C_PT;
248  num_c_points++;
249  } else
250  myPointType[i] = F_PT;
251  }
252  num_f_points = (LO)myColors.size() - num_d_points - num_c_points;
253  } else {
254  // If we read the splitting off disk, we just need to count
255  ArrayRCP<LO> myPointType = fc_splitting->getDataNonConst(0);
256 
257  for (LO i = 0; i < (LO)myPointType.size(); i++) {
258  if (myPointType[i] == DIRICHLET_PT)
259  num_d_points++;
260  else if (myPointType[i] == C_PT)
261  num_c_points++;
262  }
263  num_f_points = (LO)myPointType.size() - num_d_points - num_c_points;
264  }
265 
266  /* Output statistics on c/f/d points */
267  if (GetVerbLevel() & Statistics1) {
268  // NOTE: We batch the communication here
269  GO l_counts[] = {(GO)num_c_points, (GO)num_f_points, (GO)num_d_points};
270  GO g_counts[3];
271 
272  RCP<const Teuchos::Comm<int> > comm = A->getRowMap()->getComm();
273  Teuchos::reduceAll(*comm, Teuchos::REDUCE_SUM, 3, l_counts, g_counts);
274  GetOStream(Statistics1) << "ClassicalMapFactory(" << coloringAlgo << "): C/F/D = " << g_counts[0] << "/" << g_counts[1] << "/" << g_counts[2] << std::endl;
275  }
276 
277  /* Generate the Coarse map */
278  RCP<const Map> coarseMap;
279  {
280  SubFactoryMonitor sfm(*this, "Coarse Map", currentLevel);
281  GenerateCoarseMap(*A->getRowMap(), num_c_points, coarseMap);
282  }
283 
284  Set(currentLevel, "FC Splitting", fc_splitting);
285  Set(currentLevel, "CoarseMap", coarseMap);
286 }
287 
288 /* ************************************************************************* */
289 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
291  GenerateCoarseMap(const Map& fineMap, LO num_c_points, RCP<const Map>& coarseMap) const {
292  // FIXME: Assumes scalar PDE
293  std::vector<size_t> stridingInfo_(1);
294  stridingInfo_[0] = 1;
295  GO domainGIDOffset = 0;
296 
297  coarseMap = StridedMapFactory::Build(fineMap.lib(),
299  num_c_points,
300  fineMap.getIndexBase(),
301  stridingInfo_,
302  fineMap.getComm(),
303  domainGIDOffset);
304 }
305 
306 /* ************************************************************************* */
307 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
309  DoGraphColoring(const LWGraph& graph, ArrayRCP<LO>& myColors_out, LO& numColors) const {
310  const ParameterList& pL = GetParameterList();
311  using graph_t = typename LWGraph_kokkos::local_graph_type;
312  using KernelHandle = KokkosKernels::Experimental::
313  KokkosKernelsHandle<typename graph_t::row_map_type::value_type,
314  typename graph_t::entries_type::value_type,
315  typename graph_t::entries_type::value_type,
316  typename graph_t::device_type::execution_space,
317  typename graph_t::device_type::memory_space,
318  typename graph_t::device_type::memory_space>;
319  KernelHandle kh;
320 
321  // Leave gc algorithm choice as the default
322  kh.create_graph_coloring_handle();
323 
324  // Get the distance-1 graph coloring handle
325  auto coloringHandle = kh.get_graph_coloring_handle();
326 
327  // Set the distance-1 coloring algorithm to use
328  if (pL.get<bool>("aggregation: deterministic") == true) {
329  coloringHandle->set_algorithm(KokkosGraph::COLORING_SERIAL);
330  if (IsPrint(Statistics1)) GetOStream(Statistics1) << " algorithm: serial" << std::endl;
331  } else if (pL.get<std::string>("aggregation: coloring algorithm") == "serial") {
332  coloringHandle->set_algorithm(KokkosGraph::COLORING_SERIAL);
333  if (IsPrint(Statistics1)) GetOStream(Statistics1) << " algorithm: serial" << std::endl;
334  } else if (pL.get<std::string>("aggregation: coloring algorithm") == "vertex based") {
335  coloringHandle->set_algorithm(KokkosGraph::COLORING_VB);
336  if (IsPrint(Statistics1)) GetOStream(Statistics1) << " algorithm: vertex based" << std::endl;
337  } else if (pL.get<std::string>("aggregation: coloring algorithm") == "vertex based bit array") {
338  coloringHandle->set_algorithm(KokkosGraph::COLORING_VBBIT);
339  if (IsPrint(Statistics1)) GetOStream(Statistics1) << " algorithm: vertex based bit array" << std::endl;
340  } else if (pL.get<std::string>("aggregation: coloring algorithm") == "vertex based color set") {
341  coloringHandle->set_algorithm(KokkosGraph::COLORING_VBCS);
342  if (IsPrint(Statistics1)) GetOStream(Statistics1) << " algorithm: vertex based color set" << std::endl;
343  } else if (pL.get<std::string>("aggregation: coloring algorithm") == "vertex based deterministic") {
344  coloringHandle->set_algorithm(KokkosGraph::COLORING_VBD);
345  if (IsPrint(Statistics1)) GetOStream(Statistics1) << " algorithm: vertex based deterministic" << std::endl;
346  } else if (pL.get<std::string>("aggregation: coloring algorithm") == "vertex based deterministic bit array") {
347  coloringHandle->set_algorithm(KokkosGraph::COLORING_VBDBIT);
348  if (IsPrint(Statistics1)) GetOStream(Statistics1) << " algorithm: vertex based deterministic bit array" << std::endl;
349  } else if (pL.get<std::string>("aggregation: coloring algorithm") == "edge based") {
350  coloringHandle->set_algorithm(KokkosGraph::COLORING_EB);
351  if (IsPrint(Statistics1)) GetOStream(Statistics1) << " algorithm: edge based" << std::endl;
352  } else {
353  TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, "Unrecognized distance 1 coloring algorithm");
354  }
355 
356  // Create device views for graph rowptrs/colinds
357  size_t numRows = graph.GetNodeNumVertices();
358  // auto graphLWK = dynamic_cast<const LWGraph_kokkos*>(&graph);
359  auto graphLW = dynamic_cast<const LWGraph*>(&graph);
360  TEUCHOS_TEST_FOR_EXCEPTION(!graphLW, std::invalid_argument, "Graph is not a LWGraph object");
361  // Run d1 graph coloring
362  // Assume that the graph is symmetric so row map/entries and col map/entries are the same
363 
364  // if (graphLWK) {
365  // KokkosGraph::Experimental::graph_color(&kh,
366  // numRows,
367  // numRows, // FIXME: This should be the number of columns
368  // graphLWK->getRowPtrs(),
369  // graphLWK->getEntries(),
370  // true);
371  // } else
372  if (graphLW) {
373  auto rowptrs = graphLW->getRowPtrs();
374  auto entries = graphLW->getEntries();
375  KokkosGraph::Experimental::graph_color(&kh,
376  numRows,
377  numRows, // FIXME: This should be the number of columns
378  rowptrs,
379  entries,
380  true);
381  }
382 
383  // Extract the colors and store them in the aggregates
384  auto myColors_d = coloringHandle->get_vertex_colors();
385  numColors = static_cast<LO>(coloringHandle->get_num_colors());
386 
387  // Copy back to host
388  auto myColors_h = Kokkos::create_mirror_view(myColors_d);
389  myColors_out.resize(myColors_h.size());
390  Kokkos::View<LO*, Kokkos::LayoutLeft, Kokkos::HostSpace> myColors_v(&myColors_out[0], myColors_h.size());
391  Kokkos::deep_copy(myColors_v, myColors_h);
392 
393  // clean up coloring handle
394  kh.destroy_graph_coloring_handle();
395 
396 } // end DoGraphColoring
397 
398 /* ************************************************************************* */
399 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
401  DoMISNaive(const LWGraph& graph, ArrayRCP<LO>& myColors, LO& numColors) const {
402  // This is a fall-back routine for when we don't have Kokkos or when it isn't initialized
403  // We just do greedy MIS because this is easy to write.
404 
407 
408  // FIXME: Not efficient
409  myColors.resize(0);
410  myColors.resize(graph.GetNodeNumVertices(), LO_INVALID);
411  auto boundaryNodes = graph.GetBoundaryNodeMap();
412  LO Nrows = (LO)graph.GetNodeNumVertices();
413 
414  for (LO row = 0; row < Nrows; row++) {
415  if (boundaryNodes[row])
416  continue;
417  auto indices = graph.getNeighborVertices(row);
418  bool has_colored_neighbor = false;
419  for (LO j = 0; !has_colored_neighbor && j < (LO)indices.length; j++) {
420  // FIXME: This does not handle ghosting correctly
421  if (myColors[indices(j)] == MIS)
422  has_colored_neighbor = true;
423  }
424  if (!has_colored_neighbor)
425  myColors[row] = MIS;
426  }
427  numColors = 1;
428 }
429 
430 /* ************************************************************************* */
431 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
433  DoDistributedGraphColoring(RCP<const LWGraph>& graph, ArrayRCP<LO>& myColors_out, LO& numColors) const {
434 #ifdef HAVE_MUELU_ZOLTAN2
435  // const ParameterList& pL = GetParameterList();
436  Teuchos::ParameterList params;
437  params.set("color_choice", "FirstFit");
438  params.set("color_method", "D1");
439  // params.set("color_choice", colorMethod);
440  // params.set("color_method", colorAlg);
441  // params.set("verbose", verbose);
442  // params.set("serial_threshold",serialThreshold);
443  // params.set("recolor_degrees",recolorDegrees);
444 
445  // Do the coloring via Zoltan2
446  using GraphAdapter = MueLuGraphBaseAdapter<LWGraph>;
447  GraphAdapter z_adapter(graph);
448 
449  // We need to provide the MPI Comm, or else we wind up using the default (eep!)
450  Zoltan2::ColoringProblem<GraphAdapter> problem(&z_adapter, &params, graph->GetDomainMap()->getComm());
451  problem.solve();
452  Zoltan2::ColoringSolution<GraphAdapter>* soln = problem.getSolution();
453  ArrayRCP<int> colors = soln->getColorsRCP();
454  numColors = (LO)soln->getNumColors();
455 
456  // Assign the Array RCP or Copy Out
457  // FIXME: This probably won't work if LO!=int
458  if (std::is_same<LO, int>::value)
459  myColors_out = colors;
460  else {
461  myColors_out.resize(colors.size());
462  for (LO i = 0; i < (LO)myColors_out.size(); i++)
463  myColors_out[i] = (LO)colors[i];
464  }
465 
466  /*
467 
468  printf("CMS: numColors = %d\ncolors = ",numColors);
469  for(int i=0;i<colors.size(); i++)
470  printf("%d ",colors[i]);
471  printf("\n");
472 
473  */
474 #endif // ifdef HAVE_MUELU_ZOLTAN2
475 }
476 
477 } // namespace MueLu
478 
479 #endif /* MUELU_CLASSICALMAPFACTORY_DEF_HPP_ */
void Build(Level &currentLevel) const override
Build an object with this factory.
#define SET_VALID_ENTRY(name)
typename std::conditional< OnHost, typename local_graph_device_type::HostMirror, local_graph_device_type >::type local_graph_type
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)
void DeclareInput(Level &currentLevel) const override
Specifies the data that this class needs, and the factories that generate that data.
Timer to be used in factories. Similar to Monitor but with additional timers.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
virtual void DoDistributedGraphColoring(RCP< const LWGraph > &graph, Teuchos::ArrayRCP< LO > &myColors, LO &numColors) const
Print more statistics.
Print additional debugging information.
LocalOrdinal LO
virtual void DoMISNaive(const LWGraph &graph, Teuchos::ArrayRCP< LO > &myColors, LO &numColors) const
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.
size_type size() const
void resize(const size_type n, const T &val=T())
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
static RCP< const Map > ReadMap(const std::string &fileName, Xpetra::UnderlyingLib lib, const RCP< const Teuchos::Comm< int > > &comm)
Timer to be used in factories. Similar to SubMonitor but adds a timer level by level.
static RCP< MultiVector > ReadMultiVector(const std::string &fileName, const RCP< const Map > &map)
KOKKOS_INLINE_FUNCTION neighbor_vertices_type getNeighborVertices(LO i) const
Return the list of vertices adjacent to the vertex &#39;v&#39;.
virtual void DoGraphColoring(const LWGraph &graph, Teuchos::ArrayRCP< LO > &myColors, LO &numColors) const
virtual void GenerateCoarseMap(const Map &fineMap, LO num_c_points, Teuchos::RCP< const Map > &coarseMap) const
const RCP< const Map > GetDomainMap() const
Lightweight MueLu representation of a compressed row storage graph.
RCP< const ParameterList > GetValidParameterList() const override
Return a const parameter list of valid parameters that setParameterList() will accept.
bool is_null() const