OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
minpriority.c
Go to the documentation of this file.
1/*****************************************************************************
2/
3/ SPACE (SPArse Cholesky Elimination) Library: minpriority.c
4/
5/ author J"urgen Schulze, University of Paderborn
6/ created 01jan15
7/
8/ This file contains functions dealing with the minimum priority object
9/
10******************************************************************************
11
12Data type: struct minprior
13 gelim_t *Gelim; the elimination graph of G
14 multisector_t *ms; the multisector for G
15 bucket_t *bucket; holds unelim. vert. of actual stage
16 stageinfo_t *stageinfo; contains statistics for each stage
17 int *reachset; holds boundary vert. in each step
18 int nreach; number of vertices in reachset
19 int *auxaux; general purpose auxiliary vector
20 int *auxbin; special auxiliary vector
21 int *auxtmp; special auxiliary vector
22 int flag; flag for vector auxtmp (see below)
23 struct stageinfo
24 int nstep; # of elim. steps in each stage
25 int welim; weight of elim. vert. in each stage
26 int nzf; # of factor entries in each stage
27 FLOAT ops; # of factor ops. in each stage
28Comments:
29 o Structure used to compute a minimum priority ordering for a graph G
30 with multisector ms. The elimination process is organized in stages.
31 The stages are given by the multisector (i.e. ms->stage). The vertices
32 of a stage are eliminated in steps. In each elimination step a maximal
33 independent set of vertices with minimum priority is eliminated
34 o Structure does not own multisector object => it will not be freed
35 o Three auxiliary vectors can be used by functions working on minprior
36 IMPORTANT INVARIANTS for vectors auxbin, auxtmp
37 auxbin[i] = -1 holds at start and at end of each function
38 auxtmp[i] < flag holds at start and at end of each function
39Methods in lib/minpriority.c:
40- minprior = newMinPriority(int nvtx, int nstages);
41 o Initial: Gelim = ms = bucket = NULL,
42 nreach = 0, flag = 1;
43- void freeMinPriority(minprior_t *minprior);
44- minprior = setupMinPriority(multisector_t *ms);
45 o allocates memory for the minprior object by calling newMinPriority and
46 sets up the elimination graph by a call to setupElimGraph and the bucket
47 by a call to setupBucket; finally, it initializes the vectors, i.e.
48 auxbin[u] = -1, auxtmp[u] = 0 for all 0 <= u <= nvtx, and
49 nstep = welim = nzf = ops = 0 for all stages
50- T = orderMinPriority(minprior_t *minprior options_t *options,timings_t *cpus);
51 o MASTER_FUNCTION: computes a bottom-up ordering according to the specified
52 ordtype e { MINIMUM_PRIORITY, INCOMPLETE_ND, MULTISECTION,
53 TRISTAGE_MULTISECTION }
54 o used options:
55 OPTION_ORDTYPE, OPTION_NODE_SELECTION1, OPTION_NODE_SELECTION2
56 o returned timings: (see eliminateStage)
57 TIME_UPDSCORE, TIME_UPDADJNCY, TIME_FINDINODES
58- void eliminateStage(minprior_t *minprior, int istage, int scoretype,
59 timings_t *cpus);
60 o eliminates all principal variables u with stage[u] <= istage using
61 the score function given by scoretype
62 o returned timings:
63 TIME_UPDSCORE, TIME_UPDADJNCY, TIME_FINDINODES
64- int eliminateStep(minprior_t *minprior, int istage, int scoretype);
65 o the variables u with stage[u] <= istage are eliminated in steps;
66 in each step a maximal independet set of variables with minimum score
67 is eliminated
68 o the function returns the size of the independent set, i.e. the number
69 of variables that have been eliminated in the actual step
70
71******************************************************************************/
72
73#include <space.h>
74/* #define DEBUG */
75/* #define BE_CAUTIOUS */
76
77
78/*****************************************************************************
79******************************************************************************/
82{ minprior_t *minprior;
83 stageinfo_t *stageinfo;
84
85 mymalloc(stageinfo, nstages, stageinfo_t);
86 mymalloc(minprior, 1, minprior_t);
87 minprior->Gelim = NULL;
88 minprior->ms = NULL;
89 minprior->bucket = NULL;
90 minprior->stageinfo = stageinfo;
91
92 mymalloc(minprior->reachset, nvtx, PORD_INT);
93 mymalloc(minprior->auxaux, nvtx, PORD_INT);
94 mymalloc(minprior->auxbin, nvtx, PORD_INT);
95 mymalloc(minprior->auxtmp, nvtx, PORD_INT);
96
97 minprior->nreach = 0;
98 minprior->flag = 1;
99
100 return(minprior);
101}
102
103
104/*****************************************************************************
105******************************************************************************/
106void
108{
109 freeElimGraph(minprior->Gelim);
110 freeBucket(minprior->bucket);
111 free(minprior->stageinfo);
112 free(minprior->reachset);
113 free(minprior->auxaux);
114 free(minprior->auxbin);
115 free(minprior->auxtmp);
116 free(minprior);
117}
118
119
120/*****************************************************************************
121******************************************************************************/
124{ minprior_t *minprior;
125 stageinfo_t *stageinfo;
126 PORD_INT *auxbin, *auxtmp;
127 PORD_INT nvtx, nstages, istage, u;
128
129 nvtx = ms->G->nvtx;
130 nstages = ms->nstages;
131
132 minprior = newMinPriority(nvtx, nstages);
133 minprior->ms = ms;
134 minprior->Gelim = setupElimGraph(ms->G);
135 minprior->bucket = setupBucket(nvtx, nvtx, 0);
136
137 auxbin = minprior->auxbin;
138 auxtmp = minprior->auxtmp;
139 for (u = 0; u < nvtx; u++)
140 { auxbin[u] = -1;
141 auxtmp[u] = 0;
142 }
143
144 for (istage = 0; istage < nstages; istage++)
145 { stageinfo = minprior->stageinfo + istage;
146 stageinfo->nstep = 0;
147 stageinfo->welim = 0;
148 stageinfo->nzf = 0;
149 stageinfo->ops = 0.0;
150 }
151
152 return(minprior);
153}
154
155
156/*****************************************************************************
157******************************************************************************/
160{ elimtree_t *T;
161 PORD_INT nvtx, nstages, istage, scoretype, ordtype;
162
163 nvtx = minprior->Gelim->G->nvtx;
164 nstages = minprior->ms->nstages;
165
166 ordtype = options[OPTION_ORDTYPE];
167 scoretype = options[OPTION_NODE_SELECTION2];
168
169 /* ------------------------------
170 check whether nstages is valid
171 ------------------------------ */
172 if ((nstages < 1) || (nstages > nvtx))
173 { fprintf(stderr, "\nError in function orderMinPriority\n"
174 " no valid number of stages in multisector (#stages = %d)\n",
175 nstages);
176 quit();
177 }
178
179 if ((nstages < 2) && (ordtype != MINIMUM_PRIORITY))
180 { fprintf(stderr, "\nError in function orderMinPriority\n"
181 " not enough stages in multisector (#stages = %d)\n", nstages);
182 quit();
183 }
184
185 /* --------------------------------------------------------------
186 first stage: eliminate all vertices in the remaining subgraphs
187 -------------------------------------------------------------- */
188 scoretype = options[OPTION_NODE_SELECTION1];
189 eliminateStage(minprior, 0, scoretype, cpus);
190
191 /* -------------------------------------------------------
192 other stages: eliminate all vertices in the multisector
193 ------------------------------------------------------- */
194 switch(ordtype)
195 { case MINIMUM_PRIORITY:
196 break;
197 case INCOMPLETE_ND:
198 for (istage = 1; istage < nstages; istage++)
199 eliminateStage(minprior, istage, scoretype, cpus);
200 break;
201 case MULTISECTION:
202 eliminateStage(minprior, nstages-1, scoretype, cpus);
203 break;
204 default:
205 fprintf(stderr, "\nError in function orderMinPriority\n"
206 " unrecognized ordering type %d\n", ordtype);
207 quit();
208 }
209
210 /* -------------------------------------------
211 print statistics for the elimination stages
212 ------------------------------------------- */
213 if ((ordtype != MINIMUM_PRIORITY) && (options[OPTION_MSGLVL] > 1))
214 for (istage = 0; istage < nstages; istage++)
215 printf("%4d. stage: #steps %6d, weight %6d, nzl %8d, ops %e\n", istage,
216 minprior->stageinfo[istage].nstep,
217 minprior->stageinfo[istage].welim,
218 minprior->stageinfo[istage].nzf,
219 minprior->stageinfo[istage].ops);
220
221 /* -----------------------------------
222 extract elimination tree and return
223 ----------------------------------- */
224 T = extractElimTree(minprior->Gelim);
225 return(T);
226}
227
228
229/*****************************************************************************
230******************************************************************************/
231void
232eliminateStage(minprior_t *minprior, PORD_INT istage, PORD_INT scoretype, timings_t *cpus)
233{ gelim_t *Gelim;
234 bucket_t *bucket;
235 stageinfo_t *stageinfo;
236 PORD_INT *stage, *reachset, *auxbin, *auxtmp, *auxaux;
237 PORD_INT *degree, *score;
238 PORD_INT *pflag, nreach, nvtx, r, u, i;
239
240 Gelim = minprior->Gelim;
241 bucket = minprior->bucket;
242 stage = minprior->ms->stage;
243 stageinfo = minprior->stageinfo + istage;
244 reachset = minprior->reachset;
245 auxaux = minprior->auxaux;
246 auxbin = minprior->auxbin;
247 auxtmp = minprior->auxtmp;
248 pflag = &(minprior->flag);
249
250 nvtx = Gelim->G->nvtx;
251 degree = Gelim->degree;
252 score = Gelim->score;
253
254#ifdef DEBUG
255 printf("\nSTARTING NEW ELIMINATION STAGE (nedges %d, maxedges %d)\n\n",
256 Gelim->G->nedges, Gelim->maxedges);
257 if (istage> 0) printElimGraph(Gelim);
258 /* waitkey(); */
259#endif
260
261 /* -------------------------------------------------------------
262 load reachset with all principal variables in stage <= istage
263 ------------------------------------------------------------- */
264 nreach = 0;
265 for (u = 0; u < nvtx; u++)
266 if ((score[u] == -1) && (stage[u] <= istage))
267 { reachset[nreach++] = u;
268 score[u] = degree[u];
269 /* score[u] = degree[u]*(degree[u]-1)/2; */
270 }
271
272 /* ----------------------------------------------------------------
273 do an initial update of the vertices in reachset and fill bucket
274 ---------------------------------------------------------------- */
276 updateDegree(Gelim, reachset, nreach, auxbin);
277 updateScore(Gelim, reachset, nreach, scoretype, auxbin);
279 for (i = 0; i < nreach; i++)
280 { u = reachset[i];
281 insertBucket(bucket, score[u], u);
282 }
283
284 /* -------------------------------------
285 and now start the elimination process
286 ------------------------------------- */
287 while (TRUE)
288 { if (eliminateStep(minprior, istage, scoretype) == 0)
289 break;
290 nreach = minprior->nreach;
291
292#ifdef BE_CAUTIOUS
293 printf("checking arrays auxtmp and auxbin\n");
294 for (u = 0; u < nvtx; u++)
295 if ((auxtmp[u] >= *pflag) || (auxbin[u] != -1))
296 { printf("ERROR: flag = %d, auxtmp[%d] = %d, auxbin[%d] = %d\n",
297 *pflag, u, auxtmp[u], u, auxbin[u]);
298 quit();
299 }
300#endif
301
302 /* ----------------------------------------------------------
303 update the adjacency structure of all vertices in reachset
304 ---------------------------------------------------------- */
306 updateAdjncy(Gelim, reachset, nreach, auxtmp, pflag);
308
309 /* ----------------------------------------
310 find indistinguishable nodes in reachset
311 ---------------------------------------- */
313 findIndNodes(Gelim, reachset, nreach, auxbin, auxaux, auxtmp, pflag);
315
316#ifdef BE_CAUTIOUS
317 printf("checking arrays auxtmp and auxbin\n");
318 for (u = 0; u < nvtx; u++)
319 if ((auxtmp[u] >= *pflag) || (auxbin[u] != -1))
320 { printf("ERROR: flag = %d, auxtmp[%d] = %d, auxbin[%d] = %d\n",
321 *pflag, u, auxtmp[u], u, auxbin[u]);
322 quit();
323 }
324#endif
325
326 /* ----------------------------------------------------------------
327 clean reachset of nonprincipal nodes and nodes not in this stage
328 ---------------------------------------------------------------- */
329 r = 0;
330 for (i = 0; i < nreach; i++)
331 { u = reachset[i];
332 if (score[u] >= 0)
333 reachset[r++] = u;
334 }
335 nreach = r;
336
337 /* ---------------------------------------------------
338 update the degree/score of all vertices in reachset
339 --------------------------------------------------- */
341 updateDegree(Gelim, reachset, nreach, auxbin);
342 updateScore(Gelim, reachset, nreach, scoretype, auxbin);
344
345 /* ----------------------------
346 re-insert vertices in bucket
347 ---------------------------- */
348 for (i = 0; i < nreach; i++)
349 { u = reachset[i];
350 insertBucket(bucket, score[u], u);
351 }
352
353 stageinfo->nstep++;
354 }
355}
356
357
358/*****************************************************************************
359******************************************************************************/
361eliminateStep(minprior_t *minprior, PORD_INT istage, PORD_INT scoretype)
362{ gelim_t *Gelim;
363 bucket_t *bucket;
364 stageinfo_t *stageinfo;
365 PORD_INT *stage, *reachset, *auxtmp;
366 PORD_INT *xadj, *adjncy, *vwght, *len, *degree, *score;
367 PORD_INT *pflag, *pnreach, nelim, minscr, vwghtu, u, v, i, istart, istop;
368 FLOAT tri, rec;
369
370 Gelim = minprior->Gelim;
371 bucket = minprior->bucket;
372 stage = minprior->ms->stage;
373 stageinfo = minprior->stageinfo + istage;
374 reachset = minprior->reachset;
375 pnreach = &(minprior->nreach);
376 auxtmp = minprior->auxtmp;
377 pflag = &(minprior->flag);
378
379 xadj = Gelim->G->xadj;
380 adjncy = Gelim->G->adjncy;
381 vwght = Gelim->G->vwght;
382 len = Gelim->len;
383 degree = Gelim->degree;
384 score = Gelim->score;
385
386#ifdef DEBUG
387 printf("\nStarting new elimination step (nedges %d, maxedges %d)\n",
388 Gelim->G->nedges, Gelim->maxedges);
389 /* waitkey(); */
390#endif
391
392 /* ----------------------
393 check for empty bucket
394 ---------------------- */
395 if ((u = minBucket(bucket)) == -1)
396 return(0);
397 minscr = score[u];
398
399 /* ----------------------------------------
400 loop while nodes of minimum score remain
401 ---------------------------------------- */
402 nelim = 0;
403 *pnreach = 0;
404 while (TRUE)
405 { vwghtu = vwght[u];
406
407 /* --------------------------------------------------
408 increment welim and nelim and remove u from bucket
409 -------------------------------------------------- */
410 removeBucket(bucket, u);
411 stageinfo->welim += vwghtu;
412 nelim++;
413
414 /* -----------------------------------------------------------------
415 call buildElement to create element u and merge u's boundary with
416 the nodes in reachset; remove any vertex from bucket that belongs
417 to u's boundary and to the actual stage
418 ----------------------------------------------------------------- */
419 buildElement(Gelim, u);
420 istart = xadj[u];
421 istop = istart + len[u];
422 for (i = istart; i < istop; i++)
423 { v = adjncy[i]; /* v belongs to u's boundary */
424 if (auxtmp[v] < *pflag) /* v not yet in reachset */
425 { auxtmp[v] = *pflag;
426 if (stage[v] <= istage) /* v belongs to actual stage */
427 removeBucket(bucket, v);
428 reachset[(*pnreach)++] = v;
429 }
430 }
431
432#ifdef DEBUG
433 printf("Node %d (weight %d, score %d) eliminated: (boundary weight %d)\n",
434 u, vwghtu, minscr, degree[u]);
435 for (i = istart; i < istop; i++)
436 printf("%4d (degree %2d)", adjncy[i], degree[adjncy[i]]);
437 printf("\n");
438#endif
439
440 /* ---------------------------------------------------------------
441 increment the storage and operation counts for this elim. stage
442 --------------------------------------------------------------- */
443 tri = vwghtu;
444 rec = degree[u];
445 stageinfo->nzf += (PORD_INT)((tri * (tri+1)) / 2);
446 stageinfo->nzf += (PORD_INT)(tri * rec);
447 stageinfo->ops += (tri*tri*tri) / 3.0 + (tri*tri) / 2.0 - (5*tri) / 6.0;
448 stageinfo->ops += (tri*tri*rec) + (rec*(rec+1)*tri);
449
450 /* ---------------------------------------------------------------
451 end this elim. step, if one of the following conditions is true
452 (1) no multiple elimination
453 (2) bucket empty
454 (3) no further variable with minimum score
455 ---------------------------------------------------------------- */
456 if (scoretype / 10 == 0)
457 break;
458 if ((u = minBucket(bucket)) == -1)
459 break;
460 if (score[u] > minscr)
461 break;
462 }
463
464 /* -----------------------
465 clear auxtmp and return
466 ----------------------- */
467 (*pflag)++;
468 return(nelim);
469}
470
#define TRUE
Definition cblas_test.h:10
#define OPTION_NODE_SELECTION1
Definition const.h:79
#define MINIMUM_PRIORITY
Definition const.h:23
#define OPTION_ORDTYPE
Definition const.h:78
#define OPTION_MSGLVL
Definition const.h:83
#define TIME_UPDSCORE
Definition const.h:100
#define MULTISECTION
Definition const.h:25
#define OPTION_NODE_SELECTION2
Definition const.h:80
#define TIME_FINDINODES
Definition const.h:99
#define INCOMPLETE_ND
Definition const.h:24
#define TIME_UPDADJNCY
Definition const.h:98
#define pord_starttimer(var)
Definition macros.h:58
#define pord_stoptimer(var)
Definition macros.h:61
#define quit()
Definition macros.h:64
#define mymalloc(ptr, nr, type)
Definition macros.h:23
PORD_INT eliminateStep(minprior_t *minprior, PORD_INT istage, PORD_INT scoretype)
void freeMinPriority(minprior_t *minprior)
elimtree_t * orderMinPriority(minprior_t *minprior, options_t *options, timings_t *cpus)
minprior_t * setupMinPriority(multisector_t *ms)
minprior_t * newMinPriority(PORD_INT nvtx, PORD_INT nstages)
Definition minpriority.c:81
void eliminateStage(minprior_t *minprior, PORD_INT istage, PORD_INT scoretype, timings_t *cpus)
PORD_INT minBucket(bucket_t *)
Definition bucket.c:117
void findIndNodes(gelim_t *, PORD_INT *, PORD_INT, PORD_INT *, PORD_INT *, PORD_INT *, PORD_INT *)
Definition gelim.c:639
void insertBucket(bucket_t *, PORD_INT, PORD_INT)
Definition bucket.c:163
void freeElimGraph(gelim_t *)
Definition gelim.c:128
void printElimGraph(gelim_t *)
Definition gelim.c:143
void updateDegree(gelim_t *, PORD_INT *, PORD_INT, PORD_INT *)
Definition gelim.c:761
void freeBucket(bucket_t *)
Definition bucket.c:78
void updateAdjncy(gelim_t *, PORD_INT *, PORD_INT, PORD_INT *, PORD_INT *)
Definition gelim.c:495
void removeBucket(bucket_t *, PORD_INT)
Definition bucket.c:214
gelim_t * setupElimGraph(graph_t *)
Definition gelim.c:229
bucket_t * setupBucket(PORD_INT, PORD_INT, PORD_INT)
Definition bucket.c:91
elimtree_t * extractElimTree(gelim_t *)
Definition gelim.c:1012
void buildElement(gelim_t *Gelim, PORD_INT me)
Definition gelim.c:357
void updateScore(gelim_t *, PORD_INT *, PORD_INT, PORD_INT, PORD_INT *)
Definition gelim.c:890
PORD_INT maxedges
Definition types.h:102
graph_t * G
Definition types.h:101
PORD_INT * score
Definition types.h:107
PORD_INT * degree
Definition types.h:106
PORD_INT * len
Definition types.h:103
PORD_INT * xadj
Definition types.h:35
PORD_INT nedges
Definition types.h:32
PORD_INT nvtx
Definition types.h:31
PORD_INT * vwght
Definition types.h:37
PORD_INT * adjncy
Definition types.h:36
PORD_INT nreach
Definition types.h:134
PORD_INT * auxaux
Definition types.h:135
PORD_INT flag
Definition types.h:138
PORD_INT * auxbin
Definition types.h:136
gelim_t * Gelim
Definition types.h:129
PORD_INT * reachset
Definition types.h:133
stageinfo_t * stageinfo
Definition types.h:132
multisector_t * ms
Definition types.h:130
PORD_INT * auxtmp
Definition types.h:137
bucket_t * bucket
Definition types.h:131
graph_t * G
Definition types.h:90
PORD_INT * stage
Definition types.h:91
PORD_INT nstages
Definition types.h:92
PORD_INT nzf
Definition types.h:143
PORD_INT welim
Definition types.h:142
PORD_INT nstep
Definition types.h:141
FLOAT ops
Definition types.h:144
double FLOAT
Definition types.h:23
FLOAT timings_t
Definition types.h:25
#define PORD_INT
Definition types.h:20
struct _minprior minprior_t
struct _stageinfo stageinfo_t
Definition types.h:127
struct _multisector multisector_t
struct _elimtree elimtree_t
PORD_INT options_t
Definition types.h:24
struct _gelim gelim_t
struct _bucket bucket_t