1 #include "BSprivate.h"
2
3 /*+ BSsdo_color - Do a local IDO coloring
4
5 Input Parameters:
6 . sdo_queue - the nodes to color
7 . n_queue - the length of the sdo_queue
8 . A - the sparse matrix
9 . local_color - the local coloring
10 . global_color - the colors of global nodes adjacent to each processor
11 . local_ptr - array of pointers indicating which neighbors in
12 . each row are local neighbors (on this processor)
13 . global_ptr - array of pointers indicating which neighbors in
14 . each row are global neighbors (not on this processor)
15 . color_template - used to figure out what colors are around a node
16 . sdo_degree - a work vector
17 . sdo_queue_ptr - a work vector
18 . sdo_deg_ptr - a work vector
19 . procinfo - the usual processor info
20
21 +*/
BSsdo_color(int * sdo_queue,int n_queue,BSspmat * A,int * local_color,int ** global_color,int * local_ptr,int * global_ptr,int * color_template,int * sdo_degree,int * sdo_queue_ptr,int * sdo_deg_ptr,BSprocinfo * procinfo)22 void BSsdo_color(int *sdo_queue, int n_queue, BSspmat *A, int *local_color,
23 int **global_color, int *local_ptr, int *global_ptr,
24 int *color_template, int *sdo_degree, int *sdo_queue_ptr,
25 int *sdo_deg_ptr, BSprocinfo *procinfo)
26 {
27 BSsprow **local_col_array;
28 int *row_ptr, *adj_row_ptr;
29 BSsprow *t_node, *adj_node;
30 int i, j, k;
31 int max_sdo_deg, deg, l_vtx, t_color;
32 int adj_vertex, adj_adj_vertex;
33 int update;
34 int tmp_ptr, tmp_vertex;
35 int *in_group;
36 int n = A->num_rows;
37
38 /* Set-up */
39 MY_MALLOC(in_group,(int *),sizeof(int)*A->num_rows,1);
40
41 local_col_array = A->rows;
42
43 /* Initialize sdo_degree to be -1 for all nodes */
44 /* this indicates that a node is NOT in the sdo_queue */
45 for (i=0;i<A->num_rows;i++) {
46 in_group[i] = -1;
47 }
48
49 /* Compute sdo_degrees and store as key in sdo_queue_ptr */
50
51 for (i=0; i<n_queue; i++) {
52 l_vtx = sdo_queue[i];
53 in_group[l_vtx] = 1;
54 sdo_queue_ptr[i] = 0;
55
56 /* Check for global adjacent nodes and update sdo degree */
57
58 for (j=0; j<global_ptr[l_vtx]; j++) {
59
60 t_color = global_color[l_vtx][j];
61
62 if(color_template[t_color] != n + l_vtx) {
63 color_template[t_color] = n + l_vtx;
64 sdo_queue_ptr[i]++;
65 }
66 }
67
68 /* Check local nodes */
69
70 t_node = local_col_array[l_vtx];
71 row_ptr = t_node->col;
72
73 for (j=local_ptr[l_vtx]; j<t_node->length; j++) {
74 (*A->map->fglobal2local)
75 (1,&(row_ptr[j]),&adj_vertex,procinfo,A->map);CHKERR(0);
76
77 t_color = local_color[adj_vertex];
78 if (t_color == NO_COLOR) {
79 }
80 else {
81 if(color_template[t_color] != n + l_vtx) {
82 color_template[t_color] = n + l_vtx;
83 sdo_queue_ptr[i]++;
84 }
85 }
86 }
87 sdo_degree[l_vtx] = sdo_queue_ptr[i];
88 }
89
90 /* Sort sdo_queue by sdo_degree */
91
92 BSheap_sorthl1(n_queue,sdo_queue_ptr,sdo_queue); CHKERR(0);
93
94 /* Construct sdo_deg_ptrs for sdo_queue */
95
96 max_sdo_deg = sdo_queue_ptr[0];
97 sdo_queue_ptr[0] = 0;
98 deg = max_sdo_deg;
99 for (i=1; i<n_queue; i++) {
100
101 while (sdo_queue_ptr[i] != deg) {
102 sdo_deg_ptr[deg] = i-1;
103 deg--;
104 }
105 sdo_queue_ptr[i] = 0;
106 }
107
108 sdo_deg_ptr[deg] = n_queue - 1;
109
110 /* Construct sdo_queue_ptrs */
111
112 for (i=0; i<n_queue; i++) {
113 l_vtx = sdo_queue[i];
114 sdo_queue_ptr[l_vtx] = i;
115 }
116
117 /* Main elimination loop */
118
119 for (i=0; i<n_queue; i++) {
120
121 l_vtx = sdo_queue[i];
122
123 t_node = local_col_array[l_vtx];
124 row_ptr = t_node->col;
125
126 /* Mark colors of adjacent global vertices */
127
128 for (j=0; j<global_ptr[l_vtx]; j++) {
129 t_color = global_color[l_vtx][j];
130 color_template[t_color] = l_vtx;
131 }
132
133 /* Mark colors of adjacent local vertices */
134 for (j=local_ptr[l_vtx]; j<t_node->length; j++) {
135 (*A->map->fglobal2local)
136 (1,&(row_ptr[j]),&adj_vertex,procinfo,A->map);CHKERR(0);
137 t_color = local_color[adj_vertex];
138 if (t_color == NO_COLOR) {
139 }
140 else {
141 color_template[t_color] = l_vtx;
142 }
143 }
144
145 /* Choose t_color */
146
147 t_color = 0;
148 while (color_template[t_color] == l_vtx) {
149 t_color++;
150 }
151
152 /* delete vertex from queue, update deg pointers */
153 while ((sdo_deg_ptr[max_sdo_deg] == i) && (max_sdo_deg > 0)) {
154 max_sdo_deg--;
155 }
156
157 /* Update adjacent vertices */
158 for (j=local_ptr[l_vtx]; j<t_node->length; j++) {
159 (*A->map->fglobal2local)
160 (1,&(row_ptr[j]),&adj_vertex,procinfo,A->map);CHKERR(0);
161 /* do not update chosen vertex */
162
163 if(l_vtx == adj_vertex) {
164 MY_SETERRC(COLOR1_ERROR,"Adjacent to self\n");
165 }
166
167 /* Update sat_degree of adjacent vertices if required */
168
169 else if ((in_group[adj_vertex] != -1) && (local_color[adj_vertex] == NO_COLOR)) {
170 update = TRUE;
171 adj_node = local_col_array[adj_vertex];
172 adj_row_ptr = adj_node->col;
173 k=0;
174 while ((k<global_ptr[adj_vertex])&&(update==TRUE)) {
175
176 /* if tmp_color here, no need to promote */
177
178 if(global_color[adj_vertex][k] == t_color) {
179 update = FALSE;
180 }
181 k++;
182 }
183 k=local_ptr[adj_vertex];
184 while ((k<adj_node->length)&&(update==TRUE)) {
185
186 /* if tmp_color new, promote adj_vertex in queue */
187
188 (*A->map->fglobal2local) (1,&(adj_row_ptr[k]),
189 &adj_adj_vertex,procinfo,A->map);CHKERR(0);
190 if(local_color[adj_adj_vertex] == t_color) {
191 update = FALSE;
192 }
193 k++;
194 }
195 if(update) {
196 sdo_degree[adj_vertex]++;
197
198 /* if sdo_degree > max_sdo_deg */
199
200 if (sdo_degree[adj_vertex] > max_sdo_deg) {
201 max_sdo_deg++;
202
203 if(max_sdo_deg != sdo_degree[adj_vertex]){
204 MY_SETERRC(COLOR1_ERROR,"Max degree wrong\n");
205 }
206 sdo_deg_ptr[max_sdo_deg] = i+1;
207 }
208 else {
209 sdo_deg_ptr[sdo_degree[adj_vertex]]++;
210 }
211
212 /* swap positions, if required */
213
214 if (sdo_queue_ptr[adj_vertex] !=
215 sdo_deg_ptr[sdo_degree[adj_vertex]])
216 {
217 tmp_ptr = sdo_deg_ptr[sdo_degree[adj_vertex]];
218 tmp_vertex = sdo_queue[tmp_ptr];
219 sdo_queue[sdo_queue_ptr[adj_vertex]] = tmp_vertex;
220 sdo_queue_ptr[tmp_vertex] = sdo_queue_ptr[adj_vertex];
221 sdo_queue[tmp_ptr] = adj_vertex;
222 sdo_queue_ptr[adj_vertex] = tmp_ptr;
223 }
224 }
225 /* End if(update) */
226 }
227 /* End Update sdo_degree */
228 }
229 /* End of update adjacent vertices, mark new color */
230
231 local_color[l_vtx] = t_color;
232 }
233 /* End of main elimination loop */
234
235 /* Clean up sdo_queue_ptr */
236
237 for (i=0; i < n_queue; i++)
238 {
239 l_vtx = sdo_queue[i];
240 sdo_queue_ptr[l_vtx] = 0;
241 }
242
243 MY_FREE(in_group);
244 }
245
246