OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
nestdiss.c
Go to the documentation of this file.
1/*****************************************************************************
2/
3/ SPACE (SPArse Cholesky Elimination) Library: nestdiss.c
4/
5/ author J"urgen Schulze, University of Paderborn
6/ created 00dec29
7/
8/ This file contains functions dealing with the rec. nested dissection object
9/
10******************************************************************************
11
12Data type: struct nestdiss
13 graph_t *G; pointer to original graph
14 int *map; maps nodes of G to constructed subgraph
15 int depth; depth in nested dissection tree
16 int nvint; number of vertices in subgraph
17 int *intvertex; internal vertices of subgraph
18 int *intcolor; color of vertices in intvertex
19 int cwght[3]; weights of bisection
20 struct nestdiss *parent; pointer to parent nd node
21 struct nestdiss *childB; pointer to black descendant nd node
22 struct nestdiss *childW; pointer to white descendand nd node
23Comments:
24 o Structure used to build the nested dissection tree. Vector intvertex
25 holds the vertices of the subgraph to be partitioned. Once a separator
26 has been computed, the coloring of vertex u = intvertex[i] is stored in
27 vector intcolor[i] and the partition weights are stored in cwght[GRAY],
28 cwght[BLACK], and cwght[WHITE].
29 o Structure does not own graph object G => it will not be freed
30 Note: G is the original graph
31 o Structure does not own map array => it will not be freed
32 Note: map is a "global" array that is used when constructing the subgraph
33 induced by the vertices in intvertex. The array maps the vertices
34 of the original graph G to the vertices of the subgraph.
35Methods in lib/nestdiss.c:
36- nd = newNDnode(graph_t *G, int *map, int nvint);
37 o Initial: depth = 0, cwght[GRAY] = cwght[BLACK] = cwght[WHITE] = 0,
38 and parent = childB = childW = NULL;
39- void freeNDnode(nestdiss_t *nd);
40- ndroot = setupNDroot(graph_t *G, int *map);
41 o sets up the root of the nested dissection tree; the function first
42 calls newNDnode to allocate memory for ndroot and, then, sets
43 intvertex[i] = i for all 0 <= i < G->nvtx
44- void splitNDnode(nestdiss_t *nd, options_t *options, timings_t *cpus);
45 o constructs the subgraph induced by nd->intvertex and computes a
46 bisection for it by calling constructSeparator and smoothSeparator.
47 Then, the nd object is splitted in a black one that holds the black
48 partition and a white one that holds the white partition.
49 o used options: (see constructSeparator and smoothSeparator)
50 OPTION_MSGLVL, OPTION_NODE_SELECTION3
51 o returned timings: (also see constructSeparator)
52 TIME_INITDOMDEC, TIME_COARSEDOMDEC, TIME_INITSEP, TIME_REFINESEP
53 TIME_MULTILEVEL, TIME_SMOOTH
54- void buildNDtree(nestdiss_t *ndroot, options_t *options, timings_t *cpus);
55 o builds the nested dissection tree under root ndroot, i.e. it applies
56 the nested dissection process to the (sub)graph induced by
57 ndroot->intvertex by iteratively calling function splitNDnode.
58 o used options: (also see splitNDnode)
59 OPTION_DOMAIN_SIZE, OPTION_MSGLVL, OPTION_NODE_SELECTION3
60 o returned timings: (see splitNDnode)
61 TIME_INITDOMDEC, TIME_COARSEDOMDEC, TIME_INITSEP, TIME_REFINESEP
62 TIME_MULTILEVEL, TIME_SMOOTH
63- void freeNDtree(nestdiss_t *ndroot);
64 o removes the nested dissection tree under root ndroot
65 Note: ndroot is not freed
66
67******************************************************************************/
68
69#include <space.h>
70
71
72/*****************************************************************************
73******************************************************************************/
76{ nestdiss_t *nd;
77
78 mymalloc(nd, 1, nestdiss_t);
79 mymalloc(nd->intvertex, nvint, PORD_INT);
80 mymalloc(nd->intcolor, nvint, PORD_INT);
81
82 nd->G = G;
83 nd->map = map;
84 nd->depth = 0;
85 nd->nvint = nvint;
86 nd->cwght[GRAY] = nd->cwght[BLACK] = nd->cwght[WHITE] = 0;
87 nd->parent = nd->childB = nd->childW = NULL;
88
89 return(nd);
90}
91
92
93/*****************************************************************************
94******************************************************************************/
95void
97{
98 free(nd->intvertex);
99 free(nd->intcolor);
100 free(nd);
101}
102
103
104/*****************************************************************************
105******************************************************************************/
108{ nestdiss_t *ndroot;
109 PORD_INT *intvertex, nvtx, i;
110
111 nvtx = G->nvtx;
112 ndroot = newNDnode(G, map, nvtx);
113 intvertex = ndroot->intvertex;
114
115 for (i = 0; i < nvtx; i++)
116 intvertex[i] = i;
117
118 return(ndroot);
119}
120
121
122/*****************************************************************************
123******************************************************************************/
124void
126{ nestdiss_t *b_nd, *w_nd;
127 graph_t *Gsub;
128 gbisect_t *Gbisect;
129 PORD_INT *map, *intvertex, *intcolor, *b_intvertex, *w_intvertex;
130 PORD_INT nvint, b_nvint, w_nvint, u, i;
131
132 map = nd->map;
133 nvint = nd->nvint;
134 intvertex = nd->intvertex;
135 intcolor = nd->intcolor;
136
137 /* -------------------------------------------------------------
138 extract the subgraph for which a bisection has to be computed
139 ------------------------------------------------------------- */
140 if (nd->G->nvtx == nd->nvint)
141 { Gsub = nd->G; /* a hack to save time and space */
142 for (u = 0; u < nd->nvint; u++) /* but do not forget the map vector */
143 map[u] = u;
144 }
145 else
146 Gsub = setupSubgraph(nd->G, intvertex, nvint, map);
147 Gbisect = newGbisect(Gsub);
148
149 /* ---------------------------------
150 compute the bisection for Gbisect
151 --------------------------------- */
153 constructSeparator(Gbisect, options, cpus);
155
157 if (Gbisect->cwght[GRAY] > 0)
158 smoothSeparator(Gbisect, options);
160
161 /* ----------------------------------------
162 copy the bisection back to the nd object
163 ---------------------------------------- */
164 b_nvint = w_nvint = 0;
165 nd->cwght[GRAY] = Gbisect->cwght[GRAY];
166 nd->cwght[BLACK] = Gbisect->cwght[BLACK];
167 nd->cwght[WHITE] = Gbisect->cwght[WHITE];
168 for (i = 0; i < nvint; i++)
169 { u = intvertex[i];
170 intcolor[i] = Gbisect->color[map[u]];
171 switch(intcolor[i])
172 { case GRAY: break;
173 case BLACK: b_nvint++; break;
174 case WHITE: w_nvint++; break;
175 default:
176 fprintf(stderr, "\nError in function splitNDnode\n"
177 " node %d has unrecognized color %d\n", u, intcolor[i]);
178 quit();
179 }
180 }
181
182 /* ------------------------------------------------------
183 and now split the nd object according to the bisection
184 ------------------------------------------------------ */
185 b_nd = newNDnode(nd->G, map, b_nvint);
186 b_intvertex = b_nd->intvertex;
187 w_nd = newNDnode(nd->G, map, w_nvint);
188 w_intvertex = w_nd->intvertex;
189
190 b_nvint = w_nvint = 0;
191 for (i = 0; i < nvint; i++)
192 { u = intvertex[i];
193 if (intcolor[i] == BLACK) b_intvertex[b_nvint++] = u;
194 if (intcolor[i] == WHITE) w_intvertex[w_nvint++] = u;
195 }
196 nd->childB = b_nd; b_nd->parent = nd;
197 nd->childW = w_nd; w_nd->parent = nd;
198 b_nd->depth = nd->depth + 1;
199 w_nd->depth = nd->depth + 1;
200
201 /* -----------------
202 free the subgraph
203 ----------------- */
204 if (Gsub != nd->G)
205 freeGraph(Gsub);
206 freeGbisect(Gbisect);
207}
208
209
210/*****************************************************************************
211******************************************************************************/
212void
213buildNDtree(nestdiss_t *ndroot, options_t *options, timings_t *cpus)
214{ nestdiss_t *nd;
215 nestdiss_t *queue[2*MAX_SEPS+1];
216 PORD_INT maxseps, seps, domainsize, qhead, qtail;
217
218 maxseps = MAX_SEPS;
219 domainsize = options[OPTION_DOMAIN_SIZE];
220 if (domainsize == 1) maxseps = DEFAULT_SEPS; /* secret switch */
221
222 /* --------------------------------------------------
223 build the nested dissection tree under root ndroot
224 -------------------------------------------------- */
225 queue[0] = ndroot;
226 qhead = 0; qtail = 1; seps = 0;
227 while ((qhead != qtail) && (seps < maxseps))
228 { seps++;
229 nd = queue[qhead++];
230
231 splitNDnode(nd, options, cpus);
232 if ((nd->childB == NULL) || (nd->childW == NULL))
233 { fprintf(stderr, "\nError in function buildNDtree\n"
234 " recursive nested dissection process failed\n");
235 quit();
236 }
237
238 if (options[OPTION_MSGLVL] > 1)
239 printf("%4d. S %6d, B %6d, W %6d [bal %4.2f, rel %6.4f, cost %7.2f]\n",
240 seps, nd->cwght[GRAY], nd->cwght[BLACK], nd->cwght[WHITE],
241 (FLOAT)min(nd->cwght[BLACK], nd->cwght[WHITE])
242 / max(nd->cwght[BLACK], nd->cwght[WHITE]),
243 (FLOAT)nd->cwght[GRAY]
244 / (nd->cwght[GRAY] + nd->cwght[BLACK] + nd->cwght[WHITE]),
245 F(nd->cwght[GRAY], nd->cwght[BLACK], nd->cwght[WHITE]));
246
247 if ((nd->childB->nvint > MIN_NODES)
248 && ((nd->cwght[BLACK] > domainsize) || (qtail < DEFAULT_SEPS)))
249 queue[qtail++] = nd->childB;
250 if ((nd->childW->nvint > MIN_NODES)
251 && ((nd->cwght[WHITE] > domainsize) || (qtail < DEFAULT_SEPS)))
252 queue[qtail++] = nd->childW;
253 }
254}
255
256
257/*****************************************************************************
258******************************************************************************/
259void
261{ nestdiss_t *nd, *parent;
262
263 /* ------------------------------------------------------
264 to remove the nested dissection tree under root ndroot
265 visit the nodes in post-order
266 ------------------------------------------------------ */
267 for (nd = ndroot; nd->childB != NULL; nd = nd->childB);
268 while (nd != ndroot)
269 { parent = nd->parent;
270 if ((parent == NULL) || (parent->childB == NULL)
271 || (parent->childW == NULL))
272 { fprintf(stderr, "\nError in function removeNDtree\n"
273 " nested dissection tree corrupted\n");
274 quit();
275 }
276 if (parent->childB == nd) /* left subtree of parent visited */
277 { freeNDnode(nd); /* free root of left subtree and goto right */
278 for (nd = parent->childW; nd->childB != NULL; nd = nd->childB);
279 }
280 else /* right subtree of parent visited */
281 { freeNDnode(nd); /* free root of right subtree and goto parent */
282 nd = parent;
283 }
284 }
285}
#define OPTION_MSGLVL
Definition const.h:83
#define TIME_SMOOTH
Definition const.h:96
#define OPTION_DOMAIN_SIZE
Definition const.h:82
#define TIME_MULTILEVEL
Definition const.h:91
#define BLACK
Definition const.h:63
#define WHITE
Definition const.h:64
#define GRAY
Definition const.h:62
#define F
Definition eval.h:12
#define pord_starttimer(var)
Definition macros.h:58
#define pord_stoptimer(var)
Definition macros.h:61
#define quit()
Definition macros.h:64
#define min(a, b)
Definition macros.h:20
#define mymalloc(ptr, nr, type)
Definition macros.h:23
#define max(a, b)
Definition macros.h:21
void freeNDtree(nestdiss_t *ndroot)
Definition nestdiss.c:260
void buildNDtree(nestdiss_t *ndroot, options_t *options, timings_t *cpus)
Definition nestdiss.c:213
void freeNDnode(nestdiss_t *nd)
Definition nestdiss.c:96
void splitNDnode(nestdiss_t *nd, options_t *options, timings_t *cpus)
Definition nestdiss.c:125
nestdiss_t * newNDnode(graph_t *G, PORD_INT *map, PORD_INT nvint)
Definition nestdiss.c:75
nestdiss_t * setupNDroot(graph_t *G, PORD_INT *map)
Definition nestdiss.c:107
#define MAX_SEPS
Definition params.h:17
#define MIN_NODES
Definition params.h:15
#define DEFAULT_SEPS
Definition params.h:16
void constructSeparator(gbisect_t *, options_t *, timings_t *)
Definition gbisect.c:182
graph_t * setupSubgraph(graph_t *, PORD_INT *, PORD_INT, PORD_INT *)
Definition graph.c:132
void freeGraph(graph_t *)
Definition graph.c:73
void smoothSeparator(gbisect_t *, options_t *)
Definition gbisect.c:443
gbisect_t * newGbisect(graph_t *)
Definition gbisect.c:59
void freeGbisect(gbisect_t *)
Definition gbisect.c:77
PORD_INT * color
Definition types.h:45
PORD_INT cwght[3]
Definition types.h:46
PORD_INT nvtx
Definition types.h:31
PORD_INT * intvertex
Definition types.h:80
PORD_INT * intcolor
Definition types.h:81
PORD_INT cwght[3]
Definition types.h:82
graph_t * G
Definition types.h:76
struct _nestdiss * parent
Definition types.h:83
struct _nestdiss * childB
Definition types.h:83
PORD_INT nvint
Definition types.h:79
PORD_INT depth
Definition types.h:78
PORD_INT * map
Definition types.h:77
struct _nestdiss * childW
Definition types.h:83
double FLOAT
Definition types.h:23
FLOAT timings_t
Definition types.h:25
#define PORD_INT
Definition types.h:20
struct _nestdiss nestdiss_t
struct _graph graph_t
PORD_INT options_t
Definition types.h:24
struct _gbisect gbisect_t