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