Zoltan2
Loading...
Searching...
No Matches
Zoltan2_AlgSerialGreedy.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Zoltan2: A package of combinatorial algorithms for scientific computing
4//
5// Copyright 2012 NTESS and the Zoltan2 contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef _ZOLTAN2_ALGSERIALGREEDY_HPP_
11#define _ZOLTAN2_ALGSERIALGREEDY_HPP_
12
13#include <Zoltan2_Algorithm.hpp>
16
20
21namespace Zoltan2{
22
23template <typename Adapter>
24class AlgSerialGreedy : public Algorithm<Adapter>
25{
26 private:
27 typedef typename Adapter::lno_t lno_t;
28 typedef typename Adapter::gno_t gno_t;
29 typedef typename Adapter::offset_t offset_t;
30 typedef typename Adapter::scalar_t scalar_t;
31 // Class member variables
32 const RCP<const typename Adapter::base_adapter_t> adapter_;
33 RCP<Teuchos::ParameterList> pl_;
34 RCP<Environment> env_;
35 RCP<const Teuchos::Comm<int> > comm_;
36 modelFlag_t graphFlags_;
37
38 public:
40 const RCP<const typename Adapter::base_adapter_t> &adapter,
41 const RCP<Teuchos::ParameterList> &pl,
42 const RCP<Environment> &env,
43 const RCP<const Teuchos::Comm<int> > &comm,
44 modelFlag_t graphFlags
45 ) : adapter_(adapter), pl_(pl), env_(env), comm_(comm), graphFlags_(graphFlags)
46 {
47 }
48
49 // Main entry point for graph coloring.
50 void color(
51 const RCP<ColoringSolution<Adapter> > &solution
52 )
53 {
54 HELLO;
55
56 // Color local graph. Global coloring is supported in Zoltan (not Zoltan2).
57 // Get local graph.
58 ArrayView<const gno_t> edgeIds;
59 ArrayView<const offset_t> offsets;
60 ArrayView<StridedData<lno_t, scalar_t> > wgts; // Not used; needed by getLocalEdgeList
61
62 const auto model = rcp(new GraphModel<typename Adapter::base_adapter_t>(adapter_, env_, comm_, graphFlags_));
63 const size_t nVtx = model->getLocalNumVertices(); // Assume (0,nvtx-1)
64 model->getEdgeList(edgeIds, offsets, wgts); // Don't need wgts
65
66#if 0
67 // Debug
68 cout << "Debug: Local graph from getLocalEdgeList" << endl;
69 cout << "rank " << comm_->getRank() << ": nVtx= " << nVtx << endl;
70 cout << "rank " << comm_->getRank() << ": edgeIds: " << edgeIds << endl;
71 cout << "rank " << comm_->getRank() << ": offsets: " << offsets << endl;
72#endif
73
74 // Get color array to fill.
75 // TODO: Allow user to input an old coloring.
76 ArrayRCP<int> colors = solution->getColorsRCP();
77 for (size_t i=0; i<nVtx; i++){
78 colors[i] = 0;
79 }
80
81 // Let colorCrsGraph do the real work.
82 env_->timerStart(MACRO_TIMERS, "Coloring algorithm");
83 colorCrsGraph(nVtx, edgeIds, offsets, colors);
84 env_->timerStop(MACRO_TIMERS, "Coloring algorithm");
85 return;
86 }
87
88 // Color graph given by two arrays. API may change. Expert users only!
90 const size_t nVtx,
91 ArrayView<const gno_t> edgeIds,
92 ArrayView<const offset_t> offsets,
93 ArrayRCP<int> colors
94 )
95 {
96 HELLO;
97
98 // Find max degree, since (max degree)+1 is an upper bound.
99 offset_t maxDegree = 0;
100 for (size_t i=0; i<nVtx; i++){
101 if (offsets[i+1]-offsets[i] > maxDegree)
102 maxDegree = offsets[i+1]-offsets[i];
103 }
104
105 // Greedy coloring.
106 // Use natural order for now.
107 // TODO: Support better orderings (e.g., Smallest-Last)
108 int maxColor = 0;
109
110 // array of size #colors: forbidden[i]=v means color[v]=i so i is forbidden
111 Teuchos::Array<int> forbidden(maxDegree+2, 0);
112
113 // LeastUsed: need array of size #colors
114 Teuchos::Array<lno_t> numVerticesWithColor(maxDegree+2, 0);
115
116 // Get colorChoice from parameter list.
117 Teuchos::ParameterList &pl = env_->getParametersNonConst();
118 std::string colorChoice = pl.get<std::string>("color_choice", "FirstFit");
119
120 for (size_t i=0; i<nVtx; i++){
121 //std::cout << "Debug: i= " << i << std::endl;
122 lno_t v=i; // TODO: Use ordering here.
123 for (offset_t j=offsets[v]; j<offsets[v+1]; j++){
124 gno_t nbor = edgeIds[j];
125 //std::cout << "Debug: nbor= " << nbor << ", color= " << colors[nbor] << std::endl;
126 if (colors[nbor] > 0){
127 // Neighbors' colors are forbidden
128 forbidden[colors[nbor]] = v;
129 }
130 }
131
132 // Pick color for v
133
134 // Keep colors[v] if possible, otherwise find valid color.
135 if ((colors[v]==0) || ((colors[v]>0) && forbidden[colors[v]] == v)){
136
137 if (colorChoice.compare("FirstFit")){
138 // Pick first (smallest) available color > 0
139 for (int c=1; c <= maxColor+1; c++){
140 if (forbidden[c] != v){
141 colors[v] = c;
142 break;
143 }
144 }
145 }
146 else if (colorChoice.compare("Random")){
147 // Pick random available color.
148 // Truely random is slow, please consider RandomFast instead.
149 int numAvail = 0;
150 Teuchos::Array<int> avail(maxColor+1);
151 for (int c=1; c < maxColor+1; c++){
152 if (forbidden[c] != v){
153 avail[numAvail++] = c;
154 }
155 }
156 if (numAvail==0)
157 colors[v] = maxColor+1;
158 else
159 colors[v] = avail[rand()%numAvail];
160 }
161 else if (colorChoice.compare("RandomFast")){
162 // Pick random color, then find first available color after that.
163 bool foundColor = false;
164 int r = (rand() % maxColor) +1;
165 for (int c=r; c <= maxColor; c++){
166 if (forbidden[c] != v){
167 colors[v] = c;
168 foundColor = true;
169 break;
170 }
171 }
172 if (!foundColor){ // Look for colors in [1, r)
173 for (int c=1; c < r; c++){
174 if (forbidden[c] != v){
175 colors[v] = c;
176 foundColor = true;
177 break;
178 }
179 }
180 }
181 if (!foundColor) colors[v] = maxColor+1;
182 }
183 else if (colorChoice.compare("LeastUsed")){
184 // Pick least used available color.
185 // Simple linear algorithm; could maintain a priority queue but not sure any faster?
186 int leastUsedColor = 1;
187 for (int c=1; c <= maxColor; c++){
188 if (forbidden[c] != v){
189 if (numVerticesWithColor[c] < leastUsedColor){
190 leastUsedColor = c;
191 }
192 }
193 }
194 colors[v] = leastUsedColor;
195
196 // Update color counts
197 numVerticesWithColor[colors[v]]++;
198 }
199
200 if ((v==0) && colors[v]==0) colors[v]=1; // Corner case for first vertex
201
202 // If we used a new color, increase maxColor.
203 if (colors[v] > maxColor){
204 maxColor = colors[v];
205 }
206 }
207 }
208
209 return;
210 }
211
214 static void getValidParameters(ParameterList & pl)
215 {
216 RCP<Teuchos::StringValidator> color_choice_Validator = Teuchos::rcp(
217 new Teuchos::StringValidator(
218 Teuchos::tuple<std::string>(
219 "FirstFit", "Random", "RandomFast", "LeastUsed" )));
220 pl.set("color_choice", "FirstFit", "selection criterion for coloring",
221 color_choice_Validator);
222 }
223};
224}
225#endif
Defines the ColoringSolution class.
Defines the GraphModel interface.
#define HELLO
void color(const RCP< ColoringSolution< Adapter > > &solution)
Coloring method.
static void getValidParameters(ParameterList &pl)
Set up validators specific to this algorithm.
AlgSerialGreedy(const RCP< const typename Adapter::base_adapter_t > &adapter, const RCP< Teuchos::ParameterList > &pl, const RCP< Environment > &env, const RCP< const Teuchos::Comm< int > > &comm, modelFlag_t graphFlags)
void colorCrsGraph(const size_t nVtx, ArrayView< const gno_t > edgeIds, ArrayView< const offset_t > offsets, ArrayRCP< int > colors)
Algorithm defines the base class for all algorithms.
The class containing coloring solution.
GraphModel defines the interface required for graph models.
Created by mbenlioglu on Aug 31, 2020.
std::bitset< NUM_MODEL_FLAGS > modelFlag_t
@ MACRO_TIMERS
Time an algorithm (or other entity) as a whole.