OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
protos.h File Reference

Go to the source code of this file.

Functions

PORD_INT greg_pord (PORD_INT, PORD_INT, PORD_INT *, PORD_INT *, PORD_INT *, PORD_INT *, PORD_INT *)
graph_tnewGraph (PORD_INT, PORD_INT)
void freeGraph (graph_t *)
void printGraph (graph_t *)
void randomizeGraph (graph_t *)
graph_tsetupSubgraph (graph_t *, PORD_INT *, PORD_INT, PORD_INT *)
graph_tsetupGraphFromMtx (inputMtx_t *)
graph_tsetupGridGraph (PORD_INT, PORD_INT, PORD_INT)
PORD_INT connectedComponents (graph_t *)
graph_tcompressGraph (graph_t *, PORD_INT *)
gbisect_tnewGbisect (graph_t *)
void freeGbisect (gbisect_t *)
void printGbisect (gbisect_t *)
void checkSeparator (gbisect_t *)
void constructSeparator (gbisect_t *, options_t *, timings_t *)
PORD_INT smoothBy2Layers (gbisect_t *, PORD_INT *, PORD_INT *, PORD_INT, PORD_INT)
void smoothSeparator (gbisect_t *, options_t *)
domdec_tnewDomainDecomposition (PORD_INT, PORD_INT)
void freeDomainDecomposition (domdec_t *)
void printDomainDecomposition (domdec_t *)
void checkDomainDecomposition (domdec_t *)
void buildInitialDomains (graph_t *, PORD_INT *, PORD_INT *, PORD_INT *)
void mergeMultisecs (graph_t *G, PORD_INT *, PORD_INT *)
domdec_tinitialDomainDecomposition (graph_t *, PORD_INT *, PORD_INT *, PORD_INT *)
domdec_tconstructDomainDecomposition (graph_t *, PORD_INT *)
void computePriorities (domdec_t *, PORD_INT *, PORD_INT *, PORD_INT)
void eliminateMultisecs (domdec_t *, PORD_INT *, PORD_INT *)
void findIndMultisecs (domdec_t *, PORD_INT *, PORD_INT *)
domdec_tcoarserDomainDecomposition (domdec_t *, PORD_INT *)
void shrinkDomainDecomposition (domdec_t *, PORD_INT)
void checkDDSep (domdec_t *)
PORD_INT findPseudoPeripheralDomain (domdec_t *, PORD_INT)
void constructLevelSep (domdec_t *, PORD_INT)
void initialDDSep (domdec_t *)
void updateB2W (bucket_t *, bucket_t *, domdec_t *, PORD_INT, PORD_INT *, PORD_INT *, PORD_INT *, PORD_INT *)
void updateW2B (bucket_t *, bucket_t *, domdec_t *, PORD_INT, PORD_INT *, PORD_INT *, PORD_INT *, PORD_INT *)
void improveDDSep (domdec_t *)
gbipart_tnewBipartiteGraph (PORD_INT, PORD_INT, PORD_INT)
void freeBipartiteGraph (gbipart_t *)
void printGbipart (gbipart_t *)
gbipart_tsetupBipartiteGraph (graph_t *, PORD_INT *, PORD_INT, PORD_INT, PORD_INT *)
void maximumMatching (gbipart_t *, PORD_INT *)
void maximumFlow (gbipart_t *, PORD_INT *, PORD_INT *)
void DMviaMatching (gbipart_t *, PORD_INT *, PORD_INT *, PORD_INT *)
void DMviaFlow (gbipart_t *, PORD_INT *, PORD_INT *, PORD_INT *, PORD_INT *)
nestdiss_tnewNDnode (graph_t *, PORD_INT *, PORD_INT)
void freeNDnode (nestdiss_t *)
nestdiss_tsetupNDroot (graph_t *, PORD_INT *)
void splitNDnode (nestdiss_t *, options_t *, timings_t *)
void buildNDtree (nestdiss_t *, options_t *, timings_t *)
void freeNDtree (nestdiss_t *)
multisector_tnewMultisector (graph_t *)
void freeMultisector (multisector_t *)
multisector_ttrivialMultisector (graph_t *)
multisector_tconstructMultisector (graph_t *, options_t *, timings_t *)
multisector_textractMS2stage (nestdiss_t *)
multisector_textractMSmultistage (nestdiss_t *)
gelim_tnewElimGraph (PORD_INT, PORD_INT)
void freeElimGraph (gelim_t *)
void printElimGraph (gelim_t *)
gelim_tsetupElimGraph (graph_t *)
PORD_INT crunchElimGraph (gelim_t *)
void buildElement (gelim_t *Gelim, PORD_INT me)
void updateAdjncy (gelim_t *, PORD_INT *, PORD_INT, PORD_INT *, PORD_INT *)
void findIndNodes (gelim_t *, PORD_INT *, PORD_INT, PORD_INT *, PORD_INT *, PORD_INT *, PORD_INT *)
void updateDegree (gelim_t *, PORD_INT *, PORD_INT, PORD_INT *)
void updateScore (gelim_t *, PORD_INT *, PORD_INT, PORD_INT, PORD_INT *)
elimtree_textractElimTree (gelim_t *)
bucket_tnewBucket (PORD_INT, PORD_INT, PORD_INT)
void freeBucket (bucket_t *)
bucket_tsetupBucket (PORD_INT, PORD_INT, PORD_INT)
PORD_INT minBucket (bucket_t *)
void insertBucket (bucket_t *, PORD_INT, PORD_INT)
void removeBucket (bucket_t *, PORD_INT)
minprior_tnewMinPriority (PORD_INT nvtx, PORD_INT nstages)
void freeMinPriority (minprior_t *)
minprior_tsetupMinPriority (multisector_t *)
elimtree_torderMinPriority (minprior_t *, options_t *, timings_t *)
void eliminateStage (minprior_t *, PORD_INT, PORD_INT, timings_t *)
PORD_INT eliminateStep (minprior_t *, PORD_INT, PORD_INT)
elimtree_tnewElimTree (PORD_INT, PORD_INT)
void freeElimTree (elimtree_t *)
void printElimTree (elimtree_t *)
PORD_INT firstPostorder (elimtree_t *)
PORD_INT firstPostorder2 (elimtree_t *, PORD_INT)
PORD_INT nextPostorder (elimtree_t *, PORD_INT)
PORD_INT firstPreorder (elimtree_t *)
PORD_INT nextPreorder (elimtree_t *, PORD_INT)
elimtree_tsetupElimTree (graph_t *, PORD_INT *, PORD_INT *)
void initFchSilbRoot (elimtree_t *)
void permFromElimTree (elimtree_t *, PORD_INT *)
elimtree_texpandElimTree (elimtree_t *, PORD_INT *, PORD_INT)
elimtree_tpermuteElimTree (elimtree_t *, PORD_INT *)
elimtree_tfundamentalFronts (elimtree_t *)
elimtree_tmergeFronts (elimtree_t *, PORD_INT)
elimtree_tcompressElimTree (elimtree_t *, PORD_INT *, PORD_INT)
PORD_INT justifyFronts (elimtree_t *)
PORD_INT nWorkspace (elimtree_t *)
PORD_INT nFactorIndices (elimtree_t *)
PORD_INT nFactorEntries (elimtree_t *)
FLOAT nFactorOps (elimtree_t *)
void subtreeFactorOps (elimtree_t *, FLOAT *)
FLOAT nTriangularOps (elimtree_t *)
inputMtx_tnewInputMtx (PORD_INT, PORD_INT)
void freeInputMtx (inputMtx_t *)
void printInputMtx (inputMtx_t *)
denseMtx_tnewDenseMtx (workspace_t *, PORD_INT)
void freeDenseMtx (denseMtx_t *)
void printDenseMtx (denseMtx_t *)
void checkDenseMtx (denseMtx_t *)
workspace_tinitWorkspaceForDenseMtx (PORD_INT, PORD_INT)
FLOATgetWorkspaceForDenseMtx (workspace_t *, PORD_INT)
void freeWorkspaceForDenseMtx (workspace_t *)
inputMtx_tsetupInputMtxFromGraph (graph_t *)
inputMtx_tsetupLaplaceMtx (PORD_INT, PORD_INT, PORD_INT)
inputMtx_tpermuteInputMtx (inputMtx_t *, PORD_INT *)
css_tnewCSS (PORD_INT, PORD_INT, PORD_INT)
void freeCSS (css_t *)
css_tsetupCSSFromGraph (graph_t *, PORD_INT *, PORD_INT *)
css_tsetupCSSFromFrontSubscripts (frontsub_t *)
frontsub_tnewFrontSubscripts (elimtree_t *)
void freeFrontSubscripts (frontsub_t *)
void printFrontSubscripts (frontsub_t *)
frontsub_tsetupFrontSubscripts (elimtree_t *, inputMtx_t *)
factorMtx_tnewFactorMtx (PORD_INT)
void freeFactorMtx (factorMtx_t *)
void printFactorMtx (factorMtx_t *)
void initFactorMtx (factorMtx_t *L, inputMtx_t *)
void initFactorMtxNEW (factorMtx_t *L, inputMtx_t *)
void numfac (factorMtx_t *L, timings_t *cpus)
denseMtx_tsetupFrontalMtx (workspace_t *, factorMtx_t *, PORD_INT)
void initLocalIndices (denseMtx_t *, PORD_INT *, PORD_INT *)
denseMtx_textendedAdd (denseMtx_t *, denseMtx_t *, PORD_INT *, PORD_INT *)
denseMtx_tsetupUpdateMtxFromFrontalMtx (denseMtx_t *, factorMtx_t *)
denseMtx_tfactorize1x1Kernel (denseMtx_t *, PORD_INT)
denseMtx_tfactorize2x2Kernel (denseMtx_t *, PORD_INT)
denseMtx_tfactorize3x3Kernel (denseMtx_t *, PORD_INT)
void forwardSubst1x1 (factorMtx_t *, FLOAT *)
void backwardSubst1x1 (factorMtx_t *, FLOAT *)
void forwardSubst1x1NEW (factorMtx_t *, FLOAT *)
void backwardSubst1x1NEW (factorMtx_t *, FLOAT *)
mapping_tnewMapping (elimtree_t *, PORD_INT)
void freeMapping (mapping_t *)
void printMapping (mapping_t *)
void listing (mapping_t *, PORD_INT, PORD_INT, PORD_INT, FLOAT *, FLOAT *)
mapping_tsetupMapping (elimtree_t *, PORD_INT, PORD_INT)
void split (mapping_t *, PORD_INT, PORD_INT, PORD_INT, PORD_INT *, PORD_INT *, FLOAT *, PORD_INT)
elimtree_tSPACE_ordering (graph_t *, options_t *, timings_t *)
elimtree_tSPACE_transformElimTree (elimtree_t *, PORD_INT)
factorMtx_tSPACE_symbFac (elimtree_t *, inputMtx_t *)
void SPACE_numFac (factorMtx_t *, timings_t *)
void SPACE_solveTriangular (factorMtx_t *L, FLOAT *rhs, FLOAT *xvec)
void SPACE_solve (inputMtx_t *, FLOAT *, FLOAT *, options_t *, timings_t *)
void SPACE_solveWithPerm (inputMtx_t *, PORD_INT *, FLOAT *, FLOAT *, options_t *, timings_t *)
mapping_tSPACE_mapping (graph_t *, PORD_INT *, options_t *, timings_t *)
void insertUpInts (PORD_INT, PORD_INT *)
void insertUpIntsWithStaticIntKeys (PORD_INT, PORD_INT *, PORD_INT *)
void insertDownIntsWithStaticFloatKeys (PORD_INT, PORD_INT *, FLOAT *)
void insertUpFloatsWithIntKeys (PORD_INT, FLOAT *, PORD_INT *)
void qsortUpInts (PORD_INT, PORD_INT *, PORD_INT *)
void qsortUpFloatsWithIntKeys (PORD_INT, FLOAT *, PORD_INT *, PORD_INT *)
void distributionCounting (PORD_INT, PORD_INT *, PORD_INT *)
graph_treadChacoGraph (char *)
inputMtx_treadHarwellBoeingMtx (char *)
topology_tnewTopology (PORD_INT)
void freeTopology (topology_t *)
void printTopology (topology_t *)
topology_tsetupTopology (void)
void recMapCube (topology_t *, PORD_INT, PORD_INT, PORD_INT, PORD_INT, PORD_INT, PORD_INT)
void sendCube (topology_t *, void *, size_t, PORD_INT)
size_t recvCube (topology_t *, void *, size_t, PORD_INT)
PORD_INT myrank (void)
mask_tnewMask (PORD_INT)
void freeMask (mask_t *)
mask_tsetupMask (PORD_INT, PORD_INT, PORD_INT)
void broadcastInputMtx (topology_t *, inputMtx_t **)
void broadcastElimTree (topology_t *, elimtree_t **)
void broadcastArray (topology_t *, char *, size_t)
buffer_tnewBuffer (size_t)
void freeBuffer (buffer_t *)
buffer_texchangeBuffer (topology_t *, buffer_t *, PORD_INT)
buffer_tsetupSymbFacBuffer (frontsub_t *, PORD_INT *)
void readoutSymbFacBuffer (buffer_t *, frontsub_t *, PORD_INT *)
buffer_tsetupNumFacBuffer (workspace_t *, mask_t *, PORD_INT)
void readoutNumFacBuffer (workspace_t *, buffer_t *, denseMtx_t **)
buffer_tsetupTriangularBuffer (frontsub_t *, PORD_INT *, FLOAT *)
void readoutTriangularBuffer (buffer_t *, frontsub_t *, PORD_INT *, FLOAT *)
frontsub_tnewFrontSubscriptsPAR (mask_t *, mapping_t *, elimtree_t *)
frontsub_tsetupFrontSubscriptsPAR (topology_t *, mask_t *, mapping_t *, elimtree_t *, inputMtx_t *)
css_tsetupCSSFromFrontSubscriptsPAR (mask_t *, mapping_t *, frontsub_t *)
void initFactorMtxPAR (mask_t *, mapping_t *, factorMtx_t *, inputMtx_t *)
void numfacPAR (topology_t *, mask_t *, mapping_t *, factorMtx_t *, PORD_INT msglvl, timings_t *)
denseMtx_tsetupFrontalMtxPAR (mask_t *, PORD_INT, workspace_t *, factorMtx_t *, PORD_INT)
void initLocalIndicesPAR (denseMtx_t *, PORD_INT *, PORD_INT *)
denseMtx_textendedAddPAR (denseMtx_t *, denseMtx_t *, PORD_INT *, PORD_INT *)
denseMtx_tsetupUpdateMtxFromFrontalMtxPAR (denseMtx_t *, factorMtx_t *)
denseMtx_tsetupUpdateMtxFromBuffer (workspace_t *, FLOAT *)
void splitDenseMtxColumnWise (denseMtx_t *, mask_t *, buffer_t *, PORD_INT)
void splitDenseMtxRowWise (denseMtx_t *, mask_t *, buffer_t *, PORD_INT)
denseMtx_tfactorize1x1KernelPAR (topology_t *, mask_t *, PORD_INT, denseMtx_t *, frontsub_t *, timings_t *)
denseMtx_tfactorize2x2KernelPAR (topology_t *, mask_t *, PORD_INT, denseMtx_t *, frontsub_t *, timings_t *)
denseMtx_tfactorize3x3KernelPAR (topology_t *, mask_t *, PORD_INT, denseMtx_t *, frontsub_t *, timings_t *)
void forwardSubst1x1PAR (topology_t *, mask_t *, mapping_t *, factorMtx_t *, FLOAT *, FLOAT *)
void backwardSubst1x1PAR (topology_t *, mask_t *, mapping_t *, factorMtx_t *, FLOAT *)
void forwardSubst1x1KernelPAR (topology_t *, mask_t *, PORD_INT, PORD_INT, factorMtx_t *, FLOAT *, FLOAT *)
void backwardSubst1x1KernelPAR (topology_t *, mask_t *, PORD_INT, PORD_INT, factorMtx_t *, FLOAT *)
void accumulateVector (topology_t *, mask_t *, mapping_t *, factorMtx_t *, FLOAT *)
topology_tSPACE_setupTopology (void)
mask_tSPACE_setupMask (topology_t *, PORD_INT)
void SPACE_cleanup (topology_t *, mask_t *)
factorMtx_tSPACE_symbFacPAR (topology_t *, mask_t *, mapping_t *, elimtree_t *, inputMtx_t *)
void SPACE_numFacPAR (topology_t *, mask_t *, mapping_t *, factorMtx_t *, PORD_INT msglvl, timings_t *)
void SPACE_solveTriangularPAR (topology_t *, mask_t *, mapping_t *, factorMtx_t *, FLOAT *, FLOAT *)
void SPACE_solveWithPermPAR (topology_t *top, mask_t *mask, inputMtx_t *A, PORD_INT *perm, FLOAT *rhs, FLOAT *xvec, options_t *options, timings_t *cpus)

Function Documentation

◆ accumulateVector()

void accumulateVector ( topology_t * ,
mask_t * ,
mapping_t * ,
factorMtx_t * ,
FLOAT *  )

◆ backwardSubst1x1()

void backwardSubst1x1 ( factorMtx_t * ,
FLOAT *  )

◆ backwardSubst1x1KernelPAR()

void backwardSubst1x1KernelPAR ( topology_t * ,
mask_t * ,
PORD_INT ,
PORD_INT ,
factorMtx_t * ,
FLOAT *  )

◆ backwardSubst1x1NEW()

void backwardSubst1x1NEW ( factorMtx_t * ,
FLOAT *  )

◆ backwardSubst1x1PAR()

void backwardSubst1x1PAR ( topology_t * ,
mask_t * ,
mapping_t * ,
factorMtx_t * ,
FLOAT *  )

◆ broadcastArray()

void broadcastArray ( topology_t * ,
char * ,
size_t  )

◆ broadcastElimTree()

void broadcastElimTree ( topology_t * ,
elimtree_t **  )

◆ broadcastInputMtx()

void broadcastInputMtx ( topology_t * ,
inputMtx_t **  )

◆ buildElement()

void buildElement ( gelim_t * Gelim,
PORD_INT me )

Definition at line 357 of file gelim.c.

358{ graph_t *G;
359 PORD_INT *xadj, *adjncy, *vwght, *len, *elen, *parent, *degree, *score;
360 PORD_INT degme, elenme, vlenme, mesrcptr, medeststart, medeststart2;
361 PORD_INT medestptr, ln, p, i, j, v, e;
362
363 G = Gelim->G;
364 xadj = G->xadj;
365 adjncy = G->adjncy;
366 vwght = G->vwght;
367 len = Gelim->len;
368 elen = Gelim->elen;
369 parent = Gelim->parent;
370 degree = Gelim->degree;
371 score = Gelim->score;
372
373 /* ---------------------------------
374 construct boundary of element Lme
375 --------------------------------- */
376 degme = 0;
377 G->totvwght -= vwght[me]; /* me eliminated => reduce weight of Gelim */
378 vwght[me] = -vwght[me];
379 score[me] = -3; /* variable me becomes an element */
380
381 elenme = elen[me];
382 vlenme = len[me] - elenme;
383 mesrcptr = xadj[me];
384
385 /* -----------------------------------------------------------
386 if me is a leaf => its boundary can be constructed in-place
387 ----------------------------------------------------------- */
388 if (elenme == 0)
389 { medeststart = xadj[me]; /* Lme overwrites old variable */
390 medestptr = medeststart; /* boundary of Lme starts here */
391 for (i = 0; i < vlenme; i++)
392 { v = adjncy[mesrcptr++];
393 if (vwght[v] > 0) /* v not yet placed in boundary */
394 { degme += vwght[v]; /* increase size of Lme */
395 vwght[v] = -vwght[v]; /* flag v as being in Lme */
396 adjncy[medestptr++] = v;
397 }
398 }
399 }
400
401 /* -------------------------------------------------------------------
402 me is not a leaf => its boundary must be constructed in empty space
403 ------------------------------------------------------------------- */
404 else
405 { medeststart = G->nedges; /* Lme appended to graph */
406 medestptr = medeststart; /* boundary of Lme starts here */
407 for (i = 0; i <= elenme; i++)
408 { if (i < elenme) /* working on elements */
409 { len[me]--;
410 e = adjncy[mesrcptr++]; /* merge boundary of element e with Lme */
411 p = xadj[e]; /* adjacency list of e starts here */
412 ln = len[e];
413 }
414 else
415 { e = me; /* merge uncovered variables with Lme */
416 p = mesrcptr; /* variables start here */
417 ln = vlenme;
418 }
419 for (j = 0; j < ln; j++)
420 { len[e]--; /* pick next variable, decrease length */
421 v = adjncy[p++];
422 if (vwght[v] > 0)
423 { degme += vwght[v]; /* increase size of Lme */
424 vwght[v] = -vwght[v]; /* flag v as being in Lme */
425
426 /* ------------------------------------------
427 add v to Lme, compress adjncy if necessary
428 ------------------------------------------ */
429 if (medestptr == Gelim->maxedges)
430 { if (len[me] == 0) xadj[me] = -1;
431 else xadj[me] = mesrcptr;
432 if (len[e] == 0) xadj[e] = -1;
433 else xadj[e] = p;
434
435 /* crunch adjacency list -- !!!we need more memory!!! */
436 if (!crunchElimGraph(Gelim))
437 { fprintf(stderr, "\nError in function buildElement\n"
438 " unable to construct element (not enough memory)\n");
439 quit();
440 }
441
442 /* crunch partially constructed element me */
443 medeststart2 = G->nedges;
444 for (p = medeststart; p < medestptr; p++)
445 adjncy[G->nedges++] = adjncy[p];
446 medeststart = medeststart2;
447 medestptr = G->nedges;
448
449 mesrcptr = xadj[me];
450 p = xadj[e];
451 }
452 adjncy[medestptr++] = v;
453 }
454 }
455
456 /* ----------------------
457 mark absorbed elements
458 ---------------------- */
459 if (e != me)
460 { xadj[e] = -1;
461 parent[e] = me;
462 score[e] = -4;
463 }
464 }
465
466 G->nedges = medestptr; /* new element Lme ends here */
467 }
468
469 /* -----------------------------------
470 element me successfully constructed
471 ----------------------------------- */
472 degree[me] = degme;
473 xadj[me] = medeststart;
474 vwght[me] = -vwght[me];
475 elen[me] = 0;
476 len[me] = medestptr - medeststart;
477 if (len[me] == 0)
478 xadj[me] = -1;
479
480 /* ---------------------------
481 unmark all variables in Lme
482 --------------------------- */
483 mesrcptr = xadj[me];
484 vlenme = len[me];
485 for (i = 0; i < vlenme; i++)
486 { v = adjncy[mesrcptr++];
487 vwght[v] = -vwght[v];
488 }
489}
PORD_INT crunchElimGraph(gelim_t *Gelim)
Definition gelim.c:302
#define quit()
Definition macros.h:64
integer, dimension(:), allocatable, save score
PORD_INT * parent
Definition types.h:105
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 * elen
Definition types.h:104
PORD_INT totvwght
Definition types.h:34
PORD_INT * xadj
Definition types.h:35
PORD_INT nedges
Definition types.h:32
PORD_INT * vwght
Definition types.h:37
PORD_INT * adjncy
Definition types.h:36
#define PORD_INT
Definition types.h:20
struct _graph graph_t

◆ buildInitialDomains()

void buildInitialDomains ( graph_t * G,
PORD_INT * vtxlist,
PORD_INT * vtype,
PORD_INT * rep )

Definition at line 224 of file ddcreate.c.

225{ PORD_INT *xadj, *adjncy;
226 PORD_INT nvtx, u, v, w, i, j, jstart, jstop;
227
228 xadj = G->xadj;
229 adjncy = G->adjncy;
230 nvtx = G->nvtx;
231
232 /* --------------------------------------------------------------------
233 determine initial domains according to the order of nodes in vtxlist
234 -------------------------------------------------------------------- */
235 for (i = 0; i < nvtx; i++)
236 { u = vtxlist[i];
237 if (vtype[u] == 0)
238 { vtype[u] = 1;
239 jstart = xadj[u];
240 jstop = xadj[u+1];
241 for (j = jstart; j < jstop; j++)
242 { v = adjncy[j];
243 vtype[v] = 2;
244 }
245 }
246 }
247
248 /* ------------------------------------------------------------
249 eliminate all multisecs that are adjacent to only one domain
250 ------------------------------------------------------------ */
251 for (i = 0; i < nvtx; i++)
252 { u = vtxlist[i];
253 if (vtype[u] == 2)
254 { v = -1;
255 jstart = xadj[u];
256 jstop = xadj[u+1];
257 for (j = jstart; j < jstop; j++)
258 { w = adjncy[j];
259 if (vtype[w] == 1)
260 { if (v == -1)
261 v = rep[w]; /* u adjacent to domain v = rep[w] */
262 else if (v != rep[w])
263 { v = -1; /* u adjacent to another domain */
264 break;
265 }
266 }
267 }
268 if (v != -1) /* u absorbed by domain v */
269 { vtype[u] = 1;
270 rep[u] = v;
271 }
272 }
273 }
274}
PORD_INT nvtx
Definition types.h:31

◆ buildNDtree()

void buildNDtree ( nestdiss_t * ndroot,
options_t * options,
timings_t * cpus )

Definition at line 213 of file nestdiss.c.

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}
#define OPTION_MSGLVL
Definition const.h:83
#define OPTION_DOMAIN_SIZE
Definition const.h:82
#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 min(a, b)
Definition macros.h:20
#define max(a, b)
Definition macros.h:21
real(sp), parameter seps
void splitNDnode(nestdiss_t *nd, options_t *options, timings_t *cpus)
Definition nestdiss.c:125
#define MAX_SEPS
Definition params.h:17
#define MIN_NODES
Definition params.h:15
#define DEFAULT_SEPS
Definition params.h:16
PORD_INT cwght[3]
Definition types.h:82
struct _nestdiss * childB
Definition types.h:83
PORD_INT nvint
Definition types.h:79
struct _nestdiss * childW
Definition types.h:83
double FLOAT
Definition types.h:23
struct _nestdiss nestdiss_t

◆ checkDDSep()

void checkDDSep ( domdec_t * dd)

Definition at line 68 of file ddbisect.c.

69{ PORD_INT *xadj, *adjncy, *vwght, *vtype, *color, *cwght;
70 PORD_INT nvtx, err, u, v, i, istart, istop, nBdom, nWdom;
71 PORD_INT checkS, checkB, checkW;
72
73 nvtx = dd->G->nvtx;
74 xadj = dd->G->xadj;
75 adjncy = dd->G->adjncy;
76 vwght = dd->G->vwght;
77 vtype = dd->vtype;
78 color = dd->color;
79 cwght = dd->cwght;
80
81 err = FALSE;
82 printf("checking separator of domain decomposition (S %d, B %d, W %d)\n",
83 cwght[GRAY], cwght[BLACK], cwght[WHITE]);
84
85 checkS = checkB = checkW = 0;
86 for (u = 0; u < nvtx; u++)
87 /* check neighborhood of multisector nodes */
88 if (vtype[u] == 2)
89 { nBdom = nWdom = 0;
90 istart = xadj[u];
91 istop = xadj[u+1];
92 for (i = istart; i < istop; i++)
93 { v = adjncy[i];
94 if (color[v] == BLACK) nBdom++;
95 if (color[v] == WHITE) nWdom++;
96 }
97 switch(color[u])
98 { case GRAY:
99 checkS += vwght[u];
100 if ((nBdom == 0) || (nWdom == 0))
101 printf("WARNING: multisec %d belongs to S, but nBdom = %d and "
102 "nWdom = %d\n", u, nBdom, nWdom);
103 break;
104 case BLACK:
105 checkB += vwght[u];
106 if (nWdom > 0)
107 { printf("ERROR: black multisec %d adjacent to white domain\n", u);
108 err = TRUE;
109 }
110 break;
111 case WHITE:
112 checkW += vwght[u];
113 if (nBdom > 0)
114 { printf("ERROR: white multisec %d adjacent to black domain\n", u);
115 err = TRUE;
116 }
117 break;
118 default:
119 printf("ERROR: multisec %d has unrecognized color %d\n", u,
120 color[u]);
121 err = TRUE;
122 }
123 }
124
125 /* sum up size of white/black domains */
126 else /* if (vtype[u] == 1) */
127 switch(color[u])
128 { case BLACK:
129 checkB += vwght[u]; break;
130 case WHITE:
131 checkW += vwght[u]; break;
132 default:
133 printf("ERROR: domain %d has unrecognized color %d\n", u, color[u]);
134 err = TRUE;
135 }
136
137 /* check cwght[GRAY], cwght[BLACK], cwght[WHITE] */
138 if ((checkS != cwght[GRAY]) || (checkB != cwght[BLACK])
139 || (checkW != cwght[WHITE]))
140 { printf("ERROR in partitioning: checkS %d (S %d), checkB %d (B %d), "
141 "checkW %d (W %d)\n", checkS, cwght[GRAY], checkB, cwght[BLACK],
142 checkW, cwght[WHITE]);
143 err = TRUE;
144 }
145 if (err) quit();
146}
#define TRUE
Definition cblas_test.h:10
#define FALSE
Definition cblas_test.h:14
PORD_INT * vtype
Definition types.h:56
PORD_INT cwght[3]
Definition types.h:58
PORD_INT * color
Definition types.h:57
graph_t * G
Definition types.h:53

◆ checkDenseMtx()

void checkDenseMtx ( denseMtx_t * )

◆ checkDomainDecomposition()

void checkDomainDecomposition ( domdec_t * dd)

Definition at line 163 of file ddcreate.c.

164{ PORD_INT *xadj, *adjncy, *vwght, *vtype;
165 PORD_INT err, nvtx, ndom, domwght, dom, multi, u, v, i, istart, istop;
166
167 nvtx = dd->G->nvtx;
168 xadj = dd->G->xadj;
169 adjncy = dd->G->adjncy;
170 vwght = dd->G->vwght;
171 vtype = dd->vtype;
172
173 err = FALSE;
174 printf("checking domain decomposition (#nodes %d, #edges %d)\n",
175 dd->G->nvtx, dd->G->nedges >> 1);
176
177 ndom = domwght = 0;
178 for (u = 0; u < nvtx; u++)
179 { /* check node type */
180 if ((vtype[u] != 1) && (vtype[u] != 2))
181 { printf("ERROR: node %d is neither DOMAIN nor MULTISEC\n", u);
182 err = TRUE;
183 }
184 /* count domains and sum up their weight */
185 if (vtype[u] == 1)
186 { ndom++;
187 domwght += vwght[u];
188 }
189 /* check number of neighboring domains and multisecs */
190 dom = multi = 0;
191 istart = xadj[u];
192 istop = xadj[u+1];
193 for (i = istart; i < istop; i++)
194 { v = adjncy[i];
195 if (vtype[v] == 1) dom++;
196 if (vtype[v] == 2) multi++;
197 }
198 if ((vtype[u] == 1) && (dom > 0))
199 { printf("ERROR: domain %d is adjacent to other domain\n", u);
200 err = TRUE;
201 }
202 if ((vtype[u] == 2) && (dom < 2))
203 { printf("ERROR: less than 2 domains adjacent to multisec node %d\n", u);
204 err = TRUE;
205 }
206 if ((vtype[u] == 2) && (multi > 0))
207 { printf("ERROR: multisec %d is adjacent to other multisec nodes\n", u);
208 err = TRUE;
209 }
210 }
211 /* check number and weight of domains */
212 if ((ndom != dd->ndom) || (domwght != dd->domwght))
213 { printf("ERROR: number/size (%d/%d) of domains does not match with those in"
214 " domain decomp. (%d/%d)\n", ndom, domwght, dd->ndom, dd->domwght);
215 err = TRUE;
216 }
217 if (err) quit();
218}
PORD_INT ndom
Definition types.h:54
PORD_INT domwght
Definition types.h:55

◆ checkSeparator()

void checkSeparator ( gbisect_t * Gbisect)

Definition at line 117 of file gbisect.c.

118{ PORD_INT *xadj, *adjncy, *vwght, *color, *cwght;
119 PORD_INT nvtx, err, checkS, checkB, checkW, a, b, u, v, i, istart, istop;
120
121 nvtx = Gbisect->G->nvtx;
122 xadj = Gbisect->G->xadj;
123 adjncy = Gbisect->G->adjncy;
124 vwght = Gbisect->G->vwght;
125 color = Gbisect->color;
126 cwght = Gbisect->cwght;
127
128 err = FALSE;
129 printf("checking separator of induced subgraph (S %d, B %d, W %d)\n",
130 cwght[GRAY], cwght[BLACK], cwght[WHITE]);
131
132 checkS = checkB = checkW = 0;
133 for (u = 0; u < nvtx; u++)
134 { istart = xadj[u];
135 istop = xadj[u+1];
136 switch(color[u])
137 { case GRAY: /* is it a minimal separator? */
138 checkS += vwght[u];
139 a = b = FALSE;
140 for (i = istart; i < istop; i++)
141 { v = adjncy[i];
142 if (color[v] == WHITE) a = TRUE;
143 if (color[v] == BLACK) b = TRUE;
144 }
145 if (!((a) && (b)))
146 printf("WARNING: not a minimal separator (node %d)\n", u);
147 break;
148 case BLACK: /* is it realy a separator? */
149 checkB += vwght[u];
150 for (i = istart; i < istop; i++)
151 { v = adjncy[i];
152 if (color[v] == WHITE)
153 { printf("ERROR: white node %d adjacent to black node %d\n", u,v);
154 err = TRUE;
155 }
156 }
157 break;
158 case WHITE:
159 checkW += vwght[u];
160 break;
161 default:
162 printf("ERROR: node %d has unrecognized color %d\n", u, color[u]);
163 err = TRUE;
164 }
165 }
166
167 /* check cwght[GRAY], cwght[BLACK], cwght[WHITE] */
168 if ((checkS != cwght[GRAY]) || (checkB != cwght[BLACK])
169 || (checkW != cwght[WHITE]))
170 { printf("ERROR in partitioning: checkS %d (S %d), checkB %d (B %d), "
171 "checkW %d (W %d)\n", checkS, cwght[GRAY], checkB, cwght[BLACK],
172 checkW, cwght[WHITE]);
173 err = TRUE;
174 }
175 if (err) quit();
176}
PORD_INT * color
Definition types.h:45
graph_t * G
Definition types.h:44
PORD_INT cwght[3]
Definition types.h:46

◆ coarserDomainDecomposition()

domdec_t * coarserDomainDecomposition ( domdec_t * dd1,
PORD_INT * rep )

Definition at line 778 of file ddcreate.c.

779{ domdec_t *dd2;
780 PORD_INT *xadjdd1, *adjncydd1, *vwghtdd1, *vtypedd1, *mapdd1;
781 PORD_INT *xadjdd2, *adjncydd2, *vwghtdd2, *vtypedd2;
782 PORD_INT *tmp, *bin, nvtxdd1, nedgesdd1, nvtxdd2, nedgesdd2;
783 PORD_INT ndom, domwght, flag, u, v, w, i, istart, istop;
784
785 nvtxdd1 = dd1->G->nvtx;
786 nedgesdd1 = dd1->G->nedges;
787 xadjdd1 = dd1->G->xadj;
788 adjncydd1 = dd1->G->adjncy;
789 vwghtdd1 = dd1->G->vwght;
790 vtypedd1 = dd1->vtype;
791 mapdd1 = dd1->map;
792
793 /* ------------------------
794 allocate working storage
795 ------------------------ */
796 mymalloc(tmp, nvtxdd1, PORD_INT);
797 mymalloc(bin, nvtxdd1, PORD_INT);
798 for (u = 0; u < nvtxdd1; u++)
799 { tmp[u] = -1;
800 bin[u] = -1;
801 }
802
803 /* ------------------------------------------------------------
804 allocate memory using the upper bounds nvtxdd1 and nedgesdd1
805 ------------------------------------------------------------ */
806 dd2 = newDomainDecomposition(nvtxdd1, nedgesdd1);
807 xadjdd2 = dd2->G->xadj;
808 adjncydd2 = dd2->G->adjncy;
809 vwghtdd2 = dd2->G->vwght;
810 vtypedd2 = dd2->vtype;
811
812 /* -------------------------------------------------------
813 put all nodes u belonging to representative v in bin[v]
814 ------------------------------------------------------- */
815 for (u = 0; u < nvtxdd1; u++)
816 { v = rep[u];
817 if (u != v)
818 { bin[u] = bin[v];
819 bin[v] = u;
820 }
821 }
822
823 /* ----------------------------------------------
824 and now build the coarser domain decomposition
825 ---------------------------------------------- */
826 flag = 1;
827 nvtxdd2 = nedgesdd2 = 0;
828 ndom = domwght = 0;
829 for (u = 0; u < nvtxdd1; u++)
830 if (rep[u] == u)
831 { xadjdd2[nvtxdd2] = nedgesdd2;
832 vwghtdd2[nvtxdd2] = 0;
833 vtypedd2[nvtxdd2] = vtypedd1[u];
834 if (vtypedd2[nvtxdd2] == 3)
835 vtypedd2[nvtxdd2] = 1;
836 tmp[u] = flag;
837
838 /* find all cluster that are adjacent to u in dom. dec. */
839 v = u;
840 do
841 { mapdd1[v] = nvtxdd2;
842 vwghtdd2[nvtxdd2] += vwghtdd1[v];
843 if ((vtypedd1[v] == 1) || (vtypedd1[v] == 2))
844 { istart = xadjdd1[v];
845 istop = xadjdd1[v+1];
846 for (i = istart; i < istop; i++)
847 { w = adjncydd1[i];
848 if (tmp[rep[w]] != flag)
849 { tmp[rep[w]] = flag;
850 adjncydd2[nedgesdd2++] = rep[w];
851 }
852 }
853 }
854 v = bin[v];
855 } while (v != -1);
856
857 if (vtypedd2[nvtxdd2] == 1)
858 { ndom++;
859 domwght += vwghtdd2[nvtxdd2];
860 }
861 nvtxdd2++;
862 flag++;
863 }
864
865 /* --------------------------------------------
866 finalize the new domain decomposition object
867 -------------------------------------------- */
868 xadjdd2[nvtxdd2] = nedgesdd2;
869 dd2->G->nvtx = nvtxdd2;
870 dd2->G->nedges = nedgesdd2;
871 dd2->G->type = WEIGHTED;
872 dd2->G->totvwght = dd1->G->totvwght;
873 for (i = 0; i < nedgesdd2; i++)
874 adjncydd2[i] = mapdd1[adjncydd2[i]];
875 for (u = 0; u < nvtxdd2; u++)
876 dd2->color[u] = dd2->map[u] = -1;
877 dd2->ndom = ndom;
878 dd2->domwght = domwght;
879
880 /* --------------------------
881 set back node types in dd1
882 -------------------------- */
883 for (u = 0; u < nvtxdd1; u++)
884 if ((vtypedd1[u] == 3) || (vtypedd1[u] == 4))
885 vtypedd1[u] = 2;
886
887 /* -------------------------------
888 free working storage and return
889 ------------------------------- */
890 free(tmp); free(bin);
891 return(dd2);
892}
#define WEIGHTED
Definition const.h:20
domdec_t * newDomainDecomposition(PORD_INT nvtx, PORD_INT nedges)
Definition ddcreate.c:100
#define mymalloc(ptr, nr, type)
Definition macros.h:23
*fortran !University of Stuttgart All rights reserved Inc All rights reserved ! $COPYRIGHT$ !Additional copyrights may follow ! $HEADER$ !WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING !Do ***not ***copy this file to the directory where your Fortran !fortran application is compiled unless it is absolutely necessary !Most !modern Fortran compilers now support the I command line flag
Definition mpif.h:26
PORD_INT * map
Definition types.h:59
PORD_INT type
Definition types.h:33
struct _domdec domdec_t

◆ compressElimTree()

elimtree_t * compressElimTree ( elimtree_t * T,
PORD_INT * frontmap,
PORD_INT cnfronts )

Definition at line 689 of file tree.c.

690{ elimtree_t *T2;
691 PORD_INT *ncolfactor, *ncolupdate, *parent, *vtx2front;
692 PORD_INT nvtx, nfronts, u, K, pK, newfront, pnewfront;
693
694 nvtx = T->nvtx;
695 nfronts = T->nfronts;
696 ncolfactor = T->ncolfactor;
697 ncolupdate = T->ncolupdate;
698 parent = T->parent;
699 vtx2front = T->vtx2front;
700
701 /* --------------------------------------------
702 allocate memory for the new elimtree T2
703 and init. ncolfactor, ncolupdate, and parent
704 -------------------------------------------- */
705 T2 = newElimTree(nvtx, cnfronts);
706 for (K = 0; K < cnfronts; K++)
707 { T2->ncolfactor[K] = T2->ncolupdate[K] = 0;
708 T2->parent[K] = -1;
709 }
710
711 /* --------------------------------------------------------------
712 set the new vectors T2->ncolfactor, T2->ncolupdate, T2->parent
713 -------------------------------------------------------------- */
714 for (K = 0; K < nfronts; K++)
715 { newfront = frontmap[K];
716 T2->ncolfactor[newfront] += ncolfactor[K];
717 if (((pK = parent[K]) != -1)
718 && ((pnewfront = frontmap[pK]) != newfront))
719 { T2->parent[newfront] = pnewfront;
720 T2->ncolupdate[newfront] = ncolupdate[K];
721 }
722 }
723
724 /* ---------------------------------------------------
725 set the new vectors T2->firstchild and T2->silbings
726 --------------------------------------------------- */
727 initFchSilbRoot(T2);
728
729 /* ------------------------------------
730 set the the new vector T2->vtx2front
731 ------------------------------------ */
732 for (u = 0; u < nvtx; u++)
733 T2->vtx2front[u] = frontmap[vtx2front[u]];
734 return(T2);
735}
integer, dimension(:), allocatable newfront
Definition restart_mod.F:83
PORD_INT nfronts
Definition types.h:152
PORD_INT * parent
Definition types.h:156
PORD_INT * ncolfactor
Definition types.h:154
PORD_INT nvtx
Definition types.h:151
PORD_INT * vtx2front
Definition types.h:159
PORD_INT * ncolupdate
Definition types.h:155
elimtree_t * newElimTree(PORD_INT nvtx, PORD_INT nfronts)
Definition tree.c:110
void initFchSilbRoot(elimtree_t *T)
Definition tree.c:414
struct _elimtree elimtree_t

◆ compressGraph()

graph_t * compressGraph ( graph_t * G,
PORD_INT * vtxmap )

Definition at line 470 of file graph.c.

471{ graph_t *Gc;
472 PORD_INT *xadj, *adjncy, *vwght, *xadjGc, *adjncyGc, *vwghtGc, *perm;
473 PORD_INT nvtx, nvtxGc, nedgesGc, u, v, i, istart, istop;
474
475 nvtx = G->nvtx;
476 xadj = G->xadj;
477 adjncy = G->adjncy;
478 vwght = G->vwght;
479
480 /* --------------------------------------------------------------
481 compressed graph small enough? if so, allocate working storage
482 -------------------------------------------------------------- */
483 /* avoid print statement
484 * printf("indNodes(G, vtxmap) = %d",indNodes(G, vtxmap)); */
485 if ((nvtxGc = indNodes(G, vtxmap)) > COMPRESS_FRACTION * nvtx)
486 return(NULL);
487 mymalloc(perm, nvtx, PORD_INT);
488
489 /* -----------------------------------
490 count edges of the compressed graph
491 ----------------------------------- */
492 nedgesGc = 0;
493 for (u = 0; u < nvtx; u++)
494 if (vtxmap[u] == u)
495 { istart = xadj[u];
496 istop = xadj[u+1];
497 for (i = istart; i < istop; i++)
498 { v = adjncy[i];
499 if (vtxmap[v] == v) nedgesGc++;
500 }
501 }
502
503 /* ---------------------------------------------------------
504 allocate memory for the compressed graph and construct it
505 --------------------------------------------------------- */
506 Gc = newGraph(nvtxGc, nedgesGc);
507 xadjGc = Gc->xadj;
508 adjncyGc = Gc->adjncy;
509 vwghtGc = Gc->vwght;
510
511 nvtxGc = nedgesGc = 0;
512 for (u = 0; u < nvtx; u++)
513 if (vtxmap[u] == u)
514 { istart = xadj[u];
515 istop = xadj[u+1];
516 xadjGc[nvtxGc] = nedgesGc;
517 vwghtGc[nvtxGc] = 0;
518 perm[u] = nvtxGc++;
519 for (i = istart; i < istop; i++)
520 { v = adjncy[i];
521 if (vtxmap[v] == v) adjncyGc[nedgesGc++] = v;
522 }
523 }
524 xadjGc[nvtxGc] = nedgesGc;
525
526 for (i = 0; i < nedgesGc; i++)
527 adjncyGc[i] = perm[adjncyGc[i]];
528 for (u = 0; u < nvtx; u++)
529 { vtxmap[u] = perm[vtxmap[u]];
530 vwghtGc[vtxmap[u]] += vwght[u];
531 }
532 Gc->type = WEIGHTED;
533 Gc->totvwght = G->totvwght;
534
535 /* ----------------------
536 free memory and return
537 ---------------------- */
538 free(perm);
539 return(Gc);
540}
static PORD_INT indNodes(graph_t *G, PORD_INT *vtxmap)
Definition graph.c:400
graph_t * newGraph(PORD_INT nvtx, PORD_INT nedges)
Definition graph.c:50
#define COMPRESS_FRACTION
Definition params.h:14

◆ computePriorities()

void computePriorities ( domdec_t * dd,
PORD_INT * msvtxlist,
PORD_INT * key,
PORD_INT scoretype )

Definition at line 536 of file ddcreate.c.

537{ PORD_INT *xadj, *adjncy, *vwght, *marker;
538 PORD_INT nvtx, nlist, k, weight, deg, u, v, w;
539 PORD_INT i, istart, istop, j, jstart, jstop;
540
541 nvtx = dd->G->nvtx;
542 xadj = dd->G->xadj;
543 adjncy = dd->G->adjncy;
544 vwght = dd->G->vwght;
545 marker = dd->map;
546 nlist = nvtx - dd->ndom;
547
548 switch(scoretype)
549 { case QMRDV: /* maximal relative decrease of variables in quotient graph */
550 for (k = 0; k < nlist; k++)
551 { u = msvtxlist[k];
552 weight = vwght[u];
553 istart = xadj[u];
554 istop = xadj[u+1];
555 for (i = istart; i < istop; i++)
556 weight += vwght[adjncy[i]];
557 key[u] = weight / vwght[u];
558 }
559 break;
560
561 case QMD: /* ----------------------- minimum degree in quotient graph */
562 for (k = 0; k < nlist; k++)
563 { u = msvtxlist[k];
564 marker[u] = -1;
565 }
566 for (k = 0; k < nlist; k++)
567 { u = msvtxlist[k];
568 marker[u] = u;
569 deg = 0;
570 istart = xadj[u];
571 istop = xadj[u+1];
572 for (i = istart; i < istop; i++)
573 { v = adjncy[i];
574 jstart = xadj[v];
575 jstop = xadj[v+1];
576 for (j = jstart; j < jstop; j++)
577 { w = adjncy[j];
578 if (marker[w] != u)
579 { marker[w] = u;
580 deg += vwght[w];
581 }
582 }
583 }
584 key[u] = deg;
585 }
586 break;
587
588 case QRAND: /* ------------------------------------------------- random */
589 for (k = 0; k < nlist; k++)
590 { u = msvtxlist[k];
591 key[u] = myrandom(nvtx);
592 }
593 break;
594
595 default:
596 fprintf(stderr, "\nError in internal function computePriorities\n"
597 " unrecognized node selection strategy %d\n", scoretype);
598 quit();
599 }
600}
#define QRAND
Definition const.h:37
#define QMRDV
Definition const.h:36
#define QMD
Definition const.h:35
#define myrandom(range)
Definition macros.h:37
integer, dimension(:), allocatable weight
Definition restart_mod.F:83

◆ connectedComponents()

PORD_INT connectedComponents ( graph_t * G)

Definition at line 344 of file graph.c.

345{ PORD_INT *xadj, *adjncy, *marker, *queue;
346 PORD_INT nvtx, u, v, w, qhead, qtail, comp, i, istart, istop;
347
348 nvtx = G->nvtx;
349 xadj = G->xadj;
350 adjncy = G->adjncy;
351
352 /* ------------------------
353 allocate working storage
354 ------------------------ */
355 mymalloc(marker, nvtx, PORD_INT);
356 mymalloc(queue, nvtx, PORD_INT);
357
358 /* ---------------
359 initializations
360 --------------- */
361 comp = 0;
362 for (u = 0; u < nvtx; u++)
363 marker[u] = -1;
364
365 /* --------------------------------------
366 get the number of connected components
367 -------------------------------------- */
368 for (u = 0; u < nvtx; u++)
369 if (marker[u] == -1)
370 { comp++;
371 qhead = 0; qtail = 1;
372 queue[0] = u; marker[u] = 0;
373
374 while (qhead != qtail) /* breadth first search in each comp. */
375 { v = queue[qhead++];
376 istart = xadj[v];
377 istop = xadj[v+1];
378 for (i = istart; i < istop; i++)
379 { w = adjncy[i];
380 if (marker[w] == -1)
381 { queue[qtail++] = w;
382 marker[w] = 0;
383 }
384 }
385 }
386 }
387
388 /* -------------------------------
389 free working storage and return
390 ------------------------------- */
391 free(marker); free(queue);
392 return(comp);
393}
int comp(int a, int b)

◆ constructDomainDecomposition()

domdec_t * constructDomainDecomposition ( graph_t * G,
PORD_INT * map )

Definition at line 472 of file ddcreate.c.

473{ domdec_t *dd;
474 PORD_INT *xadj, *adjncy, *vwght, *vtxlist, *vtype, *key, *rep;
475 PORD_INT nvtx, deg, u, i, istart, istop;
476
477 nvtx = G->nvtx;
478 xadj = G->xadj;
479 adjncy = G->adjncy;
480 vwght = G->vwght;
481
482 /* ---------------------------------------------------------
483 sort the vertices in G in ascending order of their degree
484 --------------------------------------------------------- */
485 mymalloc(vtxlist, nvtx, PORD_INT);
486 mymalloc(key, nvtx, PORD_INT);
487 for (u = 0; u < nvtx; u++)
488 { vtxlist[u] = u;
489 istart = xadj[u];
490 istop = xadj[u+1];
491 switch(G->type)
492 { case UNWEIGHTED:
493 deg = istop - istart;
494 break;
495 case WEIGHTED:
496 deg = 0;
497 for (i = istart; i < istop; i++)
498 deg += vwght[adjncy[i]];
499 break;
500 default:
501 fprintf(stderr, "\nError in function constructDomainDecomposition\n"
502 " unrecognized graph type %d\n", G->type);
503 quit();
504 }
505 key[u] = deg;
506 }
507 distributionCounting(nvtx, vtxlist, key);
508 free(key);
509
510 /* -------------------------------------------------------------
511 build initial domains and cluster multisecs that do not share
512 a common domain
513 ------------------------------------------------------------- */
514 mymalloc(vtype, nvtx, PORD_INT);
515 mymalloc(rep, nvtx, PORD_INT);
516 for (u = 0; u < nvtx; u++)
517 { vtype[u] = 0;
518 rep[u] = u;
519 }
520 buildInitialDomains(G, vtxlist, vtype, rep);
521 mergeMultisecs(G, vtype, rep);
522 free(vtxlist);
523
524 /* --------------------------------------------------
525 finally, build the domain decomposition and return
526 -------------------------------------------------- */
527 dd = initialDomainDecomposition(G, map, vtype, rep);
528 free(vtype); free(rep);
529 return(dd);
530}
#define UNWEIGHTED
Definition const.h:19
domdec_t * initialDomainDecomposition(graph_t *G, PORD_INT *map, PORD_INT *vtype, PORD_INT *rep)
Definition ddcreate.c:366
void buildInitialDomains(graph_t *G, PORD_INT *vtxlist, PORD_INT *vtype, PORD_INT *rep)
Definition ddcreate.c:224
void mergeMultisecs(graph_t *G, PORD_INT *vtype, PORD_INT *rep)
Definition ddcreate.c:280
void distributionCounting(PORD_INT, PORD_INT *, PORD_INT *)
Definition sort.c:186

◆ constructLevelSep()

void constructLevelSep ( domdec_t * dd,
PORD_INT domain )

Definition at line 208 of file ddbisect.c.

209{ PORD_INT *xadj, *adjncy, *vwght, *vtype, *color, *cwght;
210 PORD_INT *queue, *deltaS, *deltaB, *deltaW;
211 PORD_INT nvtx, bestvalue, weight, qhead, qtail, qopt, q, dS, dB, dW;
212 PORD_INT u, v, w, i, istart, istop, j, jstart, jstop;
213
214 /* ======================================================================
215 vtype[u]: (u domain)
216 1 => domain u has not been touched yet (not in queue, no color flip)
217 -1 => domain u is in queue and its deltaS, deltaB, deltaW values
218 have to be updated
219 -2 => domain u is in queue and no update necessary
220 -3 => domain u has flipped its color to black
221 deltaS[u], deltaB[u], deltaW[u]:
222 u domain: denotes the change in partition size, if u flips its color
223 u multisec: deltaB/deltaW denote number of adj. black/white domains
224 ====================================================================== */
225
226 nvtx = dd->G->nvtx;
227 xadj = dd->G->xadj;
228 adjncy = dd->G->adjncy;
229 vwght = dd->G->vwght;
230 vtype = dd->vtype;
231 color = dd->color;
232 cwght = dd->cwght;
233
234 /* ------------------------------------------
235 allocate working storage + initializations
236 ------------------------------------------ */
237 mymalloc(queue, nvtx, PORD_INT);
238 mymalloc(deltaS, nvtx, PORD_INT);
239 mymalloc(deltaB, nvtx, PORD_INT);
240 mymalloc(deltaW, nvtx, PORD_INT);
241 for (u = 0; u < nvtx; u++)
242 { deltaS[u] = deltaB[u] = deltaW[u] = 0;
243 if (vtype[u] == 2)
244 deltaW[u] = xadj[u+1] - xadj[u];
245 }
246
247 /* ---------------------------------------------
248 build a BFS tree rooted at domain
249 the separator is given by the level structure
250 --------------------------------------------- */
251 queue[0] = domain;
252 qhead = 0; qtail = 1;
253 vtype[domain] = -1;
254 while ((cwght[BLACK] < cwght[WHITE]) && (qhead != qtail))
255 { qopt = 0;
256 bestvalue = MAX_INT;
257
258 /* --------------------------------------------------------------------
259 run through queue, update domains if necessary, and find best domain
260 -------------------------------------------------------------------- */
261 for (q = qhead; q < qtail; q++)
262 { u = queue[q];
263 if (vtype[u] == -1)
264 { dB = vwght[u]; dW = -dB; dS = 0;
265 istart = xadj[u];
266 istop = xadj[u+1];
267 for (i = istart; i < istop; i++)
268 { v = adjncy[i]; /* color of multisec v */
269 weight = vwght[v]; /* is GRAY or WHITE */
270 if (color[v] == WHITE)
271 { dW -= weight; dS += weight; } /* multisec will move to S */
272 else if (deltaW[v] == 1)
273 { dB += weight; dS -= weight; } /* multisec will move to B */
274 }
275 deltaS[u] = dS; deltaB[u] = dB; deltaW[u] = dW;
276 vtype[u] = -2;
277 }
278 if (cwght[GRAY] + deltaS[u] < bestvalue)
279 { bestvalue = cwght[GRAY] + deltaS[u];
280 qopt = q;
281 }
282 }
283
284 /* ----------------------------------------------------
285 move best domain to head of queue and color it black
286 ---------------------------------------------------- */
287 u = queue[qopt];
288 swap(queue[qopt], queue[qhead], v);
289 qhead++;
290 color[u] = BLACK;
291 cwght[GRAY] += deltaS[u];
292 cwght[BLACK] += deltaB[u];
293 cwght[WHITE] += deltaW[u];
294 vtype[u] = -3;
295
296 /* ------------------------------------------------------------
297 update all multisecs that are adjacent to domain u and check
298 domains adjacent to the multisecs
299 ------------------------------------------------------------ */
300 istart = xadj[u];
301 istop = xadj[u+1];
302 for (i = istart; i < istop; i++)
303 { v = adjncy[i];
304 deltaB[v]++; deltaW[v]--;
305 if (deltaW[v] == 0) /* color of multisec v changed to BLACK */
306 color[v] = BLACK;
307 else if (deltaB[v] == 1) /* color of multisec v changed to GRAY */
308 { color[v] = GRAY;
309 jstart = xadj[v];
310 jstop = xadj[v+1];
311 for (j = jstart; j < jstop; j++)
312 { w = adjncy[j];
313 if (vtype[w] == 1) /* a new domain enters the queue */
314 { queue[qtail++] = w;
315 vtype[w] = -1;
316 }
317 else if (vtype[w] == -2) /* update (old) domain in queue */
318 vtype[w] = -1;
319 }
320 }
321 else if (deltaW[v] == 1) /* color of multisec v remains GRAY for */
322 { jstart = xadj[v]; /* the last time */
323 jstop = xadj[v+1];
324 for (j = jstart; j < jstop; j++)
325 { w = adjncy[j];
326 if (vtype[w] == -2)
327 vtype[w] = -1;
328 }
329 }
330 }
331 }
332
333 /* ---------------------------
334 reset vtype and free memory
335 --------------------------- */
336 for (i = 0; i < qtail; i++)
337 { u = queue[i];
338 vtype[u] = 1;
339 }
340 free(queue);
341 free(deltaS); free(deltaB); free(deltaW);
342}
#define MAX_INT
Definition const.h:56
#define swap(a, b, tmp)
Definition macros.h:40

◆ constructMultisector()

multisector_t * constructMultisector ( graph_t * G,
options_t * options,
timings_t * cpus )

Definition at line 124 of file multisector.c.

125{ multisector_t *ms;
126 nestdiss_t *ndroot;
127 PORD_INT *map, nvtx, ordtype;
128
129 nvtx = G->nvtx;
130
131 /* ------------------------------
132 check number of nodes in graph
133 ------------------------------ */
134 /* -----------------------------------
135 JY: inserted the condition
136 "&& (options[OPTION_MSGLVL] > 0)"
137 below, to avoid systematic printing
138 ----------------------------------- */
139 if ((nvtx <= MIN_NODES) && (options[OPTION_ORDTYPE] != MINIMUM_PRIORITY)
140 && (options[OPTION_MSGLVL] > 0))
141 { printf("\nWarning in constructMultisector\n"
142 " graph has less than %d nodes, skipping separator construction\n\n",
143 MIN_NODES);
145 }
146 /* --------------------------------------------------------
147 determine the multisector according to the ordering type
148 -------------------------------------------------------- */
149 ordtype = options[OPTION_ORDTYPE];
150 switch(ordtype)
151 { case MINIMUM_PRIORITY:
152 ms = trivialMultisector(G);
153 break;
154
155 case INCOMPLETE_ND:
156 case MULTISECTION:
158 mymalloc(map, nvtx, PORD_INT);
159 ndroot = setupNDroot(G, map);
160 buildNDtree(ndroot, options, cpus);
161 if (ordtype == MULTISECTION)
162 ms = extractMS2stage(ndroot);
163 else
164 ms = extractMSmultistage(ndroot);
165 freeNDtree(ndroot);
166 freeNDnode(ndroot);
167 free(map);
168 break;
169
170 default:
171 fprintf(stderr, "\nError in function constructMultisector\n"
172 " unrecognized ordering type %d\n", ordtype);
173 quit();
174 }
175 return(ms);
176}
#define MINIMUM_PRIORITY
Definition const.h:23
#define OPTION_ORDTYPE
Definition const.h:78
#define MULTISECTION
Definition const.h:25
#define TRISTAGE_MULTISECTION
Definition const.h:26
#define INCOMPLETE_ND
Definition const.h:24
multisector_t * trivialMultisector(graph_t *G)
Definition multisector.c:96
multisector_t * extractMSmultistage(nestdiss_t *ndroot)
multisector_t * extractMS2stage(nestdiss_t *ndroot)
nestdiss_t * setupNDroot(graph_t *, PORD_INT *)
Definition nestdiss.c:107
void freeNDtree(nestdiss_t *)
Definition nestdiss.c:260
void buildNDtree(nestdiss_t *, options_t *, timings_t *)
Definition nestdiss.c:213
void freeNDnode(nestdiss_t *)
Definition nestdiss.c:96
struct _multisector multisector_t

◆ constructSeparator()

void constructSeparator ( gbisect_t * Gbisect,
options_t * options,
timings_t * cpus )

Definition at line 182 of file gbisect.c.

183{ domdec_t *dd, *dd2;
184 PORD_INT *color, *cwght, *map, nvtx, u, i;
185
186 nvtx = Gbisect->G->nvtx;
187 color = Gbisect->color;
188 cwght = Gbisect->cwght;
189
190 /* --------------------------------------------------------------
191 map vector identifies vertices of Gbisect->G in domain decomp.
192 -------------------------------------------------------------- */
193 mymalloc(map, nvtx, PORD_INT);
194
195 /* --------------------------------------
196 construct initial domain decomposition
197 -------------------------------------- */
199 dd = constructDomainDecomposition(Gbisect->G, map);
200
201#ifdef BE_CAUTIOUS
203#endif
204
205 if (options[OPTION_MSGLVL] > 2)
206 printf("\t 0. dom.dec.: #nodes %d (#domains %d, weight %d), #edges %d\n",
207 dd->G->nvtx, dd->ndom, dd->domwght, dd->G->nedges >> 1);
209
210 /* ---------------------------------------------------
211 construct sequence of coarser domain decompositions
212 --------------------------------------------------- */
214 i = 0;
215 while ((dd->ndom > MIN_DOMAINS) && (i < MAX_COARSENING_STEPS)
216 && ((dd->G->nedges >> 1) > dd->G->nvtx))
218 dd = dd->next; i++;
219
220#ifdef BE_CAUTIOUS
222#endif
223
224 if (options[OPTION_MSGLVL] > 2)
225 printf("\t %2d. dom.dec.: #nodes %d (#domains %d, weight %d), #edges %d"
226 "\n", i, dd->G->nvtx, dd->ndom, dd->domwght, dd->G->nedges >> 1);
227 }
229
230 /* -----------------------------------------------
231 determine coloring of last domain decomposition
232 ------------------------------------------------ */
234 initialDDSep(dd);
235 if (dd->cwght[GRAY] > 0)
236 improveDDSep(dd);
237
238#ifdef BE_CAUTIOUS
239 checkDDSep(dd);
240#endif
241
242 if (options[OPTION_MSGLVL] > 2)
243 printf("\t %2d. dom.dec. sep.: S %d, B %d, W %d [cost %7.2f]\n",
244 i, dd->cwght[GRAY], dd->cwght[BLACK], dd->cwght[WHITE],
245 F(dd->cwght[GRAY], dd->cwght[BLACK], dd->cwght[WHITE]));
247
248 /* --------------
249 refine coloring
250 --------------- */
251
253 while (dd->prev != NULL)
254 { dd2 = dd->prev;
255 dd2->cwght[GRAY] = dd->cwght[GRAY];
256 dd2->cwght[BLACK] = dd->cwght[BLACK];
257 dd2->cwght[WHITE] = dd->cwght[WHITE];
258 for (u = 0; u < dd2->G->nvtx; u++)
259 dd2->color[u] = dd->color[dd2->map[u]];
261 if (dd2->cwght[GRAY] > 0)
262 improveDDSep(dd2);
263
264#ifdef BE_CAUTIOUS
265 checkDDSep(dd2);
266#endif
267
268 dd = dd2;
269 i--;
270 if (options[OPTION_MSGLVL] > 2)
271 printf("\t %2d. dom.dec. sep.: S %d, B %d, W %d [cost %7.2f]\n",
272 i, dd->cwght[GRAY], dd->cwght[BLACK], dd->cwght[WHITE],
273 F(dd->cwght[GRAY], dd->cwght[BLACK], dd->cwght[WHITE]));
274 }
276
277 /* ---------------------------------
278 copy coloring to subgraph Gbisect
279 --------------------------------- */
280 cwght[GRAY] = dd->cwght[GRAY];
281 cwght[BLACK] = dd->cwght[BLACK];
282 cwght[WHITE] = dd->cwght[WHITE];
283 for (u = 0; u < nvtx; u++)
284 color[u] = dd->color[map[u]];
286 free(map);
287}
#define TIME_INITDOMDEC
Definition const.h:92
#define TIME_REFINESEP
Definition const.h:95
#define TIME_COARSEDOMDEC
Definition const.h:93
#define TIME_INITSEP
Definition const.h:94
#define OPTION_NODE_SELECTION3
Definition const.h:81
#define pord_starttimer(var)
Definition macros.h:58
#define pord_stoptimer(var)
Definition macros.h:61
#define MIN_DOMAINS
Definition params.h:18
#define MAX_COARSENING_STEPS
Definition params.h:19
void freeDomainDecomposition(domdec_t *)
Definition ddcreate.c:120
void improveDDSep(domdec_t *)
Definition ddbisect.c:607
void checkDomainDecomposition(domdec_t *)
Definition ddcreate.c:163
void checkDDSep(domdec_t *)
Definition ddbisect.c:68
void shrinkDomainDecomposition(domdec_t *, PORD_INT)
Definition ddcreate.c:898
void initialDDSep(domdec_t *)
Definition ddbisect.c:348
domdec_t * constructDomainDecomposition(graph_t *, PORD_INT *)
Definition ddcreate.c:472
struct _domdec * prev
Definition types.h:60
struct _domdec * next
Definition types.h:60

◆ crunchElimGraph()

PORD_INT crunchElimGraph ( gelim_t * Gelim)

Definition at line 302 of file gelim.c.

303{ PORD_INT *xadj, *adjncy, *len;
304 PORD_INT nvtx, nedges, u, i, isrc, idest;
305
306 nvtx = Gelim->G->nvtx;
307 nedges = Gelim->G->nedges;
308 xadj = Gelim->G->xadj;
309 adjncy = Gelim->G->adjncy;
310 len = Gelim->len;
311
312 /* ---------------------------------------------
313 mark begining of u's adjacency list by -(u+1)
314 --------------------------------------------- */
315 for (u = 0; u < nvtx; u++)
316 { i = xadj[u]; /* is adjacency list of u still in use? */
317 if (i != -1) /* verify that list is non-empty */
318 { if (len[u] == 0)
319 { fprintf(stderr, "\nError in function crunchElimGraph\n"
320 " adjacency list of node %d is empty\n", u);
321 quit();
322 }
323 xadj[u] = adjncy[i]; /* if so, move first item to xadj[u] */
324 adjncy[i] = -(u+1); /* u's adjacency list is headed by -(u+1) */
325 if (len[u] == 0)
326 printf("error: u %d, len %d\n", u, len[u]);
327 }
328 }
329
330 /* --------------------------
331 crunch all adjacency lists
332 -------------------------- */
333 idest = isrc = 0;
334 while (isrc < Gelim->G->nedges)
335 { u = adjncy[isrc++];
336 if (u < 0) /* a new adjacency list starts here */
337 { u = -u - 1; /* it's the adjacency list of u */
338 adjncy[idest] = xadj[u]; /* first item was stored in xadj[u] */
339 xadj[u] = idest++;
340 for (i = 1; i < len[u]; i++)
341 adjncy[idest++] = adjncy[isrc++];
342 }
343 }
344 Gelim->G->nedges = idest;
345
346 /* ------------------
347 was it successful?
348 ------------------ */
349 if (idest < nedges) return(TRUE);
350 else return (FALSE);
351}

◆ distributionCounting()

void distributionCounting ( PORD_INT n,
PORD_INT * node,
PORD_INT * key )

Definition at line 186 of file sort.c.

187{ register PORD_INT i;
188 PORD_INT *tmp, *count, minkey, maxkey, l, u, vk;
189
190 /* determine maximal and minimal key */
191 minkey = MAX_INT;
192 maxkey = 0;
193 for (i = 0; i < n; i++)
194 { u = node[i];
195 maxkey = max(key[u], maxkey);
196 minkey = min(key[u], minkey);
197 }
198 l = maxkey-minkey;
199 /* printf("minkey %d, maxkey %d, range %d\n", minkey, maxkey, l); */
200 mymalloc(count, (l+1), PORD_INT);
201 mymalloc(tmp, n, PORD_INT);
202 for (i = 0; i <= l; i++)
203 count[i] = 0;
204
205 /* scale down all key-values */
206 for (i = 0; i < n; i++)
207 { u = node[i];
208 vk = key[u]-minkey;
209 key[u] = vk;
210 count[vk]++;
211 }
212
213 /* now do the sorting */
214 for (i = 1; i <= l; i++)
215 count[i] += count[i-1];
216 for (i = n-1; i >= 0; i--)
217 { u = node[i];
218 tmp[--count[key[u]]] = u;
219 }
220 for (i = 0; i < n; i++)
221 node[i] = tmp[i];
222/*
223 for (i = 0; i < n; i++)
224 { u = node[i];
225 printf(" node %d, key %d\n", u, key[u]);
226 }
227*/
228 free(count);
229 free(tmp);
230}
n

◆ DMviaFlow()

void DMviaFlow ( gbipart_t * Gbipart,
PORD_INT * flow,
PORD_INT * rc,
PORD_INT * dmflag,
PORD_INT * dmwght )

Definition at line 528 of file gbipart.c.

529{ PORD_INT *xadj, *adjncy, *vwght, *queue, qhead, qtail;
530 PORD_INT u, v, x, nX, y, nY, i, istart, istop;
531
532 xadj = Gbipart->G->xadj;
533 adjncy = Gbipart->G->adjncy;
534 vwght = Gbipart->G->vwght;
535 nX = Gbipart->nX;
536 nY = Gbipart->nY;
537
538 mymalloc(queue, (nX+nY), PORD_INT);
539
540 /* ----------------------------------------------------------
541 mark all nodes reachable from source/sink with SOURCE/SINK
542 ---------------------------------------------------------- */
543 qhead = qtail = 0;
544 for (x = 0; x < nX; x++)
545 if (rc[x] > 0)
546 { queue[qtail++] = x;
547 dmflag[x] = SOURCE;
548 }
549 else dmflag[x] = FREE;
550 for (y = nX; y < nX+nY; y++)
551 if (rc[y] > 0)
552 { queue[qtail++] = y;
553 dmflag[y] = SINK;
554 }
555 else dmflag[y] = FREE;
556
557 /* --------------------------------------------------------------------
558 construct Dulmage-Mendelsohn decomp. starting with SOURCE/SINK nodes
559 -------------------------------------------------------------------- */
560 while (qhead != qtail)
561 { u = queue[qhead++];
562 istart = xadj[u];
563 istop = xadj[u+1];
564 switch(dmflag[u])
565 { case SOURCE:
566 for (i = istart; i < istop; i++)
567 { v = adjncy[i];
568 if ((dmflag[v] == FREE) && ((v >= nX) || (flow[i] < 0)))
569 { queue[qtail++] = v;
570 dmflag[v] = SOURCE; /* v reachable via forward edge u->v */
571 } /* or via backward edge u<-v */
572 }
573 break;
574 case SINK:
575 for (i = istart; i < istop; i++)
576 { v = adjncy[i];
577 if ((dmflag[v] == FREE) && ((v < nX) || (flow[i] > 0)))
578 { queue[qtail++] = v;
579 dmflag[v] = SINK; /* u reachable via forward edge v->u */
580 } /* or via backward edge v<-u */
581 }
582 break;
583 }
584 }
585
586 /* -----------------------------------------------------
587 all nodes x in X with dmflag[x] = SOURCE belong to SI
588 all nodes x in X with dmflag[x] = SINK belong to SX
589 all nodes x in X with dmflag[x] = FREE belong to SR
590 ----------------------------------------------------- */
591 dmwght[SI] = dmwght[SX] = dmwght[SR] = 0;
592 for (x = 0; x < nX; x++)
593 switch(dmflag[x])
594 { case SOURCE: dmflag[x] = SI; dmwght[SI] += vwght[x]; break;
595 case SINK: dmflag[x] = SX; dmwght[SX] += vwght[x]; break;
596 default: dmflag[x] = SR; dmwght[SR] += vwght[x];
597 }
598
599 /* -----------------------------------------------------
600 all nodes y in Y with dmflag[y] = SOURCE belong to BX
601 all nodes y in Y with dmflag[y] = SINK belong to BI
602 all nodes y in Y with dmflag[y] = FREE belong to BR
603 ----------------------------------------------------- */
604 dmwght[BI] = dmwght[BX] = dmwght[BR] = 0;
605 for (y = nX; y < nX+nY; y++)
606 switch(dmflag[y])
607 { case SOURCE: dmflag[y] = BX; dmwght[BX] += vwght[y]; break;
608 case SINK: dmflag[y] = BI; dmwght[BI] += vwght[y]; break;
609 default: dmflag[y] = BR; dmwght[BR] += vwght[y];
610 }
611
612 free(queue);
613}
bool rc
#define BX
Definition const.h:72
#define SX
Definition const.h:69
#define SI
Definition const.h:68
#define BI
Definition const.h:71
#define SR
Definition const.h:70
#define BR
Definition const.h:73
#define SOURCE
Definition gbipart.c:59
#define FREE
Definition gbipart.c:58
#define SINK
Definition gbipart.c:60
PORD_INT nX
Definition types.h:68
PORD_INT nY
Definition types.h:69
graph_t * G
Definition types.h:67

◆ DMviaMatching()

void DMviaMatching ( gbipart_t * Gbipart,
PORD_INT * matching,
PORD_INT * dmflag,
PORD_INT * dmwght )

Definition at line 435 of file gbipart.c.

436{ PORD_INT *xadj, *adjncy, *vwght, *queue, qhead, qtail;
437 PORD_INT u, x, nX, y, nY, i, istart, istop;
438
439 xadj = Gbipart->G->xadj;
440 adjncy = Gbipart->G->adjncy;
441 vwght = Gbipart->G->vwght;
442 nX = Gbipart->nX;
443 nY = Gbipart->nY;
444
445 mymalloc(queue, (nX+nY), PORD_INT);
446
447 /* ----------------------------------------------------------------------
448 mark all exposed nodes of X with SI and all exposed nodes of Y with BI
449 ---------------------------------------------------------------------- */
450 qhead = qtail = 0;
451 for (x = 0; x < nX; x++)
452 if (matching[x] == FREE)
453 { queue[qtail++] = x;
454 dmflag[x] = SI;
455 }
456 else dmflag[x] = SR;
457 for (y = nX; y < nX+nY; y++)
458 if (matching[y] == FREE)
459 { queue[qtail++] = y;
460 dmflag[y] = BI;
461 }
462 else dmflag[y] = BR;
463
464 /* ------------------------------------------------------------------
465 construct Dulmage-Mendelsohn decomp. starting with SI and BI nodes
466 ------------------------------------------------------------------ */
467 while (qhead != qtail)
468 { u = queue[qhead++];
469 istart = xadj[u];
470 istop = xadj[u+1];
471 switch(dmflag[u])
472 { case SI:
473 for (i = istart; i < istop; i++)
474 { y = adjncy[i];
475 if (dmflag[y] == BR)
476 { queue[qtail++] = y;
477 dmflag[y] = BX;
478 }
479 }
480 break;
481 case BX:
482 x = matching[u];
483 dmflag[x] = SI;
484 queue[qtail++] = x;
485 break;
486 case BI:
487 for (i = istart; i < istop; i++)
488 { x = adjncy[i];
489 if (dmflag[x] == SR)
490 { queue[qtail++] = x;
491 dmflag[x] = SX;
492 }
493 }
494 break;
495 case SX:
496 y = matching[u];
497 dmflag[y] = BI;
498 queue[qtail++] = y;
499 break;
500 }
501 }
502
503 /* ----------------------
504 fill the dmwght vector
505 ---------------------- */
506 dmwght[SI] = dmwght[SX] = dmwght[SR] = 0;
507 for (x = 0; x < nX; x++)
508 switch(dmflag[x])
509 { case SI: dmwght[SI] += vwght[x]; break;
510 case SX: dmwght[SX] += vwght[x]; break;
511 case SR: dmwght[SR] += vwght[x]; break;
512 }
513 dmwght[BI] = dmwght[BX] = dmwght[BR] = 0;
514 for (y = nX; y < nX+nY; y++)
515 switch(dmflag[y])
516 { case BI: dmwght[BI] += vwght[y]; break;
517 case BX: dmwght[BX] += vwght[y]; break;
518 case BR: dmwght[BR] += vwght[y]; break;
519 }
520
521 free(queue);
522}

◆ eliminateMultisecs()

void eliminateMultisecs ( domdec_t * dd,
PORD_INT * msvtxlist,
PORD_INT * rep )

Definition at line 606 of file ddcreate.c.

607{ PORD_INT *xadj, *adjncy, *vtype;
608 PORD_INT nvtx, nlist, keepon, u, v, w, k, i, istart, istop;
609
610 nvtx = dd->G->nvtx;
611 xadj = dd->G->xadj;
612 adjncy = dd->G->adjncy;
613 vtype = dd->vtype;
614 nlist = nvtx - dd->ndom;
615
616 /* -------------------------------------------------------
617 eliminate multisecs according to the order in msvtxlist
618 ------------------------------------------------------- */
619 for (k = 0; k < nlist; k++)
620 { u = msvtxlist[k];
621 istart = xadj[u];
622 istop = xadj[u+1];
623 keepon = TRUE;
624 for (i = istart; i < istop; i++)
625 { v = adjncy[i];
626 if (rep[v] != v) /* domain already absorbed by an eliminated */
627 { keepon = FALSE; /* multisec => multisec u cannot be deleted */
628 break;
629 }
630 }
631 if (keepon)
632 { vtype[u] = 3;
633 for (i = istart; i < istop; i++)
634 { v = adjncy[i];
635 rep[v] = u;
636 }
637 }
638 }
639
640 /* ------------------------------------------------------------
641 eliminate all multisecs that are adjacent to only one domain
642 ------------------------------------------------------------ */
643 for (k = 0; k < nlist; k++)
644 { u = msvtxlist[k];
645 if (vtype[u] == 2)
646 { v = -1;
647 istart = xadj[u];
648 istop = xadj[u+1];
649 for (i = istart; i < istop; i++)
650 { w = adjncy[i];
651 if (v == -1)
652 v = rep[w]; /* u adjacent to domain v = rep[w] */
653 else if (v != rep[w])
654 { v = -1; /* u adjacent to another domain */
655 break;
656 }
657 }
658 if (v != -1) /* u absorbed by domain v */
659 { vtype[u] = 4;
660 rep[u] = v;
661 }
662 }
663 }
664}

◆ eliminateStage()

void eliminateStage ( minprior_t * minprior,
PORD_INT istage,
PORD_INT scoretype,
timings_t * cpus )

Definition at line 232 of file minpriority.c.

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}
#define TIME_UPDSCORE
Definition const.h:100
#define TIME_FINDINODES
Definition const.h:99
#define TIME_UPDADJNCY
Definition const.h:98
PORD_INT eliminateStep(minprior_t *minprior, PORD_INT istage, PORD_INT scoretype)
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 printElimGraph(gelim_t *)
Definition gelim.c:143
void updateDegree(gelim_t *, PORD_INT *, PORD_INT, PORD_INT *)
Definition gelim.c:761
void updateAdjncy(gelim_t *, PORD_INT *, PORD_INT, PORD_INT *, PORD_INT *)
Definition gelim.c:495
void updateScore(gelim_t *, PORD_INT *, PORD_INT, PORD_INT, PORD_INT *)
Definition gelim.c:890
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
PORD_INT * stage
Definition types.h:91
PORD_INT nstep
Definition types.h:141
struct _stageinfo stageinfo_t
Definition types.h:127
struct _gelim gelim_t
struct _bucket bucket_t

◆ eliminateStep()

PORD_INT eliminateStep ( minprior_t * minprior,
PORD_INT istage,
PORD_INT scoretype )

Definition at line 361 of file minpriority.c.

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}
PORD_INT minBucket(bucket_t *)
Definition bucket.c:117
void removeBucket(bucket_t *, PORD_INT)
Definition bucket.c:214
void buildElement(gelim_t *Gelim, PORD_INT me)
Definition gelim.c:357
PORD_INT nzf
Definition types.h:143
PORD_INT welim
Definition types.h:142
FLOAT ops
Definition types.h:144

◆ exchangeBuffer()

buffer_t * exchangeBuffer ( topology_t * ,
buffer_t * ,
PORD_INT  )

◆ expandElimTree()

elimtree_t * expandElimTree ( elimtree_t * T,
PORD_INT * vtxmap,
PORD_INT nvtxorg )

Definition at line 517 of file tree.c.

518{ elimtree_t *T2;
519 PORD_INT *vtx2front, *vtx2front2;
520 PORD_INT nfronts, J, u;
521
522 nfronts = T->nfronts;
523
524 /* --------------------------------------------------------------
525 allocate space for the new elimtree object and copy front data
526 the expanded tree has the same number of fronts/tree structure
527 -------------------------------------------------------------- */
528 T2 = newElimTree(nvtxorg, nfronts);
529 T2->root = T->root;
530 for (J = 0; J < nfronts; J++)
531 { T2->ncolfactor[J] = T->ncolfactor[J];
532 T2->ncolupdate[J] = T->ncolupdate[J];
533 T2->parent[J] = T->parent[J];
534 T2->firstchild[J] = T->firstchild[J];
535 T2->silbings[J] = T->silbings[J];
536 }
537
538 /* ---------------------------------------------------------------------
539 set up the new vtx2front vector; the trees only differ in this vector
540 --------------------------------------------------------------------- */
541 vtx2front = T->vtx2front;
542 vtx2front2 = T2->vtx2front;
543 for (u = 0; u < nvtxorg; u++)
544 vtx2front2[u] = vtx2front[vtxmap[u]];
545
546 return(T2);
547}
PORD_INT * silbings
Definition types.h:158
PORD_INT * firstchild
Definition types.h:157
PORD_INT root
Definition types.h:153

◆ extendedAdd()

denseMtx_t * extendedAdd ( denseMtx_t * ,
denseMtx_t * ,
PORD_INT * ,
PORD_INT *  )

◆ extendedAddPAR()

denseMtx_t * extendedAddPAR ( denseMtx_t * ,
denseMtx_t * ,
PORD_INT * ,
PORD_INT *  )

◆ extractElimTree()

elimtree_t * extractElimTree ( gelim_t * Gelim)

Definition at line 1012 of file gelim.c.

1013{ elimtree_t *T;
1014 PORD_INT *vwght, *par, *degree, *score, *sib, *fch;
1015 PORD_INT *ncolfactor, *ncolupdate, *parent, *vtx2front;
1016 PORD_INT nvtx, nfronts, root, u, v, front;
1017
1018 nvtx = Gelim->G->nvtx;
1019 vwght = Gelim->G->vwght;
1020 par = Gelim->parent;
1021 degree = Gelim->degree;
1022 score = Gelim->score;
1023
1024 /* ------------------------
1025 allocate working storage
1026 ------------------------ */
1027 mymalloc(sib, nvtx, PORD_INT);
1028 mymalloc(fch, nvtx, PORD_INT);
1029 for (u = 0; u < nvtx; u++)
1030 sib[u] = fch[u] = -1;
1031
1032 /* --------------------------------------------------------------
1033 count fronts and create top-down view of the tree given by par
1034 -------------------------------------------------------------- */
1035 nfronts = 0;
1036 root = -1;
1037 for (u = 0; u < nvtx; u++)
1038 switch(score[u])
1039 { case -2: /* variable u is nonprincipal */
1040 break;
1041 case -3: /* variable u has been elim. and now forms an elem. */
1042 sib[u] = root;
1043 root = u;
1044 nfronts++;
1045 break;
1046 case -4: /* element u has been absorbed by par[u] */
1047 v = par[u];
1048 sib[u] = fch[v];
1049 fch[v] = u;
1050 nfronts++;
1051 break;
1052 default:
1053 fprintf(stderr, "\nError in function extractElimTree\n"
1054 " ordering not complete (score[%d] = %d)\n", u, score[u]);
1055 quit();
1056 }
1057
1058#ifdef DEBUG
1059 for (u = 0; u < nvtx; u++)
1060 printf("node %d: score %d, par %d, fch %d, sib %d\n", u, score[u],
1061 par[u], fch[u], sib[u]);
1062#endif
1063
1064 /* --------------------------------------
1065 allocate space for the elimtree object
1066 -------------------------------------- */
1067 T = newElimTree(nvtx, nfronts);
1068 ncolfactor = T->ncolfactor;
1069 ncolupdate = T->ncolupdate;
1070 parent = T->parent;
1071 vtx2front = T->vtx2front;
1072
1073 /* -------------------------------------------------------------
1074 fill the vtx2front vector so that representative vertices are
1075 mapped in a post-order traversal
1076 ------------------------------------------------------------- */
1077 nfronts = 0;
1078 u = root;
1079 while (u != -1)
1080 { while (fch[u] != -1)
1081 u = fch[u];
1082 vtx2front[u] = nfronts++;
1083 while ((sib[u] == -1) && (par[u] != -1))
1084 { u = par[u];
1085 vtx2front[u] = nfronts++;
1086 }
1087 u = sib[u];
1088 }
1089
1090 /* ---------------------------------------------------
1091 fill in the vtx2front map for nonprincipal vertices
1092 --------------------------------------------------- */
1093 for (u = 0; u < nvtx; u++)
1094 if (score[u] == -2)
1095 { v = u;
1096 while ((par[v] != -1) && (score[v] == -2))
1097 v = par[v];
1098 vtx2front[u] = vtx2front[v];
1099 }
1100
1101 /* -------------------------------------------------------------
1102 set up the parent vector of T and fill ncolfactor, ncolupdate
1103 ------------------------------------------------------------- */
1104 for (u = 0; u < nvtx; u++)
1105 { front = vtx2front[u];
1106 if (score[u] == -3)
1107 { parent[front] = -1;
1108 ncolfactor[front] = vwght[u];
1109 ncolupdate[front] = degree[u];
1110 }
1111 if (score[u] == -4)
1112 { parent[front] = vtx2front[par[u]];
1113 ncolfactor[front] = vwght[u];
1114 ncolupdate[front] = degree[u];
1115 }
1116 }
1117
1118 /* ----------------------------
1119 set up all other arrays of T
1120 ---------------------------- */
1121 initFchSilbRoot(T);
1122
1123 /* ----------------------
1124 free memory and return
1125 ---------------------- */
1126 free(sib); free(fch);
1127 return(T);
1128}
void initFchSilbRoot(elimtree_t *)
Definition tree.c:414
elimtree_t * newElimTree(PORD_INT, PORD_INT)
Definition tree.c:110
char root[ROOTLEN]
Definition rad2rad_c.c:124

◆ extractMS2stage()

multisector_t * extractMS2stage ( nestdiss_t * ndroot)

Definition at line 182 of file multisector.c.

183{ multisector_t *ms;
184 nestdiss_t *nd, *parent;
185 PORD_INT *stage, *intvertex, *intcolor;
186 PORD_INT nvint, nnodes, totmswght, i;
187
188 /* -----------------------------------------------------------------
189 allocate memory for the multisector object and init. stage vector
190 ----------------------------------------------------------------- */
191 ms = trivialMultisector(ndroot->G);
192 stage = ms->stage;
193
194 /* ------------------------------------------------------------
195 extract the stages of the separator vertices:
196 stage[u] = 1, iff u belongs to a separator
197 ------------------------------------------------------------ */
198 nnodes = totmswght = 0;
199 for (nd = ndroot; nd->childB != NULL; nd = nd->childB);
200 while (nd != ndroot)
201 { parent = nd->parent;
202 if ((parent == NULL) || (parent->childB == NULL)
203 || (parent->childW == NULL))
204 { fprintf(stderr, "\nError in function extractMS2stage\n"
205 " nested dissection tree corrupted\n");
206 quit();
207 }
208 if (parent->childB == nd) /* left subtree of parent visited */
209 for (nd = parent->childW; nd->childB != NULL; nd = nd->childB);
210 else /* right subtree of parent visited */
211 { nd = parent; /* extract the separator of parent */
212 totmswght += nd->cwght[GRAY];
213 nvint = nd->nvint;
214 intvertex = nd->intvertex;
215 intcolor = nd->intcolor;
216 for (i = 0; i < nvint; i++)
217 if (intcolor[i] == GRAY)
218 { nnodes++;
219 stage[intvertex[i]] = 1;
220 }
221 }
222 }
223
224 /* ------------------------------------------
225 finalize the multisector object and return
226 ------------------------------------------ */
227 ms->nstages = 2;
228 ms->nnodes = nnodes;
229 ms->totmswght = totmswght;
230
231 return(ms);
232}
PORD_INT totmswght
Definition types.h:94
PORD_INT nstages
Definition types.h:92
PORD_INT nnodes
Definition types.h:93
PORD_INT * intvertex
Definition types.h:80
PORD_INT * intcolor
Definition types.h:81
graph_t * G
Definition types.h:76
struct _nestdiss * parent
Definition types.h:83

◆ extractMSmultistage()

multisector_t * extractMSmultistage ( nestdiss_t * ndroot)

Definition at line 238 of file multisector.c.

239{ multisector_t *ms;
240 nestdiss_t *nd, *parent;
241 PORD_INT *stage, *intvertex, *intcolor;
242 PORD_INT nvtx, nvint, maxstage, istage, nnodes, totmswght, i, u;
243
244 /* -----------------------------------------------------------------
245 allocate memory for the multisector object and init. stage vector
246 ----------------------------------------------------------------- */
247 ms = trivialMultisector(ndroot->G);
248 stage = ms->stage;
249
250 /* ------------------------------------------------------------
251 extract the stages of the separator vertices:
252 stage[u] = i, i>0, iff u belongs to a separator in depth i-1
253 ------------------------------------------------------------ */
254 maxstage = nnodes = totmswght = 0;
255 for (nd = ndroot; nd->childB != NULL; nd = nd->childB);
256 while (nd != ndroot)
257 { parent = nd->parent;
258 if ((parent == NULL) || (parent->childB == NULL)
259 || (parent->childW == NULL))
260 { fprintf(stderr, "\nError in function extractMSmultistage\n"
261 " nested dissection tree corrupted\n");
262 quit();
263 }
264 if (parent->childB == nd) /* left subtree of parent visited */
265 for (nd = parent->childW; nd->childB != NULL; nd = nd->childB);
266 else /* right subtree of parent visited */
267 { nd = parent; /* extract the separator of parent */
268 istage = nd->depth + 1; /* sep. vertices belong to this stage */
269 maxstage = max(maxstage, istage);
270 totmswght += nd->cwght[GRAY];
271 nvint = nd->nvint;
272 intvertex = nd->intvertex;
273 intcolor = nd->intcolor;
274 for (i = 0; i < nvint; i++)
275 if (intcolor[i] == GRAY)
276 { nnodes++;
277 stage[intvertex[i]] = istage;
278 }
279 }
280 }
281
282 /* --------------------------------------------------------------------
283 we have: stage[u] = 0 => u belongs to a domain
284 stage[u] = 1 => u belongs to the root separator (depth = 0)
285 :
286 stage[u] = maxstage => u belongs to a leaf separator
287 but we must eliminate the separators in a bottom-up fashion; we like
288 to have: stage[u] = 0 => u belongs to a domain
289 stage[u] = 1 => u belongs to a leaf separator
290 :
291 stage[u] = maxstage => u belongs to the root separator
292 -------------------------------------------------------------------- */
293 nvtx = ndroot->G->nvtx;
294 for (u = 0; u < nvtx; u++)
295 if (stage[u] > 0)
296 stage[u] = maxstage - stage[u] + 1;
297
298 /* ------------------------------------------
299 finalize the multisector object and return
300 ------------------------------------------ */
301 ms->nstages = maxstage + 1;
302 ms->nnodes = nnodes;
303 ms->totmswght = totmswght;
304
305 return(ms);
306}
PORD_INT depth
Definition types.h:78

◆ factorize1x1Kernel()

denseMtx_t * factorize1x1Kernel ( denseMtx_t * ,
PORD_INT  )

◆ factorize1x1KernelPAR()

denseMtx_t * factorize1x1KernelPAR ( topology_t * ,
mask_t * ,
PORD_INT ,
denseMtx_t * ,
frontsub_t * ,
timings_t *  )

◆ factorize2x2Kernel()

denseMtx_t * factorize2x2Kernel ( denseMtx_t * ,
PORD_INT  )

◆ factorize2x2KernelPAR()

denseMtx_t * factorize2x2KernelPAR ( topology_t * ,
mask_t * ,
PORD_INT ,
denseMtx_t * ,
frontsub_t * ,
timings_t *  )

◆ factorize3x3Kernel()

denseMtx_t * factorize3x3Kernel ( denseMtx_t * ,
PORD_INT  )

◆ factorize3x3KernelPAR()

denseMtx_t * factorize3x3KernelPAR ( topology_t * ,
mask_t * ,
PORD_INT ,
denseMtx_t * ,
frontsub_t * ,
timings_t *  )

◆ findIndMultisecs()

void findIndMultisecs ( domdec_t * dd,
PORD_INT * msvtxlist,
PORD_INT * rep )

Definition at line 670 of file ddcreate.c.

671{ PORD_INT *xadj, *adjncy, *vtype, *tmp, *bin, *checksum, *next, *key;
672 PORD_INT nvtx, nlist, flag, keepon, deg, chk, ulast, u, v, k, i, istart, istop;
673
674 nvtx = dd->G->nvtx;
675 xadj = dd->G->xadj;
676 adjncy = dd->G->adjncy;
677 vtype = dd->vtype;
678 nlist = nvtx - dd->ndom;
679 checksum = dd->map;
680
681 /* ------------------------
682 allocate working storage
683 ------------------------ */
684 mymalloc(tmp, nvtx, PORD_INT);
685 mymalloc(bin, nvtx, PORD_INT);
686 mymalloc(next, nvtx, PORD_INT);
687 mymalloc(key, nvtx, PORD_INT);
688 for (u = 0; u < nvtx; u++)
689 { tmp[u] = -1;
690 bin[u] = -1;
691 }
692
693 /* -------------------------------------------------------------------
694 compute checksums for all unelim./unabsorbed multisecs in msvtxlist
695 ------------------------------------------------------------------- */
696 flag = 1;
697 for (k = 0; k < nlist; k++)
698 { u = msvtxlist[k];
699 if (vtype[u] == 2)
700 { deg = chk = 0;
701 istart = xadj[u];
702 istop = xadj[u+1];
703 for (i = istart; i < istop; i++)
704 { v = adjncy[i];
705 if (tmp[rep[v]] != flag)
706 { tmp[rep[v]] = flag;
707 chk += rep[v];
708 deg++;
709 }
710 }
711 chk = chk % nvtx;
712 checksum[u] = chk;
713 key[u] = deg;
714 next[u] = bin[chk];
715 bin[chk] = u;
716 flag++;
717 }
718 }
719
720 /* ---------------------------------
721 merge indistinguishable multisecs
722 --------------------------------- */
723 for (k = 0; k < nlist; k++)
724 { u = msvtxlist[k];
725 if (vtype[u] == 2)
726 { chk = checksum[u];
727 v = bin[chk]; /* examine all multisecs in bin[hash] */
728 bin[chk] = -1; /* do this only once */
729 while (v != -1)
730 { istart = xadj[v];
731 istop = xadj[v+1];
732 for (i = istart; i < istop; i++)
733 tmp[rep[adjncy[i]]] = flag;
734 ulast = v; /* v is principal and u is a potiential */
735 u = next[v]; /* nonprincipal variable */
736 while (u != -1)
737 { keepon = TRUE;
738 if (key[u] != key[v])
739 keepon = FALSE;
740 if (keepon)
741 { istart = xadj[u];
742 istop = xadj[u+1];
743 for (i = istart; i < istop; i++)
744 if (tmp[rep[adjncy[i]]] != flag)
745 { keepon = FALSE;
746 break;
747 }
748 }
749 if (keepon) /* found it! mark u as nonprincipal */
750 { rep[u] = v;
751 /* printf(" >> mapping %d onto %d\n", u, v); */
752 vtype[u] = 4;
753 u = next[u];
754 next[ulast] = u; /* remove u from bin */
755 }
756 else /* failed */
757 { ulast = u;
758 u = next[u];
759 }
760 }
761 v = next[v]; /* no more variables can be absorbed by v */
762 flag++; /* clear tmp vector for next round */
763 }
764 }
765 }
766
767 /* --------------------
768 free working storage
769 -------------------- */
770 free(tmp); free(bin);
771 free(next); free(key);
772}

◆ findIndNodes()

void findIndNodes ( gelim_t * Gelim,
PORD_INT * reachset,
PORD_INT nreach,
PORD_INT * bin,
PORD_INT * next,
PORD_INT * tmp,
PORD_INT * pflag )

Definition at line 639 of file gelim.c.

641{ PORD_INT *xadj, *adjncy, *vwght, *len, *elen, *parent, *score;
642 PORD_INT nvtx, chk, keepon, u, v, w, wlast, i, j, jstart, jstop, jstep, jj, jjstop;
643 nvtx = Gelim->G->nvtx;
644 xadj = Gelim->G->xadj;
645 adjncy = Gelim->G->adjncy;
646 vwght = Gelim->G->vwght;
647 len = Gelim->len;
648 elen = Gelim->elen;
649 parent = Gelim->parent;
650 score = Gelim->score;
651
652#ifdef DEBUG
653 printf("Checking reachset for indistinguishable variables\n");
654#endif
655
656 /* -----------------------------------------------------------------------
657 compute checksums for all principal variables on reachset and fill bins
658 NOTE: checksums are stored in parent vector
659 ----------------------------------------------------------------------- */
660 for (i = 0; i < nreach; i++)
661 { u = reachset[i];
662 chk = 0;
663 jstart = xadj[u];
664 jstop = jstart + len[u];
665 /* Modified by JYL: 16 march 2005:
666 * This code was failing in case of
667 * overflow.
668 for (j = jstart; j < jstop; j++)
669 chk += adjncy[j];
670 chk = chk % nvtx;
671 */
672 jstep=max(1000000000/nvtx,1);
673 for (j = jstart; j < jstop; j+=jstep)
674 {
675 jjstop = min(jstop, j+jstep);
676 for (jj = j; jj < jjstop; jj++)
677 chk += adjncy[jj];
678 chk = chk % nvtx;
679 }
680
681 parent[u] = chk;
682 /* JYL: temporary:
683 if (parent[u] < - 10)
684 printf("Probleme %d \n",chk);*/
685 next[u] = bin[chk];
686 bin[chk] = u;
687 }
688
689 /* -----------------------
690 supervariable detection
691 ----------------------- */
692 for (i = 0; i < nreach; i++)
693 { u = reachset[i];
694 if (vwght[u] > 0) /* u is a principal variable */
695 { chk = parent[u]; /* search bin[chk] for ind. nodes */
696 v = bin[chk]; /* okay, v is the first node in this bin */
697 bin[chk] = -1; /* no further examinations of this bin */
698 while (v != -1)
699 { jstart = xadj[v];
700 jstop = xadj[v] + len[v];
701 for (j = jstart; j < jstop; j++)
702 tmp[adjncy[j]] = *pflag;
703 w = next[v]; /* v is principal and w is a potential */
704 wlast = v; /* nonprincipal variable */
705 while (w != -1)
706 { keepon = TRUE;
707 if ((len[w] != len[v]) || (elen[w] != elen[v])
708 || ((score[w] < 0) && (score[v] >= 0))
709 || ((score[w] >= 0) && (score[v] < 0)))
710 keepon = FALSE;
711 if (keepon)
712 { for (jj = xadj[w]; jj < xadj[w] + len[w]; jj++)
713 if (tmp[adjncy[jj]] < *pflag)
714 { keepon = FALSE;
715 break;
716 }
717 }
718 if (keepon) /* found it! mark w as nonprincipal */
719 { parent[w] = v; /* representative of w is v */
720 /* Temporary JY
721 if (parent[w] < - 10)
722 printf("Probleme\n");
723 */
724#ifdef DEBUG
725 printf(" non-principal variable %d (score %d) mapped onto "
726 "%d (score %d)\n", w, score[w], v, score[v]);
727#endif
728
729 vwght[v] += vwght[w]; /* add weight of w */
730 vwght[w] = 0;
731 xadj[w] = -1; /* w's adjacency list can be over- */
732 score[w] = -2; /* written during next crunch */
733 w = next[w];
734 next[wlast] = w; /* remove w from bin */
735 }
736 else /* failed */
737 { wlast = w;
738 w = next[w];
739 }
740 }
741 v = next[v]; /* no more variables can be absorbed by v */
742 (*pflag)++; /* clear tmp vector for next round */
743 }
744 }
745 }
746
747 /* -------------------------------------------------------
748 re-initialize parent vector for all principal variables
749 ------------------------------------------------------- */
750 for (i = 0; i < nreach; i++)
751 { u = reachset[i];
752 if (vwght[u] > 0)
753 parent[u] = -1;
754 }
755}

◆ findPseudoPeripheralDomain()

PORD_INT findPseudoPeripheralDomain ( domdec_t * dd,
PORD_INT domain )

Definition at line 152 of file ddbisect.c.

153{ PORD_INT *xadj, *adjncy, *vtype, *level, *queue;
154 PORD_INT nvtx, qhead, qtail, nlev, lastdomain, u, v, i, istart, istop;
155
156 nvtx = dd->G->nvtx;
157 xadj = dd->G->xadj;
158 adjncy = dd->G->adjncy;
159 vtype = dd->vtype;
160
161 /* ------------------------
162 allocate working storage
163 ------------------------ */
164 mymalloc(level, nvtx, PORD_INT);
165 mymalloc(queue, nvtx, PORD_INT);
166
167 /* ---------------------------------------
168 find a domain with maximal excentricity
169 --------------------------------------- */
170 nlev = 0; lastdomain = domain;
171 while (TRUE)
172 { for (u = 0; u < nvtx; u++)
173 level[u] = -1;
174 queue[0] = domain; level[domain] = 0;
175 qhead = 0; qtail = 1;
176 while (qhead != qtail)
177 { u = queue[qhead++];
178 if (vtype[u] == 1) /* remember last domain */
179 lastdomain = u;
180 istart = xadj[u];
181 istop = xadj[u+1];
182 for (i = istart; i < istop; i++)
183 { v = adjncy[i];
184 if (level[v] == -1)
185 { queue[qtail++] = v;
186 level[v] = level[u] + 1;
187 }
188 }
189 }
190 if (level[lastdomain] > nlev)
191 { nlev = level[lastdomain];
192 domain = lastdomain;
193 }
194 else break;
195 }
196
197 /* -------------------------------
198 free working storage and return
199 ------------------------------- */
200 free(level); free(queue);
201 return(domain);
202}

◆ firstPostorder()

PORD_INT firstPostorder ( elimtree_t * T)

Definition at line 213 of file tree.c.

214{ PORD_INT *firstchild, J;
215
216 firstchild = T->firstchild;
217
218 if ((J = T->root) != -1)
219 while (firstchild[J] != -1)
220 J = firstchild[J];
221 return(J);
222}

◆ firstPostorder2()

PORD_INT firstPostorder2 ( elimtree_t * T,
PORD_INT root )

Definition at line 228 of file tree.c.

229{ PORD_INT *firstchild, J;
230
231 firstchild = T->firstchild;
232
233 if ((J = root) != -1)
234 while (firstchild[J] != -1)
235 J = firstchild[J];
236 return(J);
237}

◆ firstPreorder()

PORD_INT firstPreorder ( elimtree_t * T)

Definition at line 263 of file tree.c.

264{
265 return(T->root);
266}

◆ forwardSubst1x1()

void forwardSubst1x1 ( factorMtx_t * ,
FLOAT *  )

◆ forwardSubst1x1KernelPAR()

void forwardSubst1x1KernelPAR ( topology_t * ,
mask_t * ,
PORD_INT ,
PORD_INT ,
factorMtx_t * ,
FLOAT * ,
FLOAT *  )

◆ forwardSubst1x1NEW()

void forwardSubst1x1NEW ( factorMtx_t * ,
FLOAT *  )

◆ forwardSubst1x1PAR()

void forwardSubst1x1PAR ( topology_t * ,
mask_t * ,
mapping_t * ,
factorMtx_t * ,
FLOAT * ,
FLOAT *  )

◆ freeBipartiteGraph()

void freeBipartiteGraph ( gbipart_t * Gbipart)

Definition at line 81 of file gbipart.c.

82{
83 freeGraph(Gbipart->G);
84 free(Gbipart);
85}
void freeGraph(graph_t *)
Definition graph.c:73

◆ freeBucket()

void freeBucket ( bucket_t * bucket)

Definition at line 78 of file bucket.c.

79{
80 free(bucket->bin);
81 free(bucket->next);
82 free(bucket->last);
83 free(bucket->key);
84 free(bucket);
85}
PORD_INT * last
Definition types.h:120
PORD_INT * next
Definition types.h:119
PORD_INT * bin
Definition types.h:118
PORD_INT * key
Definition types.h:121

◆ freeBuffer()

void freeBuffer ( buffer_t * )

◆ freeCSS()

void freeCSS ( css_t * css)

Definition at line 77 of file symbfac.c.

78{
79 free(css->xnzl);
80 free(css->xnzlsub);
81 if (css->owned)
82 free(css->nzlsub);
83 free(css);
84}
PORD_INT * xnzlsub
Definition types.h:210
PORD_INT owned
Definition types.h:207
PORD_INT * nzlsub
Definition types.h:209
PORD_INT * xnzl
Definition types.h:208

◆ freeDenseMtx()

void freeDenseMtx ( denseMtx_t * )

◆ freeDomainDecomposition()

void freeDomainDecomposition ( domdec_t * dd)

Definition at line 120 of file ddcreate.c.

121{
122 freeGraph(dd->G);
123 free(dd->vtype);
124 free(dd->color);
125 free(dd->map);
126 free(dd);
127}

◆ freeElimGraph()

void freeElimGraph ( gelim_t * Gelim)

Definition at line 128 of file gelim.c.

129{
130 freeGraph(Gelim->G);
131 free(Gelim->len);
132 free(Gelim->elen);
133 free(Gelim->parent);
134 free(Gelim->degree);
135 free(Gelim->score);
136 free(Gelim);
137}

◆ freeElimTree()

void freeElimTree ( elimtree_t * T)

Definition at line 132 of file tree.c.

133{
134 free(T->ncolfactor);
135 free(T->ncolupdate);
136 free(T->parent);
137 free(T->firstchild);
138 free(T->silbings);
139 free(T->vtx2front);
140 free(T);
141}

◆ freeFactorMtx()

void freeFactorMtx ( factorMtx_t * L)

Definition at line 465 of file symbfac.c.

466{
467 freeCSS(L->css);
469 free(L->nzl);
470 free(L->perm);
471 free(L);
472}
frontsub_t * frontsub
Definition types.h:231
PORD_INT * perm
Definition types.h:228
FLOAT * nzl
Definition types.h:229
css_t * css
Definition types.h:230
void freeCSS(css_t *css)
Definition symbfac.c:77
void freeFrontSubscripts(frontsub_t *frontsub)
Definition symbfac.c:286

◆ freeFrontSubscripts()

void freeFrontSubscripts ( frontsub_t * frontsub)

Definition at line 286 of file symbfac.c.

287{
288 freeElimTree(frontsub->PTP);
289 free(frontsub->xnzf);
290 free(frontsub->nzfsub);
291 free(frontsub);
292}
void freeElimTree(elimtree_t *)
Definition tree.c:132
PORD_INT * nzfsub
Definition types.h:220
elimtree_t * PTP
Definition types.h:217
PORD_INT * xnzf
Definition types.h:219

◆ freeGbisect()

void freeGbisect ( gbisect_t * Gbisect)

Definition at line 77 of file gbisect.c.

78{
79 free(Gbisect->color);
80 free(Gbisect);
81}

◆ freeGraph()

void freeGraph ( graph_t * G)

Definition at line 73 of file graph.c.

74{
75 free(G->xadj);
76 free(G->adjncy);
77 free(G->vwght);
78 free(G);
79}

◆ freeInputMtx()

void freeInputMtx ( inputMtx_t * )

◆ freeMapping()

void freeMapping ( mapping_t * )

◆ freeMask()

void freeMask ( mask_t * )

◆ freeMinPriority()

void freeMinPriority ( minprior_t * minprior)

Definition at line 107 of file minpriority.c.

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}
void freeElimGraph(gelim_t *)
Definition gelim.c:128
void freeBucket(bucket_t *)
Definition bucket.c:78

◆ freeMultisector()

void freeMultisector ( multisector_t * ms)

Definition at line 86 of file multisector.c.

87{
88 free(ms->stage);
89 free(ms);
90}

◆ freeNDnode()

void freeNDnode ( nestdiss_t * nd)

Definition at line 96 of file nestdiss.c.

97{
98 free(nd->intvertex);
99 free(nd->intcolor);
100 free(nd);
101}

◆ freeNDtree()

void freeNDtree ( nestdiss_t * ndroot)

Definition at line 260 of file nestdiss.c.

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}
void freeNDnode(nestdiss_t *nd)
Definition nestdiss.c:96

◆ freeTopology()

void freeTopology ( topology_t * )

◆ freeWorkspaceForDenseMtx()

void freeWorkspaceForDenseMtx ( workspace_t * )

◆ fundamentalFronts()

elimtree_t * fundamentalFronts ( elimtree_t * T)

Definition at line 553 of file tree.c.

554{ elimtree_t *T2;
555 PORD_INT *ncolfactor, *ncolupdate, *parent, *firstchild, *silbings;
556 PORD_INT *frontmap, nfronts, cnfronts, J, child;
557
558 nfronts = T->nfronts;
559 ncolfactor = T->ncolfactor;
560 ncolupdate = T->ncolupdate;
561 parent = T->parent;
562 firstchild = T->firstchild;
563 silbings = T->silbings;
564
565 /* -------------------------
566 set up the working arrays
567 ------------------------- */
568 mymalloc(frontmap, nfronts, PORD_INT);
569
570 /* -----------------------------
571 search the fundamental fronts
572 ----------------------------- */
573 cnfronts = 0;
574 J = T->root;
575 while (J != -1)
576 { while (firstchild[J] != -1)
577 J = firstchild[J];
578 frontmap[J] = cnfronts++;
579 while ((silbings[J] == -1) && (parent[J] != -1))
580 { J = parent[J];
581 child = firstchild[J];
582 if ((silbings[child] != -1)
583 || (ncolupdate[child] != ncolfactor[J] + ncolupdate[J]))
584 frontmap[J] = cnfronts++;
585 else
586 frontmap[J] = frontmap[child];
587 }
588 J = silbings[J];
589 }
590
591 /* ------------------------------
592 construct new elimination tree
593 ------------------------------ */
594 T2 = compressElimTree(T, frontmap, cnfronts);
595
596 /* ----------------------
597 free memory and return
598 ---------------------- */
599 free(frontmap);
600 return(T2);
601}
elimtree_t * compressElimTree(elimtree_t *T, PORD_INT *frontmap, PORD_INT cnfronts)
Definition tree.c:689

◆ getWorkspaceForDenseMtx()

FLOAT * getWorkspaceForDenseMtx ( workspace_t * ,
PORD_INT  )

◆ greg_pord()

PORD_INT greg_pord ( PORD_INT ,
PORD_INT ,
PORD_INT * ,
PORD_INT * ,
PORD_INT * ,
PORD_INT * ,
PORD_INT *  )

◆ improveDDSep()

void improveDDSep ( domdec_t * dd)

Definition at line 607 of file ddbisect.c.

608{ bucket_t *b_bucket, *w_bucket;
609 PORD_INT *xadj, *adjncy, *vwght, *vtype, *color, *cwght;
610 PORD_INT *tmp_color, *deltaS, *deltaB, *deltaW;
611 PORD_INT nvtx, weight, tmp_S, tmp_B, tmp_W;
612 PORD_INT pos, bestglobalpos, badflips, b_domain, w_domain, domain, nxtdomain;
613 PORD_INT fhead, ftail, u, v, i, istart, istop;
614 FLOAT bestglobalvalue, b_value, w_value, value;
615
616 /* ======================================================================
617 vtype[u]: (u domain)
618 1 => color of domain u has not been changed
619 < 0 => points to next domain in flipping list
620 (fhead points to first, ftail points to last domain in list)
621 = 0 => domain is last domain in flipping list
622 ====================================================================== */
623
624 nvtx = dd->G->nvtx;
625 xadj = dd->G->xadj;
626 adjncy = dd->G->adjncy;
627 vwght = dd->G->vwght;
628 vtype = dd->vtype;
629 color = dd->color;
630 cwght = dd->cwght;
631
632 mymalloc(tmp_color, nvtx, PORD_INT);
633 mymalloc(deltaS, nvtx, PORD_INT);
634 mymalloc(deltaB, nvtx, PORD_INT);
635 mymalloc(deltaW, nvtx, PORD_INT);
636
637OUTER_LOOP_START:
638
639 /* ----------------------------------------------------------------------
640 copy data of actual bisection and initialize buckets and flipping list
641 ---------------------------------------------------------------------- */
642 tmp_S = cwght[GRAY];
643 tmp_B = cwght[BLACK];
644 tmp_W = cwght[WHITE];
645 bestglobalpos = badflips = 0;
646 bestglobalvalue = F(tmp_S, tmp_B, tmp_W);
647
648 b_bucket = setupBucket(nvtx, nvtx, (nvtx >> 1));
649 w_bucket = setupBucket(nvtx, nvtx, (nvtx >> 1));
650
651 fhead = 0; ftail = -1;
652 pos = 0;
653
654 /* ----------------------------------------------------------
655 initialize tmp_color, deltaB, and deltaW for all multisecs
656 ---------------------------------------------------------- */
657 for (u = 0; u < nvtx; u++)
658 if (vtype[u] == 2)
659 { deltaB[u] = deltaW[u] = 0;
660 istart = xadj[u];
661 istop = xadj[u+1];
662 for (i = istart; i < istop; i++)
663 { v = adjncy[i];
664 if (color[v] == BLACK) deltaB[u]++;
665 else deltaW[u]++;
666 }
667 if ((deltaB[u] > 0) && (deltaW[u] > 0)) /* update multisec coloring */
668 tmp_color[u] = GRAY;
669 else if (deltaB[u] > 0) tmp_color[u] = BLACK;
670 else tmp_color[u] = WHITE;
671 color[u] = tmp_color[u];
672 }
673
674 /* -----------------------------------------------------------------
675 initialize tmp_color, deltaS,B,W for all domains and fill buckets
676 ----------------------------------------------------------------- */
677 for (u = 0; u < nvtx; u++)
678 if (vtype[u] == 1)
679 { tmp_color[u] = color[u];
680 if (tmp_color[u] == BLACK) /* domain may be flipped to WHITE */
681 { deltaW[u] = vwght[u]; deltaB[u] = -deltaW[u]; deltaS[u] = 0;
682 istart = xadj[u];
683 istop = xadj[u+1];
684 for (i = istart; i < istop; i++)
685 { v = adjncy[i]; /* tmp_color[v] e {GRAY, BLACK} */
686 weight = vwght[v];
687 if (tmp_color[v] == BLACK) /* multisec v will move into S */
688 { deltaB[u] -= weight;
689 deltaS[u] += weight;
690 }
691 else if (deltaB[v] == 1) /* multisec v will move into W */
692 { deltaW[u] += weight;
693 deltaS[u] -= weight;
694 deltaB[v] = -(u+1);
695 }
696 }
697 insertBucket(b_bucket, deltaS[u], u);
698 }
699 if (tmp_color[u] == WHITE) /* domain may be flipped to BLACK */
700 { deltaB[u] = vwght[u]; deltaW[u] = -deltaB[u]; deltaS[u] = 0;
701 istart = xadj[u];
702 istop = xadj[u+1];
703 for (i = istart; i < istop; i++)
704 { v = adjncy[i]; /* tmp_color[v] e {GRAY, WHITE} */
705 weight = vwght[v];
706 if (tmp_color[v] == WHITE) /* multisec v will move into S */
707 { deltaW[u] -= weight;
708 deltaS[u] += weight;
709 }
710 else if (deltaW[v] == 1) /* multisec v will move into B */
711 { deltaB[u] += weight;
712 deltaS[u] -= weight;
713 deltaW[v] = -(u+1);
714 }
715 }
716 insertBucket(w_bucket, deltaS[u], u);
717 }
718 }
719
720#ifdef DEBUG
721 printf("starting inner loop: b_bucket->nobj %d, w_bucket->nobj %d\n",
722 b_bucket->nobj, w_bucket->nobj);
723 waitkey();
724#endif
725
726INNER_LOOP_START:
727
728 /* -------------------------------------------
729 extract best domain from b_bucket, w_bucket
730 ------------------------------------------- */
731 b_value = w_value = MAX_FLOAT;
732 if ((b_domain = minBucket(b_bucket)) != -1)
733 { b_value = F((tmp_S+deltaS[b_domain]), (tmp_B+deltaB[b_domain]),
734 (tmp_W+deltaW[b_domain]));
735
736#ifdef DEBUG
737 printf("best black domain: %d, deltaS %d, deltaB %d, deltaW %d, "
738 "cost %7.2f\n", b_domain, deltaS[b_domain], deltaB[b_domain],
739 deltaW[b_domain], b_value);
740#endif
741 }
742 if ((w_domain = minBucket(w_bucket)) != -1)
743 { w_value = F((tmp_S+deltaS[w_domain]), (tmp_B+deltaB[w_domain]),
744 (tmp_W+deltaW[w_domain]));
745
746#ifdef DEBUG
747 printf("best white domain: %d, deltaS %d, deltaB %d, deltaW %d, "
748 "cost %7.2f\n", w_domain, deltaS[w_domain], deltaB[w_domain],
749 deltaW[w_domain], w_value);
750#endif
751 }
752
753 if ((b_domain == ERR) && (w_domain == ERR)) goto INNER_LOOP_END;
754
755 if (b_value + EPS < w_value)
756 { domain = b_domain; value = b_value;
757 removeBucket(b_bucket, domain);
758 }
759 else
760 { domain = w_domain; value = w_value;
761 removeBucket(w_bucket, domain);
762 }
763
764#ifdef DEBUG
765 printf(" domain %d removed from bucket\n", domain);
766#endif
767
768 /* -------------------------------------------------------------------
769 flip the color of domain and put it in list of log. flipped domains
770 ------------------------------------------------------------------- */
771 if (ftail != -1)
772 vtype[ftail] = -(domain+1); /* append domain */
773 else fhead = -(domain+1); /* list starts with domain */
774 vtype[domain] = 0; /* mark end of list */
775 ftail = domain; /* domain is last element in list */
776
777 if (tmp_color[domain] == BLACK)
778 { tmp_color[domain] = WHITE;
779 updateB2W(w_bucket,b_bucket,dd,domain,tmp_color,deltaW,deltaB,deltaS);
780 }
781 else if (tmp_color[domain] == WHITE)
782 { tmp_color[domain] = BLACK;
783 updateW2B(w_bucket,b_bucket,dd,domain,tmp_color,deltaW,deltaB,deltaS);
784 }
785 tmp_S += deltaS[domain];
786 tmp_B += deltaB[domain];
787 tmp_W += deltaW[domain];
788
789 pos++;
790 if (value + EPS < bestglobalvalue)
791 { bestglobalvalue = value;
792 bestglobalpos = pos;
793 badflips = 0;
794 }
795 else badflips++;
796 if (badflips < MAX_BAD_FLIPS) goto INNER_LOOP_START;
797
798INNER_LOOP_END:
799
800 /* --------------------------------------------
801 end of inner loop: now do the physical flips
802 -------------------------------------------- */
803 pos = 0;
804 nxtdomain = fhead;
805 while (nxtdomain != 0)
806 { domain = -nxtdomain - 1;
807 if (pos < bestglobalpos)
808 { if (color[domain] == BLACK) color[domain] = WHITE;
809 else color[domain] = BLACK;
810 cwght[GRAY] += deltaS[domain];
811 cwght[BLACK] += deltaB[domain];
812 cwght[WHITE] += deltaW[domain];
813 pos++;
814 }
815 nxtdomain = vtype[domain];
816 vtype[domain] = 1;
817 }
818
819 /* ----------------------------------------------
820 partition improved => re-start the whole stuff
821 ---------------------------------------------- */
822#ifdef DEBUG
823 printf(" INNER_LOOP_END (#pyhs. flips %d): S %d, B %d, W %d (%7.2f)\n",
824 bestglobalpos, cwght[GRAY], cwght[BLACK], cwght[WHITE],
825 bestglobalvalue);
826 waitkey();
827#endif
828
829 /* JY: moved next instruction after the two
830 * freeBucket instructions because
831 * this was the cause of a memory leak.
832 * if (bestglobalpos > 0) goto OUTER_LOOP_START;
833 */
834
835 freeBucket(b_bucket);
836 freeBucket(w_bucket);
837
838 if (bestglobalpos > 0) goto OUTER_LOOP_START;
839 free(tmp_color); free(deltaS); free(deltaB); free(deltaW);
840}
#define EPS
Definition const.h:58
#define ERR
Definition const.h:53
#define MAX_FLOAT
Definition const.h:57
void updateW2B(bucket_t *w_bucket, bucket_t *b_bucket, domdec_t *dd, PORD_INT domain, PORD_INT *tmp_color, PORD_INT *deltaW, PORD_INT *deltaB, PORD_INT *deltaS)
Definition ddbisect.c:495
void updateB2W(bucket_t *w_bucket, bucket_t *b_bucket, domdec_t *dd, PORD_INT domain, PORD_INT *tmp_color, PORD_INT *deltaW, PORD_INT *deltaB, PORD_INT *deltaS)
Definition ddbisect.c:383
#define waitkey()
Definition macros.h:52
#define MAX_BAD_FLIPS
Definition params.h:13
bucket_t * setupBucket(PORD_INT, PORD_INT, PORD_INT)
Definition bucket.c:91
PORD_INT nobj
Definition types.h:116

◆ initFactorMtx()

void initFactorMtx ( factorMtx_t * L,
inputMtx_t * PAP )

Definition at line 510 of file symbfac.c.

511{ elimtree_t *PTP;
512 frontsub_t *frontsub;
513 css_t *css;
514 PORD_INT *ncolfactor;
515 FLOAT *nzl, *nza, *diag;
516 PORD_INT *xnzl, *nzlsub, *xnzlsub, *xnza, *nzasub, *xnzf, *nzfsub;
517 PORD_INT nelem, K, k, kstart, h, hstart, dis, i, istart, istop;
518 PORD_INT firstcol, lastcol;
519
520 nelem = L->nelem;
521 nzl = L->nzl;
522 css = L->css;
523 xnzl = css->xnzl;
524 nzlsub = css->nzlsub;
525 xnzlsub = css->xnzlsub;
526
527 frontsub = L->frontsub;
528 PTP = frontsub->PTP;
529 ncolfactor = PTP->ncolfactor;
530 xnzf = frontsub->xnzf;
531 nzfsub = frontsub->nzfsub;
532
533 diag = PAP->diag;
534 nza = PAP->nza;
535 xnza = PAP->xnza;
536 nzasub = PAP->nzasub;
537
538 /* ------------------------------------
539 set all numerical values of L to 0.0
540 ------------------------------------ */
541 for (i = 0; i < nelem; i++)
542 nzl[i] = 0.0;
543
544 /* --------------------------------------------
545 init. factor matrix with the nonzeros of PAP
546 -------------------------------------------- */
547 for (K = firstPostorder(PTP); K != -1; K = nextPostorder(PTP, K))
548 { firstcol = nzfsub[xnzf[K]];
549 lastcol = firstcol + ncolfactor[K];
550 for (k = firstcol; k < lastcol; k++)
551 { istart = xnza[k];
552 istop = xnza[k+1];
553 kstart = xnzl[k];
554 hstart = xnzlsub[k];
555 h = hstart;
556 for (i = istart; i < istop; i++)
557 { for (; nzlsub[h] != nzasub[i]; h++);
558 dis = h - hstart;
559 nzl[kstart+dis] = nza[i];
560 }
561 nzl[kstart] = diag[k];
562 }
563 }
564}
PORD_INT nextPostorder(elimtree_t *, PORD_INT)
Definition tree.c:243
PORD_INT firstPostorder(elimtree_t *)
Definition tree.c:213
PORD_INT nelem
Definition types.h:227
PORD_INT * xnza
Definition types.h:170
FLOAT * nza
Definition types.h:169
PORD_INT * nzasub
Definition types.h:171
FLOAT * diag
Definition types.h:168
struct _frontsub frontsub_t
struct _css css_t

◆ initFactorMtxNEW()

void initFactorMtxNEW ( factorMtx_t * L,
inputMtx_t * PAP )

Definition at line 570 of file symbfac.c.

571{ elimtree_t *PTP;
572 frontsub_t *frontsub;
573 css_t *css;
574 PORD_INT *ncolfactor;
575 FLOAT *nzl, *nza, *diag, *entriesL;
576 PORD_INT *xnzl, *xnza, *nzasub, *xnzf, *nzfsub;
577 PORD_INT *tmp, neqs, nelem, K, k, len, row, i, istart, istop;
578 PORD_INT firstcol, lastcol;
579
580 nelem = L->nelem;
581 nzl = L->nzl;
582 css = L->css;
583 xnzl = css->xnzl;
584
585 frontsub = L->frontsub;
586 PTP = frontsub->PTP;
587 ncolfactor = PTP->ncolfactor;
588 xnzf = frontsub->xnzf;
589 nzfsub = frontsub->nzfsub;
590
591 neqs = PAP->neqs;
592 diag = PAP->diag;
593 nza = PAP->nza;
594 xnza = PAP->xnza;
595 nzasub = PAP->nzasub;
596
597 /* ------------------------
598 allocate working storage
599 ------------------------ */
600 mymalloc(tmp, neqs, PORD_INT);
601
602 /* ------------------------------------
603 set all numerical values of L to 0.0
604 ------------------------------------ */
605 for (i = 0; i < nelem; i++)
606 nzl[i] = 0.0;
607
608 /* --------------------------------------------
609 init. factor matrix with the nonzeros of PAP
610 -------------------------------------------- */
611 for (K = firstPostorder(PTP); K != -1; K = nextPostorder(PTP, K))
612 { len = 0;
613 istart = xnzf[K];
614 istop = xnzf[K+1];
615 for (i = istart; i < istop; i++)
616 tmp[nzfsub[i]] = len++;
617
618 firstcol = nzfsub[istart];
619 lastcol = firstcol + ncolfactor[K];
620 entriesL = nzl + xnzl[firstcol];
621 for (k = firstcol; k < lastcol; k++)
622 { istart = xnza[k];
623 istop = xnza[k+1];
624 for (i = istart; i < istop; i++)
625 { row = nzasub[i];
626 entriesL[tmp[row]] = nza[i];
627 }
628 entriesL[tmp[k]] = diag[k];
629 entriesL += --len;
630 }
631 }
632
633 /* --------------------
634 free working storage
635 -------------------- */
636 free(tmp);
637}
PORD_INT neqs
Definition types.h:166

◆ initFactorMtxPAR()

void initFactorMtxPAR ( mask_t * ,
mapping_t * ,
factorMtx_t * ,
inputMtx_t *  )

◆ initFchSilbRoot()

void initFchSilbRoot ( elimtree_t * T)

Definition at line 414 of file tree.c.

415{ PORD_INT *parent, *firstchild, *silbings, nfronts, J, pJ;
416
417 nfronts = T->nfronts;
418 parent = T->parent;
419 firstchild = T->firstchild;
420 silbings = T->silbings;
421
422 for (J = 0; J < nfronts; J++)
423 silbings[J] = firstchild[J] = -1;
424
425 for (J = nfronts-1; J >= 0; J--)
426 if ((pJ = parent[J]) != -1)
427 { silbings[J] = firstchild[pJ];
428 firstchild[pJ] = J;
429 }
430 else
431 { silbings[J] = T->root;
432 T->root = J;
433 }
434}

◆ initialDDSep()

void initialDDSep ( domdec_t * dd)

Definition at line 348 of file ddbisect.c.

349{ PORD_INT *vtype, *color, *cwght;
350 PORD_INT nvtx, totvwght, domain, u;
351
352 nvtx = dd->G->nvtx;
353 totvwght = dd->G->totvwght;
354 vtype = dd->vtype;
355 color = dd->color;
356 cwght = dd->cwght;
357
358 /* --------------------------------------------------------
359 initializations (all nodes are colored white by default)
360 -------------------------------------------------------- */
361 cwght[GRAY] = 0;
362 cwght[BLACK] = 0;
363 cwght[WHITE] = totvwght;
364 for (u = 0; u < nvtx; u++)
365 color[u] = WHITE;
366
367 /* ----------------------------------------------------------------------
368 scan over connected components and create level based vertex separator
369 ---------------------------------------------------------------------- */
370 for (u = 0; u < nvtx; u++)
371 if ((vtype[u] == 1) && (color[u] == WHITE))
372 { domain = findPseudoPeripheralDomain(dd, u);
373 constructLevelSep(dd, domain);
374 if (cwght[BLACK] >= cwght[WHITE])
375 break;
376 }
377}
void constructLevelSep(domdec_t *dd, PORD_INT domain)
Definition ddbisect.c:208
PORD_INT findPseudoPeripheralDomain(domdec_t *dd, PORD_INT domain)
Definition ddbisect.c:152

◆ initialDomainDecomposition()

domdec_t * initialDomainDecomposition ( graph_t * G,
PORD_INT * map,
PORD_INT * vtype,
PORD_INT * rep )

Definition at line 366 of file ddcreate.c.

367{ domdec_t *dd;
368 PORD_INT *xadj, *adjncy, *vwght, *xadjdd, *adjncydd, *vwghtdd, *vtypedd;
369 PORD_INT *tmp, *bin, nvtx, nedges, nvtxdd, nedgesdd, ndom, domwght, flag;
370 PORD_INT i, j, jstart, jstop, u, v, w;
371
372 nvtx = G->nvtx;
373 nedges = G->nedges;
374 xadj = G->xadj;
375 adjncy = G->adjncy;
376 vwght = G->vwght;
377
378 /* ------------------------
379 allocate working storage
380 ------------------------ */
381 mymalloc(tmp, nvtx, PORD_INT);
382 mymalloc(bin, nvtx, PORD_INT);
383 for (u = 0; u < nvtx; u++)
384 { tmp[u] = -1;
385 bin[u] = -1;
386 }
387
388 /* -------------------------------------------------------------
389 allocate memory for the dd using upper bounds nvtx and nedges
390 ------------------------------------------------------------- */
391 dd = newDomainDecomposition(nvtx, nedges);
392 xadjdd = dd->G->xadj;
393 adjncydd = dd->G->adjncy;
394 vwghtdd = dd->G->vwght;
395 vtypedd = dd->vtype;
396
397 /* -------------------------------------------------------
398 put all nodes u belonging to representative v in bin[v]
399 ------------------------------------------------------- */
400 for (u = 0; u < nvtx; u++)
401 { v = rep[u];
402 if (u != v)
403 { bin[u] = bin[v];
404 bin[v] = u;
405 }
406 }
407
408 /* ----------------------------------------------
409 and now build the initial domain decomposition
410 ---------------------------------------------- */
411 flag = 1;
412 nedgesdd = nvtxdd = 0;
413 ndom = domwght = 0;
414 for (u = 0; u < nvtx; u++)
415 if (rep[u] == u)
416 { xadjdd[nvtxdd] = nedgesdd;
417 vtypedd[nvtxdd] = vtype[u];
418 vwghtdd[nvtxdd] = 0;
419 tmp[u] = flag;
420
421 /* find all cluster that are adjacent to u in dom. dec. */
422 v = u;
423 do
424 { map[v] = nvtxdd;
425 vwghtdd[nvtxdd] += vwght[v];
426 jstart = xadj[v];
427 jstop = xadj[v+1];
428 for (j = jstart; j < jstop; j++)
429 { w = adjncy[j];
430 if ((vtype[w] != vtype[u]) && (tmp[rep[w]] != flag))
431 { tmp[rep[w]] = flag;
432 adjncydd[nedgesdd++] = rep[w];
433 }
434 }
435 v = bin[v];
436 } while (v != -1);
437
438 if (vtypedd[nvtxdd] == 1)
439 { ndom++;
440 domwght += vwghtdd[nvtxdd];
441 }
442 nvtxdd++;
443 flag++;
444 }
445
446 /* --------------------------------------------
447 finalize the new domain decomposition object
448 -------------------------------------------- */
449 xadjdd[nvtxdd] = nedgesdd;
450 dd->G->nvtx = nvtxdd;
451 dd->G->nedges = nedgesdd;
452 dd->G->type = WEIGHTED;
453 dd->G->totvwght = G->totvwght;
454 for (i = 0; i < nedgesdd; i++)
455 adjncydd[i] = map[adjncydd[i]];
456 for (u = 0; u < nvtxdd; u++)
457 dd->color[u] = dd->map[u] = -1;
458 dd->ndom = ndom;
459 dd->domwght = domwght;
460
461 /* -------------------------------
462 free working storage and return
463 ------------------------------- */
464 free(tmp); free(bin);
465 return(dd);
466}

◆ initLocalIndices()

void initLocalIndices ( denseMtx_t * ,
PORD_INT * ,
PORD_INT *  )

◆ initLocalIndicesPAR()

void initLocalIndicesPAR ( denseMtx_t * ,
PORD_INT * ,
PORD_INT *  )

◆ initWorkspaceForDenseMtx()

workspace_t * initWorkspaceForDenseMtx ( PORD_INT ,
PORD_INT  )

◆ insertBucket()

void insertBucket ( bucket_t * bucket,
PORD_INT k,
PORD_INT item )

Definition at line 163 of file bucket.c.

164{ PORD_INT s, nextitem;
165
166 /* ------------------------------------
167 check whether there are any problems
168 ------------------------------------ */
169 if (abs(k) >= MAX_INT - bucket->offset - 1)
170 { fprintf(stderr, "\nError in function insertBucket\n"
171 " key %d too large/small for bucket\n", k);
172 quit();
173 }
174 if (item > bucket->maxitem)
175 { fprintf(stderr, "\nError in function insertBucket\n"
176 " item %d too large for bucket (maxitem is %d)\n", item,
177 bucket->maxitem);
178 quit();
179 }
180 if (bucket->key[item] != MAX_INT)
181 { fprintf(stderr, "\nError in function insertBucket\n"
182 " item %d already in bucket\n", item);
183 quit();
184 }
185
186 /* -------------------------------------
187 determine the bin that holds the item
188 ------------------------------------- */
189 s = max(0, (k + bucket->offset));
190 s = min(s, bucket->maxbin);
191
192 /* --------------------------------------------------------------
193 adjust minbin, increase nobj, and mark item as being in bucket
194 -------------------------------------------------------------- */
195 bucket->minbin = min(bucket->minbin, s);
196 bucket->nobj++;
197 bucket->key[item] = k;
198
199 /* -----------------------------
200 finally, insert item in bin s
201 ----------------------------- */
202 nextitem = bucket->bin[s];
203 if (nextitem != -1)
204 bucket->last[nextitem] = item;
205 bucket->next[item] = nextitem;
206 bucket->last[item] = -1;
207 bucket->bin[s] = item;
208}
PORD_INT offset
Definition types.h:115
PORD_INT maxitem
Definition types.h:114
PORD_INT minbin
Definition types.h:117
PORD_INT maxbin
Definition types.h:114

◆ insertDownIntsWithStaticFloatKeys()

void insertDownIntsWithStaticFloatKeys ( PORD_INT n,
PORD_INT * array,
FLOAT * key )

Definition at line 58 of file sort.c.

59{ PORD_INT i, j, e;
60 FLOAT ke;
61
62 for (i = 1; i < n; i++)
63 { e = array[i]; ke = key[e]; j = i;
64 while ((j > 0) && (key[array[j-1]] < ke))
65 { array[j] = array[j-1];
66 j--;
67 }
68 array[j] = e;
69 }
70}

◆ insertUpFloatsWithIntKeys()

void insertUpFloatsWithIntKeys ( PORD_INT n,
FLOAT * array,
PORD_INT * key )

Definition at line 77 of file sort.c.

78{ PORD_INT i, j, ke;
79 FLOAT e;
80
81 for (i = 1; i < n; i++)
82 { e = array[i]; ke = key[i]; j = i;
83 while ((j > 0) && (key[j-1] > ke))
84 { array[j] = array[j-1];
85 key[j] = key[j-1];
86 j--;
87 }
88 array[j] = e;
89 key[j] = ke;
90 }
91}

◆ insertUpInts()

void insertUpInts ( PORD_INT n,
PORD_INT * array )

Definition at line 21 of file sort.c.

22{ PORD_INT i, j, v;
23
24 for (i = 1; i < n; i++)
25 { v = array[i]; j = i;
26 while ((j > 0) && (array[j-1] > v))
27 { array[j] = array[j-1];
28 j--;
29 }
30 array[j] = v;
31 }
32}

◆ insertUpIntsWithStaticIntKeys()

void insertUpIntsWithStaticIntKeys ( PORD_INT n,
PORD_INT * array,
PORD_INT * key )

Definition at line 39 of file sort.c.

40{ PORD_INT i, j, ke;
41 PORD_INT e;
42
43 for (i = 1; i < n; i++)
44 { e = array[i]; ke = key[e]; j = i;
45 while ((j > 0) && (key[array[j-1]] > ke))
46 { array[j] = array[j-1];
47 j--;
48 }
49 array[j] = e;
50 }
51}

◆ justifyFronts()

PORD_INT justifyFronts ( elimtree_t * T)

Definition at line 741 of file tree.c.

742{ PORD_INT *ncolfactor, *ncolupdate, *firstchild, *silbings, *minWspace, *list;
743 PORD_INT nfronts, K, ncolfrontK, frontsizeK, wspace, child, nxtchild;
744 PORD_INT count, m, s, i;
745
746 nfronts = T->nfronts;
747 ncolfactor = T->ncolfactor;
748 ncolupdate = T->ncolupdate;
749 firstchild = T->firstchild;
750 silbings = T->silbings;
751
752 /* -------------------------
753 set up the working arrays
754 ------------------------- */
755 mymalloc(minWspace, nfronts, PORD_INT);
756 mymalloc(list, nfronts, PORD_INT);
757
758 /* ---------------------------------------------------------
759 postorder traversal of the elimination tree to obtain the
760 optimal justification of the children of each front
761 ---------------------------------------------------------- */
762 wspace = 0;
763 for (K = firstPostorder(T); K != -1; K = nextPostorder(T, K))
764 { ncolfrontK = ncolfactor[K] + ncolupdate[K];
765 frontsizeK = (ncolfrontK * (ncolfrontK + 1)) >> 1;
766
767 if ((child = firstchild[K]) == -1)
768 minWspace[K] = frontsizeK;
769 else
770 { count = 0;
771
772 /* sort children according to their minWspace value */
773 while (child != -1)
774 { list[count++] = child;
775 child = silbings[child];
776 }
777 insertUpIntsWithStaticIntKeys(count, list, minWspace);
778 firstchild[K] = -1;
779 for (i = 0; i < count; i++)
780 { child = list[i];
781 silbings[child] = firstchild[K];
782 firstchild[K] = child;
783 }
784
785 /* compute minWspace[K] */
786 child = firstchild[K];
787 nxtchild = silbings[child];
788 m = s = minWspace[child];
789 while (nxtchild != -1)
790 { s = s - minWspace[child]
791 + ((ncolupdate[child] * (ncolupdate[child] + 1)) >> 1)
792 + minWspace[nxtchild];
793 m = max(m, s);
794 child = nxtchild;
795 nxtchild = silbings[nxtchild];
796 }
797 s = s - minWspace[child]
798 + ((ncolupdate[child] * (ncolupdate[child] + 1)) >> 1)
799 + frontsizeK;
800 minWspace[K] = max(m, s);
801 }
802
803 wspace = max(wspace, minWspace[K]);
804 }
805
806 /* ----------------------
807 free memory and return
808 ---------------------- */
809 free(minWspace); free(list);
810 return(wspace);
811}
void insertUpIntsWithStaticIntKeys(PORD_INT, PORD_INT *, PORD_INT *)
Definition sort.c:39
PORD_INT firstPostorder(elimtree_t *T)
Definition tree.c:213
PORD_INT nextPostorder(elimtree_t *T, PORD_INT J)
Definition tree.c:243

◆ listing()

void listing ( mapping_t * ,
PORD_INT ,
PORD_INT ,
PORD_INT ,
FLOAT * ,
FLOAT *  )

◆ maximumFlow()

void maximumFlow ( gbipart_t * Gbipart,
PORD_INT * flow,
PORD_INT * rc )

Definition at line 322 of file gbipart.c.

323{ PORD_INT *xadj, *adjncy, *vwght, *parent, *marker, *queue;
324 PORD_INT nedges, u, v, x, y, nX, nY, j, i, istart, istop;
325 PORD_INT qhead, qtail, capacity;
326
327 nedges = Gbipart->G->nedges;
328 xadj = Gbipart->G->xadj;
329 adjncy = Gbipart->G->adjncy;
330 vwght = Gbipart->G->vwght;
331 nX = Gbipart->nX;
332 nY = Gbipart->nY;
333
334 mymalloc(parent, (nX+nY), PORD_INT);
335 mymalloc(marker, (nX+nY), PORD_INT);
336 mymalloc(queue, (nX+nY), PORD_INT);
337
338 /* -------------------------------------
339 initialize flow and residual capacity
340 ------------------------------------- */
341 for (u = 0; u < nX+nY; u++)
342 rc[u] = vwght[u];
343 for (i = 0; i < nedges; i++)
344 flow[i] = 0;
345
346 /* --------------------------------------------------
347 determine an initial flow in the bipartite network
348 -------------------------------------------------- */
349 for (x = 0; x < nX; x++)
350 { istart = xadj[x];
351 istop = xadj[x+1];
352 for (i = istart; i < istop; i++)
353 { y = adjncy[i];
354 capacity = min(rc[x], rc[y]);
355 if (capacity > 0)
356 { rc[x] -= capacity;
357 rc[y] -= capacity;
358 flow[i] = capacity;
359 for (j = xadj[y]; adjncy[j] != x; j++);
360 flow[j] = -capacity;
361 }
362 if (rc[x] == 0) break;
363 }
364 }
365
366 /* -----------------------------------------------------------
367 construct maximum flow in bipartite network (Edmonds, Karp)
368 ----------------------------------------------------------- */
369 while (TRUE)
370 { for (u = 0; u < nX+nY; u++)
371 parent[u] = marker[u] = -1;
372 qhead = qtail = 0; /* fill queue with free X nodes */
373 for (x = 0; x < nX; x++)
374 if (rc[x] > 0)
375 { queue[qtail++] = x;
376 parent[x] = x;
377 }
378
379 /* ---------------------------------------------------------
380 breadth first search to find the shortest augmenting path
381 --------------------------------------------------------- */
382 capacity = 0;
383 while (qhead != qtail)
384 { u = queue[qhead++];
385 istart = xadj[u];
386 istop = xadj[u+1];
387 for (i = istart; i < istop; i++)
388 { v = adjncy[i];
389 if ((parent[v] == -1) && ((v >= nX) || (flow[i] < 0)))
390 /* v >= nX => u->v is a forward edge having infty capacity */
391 /* otherwise u<-v is a backward edge and (v,u) must have */
392 /* positive capacity (i.e. (u,v) has neg. capacity) */
393 { parent[v] = u;
394 marker[v] = i;
395 queue[qtail++] = v;
396 if ((v >= nX) && (rc[v] > 0)) /* found it! */
397 { u = v; /* (v,sink) is below capacity */
398 capacity = rc[u];
399 while (parent[u] != u) /* get minimal residual capa. */
400 { i = marker[u];
401 u = parent[u];
402 if (u >= nX)
403 capacity = min(capacity, -flow[i]);
404 }
405 capacity = min(capacity, rc[u]);
406 rc[v] -= capacity; /* augment flow by min. rc */
407 while (parent[v] != v)
408 { i = marker[v];
409 u = parent[v];
410 flow[i] += capacity;
411 for (j = xadj[v]; adjncy[j] != u; j++);
412 flow[j] = -flow[i];
413 v = u;
414 }
415 rc[v] -= capacity;
416 qhead = qtail; /* escape inner while loop */
417 break;
418 }
419 }
420 }
421 }
422
423 if (capacity == 0)
424 break;
425 }
426
427 free(parent); free(marker);
428 free(queue);
429}

◆ maximumMatching()

void maximumMatching ( gbipart_t * Gbipart,
PORD_INT * matching )

Definition at line 195 of file gbipart.c.

196{ PORD_INT *xadj, *adjncy, *level, *marker, *queue, *stack;
197 PORD_INT top, top2, u, x, x2, y, y2, nX, nY, i, istart, istop;
198 PORD_INT qhead, qtail, max_level;
199
200 xadj = Gbipart->G->xadj;
201 adjncy = Gbipart->G->adjncy;
202 nX = Gbipart->nX;
203 nY = Gbipart->nY;
204
205 mymalloc(level, (nX+nY), PORD_INT);
206 mymalloc(marker, (nX+nY), PORD_INT);
207 mymalloc(queue, nX, PORD_INT);
208 mymalloc(stack, nY, PORD_INT);
209
210 /* -------------------
211 initialize matching
212 ------------------- */
213 for (u = 0; u < nX+nY; u++)
214 matching[u] = FREE;
215
216 /* ---------------------------------------------------
217 construct maximal matching in bipartite graph (X,Y)
218 --------------------------------------------------- */
219 for (x = 0; x < nX; x++)
220 { istart = xadj[x];
221 istop = xadj[x+1];
222 for (i = istart; i < istop; i++)
223 { y = adjncy[i];
224 if (matching[y] == FREE)
225 { matching[x] = y;
226 matching[y] = x;
227 break;
228 }
229 }
230 }
231
232 /* --------------------------------------------------------------------
233 construct maximum matching in bipartite graph (X,Y) (Hopcroft, Karp)
234 -------------------------------------------------------------------- */
235 while (TRUE)
236 { for (u = 0; u < nX+nY; u++)
237 level[u] = marker[u] = -1;
238 qhead = qtail = 0; /* fill queue with free X nodes */
239 for (x = 0; x < nX; x++)
240 if (matching[x] == FREE)
241 { queue[qtail++] = x;
242 level[x] = 0;
243 }
244
245 /* --------------------------------------------------------------
246 breadth first search to construct layer network containing all
247 vertex disjoint augmenting paths of minimal length
248 -------------------------------------------------------------- */
249 top = 0;
250 max_level = MAX_INT;
251 while (qhead != qtail)
252 { x = queue[qhead++]; /* note: queue contains only */
253 if (level[x] < max_level) /* nodes from X */
254 { istart = xadj[x];
255 istop = xadj[x+1];
256 for (i = istart; i < istop; i++)
257 { y = adjncy[i];
258 if (level[y] == -1)
259 { level[y] = level[x] + 1;
260 if (matching[y] == FREE)
261 { max_level = level[y]; /* note: stack contains only */
262 stack[top++] = y; /* nodes form Y */
263 }
264 else if (level[y] < max_level)
265 { x2 = matching[y];
266 level[x2] = level[y] + 1;
267 queue[qtail++] = x2;
268 }
269 }
270 }
271 }
272 }
273 if (top == 0) break; /* no augmenting path found */
274
275 /* ------------------------------------------------------------
276 restricted depth first search to construct maximal number of
277 vertex disjoint augmenting paths in layer network
278 ------------------------------------------------------------ */
279 while (top > 0)
280 { top2 = top--;
281 y = stack[top2-1]; /* get the next exposed node in Y */
282 marker[y] = xadj[y]; /* points to next neighbor of y */
283
284 while (top2 > top)
285 { y = stack[top2-1];
286 i = marker[y]++;
287 if (i < xadj[y+1]) /* not all neighbors of y visited */
288 { x = adjncy[i];
289 if ((marker[x] == -1) && (level[x] == level[y]-1))
290 { marker[x] = 0;
291 if (level[x] == 0) /* augmenting path found */
292 while (top2 > top) /* pop stack */
293 { y2 = stack[--top2];
294 x2 = matching[y2]; /* / o == o */
295 matching[x] = y2; /* / */
296 matching[y2] = x; /* x -- y2 == x2 -- y */
297 x = x2; /* \ */
298 } /* \ o == o */
299 else
300 { y2 = matching[x];
301 stack[top2++] = y2;
302 marker[y2] = xadj[y2];
303 }
304 }
305 }
306 else top2--;
307 }
308 }
309 }
310
311 /* -------------------------------
312 free working storage and return
313 ------------------------------- */
314 free(level); free(marker);
315 free(queue); free(stack);
316}

◆ mergeFronts()

elimtree_t * mergeFronts ( elimtree_t * T,
PORD_INT maxzeros )

Definition at line 607 of file tree.c.

608{ elimtree_t *T2;
609 PORD_INT *ncolfactor, *ncolupdate, *firstchild, *silbings;
610 PORD_INT *frontmap, *newncolfactor, *nzeros, *rep;
611 PORD_INT nfronts, cnfronts, K, ncolfrontK, J, Jall, cost;
612
613 nfronts = T->nfronts;
614 ncolfactor = T->ncolfactor;
615 ncolupdate = T->ncolupdate;
616 firstchild = T->firstchild;
617 silbings = T->silbings;
618
619 /* -------------------------
620 set up the working arrays
621 ------------------------- */
622 mymalloc(frontmap, nfronts, PORD_INT);
623 mymalloc(newncolfactor, nfronts, PORD_INT);
624 mymalloc(nzeros, nfronts, PORD_INT);
625 mymalloc(rep, nfronts, PORD_INT);
626 for (K = 0; K < nfronts; K++)
627 { newncolfactor[K] = ncolfactor[K];
628 nzeros[K] = 0;
629 rep[K] = K;
630 }
631
632 /* -----------------------------------------------------
633 perform a postorder traversal of the elimination tree
634 ----------------------------------------------------- */
635 for (K = firstPostorder(T); K != -1; K = nextPostorder(T, K))
636 if (firstchild[K] != -1)
637 { ncolfrontK = newncolfactor[K] + ncolupdate[K];
638 Jall = 0;
639 cost = 0;
640 for (J = firstchild[K]; J != -1; J = silbings[J])
641 { Jall += newncolfactor[J];
642 cost -= newncolfactor[J] * newncolfactor[J];
643 cost += 2*newncolfactor[J] * (ncolfrontK - ncolupdate[J]);
644 cost += 2*nzeros[J];
645 }
646 cost += Jall * Jall;
647 cost = cost / 2;
648 if (cost < maxzeros)
649 { for (J = firstchild[K]; J != -1; J = silbings[J])
650 { rep[J] = K;
651 newncolfactor[K] += newncolfactor[J];
652 }
653 nzeros[K] = cost;
654 }
655 }
656
657 /* ----------------------------------
658 construct frontmap from vector rep
659 ---------------------------------- */
660 cnfronts = 0;
661 for (K = 0; K < nfronts; K++)
662 if (rep[K] == K)
663 frontmap[K] = cnfronts++;
664 else
665 { for (J = K; rep[J] != J; J = rep[J]);
666 rep[K] = J;
667 }
668 for (K = 0; K < nfronts; K++)
669 if ((J = rep[K]) != K)
670 frontmap[K] = frontmap[J];
671
672 /* ------------------------------
673 construct new elimination tree
674 ------------------------------ */
675 T2 = compressElimTree(T, frontmap, cnfronts);
676
677 /* ----------------------
678 free memory and return
679 ---------------------- */
680 free(frontmap); free(newncolfactor);
681 free(nzeros); free(rep);
682 return(T2);
683}

◆ mergeMultisecs()

void mergeMultisecs ( graph_t * G,
PORD_INT * vtype,
PORD_INT * rep )

Definition at line 280 of file ddcreate.c.

281{ PORD_INT *xadj, *adjncy, *tmp, *queue;
282 PORD_INT nvtx, qhead, qtail, flag, keepon, u, v, w, x;
283 PORD_INT i, istart, istop, j, jstart, jstop;
284
285 nvtx = G->nvtx;
286 xadj = G->xadj;
287 adjncy = G->adjncy;
288
289 /* ------------------------
290 allocate working storage
291 ------------------------ */
292 mymalloc(tmp, nvtx, PORD_INT);
293 mymalloc(queue, nvtx, PORD_INT);
294 for (u = 0; u < nvtx; u++)
295 tmp[u] = -1;
296
297 /* -------------------------------------------------------
298 merge all adjacent multisecs that do not share a domain
299 ------------------------------------------------------- */
300 flag = 1;
301 for (u = 0; u < nvtx; u++)
302 if (vtype[u] == 2)
303 { qhead = 0; qtail = 1;
304 queue[0] = u;
305 vtype[u] = -2;
306
307 /* multisec u is the seed of a new cluster, mark all adj. domains */
308 istart = xadj[u];
309 istop = xadj[u+1];
310 for (i = istart; i < istop; i++)
311 { v = adjncy[i];
312 if (vtype[v] == 1)
313 tmp[rep[v]] = flag;
314 }
315
316 /* and now build the cluster */
317 while (qhead != qtail)
318 { v = queue[qhead++];
319 istart = xadj[v];
320 istop = xadj[v+1];
321 for (i = istart; i < istop; i++)
322 { keepon = TRUE;
323 w = adjncy[i];
324 if (vtype[w] == 2)
325 { jstart = xadj[w];
326 jstop = xadj[w+1];
327 for (j = jstart; j < jstop; j++)
328 { x = adjncy[j];
329 if ((vtype[x] == 1) && (tmp[rep[x]] == flag))
330 { keepon = FALSE;
331 break;
332 }
333 }
334 if (keepon)
335 /* multisecs v and w have no domain in common; mark */
336 /* all domains adjacent to w and put w in cluster u */
337 { for (j = jstart; j < jstop; j++)
338 { x = adjncy[j];
339 if (vtype[x] == 1) tmp[rep[x]] = flag;
340 }
341 queue[qtail++] = w;
342 rep[w] = u;
343 vtype[w] = -2;
344 }
345 }
346 }
347 }
348
349 /* clear tmp vector for next round */
350 flag++;
351 }
352
353 /* ------------------------------------
354 reset vtype and free working storage
355 ------------------------------------ */
356 for (u = 0; u < nvtx; u++)
357 if (vtype[u] == -2)
358 vtype[u] = 2;
359 free(tmp); free(queue);
360}

◆ minBucket()

PORD_INT minBucket ( bucket_t * bucket)

Definition at line 117 of file bucket.c.

118{ PORD_INT *bin, *next, *key, maxbin, minbin, nobj;
119 PORD_INT item, bestitem, bestkey;
120
121 maxbin = bucket->maxbin;
122 nobj = bucket->nobj;
123 minbin = bucket->minbin;
124 bin = bucket->bin;
125 next = bucket->next;
126 key = bucket->key;
127
128 if (nobj > 0)
129 { /* ---------------------------------------------
130 get the first item from leftmost nonempty bin
131 --------------------------------------------- */
132 while (bin[minbin] == -1) minbin++;
133 bucket->minbin = minbin;
134 bestitem = bin[minbin];
135 bestkey = minbin;
136
137 /* --------------------------------------------------
138 items in bins 0 and maxbin can have different keys
139 => search for item with smallest key
140 -------------------------------------------------- */
141 if ((minbin == 0) || (minbin == maxbin))
142 { item = next[bestitem];
143 while (item != -1)
144 { if (key[item] < bestkey)
145 { bestitem = item;
146 bestkey = key[item];
147 }
148 item = next[item];
149 }
150 }
151 /* ---------------------------------
152 return the item with smallest key
153 --------------------------------- */
154 return(bestitem);
155 }
156 else return(-1);
157}

◆ myrank()

PORD_INT myrank ( void )

◆ newBipartiteGraph()

gbipart_t * newBipartiteGraph ( PORD_INT nX,
PORD_INT nY,
PORD_INT nedges )

Definition at line 66 of file gbipart.c.

67{ gbipart_t *Gbipart;
68
69 mymalloc(Gbipart, 1, gbipart_t);
70 Gbipart->G = newGraph(nX+nY, nedges);
71 Gbipart->nX = nX;
72 Gbipart->nY = nY;
73
74 return(Gbipart);
75}
graph_t * newGraph(PORD_INT, PORD_INT)
Definition graph.c:50
struct _gbipart gbipart_t

◆ newBucket()

bucket_t * newBucket ( PORD_INT maxbin,
PORD_INT maxitem,
PORD_INT offset )

Definition at line 56 of file bucket.c.

57{ bucket_t *bucket;
58
59 mymalloc(bucket, 1, bucket_t);
60 mymalloc(bucket->bin, (maxbin+1), PORD_INT);
61 mymalloc(bucket->next, (maxitem+1), PORD_INT);
62 mymalloc(bucket->last, (maxitem+1), PORD_INT);
63 mymalloc(bucket->key, (maxitem+1), PORD_INT);
64
65 bucket->maxbin = maxbin;
66 bucket->maxitem = maxitem;
67 bucket->offset = offset;
68 bucket->nobj = 0;
69 bucket->minbin = MAX_INT;
70
71 return(bucket);
72}
integer, dimension(:), allocatable offset
Definition rad2r.F:53

◆ newBuffer()

buffer_t * newBuffer ( size_t )

◆ newCSS()

css_t * newCSS ( PORD_INT neqs,
PORD_INT nind,
PORD_INT owned )

Definition at line 56 of file symbfac.c.

57{ css_t *css;
58
59 mymalloc(css, 1, css_t);
60 mymalloc(css->xnzl, (neqs+1), PORD_INT);
61 mymalloc(css->xnzlsub, neqs, PORD_INT);
62 if (owned)
63 { mymalloc(css->nzlsub, nind, PORD_INT); }
64 else
65 { css->nzlsub = NULL; }
66 css->neqs = neqs;
67 css->nind = nind;
68 css->owned = owned;
69
70 return(css);
71}
PORD_INT neqs
Definition types.h:205
PORD_INT nind
Definition types.h:206

◆ newDenseMtx()

denseMtx_t * newDenseMtx ( workspace_t * ,
PORD_INT  )

◆ newDomainDecomposition()

domdec_t * newDomainDecomposition ( PORD_INT nvtx,
PORD_INT nedges )

Definition at line 100 of file ddcreate.c.

101{ domdec_t *dd;
102
103 mymalloc(dd, 1, domdec_t);
104 mymalloc(dd->vtype, nvtx, PORD_INT);
105 mymalloc(dd->color, nvtx, PORD_INT);
106 mymalloc(dd->map, nvtx, PORD_INT);
107
108 dd->G = newGraph(nvtx, nedges);
109 dd->ndom = dd->domwght = 0;
110 dd->cwght[GRAY] = dd->cwght[BLACK] = dd->cwght[WHITE] = 0;
111 dd->prev = dd->next = NULL;
112
113 return(dd);
114}

◆ newElimGraph()

gelim_t * newElimGraph ( PORD_INT nvtx,
PORD_INT nedges )

Definition at line 108 of file gelim.c.

109{ gelim_t *Gelim;
110
111 mymalloc(Gelim, 1, gelim_t);
112 Gelim->G = newGraph(nvtx, nedges);
113 Gelim->maxedges = nedges;
114
115 mymalloc(Gelim->len, nvtx, PORD_INT);
116 mymalloc(Gelim->elen, nvtx, PORD_INT);
117 mymalloc(Gelim->parent, nvtx, PORD_INT);
118 mymalloc(Gelim->degree, nvtx, PORD_INT);
119 mymalloc(Gelim->score, nvtx, PORD_INT);
120
121 return(Gelim);
122}

◆ newElimTree()

elimtree_t * newElimTree ( PORD_INT nvtx,
PORD_INT nfronts )

Definition at line 110 of file tree.c.

111{ elimtree_t *T;
112
113 mymalloc(T, 1, elimtree_t);
114 mymalloc(T->ncolfactor, nfronts, PORD_INT);
115 mymalloc(T->ncolupdate, nfronts, PORD_INT);
116 mymalloc(T->parent, nfronts, PORD_INT);
117 mymalloc(T->firstchild, nfronts, PORD_INT);
118 mymalloc(T->silbings, nfronts, PORD_INT);
119 mymalloc(T->vtx2front, nvtx, PORD_INT);
120
121 T->nvtx = nvtx;
122 T->nfronts = nfronts;
123 T->root = -1;
124
125 return(T);
126}

◆ newFactorMtx()

factorMtx_t * newFactorMtx ( PORD_INT nelem)

Definition at line 447 of file symbfac.c.

448{ factorMtx_t *L;
449
450 mymalloc(L, 1, factorMtx_t);
451 mymalloc(L->nzl, nelem, FLOAT);
452
453 L->nelem = nelem;
454 L->css = NULL;
455 L->frontsub = NULL;
456 L->perm = NULL;
457
458 return(L);
459}
struct _factorMtx factorMtx_t

◆ newFrontSubscripts()

frontsub_t * newFrontSubscripts ( elimtree_t * PTP)

Definition at line 265 of file symbfac.c.

266{ frontsub_t *frontsub;
267 PORD_INT nfronts, nind;
268
269 nfronts = PTP->nfronts;
270 nind = nFactorIndices(PTP);
271
272 mymalloc(frontsub, 1, frontsub_t);
273 mymalloc(frontsub->xnzf, (nfronts+1), PORD_INT);
274 mymalloc(frontsub->nzfsub, nind, PORD_INT);
275
276 frontsub->PTP = PTP;
277 frontsub->nind = nind;
278
279 return(frontsub);
280}
PORD_INT nFactorIndices(elimtree_t *)
Definition tree.c:874
PORD_INT nind
Definition types.h:218

◆ newFrontSubscriptsPAR()

frontsub_t * newFrontSubscriptsPAR ( mask_t * ,
mapping_t * ,
elimtree_t *  )

◆ newGbisect()

gbisect_t * newGbisect ( graph_t * G)

Definition at line 59 of file gbisect.c.

60{ gbisect_t *Gbisect;
61
62 mymalloc(Gbisect, 1, gbisect_t);
63 mymalloc(Gbisect->color, G->nvtx, PORD_INT);
64
65 Gbisect->G = G;
66 Gbisect->cwght[GRAY] = 0;
67 Gbisect->cwght[BLACK] = 0;
68 Gbisect->cwght[WHITE] = 0;
69
70 return(Gbisect);
71}
struct _gbisect gbisect_t

◆ newGraph()

graph_t * newGraph ( PORD_INT nvtx,
PORD_INT nedges )

Definition at line 50 of file graph.c.

51{ graph_t *G;
52 PORD_INT i;
53
54 mymalloc(G, 1, graph_t);
55 mymalloc(G->xadj, (nvtx+1), PORD_INT);
56 mymalloc(G->adjncy, nedges, PORD_INT);
57 mymalloc(G->vwght, nvtx, PORD_INT);
58
59 G->nvtx = nvtx;
60 G->nedges = nedges;
61 G->type = UNWEIGHTED;
62 G->totvwght = nvtx;
63 for (i = 0; i < nvtx; i++)
64 G->vwght[i] = 1;
65
66 return(G);
67}

◆ newInputMtx()

inputMtx_t * newInputMtx ( PORD_INT ,
PORD_INT  )

◆ newMapping()

mapping_t * newMapping ( elimtree_t * ,
PORD_INT  )

◆ newMask()

mask_t * newMask ( PORD_INT )

◆ newMinPriority()

minprior_t * newMinPriority ( PORD_INT nvtx,
PORD_INT nstages )

Definition at line 81 of file minpriority.c.

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}
struct _minprior minprior_t

◆ newMultisector()

multisector_t * newMultisector ( graph_t * G)

Definition at line 68 of file multisector.c.

69{ multisector_t *ms;
70
71 mymalloc(ms, 1, multisector_t);
72 mymalloc(ms->stage, G->nvtx, PORD_INT);
73
74 ms->G = G;
75 ms->nstages = 0;
76 ms->nnodes = 0;
77 ms->totmswght = 0;
78
79 return(ms);
80}
graph_t * G
Definition types.h:90

◆ newNDnode()

nestdiss_t * newNDnode ( graph_t * G,
PORD_INT * map,
PORD_INT nvint )

Definition at line 75 of file nestdiss.c.

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}
PORD_INT * map
Definition types.h:77

◆ newTopology()

topology_t * newTopology ( PORD_INT )

◆ nextPostorder()

PORD_INT nextPostorder ( elimtree_t * T,
PORD_INT J )

Definition at line 243 of file tree.c.

244{ PORD_INT *parent, *firstchild, *silbings;
245
246 parent = T->parent;
247 firstchild = T->firstchild;
248 silbings = T->silbings;
249
250 if (silbings[J] != -1)
251 { J = silbings[J];
252 while (firstchild[J] != -1)
253 J = firstchild[J];
254 }
255 else J = parent[J];
256 return(J);
257}

◆ nextPreorder()

PORD_INT nextPreorder ( elimtree_t * T,
PORD_INT J )

Definition at line 272 of file tree.c.

273{ PORD_INT *parent, *firstchild, *silbings;
274
275 parent = T->parent;
276 firstchild = T->firstchild;
277 silbings = T->silbings;
278
279 if (firstchild[J] != -1)
280 J = firstchild[J];
281 else
282 { while ((silbings[J] == -1) && (parent[J] != -1))
283 J = parent[J];
284 J = silbings[J];
285 }
286 return(J);
287}

◆ nFactorEntries()

PORD_INT nFactorEntries ( elimtree_t * T)

Definition at line 892 of file tree.c.

893{ PORD_INT *ncolfactor, *ncolupdate;
894 PORD_INT ent, tri, rec, K;
895
896 ncolfactor = T->ncolfactor;
897 ncolupdate = T->ncolupdate;
898
899 ent = 0;
900 for (K = firstPostorder(T); K != -1; K = nextPostorder(T, K))
901 { tri = ncolfactor[K];
902 rec = ncolupdate[K];
903 ent += (tri * (tri+1)) / 2;
904 ent += (tri * rec);
905 }
906 return(ent);
907}

◆ nFactorIndices()

PORD_INT nFactorIndices ( elimtree_t * T)

Definition at line 874 of file tree.c.

875{ PORD_INT *ncolfactor, *ncolupdate;
876 PORD_INT nfronts, ind, K;
877
878 nfronts = T->nfronts;
879 ncolfactor = T->ncolfactor;
880 ncolupdate = T->ncolupdate;
881
882 ind = 0;
883 for (K = 0; K < nfronts; K++)
884 ind += (ncolfactor[K] + ncolupdate[K]);
885 return(ind);
886}

◆ nFactorOps()

FLOAT nFactorOps ( elimtree_t * T)

Definition at line 913 of file tree.c.

914{ PORD_INT *ncolfactor, *ncolupdate;
915 FLOAT ops, tri, rec;
916 PORD_INT K;
917
918 ncolfactor = T->ncolfactor;
919 ncolupdate = T->ncolupdate;
920
921 ops = 0.0;
922 for (K = firstPostorder(T); K != -1; K = nextPostorder(T, K))
923 { tri = ncolfactor[K];
924 rec = ncolupdate[K];
925 ops += (tri*tri*tri) / 3.0 + (tri*tri) / 2.0 - (5*tri) / 6.0;
926 ops += (tri*tri*rec) + (rec*(rec+1)*tri);
927 }
928 return(ops);
929}

◆ nTriangularOps()

FLOAT nTriangularOps ( elimtree_t * T)

Definition at line 957 of file tree.c.

958{ PORD_INT *ncolfactor, *ncolupdate;
959 FLOAT ops, tri, rec;
960 PORD_INT K;
961
962 ncolfactor = T->ncolfactor;
963 ncolupdate = T->ncolupdate;
964
965 ops = 0.0;
966 for (K = firstPostorder(T); K != -1; K = nextPostorder(T, K))
967 { tri = ncolfactor[K];
968 rec = ncolupdate[K];
969 ops += (tri*tri) + 2.0*tri*rec; /* forward ops */
970 ops += (tri*tri) + 2.0*tri*rec; /* backward ops */
971 }
972 return(ops);
973}

◆ numfac()

void numfac ( factorMtx_t * L,
timings_t * cpus )

◆ numfacPAR()

void numfacPAR ( topology_t * ,
mask_t * ,
mapping_t * ,
factorMtx_t * ,
PORD_INT msglvl,
timings_t *  )

◆ nWorkspace()

PORD_INT nWorkspace ( elimtree_t * T)

Definition at line 817 of file tree.c.

818{ PORD_INT *ncolfactor, *ncolupdate, *firstchild, *silbings, *minWspace;
819 PORD_INT nfronts, K, ncolfrontK, frontsizeK, wspace, child, nxtchild, m, s;
820
821 nfronts = T->nfronts;
822 ncolfactor = T->ncolfactor;
823 ncolupdate = T->ncolupdate;
824 firstchild = T->firstchild;
825 silbings = T->silbings;
826
827 /* -------------------------
828 set up the working arrays
829 ------------------------- */
830 mymalloc(minWspace, nfronts, PORD_INT);
831
832 /* -------------------------------------------
833 postorder traversal of the elimination tree
834 ------------------------------------------- */
835 wspace = 0;
836 for (K = firstPostorder(T); K != -1; K = nextPostorder(T, K))
837 { ncolfrontK = ncolfactor[K] + ncolupdate[K];
838 frontsizeK = (ncolfrontK * (ncolfrontK + 1)) >> 1;
839
840 if ((child = firstchild[K]) == -1)
841 minWspace[K] = frontsizeK;
842 else
843 { child = firstchild[K];
844 nxtchild = silbings[child];
845 m = s = minWspace[child];
846 while (nxtchild != -1)
847 { s = s - minWspace[child]
848 + ((ncolupdate[child] * (ncolupdate[child] + 1)) >> 1)
849 + minWspace[nxtchild];
850 m = max(m, s);
851 child = nxtchild;
852 nxtchild = silbings[nxtchild];
853 }
854 s = s - minWspace[child]
855 + ((ncolupdate[child] * (ncolupdate[child] + 1)) >> 1)
856 + frontsizeK;
857 minWspace[K] = max(m, s);
858 }
859
860 wspace = max(wspace, minWspace[K]);
861 }
862
863 /* ----------------------
864 free memory and return
865 ---------------------- */
866 free(minWspace);
867 return(wspace);
868}

◆ orderMinPriority()

elimtree_t * orderMinPriority ( minprior_t * minprior,
options_t * options,
timings_t * cpus )

Definition at line 159 of file minpriority.c.

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}
#define OPTION_NODE_SELECTION1
Definition const.h:79
#define OPTION_NODE_SELECTION2
Definition const.h:80
void eliminateStage(minprior_t *minprior, PORD_INT istage, PORD_INT scoretype, timings_t *cpus)
elimtree_t * extractElimTree(gelim_t *)
Definition gelim.c:1012

◆ permFromElimTree()

void permFromElimTree ( elimtree_t * T,
PORD_INT * perm )

Definition at line 440 of file tree.c.

441{ PORD_INT *vtx2front, *first, *link;
442 PORD_INT nvtx, nfronts, K, u, count;
443
444 nvtx = T->nvtx;
445 nfronts = T->nfronts;
446 vtx2front = T->vtx2front;
447
448 /* -----------------------------------------------------------
449 store the vertices/columns of a front in a bucket structure
450 ----------------------------------------------------------- */
451 mymalloc(first, nfronts, PORD_INT);
452 mymalloc(link, nvtx, PORD_INT);
453
454 for (K = 0; K < nfronts; K++)
455 first[K] = -1;
456 for (u = nvtx-1; u >= 0; u--)
457 { K = vtx2front[u];
458 link[u] = first[K];
459 first[K] = u;
460 }
461
462 /* -----------------------------------------------------
463 postorder traversal of the elimination tree to obtain
464 the permutation vectors perm, invp
465 ----------------------------------------------------- */
466 count = 0;
467 for (K = firstPostorder(T); K != -1; K = nextPostorder(T, K))
468 for (u = first[K]; u != -1; u = link[u])
469 { perm[u] = count;
470 count++;
471 }
472
473 /* ----------------------
474 free memory and return
475 ---------------------- */
476 free(first); free(link);
477}

◆ permuteElimTree()

elimtree_t * permuteElimTree ( elimtree_t * T,
PORD_INT * perm )

Definition at line 483 of file tree.c.

484{ elimtree_t *PTP;
485 PORD_INT nvtx, nfronts, J, u;
486
487 nvtx = T->nvtx;
488 nfronts = T->nfronts;
489
490 /* --------------------------------------------------------------
491 allocate space for the new elimtree object and copy front data
492 the permuted tree has the same number of fronts/tree structure
493 -------------------------------------------------------------- */
494 PTP = newElimTree(nvtx, nfronts);
495 PTP->root = T->root;
496 for (J = 0; J < nfronts; J++)
497 { PTP->ncolfactor[J] = T->ncolfactor[J];
498 PTP->ncolupdate[J] = T->ncolupdate[J];
499 PTP->parent[J] = T->parent[J];
500 PTP->firstchild[J] = T->firstchild[J];
501 PTP->silbings[J] = T->silbings[J];
502 }
503
504 /* ---------------------------------------------------------------------
505 set up the new vtx2front vector; the trees only differ in this vector
506 --------------------------------------------------------------------- */
507 for (u = 0; u < nvtx; u++)
508 PTP->vtx2front[perm[u]] = T->vtx2front[u];
509
510 return(PTP);
511}

◆ permuteInputMtx()

inputMtx_t * permuteInputMtx ( inputMtx_t * ,
PORD_INT *  )

◆ printDenseMtx()

void printDenseMtx ( denseMtx_t * )

◆ printDomainDecomposition()

void printDomainDecomposition ( domdec_t * dd)

Definition at line 133 of file ddcreate.c.

134{ graph_t *G;
135 PORD_INT count, u, v, i, istart, istop;
136
137 G = dd->G;
138 printf("\n#nodes %d (#domains %d, weight %d), #edges %d, totvwght %d\n",
139 G->nvtx, dd->ndom, dd->domwght, G->nedges >> 1, G->totvwght);
140 printf("partition weights: S %d, B %d, W %d\n", dd->cwght[GRAY],
141 dd->cwght[BLACK], dd->cwght[WHITE]);
142 for (u = 0; u < G->nvtx; u++)
143 { count = 0;
144 printf("--- adjacency list of node %d (vtype %d, color %d, map %d\n",
145 u, dd->vtype[u], dd->color[u], dd->map[u]);
146 istart = G->xadj[u];
147 istop = G->xadj[u+1];
148 for (i = istart; i < istop; i++)
149 { v = G->adjncy[i];
150 printf("%5d (vtype %2d, color %2d)", v, dd->vtype[v], dd->color[v]);
151 if ((++count % 3) == 0)
152 printf("\n");
153 }
154 if ((count % 3) != 0)
155 printf("\n");
156 }
157}

◆ printElimGraph()

void printElimGraph ( gelim_t * Gelim)

Definition at line 143 of file gelim.c.

144{ graph_t *G;
145 PORD_INT count, u, v, i, istart;
146
147 G = Gelim->G;
148 for (u = 0; u < G->nvtx; u++)
149 { istart = G->xadj[u];
150
151 /* ---------------------------------------------------------------
152 case 1: u is a principal variable
153 => vwght[u]: weight of all mapped indistinguishable variables
154 => degree[u]: approximate degree
155 ---------------------------------------------------------------- */
156 if ((Gelim->score[u] == -1) || (Gelim->score[u] >= 0))
157 { printf("--- adjacency list of variable %d (weight %d, degree %d, "
158 "score %d):\n", u, G->vwght[u], Gelim->degree[u],
159 Gelim->score[u]);
160 printf("elements:\n");
161 count = 0;
162 for (i = istart; i < istart + Gelim->elen[u]; i++)
163 { printf("%5d", G->adjncy[i]);
164 if ((++count % 16) == 0)
165 printf("\n");
166 }
167 if ((count % 16) != 0)
168 printf("\n");
169 printf("variables:\n");
170 count = 0;
171 for (i = istart + Gelim->elen[u]; i < istart + Gelim->len[u]; i++)
172 { printf("%5d", G->adjncy[i]);
173 if ((++count % 16) == 0)
174 printf("\n");
175 }
176 if ((count % 16) != 0)
177 printf("\n");
178 }
179
180 /* ---------------------------------------------------------------
181 case 2: u is nonprincipal/removed by mass elimination
182 ---------------------------------------------------------------- */
183 else if (Gelim->score[u] == -2)
184 printf("--- variable %d is nonprincipal/removed by mass elim. "
185 "(parent %d)\n", u, Gelim->parent[u]);
186
187 /* -----------------------------------------------
188 case 3: u is an element:
189 => degree[u]: weight of boundary
190 ----------------------------------------------- */
191 else if (Gelim->score[u] == -3)
192 { printf("--- boundary of element %d (degree %d, score %d):"
193 "\n", u, Gelim->degree[u], Gelim->score[u]);
194 count = 0;
195 for (i = istart; i < istart + Gelim->len[u]; i++)
196 { v = G->adjncy[i];
197 if (G->vwght[v] > 0)
198 { printf("%5d", G->adjncy[i]);
199 if ((++count % 16) == 0)
200 printf("\n");
201 }
202 }
203 if ((count % 16) != 0)
204 printf("\n");
205 }
206
207 /* --------------------------------
208 case 4: u is an absorbed element
209 -------------------------------- */
210 else if (Gelim->score[u] == -4)
211 printf("--- element %d has been absorbed (parent %d)\n", u,
212 Gelim->parent[u]);
213
214 /* ----------------------------------------
215 none of the above cases is true => error
216 ---------------------------------------- */
217 else
218 { fprintf(stderr, "\nError in function printElimGraph\n"
219 " node %d has invalid score %d\n", u, Gelim->score[u]);
220 quit();
221 }
222 }
223}

◆ printElimTree()

void printElimTree ( elimtree_t * T)

Definition at line 147 of file tree.c.

148{ PORD_INT *ncolfactor, *ncolupdate, *parent, *firstchild, *silbings, *vtx2front;
149 PORD_INT *first, *link, nvtx, nfronts, root, J, K, u, count, child;
150
151 nvtx = T->nvtx;
152 nfronts = T->nfronts;
153 root = T->root;
154 ncolfactor = T->ncolfactor;
155 ncolupdate = T->ncolupdate;
156 parent = T->parent;
157 firstchild = T->firstchild;
158 silbings = T->silbings;
159 vtx2front = T->vtx2front;
160
161 printf("#fronts %d, root %d\n", nfronts, root);
162
163 /* -----------------------------------------------------------
164 store the vertices/columns of a front in a bucket structure
165 ----------------------------------------------------------- */
166 mymalloc(first, nfronts, PORD_INT);
167 mymalloc(link, nvtx, PORD_INT);
168
169 for (J = 0; J < nfronts; J++)
170 first[J] = -1;
171 for (u = nvtx-1; u >= 0; u--)
172 { J = vtx2front[u];
173 link[u] = first[J];
174 first[J] = u;
175 }
176
177 /* -----------------------------------------------------------
178 print fronts according to a postorder traversal of the tree
179 ----------------------------------------------------------- */
180 for (K = firstPostorder(T); K != -1; K = nextPostorder(T, K))
181 { printf("--- front %d, ncolfactor %d, ncolupdate %d, parent %d\n",
182 K, ncolfactor[K], ncolupdate[K], parent[K]);
183 count = 0;
184 printf("children:\n");
185 for (child = firstchild[K]; child != -1; child = silbings[child])
186 { printf("%5d", child);
187 if ((++count % 16) == 0)
188 printf("\n");
189 }
190 if ((count % 16) != 0)
191 printf("\n");
192 count = 0;
193 printf("vertices mapped to front:\n");
194 for (u = first[K]; u != -1; u = link[u])
195 { printf("%5d", u);
196 if ((++count % 16) == 0)
197 printf("\n");
198 }
199 if ((count % 16) != 0)
200 printf("\n");
201 }
202
203 /* ----------------------
204 free memory and return
205 ---------------------- */
206 free(first); free(link);
207}

◆ printFactorMtx()

void printFactorMtx ( factorMtx_t * L)

Definition at line 478 of file symbfac.c.

479{ css_t *css;
480 FLOAT *nzl;
481 PORD_INT *xnzl, *nzlsub, *xnzlsub;
482 PORD_INT neqs, nelem, nind, k, ksub, i, istart, istop;
483
484 nelem = L->nelem;
485 nzl = L->nzl;
486 css = L->css;
487
488 neqs = css->neqs;
489 nind = css->nind;
490 xnzl = css->xnzl;
491 nzlsub = css->nzlsub;
492 xnzlsub = css->xnzlsub;
493
494 printf("#equations %d, #elements (+diag.) %d, #indices (+diag.) %d\n",
495 neqs, nelem, nind);
496 for (k = 0; k < neqs; k++)
497 { printf("--- column %d\n", k);
498 ksub = xnzlsub[k];
499 istart = xnzl[k];
500 istop = xnzl[k+1];
501 for (i = istart; i < istop; i++)
502 printf(" row %5d, entry %e\n", nzlsub[ksub++], nzl[i]);
503 }
504}

◆ printFrontSubscripts()

void printFrontSubscripts ( frontsub_t * frontsub)

Definition at line 298 of file symbfac.c.

299{ elimtree_t *PTP;
300 PORD_INT *xnzf, *nzfsub, *ncolfactor, *ncolupdate, *parent;
301 PORD_INT nfronts, root, K, count, i, istart, istop;
302
303 PTP = frontsub->PTP;
304 xnzf = frontsub->xnzf;
305 nzfsub = frontsub->nzfsub;
306
307 nfronts = PTP->nfronts;
308 root = PTP->root;
309 ncolfactor = PTP->ncolfactor;
310 ncolupdate = PTP->ncolupdate;
311 parent = PTP->parent;
312
313 printf("#fronts %d, root %d\n", nfronts, root);
314 for (K = firstPostorder(PTP); K != -1; K = nextPostorder(PTP, K))
315 { printf("--- front %d, ncolfactor %d, ncolupdate %d, parent %d\n",
316 K, ncolfactor[K], ncolupdate[K], parent[K]);
317 count = 0;
318 istart = xnzf[K];
319 istop = xnzf[K+1];
320 for (i = istart; i < istop; i++)
321 { printf("%5d", nzfsub[i]);
322 if ((++count % 16) == 0)
323 printf("\n");
324 }
325 if ((count % 16) != 0)
326 printf("\n");
327 }
328}

◆ printGbipart()

void printGbipart ( gbipart_t * Gbipart)

Definition at line 91 of file gbipart.c.

92{ graph_t *G;
93 PORD_INT count, u, i, istart, istop;
94
95 G = Gbipart->G;
96 printf("\n#vertices %d (nX %d, nY %d), #edges %d, type %d, totvwght %d\n",
97 G->nvtx, Gbipart->nX, Gbipart->nY, G->nedges >> 1, G->type,
98 G->totvwght);
99 for (u = 0; u < G->nvtx; u++)
100 { count = 0;
101 printf("--- adjacency list of vertex %d (weight %d):\n", u, G->vwght[u]);
102 istart = G->xadj[u];
103 istop = G->xadj[u+1];
104 for (i = istart; i < istop; i++)
105 { printf("%5d", G->adjncy[i]);
106 if ((++count % 16) == 0)
107 printf("\n");
108 }
109 if ((count % 16) != 0)
110 printf("\n");
111 }
112}

◆ printGbisect()

void printGbisect ( gbisect_t * Gbisect)

Definition at line 87 of file gbisect.c.

88{ graph_t *G;
89 PORD_INT count, u, v, i, istart, istop;
90
91 G = Gbisect->G;
92 printf("\n#nodes %d, #edges %d, totvwght %d\n", G->nvtx, G->nedges >> 1,
93 G->totvwght);
94 printf("partition weights: S %d, B %d, W %d\n", Gbisect->cwght[GRAY],
95 Gbisect->cwght[BLACK], Gbisect->cwght[WHITE]);
96 for (u = 0; u < G->nvtx; u++)
97 { count = 0;
98 printf("--- adjacency list of node %d (weight %d, color %d)\n", u,
99 G->vwght[u], Gbisect->color[u]);
100 istart = G->xadj[u];
101 istop = G->xadj[u+1];
102 for (i = istart; i < istop; i++)
103 { v = G->adjncy[i];
104 printf("%5d (color %2d)", v, Gbisect->color[v]);
105 if ((++count % 4) == 0)
106 printf("\n");
107 }
108 if ((count % 4) != 0)
109 printf("\n");
110 }
111}

◆ printGraph()

void printGraph ( graph_t * G)

Definition at line 85 of file graph.c.

86{ PORD_INT count, u, i, istart, istop;
87
88 printf("\n#vertices %d, #edges %d, type %d, totvwght %d\n", G->nvtx,
89 G->nedges >> 1, G->type, G->totvwght);
90 for (u = 0; u < G->nvtx; u++)
91 { count = 0;
92 printf("--- adjacency list of vertex %d (weight %d):\n", u, G->vwght[u]);
93 istart = G->xadj[u];
94 istop = G->xadj[u+1];
95 for (i = istart; i < istop; i++)
96 { printf("%5d", G->adjncy[i]);
97 if ((++count % 16) == 0)
98 printf("\n");
99 }
100 if ((count % 16) != 0)
101 printf("\n");
102 }
103}

◆ printInputMtx()

void printInputMtx ( inputMtx_t * )

◆ printMapping()

void printMapping ( mapping_t * )

◆ printTopology()

void printTopology ( topology_t * )

◆ qsortUpFloatsWithIntKeys()

void qsortUpFloatsWithIntKeys ( PORD_INT n,
FLOAT * array,
PORD_INT * key,
PORD_INT * stack )

Definition at line 140 of file sort.c.

141{ register PORD_INT i, j;
142 PORD_INT t, l, m, r, p;
143 FLOAT e;
144
145 l = 0; r = n-1; p = 2;
146 while (p > 0)
147 if ((r-l) > THRES)
148 { m = l + ((r-l) >> 1);
149 if (key[l] > key[r])
150 { swap(array[l], array[r], e); swap(key[l], key[r], t); }
151 if (key[l] > key[m])
152 { swap(array[l], array[m], e); swap(key[l], key[m], t); }
153 if (key[r] > key[m])
154 { swap(array[m], array[r], e); swap(key[m], key[r], t); }
155 m = key[r]; i = l-1; j = r;
156 for (;;)
157 { while (key[++i] < m);
158 while (key[--j] > m);
159 if (i >= j) break;
160 swap(array[i], array[j], e); swap(key[i], key[j], t);
161 }
162 swap(array[i], array[r], e); swap(key[i], key[r], t);
163 if ((i-l) > (r-i))
164 { stack[p++] = l;
165 stack[p++] = i-1;
166 l = i+1;
167 }
168 else
169 { stack[p++] = i+1;
170 stack[p++] = r;
171 r = i-1;
172 }
173 }
174 else
175 { r = stack[--p];
176 l = stack[--p];
177 }
178 if (THRES > 0) insertUpFloatsWithIntKeys(n, array, key);
179}
void insertUpFloatsWithIntKeys(PORD_INT n, FLOAT *array, PORD_INT *key)
Definition sort.c:77
#define THRES
Definition sort.c:14

◆ qsortUpInts()

void qsortUpInts ( PORD_INT n,
PORD_INT * array,
PORD_INT * stack )

Definition at line 98 of file sort.c.

99{ register PORD_INT i, j;
100 PORD_INT t, l, m, r, p;
101
102 l = 0; r = n-1; p = 2;
103 while (p > 0)
104 if ((r-l) > THRES)
105 { m = l + ((r-l) >> 1);
106 if (array[l] > array[r]) swap(array[l], array[r], t);
107 if (array[l] > array[m]) swap(array[l], array[m], t);
108 if (array[r] > array[m]) swap(array[m], array[r], t);
109 m = array[r]; i = l-1; j = r;
110 for (;;)
111 { while (array[++i] < m);
112 while (array[--j] > m);
113 if (i >= j) break;
114 swap(array[i], array[j], t);
115 }
116 swap(array[i], array[r], t);
117 if ((i-l) > (r-i))
118 { stack[p++] = l;
119 stack[p++] = i-1;
120 l = i+1;
121 }
122 else
123 { stack[p++] = i+1;
124 stack[p++] = r;
125 r = i-1;
126 }
127 }
128 else
129 { r = stack[--p];
130 l = stack[--p];
131 }
132 if (THRES > 0) insertUpInts(n, array);
133}
void insertUpInts(PORD_INT n, PORD_INT *array)
Definition sort.c:21

◆ randomizeGraph()

void randomizeGraph ( graph_t * G)

Definition at line 109 of file graph.c.

110{ PORD_INT *xadj, *adjncy, nvtx, u, v, len, j, i, istart, istop;
111
112 nvtx = G->nvtx;
113 xadj = G->xadj;
114 adjncy = G->adjncy;
115
116 for (u = 0; u < nvtx; u++)
117 { istart = xadj[u];
118 istop = xadj[u+1];
119 if ((len = istop - istart) > 1)
120 for (i = istart; i < istop; i++)
121 { j = myrandom(len);
122 swap(adjncy[i], adjncy[i+j], v);
123 len--;
124 }
125 }
126}

◆ readChacoGraph()

graph_t * readChacoGraph ( char * )

◆ readHarwellBoeingMtx()

inputMtx_t * readHarwellBoeingMtx ( char * )

◆ readoutNumFacBuffer()

void readoutNumFacBuffer ( workspace_t * ,
buffer_t * ,
denseMtx_t **  )

◆ readoutSymbFacBuffer()

void readoutSymbFacBuffer ( buffer_t * ,
frontsub_t * ,
PORD_INT *  )

◆ readoutTriangularBuffer()

void readoutTriangularBuffer ( buffer_t * ,
frontsub_t * ,
PORD_INT * ,
FLOAT *  )

◆ recMapCube()

void recMapCube ( topology_t * ,
PORD_INT ,
PORD_INT ,
PORD_INT ,
PORD_INT ,
PORD_INT ,
PORD_INT  )

◆ recvCube()

size_t recvCube ( topology_t * ,
void * ,
size_t ,
PORD_INT  )

◆ removeBucket()

void removeBucket ( bucket_t * bucket,
PORD_INT item )

Definition at line 214 of file bucket.c.

215{ PORD_INT s, nextitem, lastitem;
216
217 /* ----------------------------
218 check whether item in bucket
219 ---------------------------- */
220 if (bucket->key[item] == MAX_INT)
221 { fprintf(stderr, "\nError in function removeBucket\n"
222 " item %d is not in bucket\n", item);
223 quit();
224 }
225
226 /* -----------------------
227 remove item from bucket
228 ----------------------- */
229 nextitem = bucket->next[item];
230 lastitem = bucket->last[item];
231 if (nextitem != -1)
232 bucket->last[nextitem] = lastitem;
233 if (lastitem != -1)
234 bucket->next[lastitem] = nextitem;
235 else
236 { s = max(0, (bucket->key[item] + bucket->offset));
237 s = min(s, bucket->maxbin);
238 bucket->bin[s] = nextitem;
239 }
240
241 /* --------------------------------------------
242 decrease nobj and mark item as being removed
243 -------------------------------------------- */
244 bucket->nobj--;
245 bucket->key[item] = MAX_INT;
246}

◆ sendCube()

void sendCube ( topology_t * ,
void * ,
size_t ,
PORD_INT  )

◆ setupBipartiteGraph()

gbipart_t * setupBipartiteGraph ( graph_t * G,
PORD_INT * bipartvertex,
PORD_INT nX,
PORD_INT nY,
PORD_INT * vtxmap )

Definition at line 118 of file gbipart.c.

119{ gbipart_t *Gbipart;
120 PORD_INT *xadj, *adjncy, *vwght, *xadjGb, *adjncyGb, *vwghtGb;
121 PORD_INT nvtx, nedgesGb, totvwght, u, x, y, i, j, jstart, jstop, ptr;
122
123 nvtx = G->nvtx;
124 xadj = G->xadj;
125 adjncy = G->adjncy;
126 vwght = G->vwght;
127
128 /* ----------------------------------------------------------------
129 compute number of edges and local indices of vertices in Gbipart
130 ---------------------------------------------------------------- */
131 nedgesGb = 0;
132 for (i = 0; i < nX+nY; i++)
133 { u = bipartvertex[i];
134 if ((u < 0) || (u >= nvtx))
135 { fprintf(stderr, "\nError in function setupBipartiteGraph\n"
136 " node %d does not belong to graph\n", u);
137 quit();
138 }
139 jstart = xadj[u];
140 jstop = xadj[u+1];
141 for (j = jstart; j < jstop; j++)
142 vtxmap[adjncy[j]] = -1;
143 nedgesGb += (jstop - jstart);
144 }
145 for (i = 0; i < nX+nY; i++)
146 { u = bipartvertex[i];
147 vtxmap[u] = i;
148 }
149
150 Gbipart = newBipartiteGraph(nX, nY, nedgesGb);
151 xadjGb = Gbipart->G->xadj;
152 adjncyGb = Gbipart->G->adjncy;
153 vwghtGb = Gbipart->G->vwght;
154
155 /* ---------------------------------
156 build the induced bipartite graph
157 --------------------------------- */
158 totvwght = 0; ptr = 0;
159 for (i = 0; i < nX; i++)
160 { x = bipartvertex[i];
161 xadjGb[i] = ptr;
162 vwghtGb[i] = vwght[x];
163 totvwght += vwght[x];
164 jstart = xadj[x];
165 jstop = xadj[x+1];
166 for (j = jstart; j < jstop; j++)
167 { y = adjncy[j];
168 if (vtxmap[y] >= nX)
169 adjncyGb[ptr++] = vtxmap[y];
170 }
171 }
172 for (i = nX; i < nX+nY; i++)
173 { y = bipartvertex[i];
174 xadjGb[i] = ptr;
175 vwghtGb[i] = vwght[y];
176 totvwght += vwght[y];
177 jstart = xadj[y];
178 jstop = xadj[y+1];
179 for (j = jstart; j < jstop; j++)
180 { x = adjncy[j];
181 if ((vtxmap[x] >= 0) && (vtxmap[x] < nX))
182 adjncyGb[ptr++] = vtxmap[x];
183 }
184 }
185 xadjGb[nX+nY] = ptr;
186 Gbipart->G->type = G->type;
187 Gbipart->G->totvwght = totvwght;
188 return(Gbipart);
189}
gbipart_t * newBipartiteGraph(PORD_INT nX, PORD_INT nY, PORD_INT nedges)
Definition gbipart.c:66

◆ setupBucket()

bucket_t * setupBucket ( PORD_INT maxbin,
PORD_INT maxitem,
PORD_INT offset )

Definition at line 91 of file bucket.c.

92{ bucket_t *bucket;
93 PORD_INT i, u;
94
95 if (offset < 0)
96 { fprintf(stderr, "\nError in function setupBucket\n"
97 " offset must be >= 0\n");
98 quit();
99 }
100
101 bucket = newBucket(maxbin, maxitem, offset);
102
103 for (i = 0; i <= maxbin; i++)
104 bucket->bin[i] = -1;
105 for (u = 0; u <= maxitem; u++)
106 { bucket->next[u] = bucket->last[u] = -1;
107 bucket->key[u] = MAX_INT;
108 }
109
110 return(bucket);
111}
bucket_t * newBucket(PORD_INT maxbin, PORD_INT maxitem, PORD_INT offset)
Definition bucket.c:56

◆ setupCSSFromFrontSubscripts()

css_t * setupCSSFromFrontSubscripts ( frontsub_t * frontsub)

Definition at line 221 of file symbfac.c.

222{ elimtree_t *PTP;
223 css_t *css;
224 PORD_INT *xnzf, *nzfsub, *ncolfactor, *xnzl, *xnzlsub;
225 PORD_INT nind, nvtx, K, beg, knz, firstcol, col;
226
227 PTP = frontsub->PTP;
228 xnzf = frontsub->xnzf;
229 nzfsub = frontsub->nzfsub;
230 nind = frontsub->nind;
231
232 nvtx = PTP->nvtx;
233 ncolfactor = PTP->ncolfactor;
234
235 /* -------------------------------------------------------
236 allocate storage for the compressed subscript structure
237 ------------------------------------------------------- */
238 css = newCSS(nvtx, nind, FALSE);
239 css->nzlsub = nzfsub;
240
241 xnzl = css->xnzl;
242 xnzlsub = css->xnzlsub;
243
244 /* ---------------------------------------
245 fill the compressed subscript structure
246 --------------------------------------- */
247 xnzl[0] = 0;
248 for (K = firstPostorder(PTP); K != -1; K = nextPostorder(PTP, K))
249 { beg = xnzf[K];
250 knz = xnzf[K+1] - beg;
251 firstcol = nzfsub[beg];
252 for (col = firstcol; col < firstcol + ncolfactor[K]; col++)
253 { xnzlsub[col] = beg++;
254 xnzl[col+1] = xnzl[col] + knz--;
255 }
256 }
257
258 return(css);
259}
css_t * newCSS(PORD_INT neqs, PORD_INT nind, PORD_INT owned)
Definition symbfac.c:56

◆ setupCSSFromFrontSubscriptsPAR()

css_t * setupCSSFromFrontSubscriptsPAR ( mask_t * ,
mapping_t * ,
frontsub_t *  )

◆ setupCSSFromGraph()

css_t * setupCSSFromGraph ( graph_t * G,
PORD_INT * perm,
PORD_INT * invp )

Definition at line 90 of file symbfac.c.

91{ css_t *css;
92 PORD_INT *marker, *mergelink, *indices, *tmp, *xnzl, *xnzlsub, *nzlsub;
93 PORD_INT neqs, maxmem, u, v, col, mergecol, knz, mrk, beg, end;
94 PORD_INT fast, len, k, p, e, i, istart, istop;
95
96 neqs = G->nvtx;
97 maxmem = 2 * neqs;
98
99 /* -------------------------
100 set up the working arrays
101 ------------------------- */
102 mymalloc(marker, neqs, PORD_INT);
103 mymalloc(indices, neqs, PORD_INT);
104 mymalloc(mergelink, neqs, PORD_INT);
105 mymalloc(tmp, neqs, PORD_INT);
106 for (k = 0; k < neqs; k++)
107 marker[k] = mergelink[k] = -1;
108
109 /* -------------------------------------------------------
110 allocate storage for the compressed subscript structure
111 ------------------------------------------------------- */
112 css = newCSS(neqs, maxmem, TRUE);
113
114 xnzl = css->xnzl;
115 nzlsub = css->nzlsub;
116 xnzlsub = css->xnzlsub;
117
118 /* ------------------------------------------------------------
119 main loop: determine the subdiag. row indices of each column
120 ------------------------------------------------------------ */
121 xnzl[0] = 0;
122 beg = end = 0;
123 for (k = 0; k < neqs; k++)
124 { indices[0] = k;
125 knz = 1;
126
127 if ((mergecol = mergelink[k]) != -1) /* is k a leaf ??? */
128 { mrk = marker[mergecol];
129 fast = TRUE;
130 }
131 else
132 { mrk = k;
133 fast = FALSE;
134 }
135
136 /* --------------------------
137 original columns (indices)
138 -------------------------- */
139 u = invp[k];
140 istart = G->xadj[u];
141 istop = G->xadj[u+1];
142 for (i = istart; i < istop; i++)
143 { v = G->adjncy[i];
144 if ((col = perm[v]) > k)
145 { indices[knz++] = col;
146 if (marker[col] != mrk) fast = FALSE;
147 }
148 }
149
150 /* --------------------------
151 external columns (indices)
152 -------------------------- */
153 if ((fast) && (mergelink[mergecol] == -1))
154 { xnzlsub[k] = xnzlsub[mergecol] + 1;
155 knz = xnzl[mergecol+1] - xnzl[mergecol] - 1;
156 }
157 else
158 { for (i = 0; i < knz; i++)
159 marker[indices[i]] = k;
160 while (mergecol != -1)
161 { len = xnzl[mergecol+1] - xnzl[mergecol];
162 istart = xnzlsub[mergecol];
163 istop = istart + len;
164 for (i = istart; i < istop; i++)
165 { col = nzlsub[i];
166 if ((col > k) && (marker[col] != k))
167 { indices[knz++] = col;
168 marker[col] = k;
169 }
170 }
171 mergecol = mergelink[mergecol];
172 }
173 qsortUpInts(knz, indices, tmp);
174
175 /* ---------------------------------------------------
176 store indices in nzlsub; resize nzlsub if too small
177 --------------------------------------------------- */
178 beg = end;
179 xnzlsub[k] = beg;
180 end = beg + knz;
181 if (end > maxmem)
182 { maxmem += neqs;
183 myrealloc(nzlsub, maxmem, PORD_INT);
184 }
185 len = 0;
186 for (i = beg; i < end; i++)
187 nzlsub[i] = indices[len++];
188 }
189
190 /* ----------------------------
191 append column k to mergelink
192 ---------------------------- */
193 if (knz > 1)
194 { p = xnzlsub[k]+1;
195 e = nzlsub[p];
196 mergelink[k] = mergelink[e];
197 mergelink[e] = k;
198 }
199 xnzl[k+1] = xnzl[k] + knz;
200 }
201
202 /* -----------------------------
203 end of main loop: free memory
204 ----------------------------- */
205 free(marker); free(indices);
206 free(tmp); free(mergelink);
207
208 /* ------------------------------------------------------
209 finalize the compressed subscript structure and return
210 ------------------------------------------------------ */
211 css->nind = xnzlsub[neqs-1] + 1;
212 myrealloc(nzlsub, css->nind, PORD_INT);
213 css->nzlsub = nzlsub;
214 return(css);
215}
end[inform, rinform, sol, inst, schur, redrhs, pivnul_list, sym_perm, uns_perm, icntl, cntl, colsca_out, rowsca_out, keep_out, dkeep_out]
Definition dmumps.m:40
#define myrealloc(ptr, nr, type)
Definition macros.h:30
void qsortUpInts(PORD_INT, PORD_INT *, PORD_INT *)
Definition sort.c:98

◆ setupElimGraph()

gelim_t * setupElimGraph ( graph_t * G)

Definition at line 229 of file gelim.c.

230{ gelim_t *Gelim;
231 PORD_INT *xadj, *adjncy, *vwght, *xadjGelim, *adjncyGelim, *vwghtGelim;
232 PORD_INT *len, *elen, *parent, *degree, *score;
233 PORD_INT nvtx, nedges, deg, u, i, istart, istop;
234
235 nvtx = G->nvtx;
236 nedges = G->nedges;
237 xadj = G->xadj;
238 adjncy = G->adjncy;
239 vwght = G->vwght;
240
241 Gelim = newElimGraph(nvtx, nedges+nvtx);
242 xadjGelim = Gelim->G->xadj;
243 adjncyGelim = Gelim->G->adjncy;
244 vwghtGelim = Gelim->G->vwght;
245 len = Gelim->len;
246 elen = Gelim->elen;
247 parent = Gelim->parent;
248 degree = Gelim->degree;
249 score = Gelim->score;
250
251 /* --------------
252 copy the graph
253 -------------- */
254 Gelim->G->type = G->type;
255 Gelim->G->totvwght = G->totvwght;
256 for (u = 0; u < nvtx; u++)
257 { xadjGelim[u] = xadj[u];
258 vwghtGelim[u] = vwght[u];
259 }
260 xadjGelim[nvtx] = xadj[nvtx];
261 for (i = 0; i < nedges; i++)
262 adjncyGelim[i] = adjncy[i];
263 Gelim->G->nedges = nedges;
264
265 /* ----------------------
266 initialize all vectors
267 ---------------------- */
268 for (u = 0; u < nvtx; u++)
269 { istart = xadj[u];
270 istop = xadj[u+1];
271 len[u] = istop - istart;
272 elen[u] = 0;
273 parent[u] = -1;
274 deg = 0;
275
276 switch(Gelim->G->type) /* compute the external degree of u */
277 { case UNWEIGHTED:
278 deg = len[u];
279 break;
280 case WEIGHTED:
281 for (i = istart; i < istop; i++)
282 deg += vwght[adjncy[i]];
283 break;
284 default:
285 fprintf(stderr, "\nError in function setupElimGraph\n"
286 " unrecognized graph type %d\n", Gelim->G->type);
287 }
288 degree[u] = deg;
289
290 if (len[u] == 0) /* len(u) = 0 => adjncy list of u not in use */
291 xadjGelim[u] = -1; /* mark with -1, otherwise crunchElimGraph fails */
292 score[u] = -1;
293 }
294
295 return(Gelim);
296}
gelim_t * newElimGraph(PORD_INT nvtx, PORD_INT nedges)
Definition gelim.c:108

◆ setupElimTree()

elimtree_t * setupElimTree ( graph_t * G,
PORD_INT * perm,
PORD_INT * invp )

Definition at line 293 of file tree.c.

294{ elimtree_t *T;
295 css_t *css;
296 PORD_INT *xadj, *adjncy, *vwght, *ncolfactor, *ncolupdate, *parent;
297 PORD_INT *vtx2front, *realroot, *uf_father, *uf_size;
298 PORD_INT *xnzl, *nzlsub, *xnzlsub;
299 PORD_INT nvtx, front, front2, froot, f, r, u, v, i, istart, istop;
300 PORD_INT prevlen, len, h, hsub;
301
302 nvtx = G->nvtx;
303 xadj = G->xadj;
304 adjncy = G->adjncy;
305 vwght = G->vwght;
306
307 /* --------------------------
308 set up the working storage
309 -------------------------- */
310 mymalloc(realroot, nvtx, PORD_INT);
311 mymalloc(uf_father, nvtx, PORD_INT);
312 mymalloc(uf_size, nvtx, PORD_INT);
313
314 /* ------------------------------------------------
315 allocate storage for the elimination tree object
316 ------------------------------------------------ */
317 T = newElimTree(nvtx, nvtx);
318 ncolfactor = T->ncolfactor;
319 ncolupdate = T->ncolupdate;
320 parent = T->parent;
321 vtx2front = T->vtx2front;
322
323 /* -----------------------------
324 set up the parent vector of T
325 ----------------------------- */
326 for (front = 0; front < nvtx; front++)
327 { parent[front] = -1;
328 u = invp[front]; /* only vertex u belongs to this front */
329 uf_father[front] = front; /* front forms a set in union-find structure */
330 uf_size[front] = 1; /* the set consists of a single front */
331 realroot[front] = front;
332 froot = front;
333
334 /* run through the adjacency list of u */
335 istart = xadj[u];
336 istop = xadj[u+1];
337 for (i = istart; i < istop; i++)
338 { v = adjncy[i];
339 front2 = perm[v];
340 if (front2 < front)
341 { r = front2;
342
343 while (uf_father[r] != r) /* find root of front2 in union-find */
344 r = uf_father[r];
345 while (front2 != r) /* path compression */
346 { f = front2;
347 front2 = uf_father[front2];
348 uf_father[f] = r;
349 }
350
351 f = realroot[r]; /* merge union-find sets */
352 if ((parent[f] == -1) && (f != front))
353 { parent[f] = front;
354 if (uf_size[froot] < uf_size[r])
355 { uf_father[froot] = r;
356 uf_size[r] += uf_size[froot];
357 froot = r;
358 }
359 else
360 { uf_father[r] = froot;
361 uf_size[froot] += uf_size[r];
362 }
363 realroot[froot] = front;
364 }
365 }
366 }
367 }
368
369 /* ---------------------------------------------
370 set the vectors T->firstchild and T->silbings
371 --------------------------------------------- */
373
374 /* ----------------------------------------------------------
375 set the vectors T->vtx2front, T->ncolfactor, T->ncolupdate
376 ---------------------------------------------------------- */
377 css = setupCSSFromGraph(G, perm, invp);
378 xnzl = css->xnzl;
379 nzlsub = css->nzlsub;
380 xnzlsub = css->xnzlsub;
381
382 prevlen = 0;
383 for (front = 0; front < nvtx; front++)
384 { u = invp[front];
385 ncolfactor[front] = vwght[u];
386 ncolupdate[front] = 0;
387 vtx2front[u] = front;
388 len = xnzl[front+1] - xnzl[front];
389 if (prevlen - 1 == len)
390 ncolupdate[front] = ncolupdate[front-1] - vwght[u];
391 else
392 { h = xnzlsub[front] + 1;
393 for (i = 1; i < len; i++)
394 { hsub = nzlsub[h++];
395 v = invp[hsub];
396 ncolupdate[front] += vwght[v];
397 }
398 }
399 prevlen = len;
400 }
401
402 /* ----------------------
403 free memory and return
404 ---------------------- */
405 free(css);
406 free(realroot); free(uf_father); free(uf_size);
407 return(T);
408}
css_t * setupCSSFromGraph(graph_t *, PORD_INT *, PORD_INT *)
Definition symbfac.c:90

◆ setupFrontalMtx()

denseMtx_t * setupFrontalMtx ( workspace_t * ,
factorMtx_t * ,
PORD_INT  )

◆ setupFrontalMtxPAR()

denseMtx_t * setupFrontalMtxPAR ( mask_t * ,
PORD_INT ,
workspace_t * ,
factorMtx_t * ,
PORD_INT  )

◆ setupFrontSubscripts()

frontsub_t * setupFrontSubscripts ( elimtree_t * PTP,
inputMtx_t * PAP )

Definition at line 334 of file symbfac.c.

335{ frontsub_t *frontsub;
336 PORD_INT *ncolfactor, *ncolupdate, *firstchild, *silbings, *vtx2front;
337 PORD_INT *xnza, *nzasub, *xnzf, *nzfsub;
338 PORD_INT *marker, *tmp, *first, *indices;
339 PORD_INT nvtx, nfronts, col, firstcol, knz;
340 PORD_INT u, i, istart, istop, K, J;
341
342 nvtx = PTP->nvtx;
343 nfronts = PTP->nfronts;
344 ncolfactor = PTP->ncolfactor;
345 ncolupdate = PTP->ncolupdate;
346 firstchild = PTP->firstchild;
347 silbings = PTP->silbings;
348 vtx2front = PTP->vtx2front;
349
350 xnza = PAP->xnza;
351 nzasub = PAP->nzasub;
352
353 /* -------------------------
354 set up the working arrays
355 ------------------------- */
356 mymalloc(marker, nvtx, PORD_INT);
357 mymalloc(tmp, nvtx, PORD_INT);
358 mymalloc(first, nfronts, PORD_INT);
359 for (i = 0; i < nvtx; i++)
360 marker[i] = -1;
361
362 /* --------------------------------
363 find the first column of a front
364 -------------------------------- */
365 for (u = nvtx-1; u >= 0; u--)
366 { K = vtx2front[u];
367 first[K] = u;
368 }
369
370 /* -----------------------------------------
371 allocate storage for the front subscripts
372 ----------------------------------------- */
373 frontsub = newFrontSubscripts(PTP);
374 xnzf = frontsub->xnzf;
375 nzfsub = frontsub->nzfsub;
376
377 knz = 0;
378 for (K = 0; K < nfronts; K++)
379 { xnzf[K] = knz;
380 knz += (ncolfactor[K] + ncolupdate[K]);
381 }
382 xnzf[K] = knz;
383
384 /* -------------------------------------------
385 postorder traversal of the elimination tree
386 ------------------------------------------- */
387 for (K = firstPostorder(PTP); K != -1; K = nextPostorder(PTP, K))
388 { knz = 0;
389 indices = nzfsub + xnzf[K];
390 firstcol = first[K];
391
392 /* -------------------------------------
393 internal columns (indices) of front K
394 ------------------------------------- */
395 for (col = firstcol; col < firstcol + ncolfactor[K]; col++)
396 { indices[knz++] = col;
397 marker[col] = K;
398 }
399
400 /* -------------------------------------
401 external columns (indices) of front K
402 ------------------------------------- */
403 for (J = firstchild[K]; J != -1; J = silbings[J])
404 { istart = xnzf[J];
405 istop = xnzf[J+1];
406 for (i = istart; i < istop; i++)
407 { col = nzfsub[i];
408 if ((col > firstcol) && (marker[col] != K))
409 { marker[col] = K;
410 indices[knz++] = col;
411 }
412 }
413 }
414
415 /* -------------------------------------
416 original columns (indices) of front K
417 ------------------------------------- */
418 for (u = 0; u < ncolfactor[K]; u++)
419 { istart = xnza[firstcol + u];
420 istop = xnza[firstcol + u + 1];
421 for (i = istart; i < istop; i++)
422 { col = nzasub[i];
423 if ((col > firstcol) && (marker[col] != K))
424 { marker[col] = K;
425 indices[knz++] = col;
426 }
427 }
428 }
429
430 /* ----------------
431 sort the indices
432 ---------------- */
433 qsortUpInts(knz, indices, tmp);
434 }
435
436 /* ----------------------
437 free memory and return
438 ---------------------- */
439 free(marker); free(tmp); free(first);
440 return(frontsub);
441}
frontsub_t * newFrontSubscripts(elimtree_t *PTP)
Definition symbfac.c:265

◆ setupFrontSubscriptsPAR()

frontsub_t * setupFrontSubscriptsPAR ( topology_t * ,
mask_t * ,
mapping_t * ,
elimtree_t * ,
inputMtx_t *  )

◆ setupGraphFromMtx()

graph_t * setupGraphFromMtx ( inputMtx_t * A)

Definition at line 195 of file graph.c.

196{ graph_t *G;
197 PORD_INT *xnza, *nzasub, *xadj, *adjncy;
198 PORD_INT neqs, nelem, nvtx, k, h1, h2, j, i, istart, istop;
199
200 neqs = A->neqs;
201 nelem = A->nelem;
202 xnza = A->xnza;
203 nzasub = A->nzasub;
204
205 /* ------------------------------------
206 allocate memory for unweighted graph
207 ------------------------------------ */
208 G = newGraph(neqs, 2*nelem);
209 nvtx = G->nvtx;
210 xadj = G->xadj;
211 adjncy = G->adjncy;
212
213 /* -----------------------------------------
214 determine the size of each adjacency list
215 ----------------------------------------- */
216 for (k = 0; k < neqs; k++)
217 xadj[k] = xnza[k+1] - xnza[k];
218 for (k = 0; k < nelem; k++)
219 xadj[nzasub[k]]++;
220
221 /* -------------------------------------------------------------
222 determine for each vertex where its adjacency list will start
223 ------------------------------------------------------------- */
224 h1 = xadj[0];
225 xadj[0] = 0;
226 for (k = 1; k <= nvtx; k++)
227 { h2 = xadj[k];
228 xadj[k] = xadj[k-1] + h1;
229 h1 = h2;
230 }
231
232 /* ------------------------
233 fill the adjacency lists
234 ------------------------ */
235 for (k = 0; k < neqs; k++)
236 { istart = xnza[k];
237 istop = xnza[k+1];
238 for (i = istart; i < istop; i++)
239 { j = nzasub[i];
240 adjncy[xadj[k]++] = j; /* store {k,j} in adjacency list of k */
241 adjncy[xadj[j]++] = k; /* store {j,k} in adjacency list of j */
242 }
243 }
244
245 /* --------------------------------------------
246 restore startpoint of each vertex and return
247 -------------------------------------------- */
248 for (k = nvtx-1; k > 0; k--)
249 xadj[k] = xadj[k-1];
250 xadj[0] = 0;
251 return(G);
252}
PORD_INT nelem
Definition types.h:167

◆ setupGridGraph()

graph_t * setupGridGraph ( PORD_INT dimX,
PORD_INT dimY,
PORD_INT type )

Definition at line 258 of file graph.c.

259{ graph_t *G;
260 PORD_INT *xadj, *adjncy, nvtx, nedges, knz, k;
261
262 /* ---------------
263 initializations
264 --------------- */
265 G = NULL;
266 knz = 0;
267 nvtx = dimX * dimY;
268
269 /* ---------------------------------
270 create unweighted grid/mesh graph
271 --------------------------------- */
272 if ((type == GRID) || (type == MESH))
273 { nedges = 8 /* for edge vertices */
274 + 6 * (dimX-2 + dimY-2) /* for border vertices */
275 + 4 * (dimX-2) * (dimY-2); /* for interior vertices */
276 if (type == MESH)
277 nedges += 4 * (dimX-1) * (dimY-1); /* diagonals */
278
279 G = newGraph(nvtx, nedges);
280 xadj = G->xadj;
281 adjncy = G->adjncy;
282
283 for (k = 0; k < nvtx; k++)
284 { xadj[k] = knz;
285 if ((k+1) % dimX > 0) /* / k+1-dimX (MESH) */
286 { adjncy[knz++] = k+1; /* k - k+1 (GRID) */
287 if (type == MESH) /* \ k+1+dimX (MESH) */
288 { if (k+1+dimX < nvtx)
289 adjncy[knz++] = k+1+dimX;
290 if (k+1-dimX >= 0)
291 adjncy[knz++] = k+1-dimX;
292 }
293 }
294 if (k % dimX > 0) /* k-1-dimX \ (MESH) */
295 { adjncy[knz++] = k-1; /* k-1 - k (GRID) */
296 if (type == MESH) /* k-1+dimX / (MESH) */
297 { if (k-1+dimX < nvtx)
298 adjncy[knz++] = k-1+dimX;
299 if (k-1-dimX >= 0)
300 adjncy[knz++] = k-1-dimX;
301 }
302 }
303 if (k+dimX < nvtx) /* k-dimX (GRID) */
304 adjncy[knz++] = k+dimX; /* | */
305 if (k-dimX >= 0) /* k */
306 adjncy[knz++] = k-dimX; /* | */
307 } /* k+dimX (GRID) */
308 xadj[nvtx] = knz;
309 }
310
311 /* -----------------------------
312 create unweighted torus graph
313 ----------------------------- */
314 if (type == TORUS)
315 { nedges = 4 * dimX * dimY;
316
317 G = newGraph(nvtx, nedges);
318 xadj = G->xadj;
319 adjncy = G->adjncy;
320
321 for (k = 0; k < nvtx; k++)
322 { xadj[k] = knz;
323 if (((k+1) % dimX) == 0) /* k -- k+1 */
324 adjncy[knz++] = k+1-dimX;
325 else
326 adjncy[knz++] = k+1;
327 if ((k % dimX) == 0) /* k-1 -- k */
328 adjncy[knz++] = k-1+dimX;
329 else
330 adjncy[knz++] = k-1;
331 adjncy[knz++] = (k+dimX) % nvtx; /* k-dimX */
332 adjncy[knz++] = (k+dimX*(dimY-1)) % nvtx; /* | */
333 } /* k */
334 xadj[nvtx] = knz; /* | */
335 } /* k+dimX */
336
337 return(G);
338}
#define MESH
Definition const.h:14
#define TORUS
Definition const.h:15
#define GRID
Definition const.h:13

◆ setupInputMtxFromGraph()

inputMtx_t * setupInputMtxFromGraph ( graph_t * )

◆ setupLaplaceMtx()

inputMtx_t * setupLaplaceMtx ( PORD_INT ,
PORD_INT ,
PORD_INT  )

◆ setupMapping()

mapping_t * setupMapping ( elimtree_t * ,
PORD_INT ,
PORD_INT  )

◆ setupMask()

mask_t * setupMask ( PORD_INT ,
PORD_INT ,
PORD_INT  )

◆ setupMinPriority()

minprior_t * setupMinPriority ( multisector_t * ms)

Definition at line 123 of file minpriority.c.

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}
minprior_t * newMinPriority(PORD_INT nvtx, PORD_INT nstages)
Definition minpriority.c:81
gelim_t * setupElimGraph(graph_t *)
Definition gelim.c:229

◆ setupNDroot()

nestdiss_t * setupNDroot ( graph_t * G,
PORD_INT * map )

Definition at line 107 of file nestdiss.c.

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}
nestdiss_t * newNDnode(graph_t *G, PORD_INT *map, PORD_INT nvint)
Definition nestdiss.c:75

◆ setupNumFacBuffer()

buffer_t * setupNumFacBuffer ( workspace_t * ,
mask_t * ,
PORD_INT  )

◆ setupSubgraph()

graph_t * setupSubgraph ( graph_t * G,
PORD_INT * intvertex,
PORD_INT nvint,
PORD_INT * vtxmap )

Definition at line 132 of file graph.c.

133{ graph_t *Gsub;
134 PORD_INT *xadj, *adjncy, *vwght, *xadjGsub, *adjncyGsub, *vwghtGsub;
135 PORD_INT nvtx, nedgesGsub, totvwght, u, v, i, j, jstart, jstop, ptr;
136
137 nvtx = G->nvtx;
138 xadj = G->xadj;
139 adjncy = G->adjncy;
140 vwght = G->vwght;
141
142 /* -------------------------------------------------------------
143 compute number of edges and local indices of vertices in Gsub
144 ------------------------------------------------------------- */
145 nedgesGsub = 0;
146 for (i = 0; i < nvint; i++)
147 { u = intvertex[i];
148 if ((u < 0) || (u >= nvtx))
149 { fprintf(stderr, "\nError in function setupSubgraph\n"
150 " node %d does not belong to graph\n", u);
151 quit();
152 }
153 jstart = xadj[u];
154 jstop = xadj[u+1];
155 for (j = jstart; j < jstop; j++)
156 vtxmap[adjncy[j]] = -1;
157 nedgesGsub += (jstop - jstart);
158 }
159 for (i = 0; i < nvint; i++)
160 { u = intvertex[i];
161 vtxmap[u] = i;
162 }
163
164 Gsub = newGraph(nvint, nedgesGsub);
165 xadjGsub = Gsub->xadj;
166 adjncyGsub = Gsub->adjncy;
167 vwghtGsub = Gsub->vwght;
168
169 /* --------------------------
170 build the induced subgraph
171 -------------------------- */
172 totvwght = 0; ptr = 0;
173 for (i = 0; i < nvint; i++)
174 { u = intvertex[i];
175 xadjGsub[i] = ptr;
176 vwghtGsub[i] = vwght[u];
177 totvwght += vwght[u];
178 jstart = xadj[u];
179 jstop = xadj[u+1];
180 for (j = jstart; j < jstop; j++)
181 { v = adjncy[j];
182 if (vtxmap[v] >= 0)
183 adjncyGsub[ptr++] = vtxmap[v];
184 }
185 }
186 xadjGsub[nvint] = ptr;
187 Gsub->type = G->type;
188 Gsub->totvwght = totvwght;
189 return(Gsub);
190}

◆ setupSymbFacBuffer()

buffer_t * setupSymbFacBuffer ( frontsub_t * ,
PORD_INT *  )

◆ setupTopology()

topology_t * setupTopology ( void )

◆ setupTriangularBuffer()

buffer_t * setupTriangularBuffer ( frontsub_t * ,
PORD_INT * ,
FLOAT *  )

◆ setupUpdateMtxFromBuffer()

denseMtx_t * setupUpdateMtxFromBuffer ( workspace_t * ,
FLOAT *  )

◆ setupUpdateMtxFromFrontalMtx()

denseMtx_t * setupUpdateMtxFromFrontalMtx ( denseMtx_t * ,
factorMtx_t *  )

◆ setupUpdateMtxFromFrontalMtxPAR()

denseMtx_t * setupUpdateMtxFromFrontalMtxPAR ( denseMtx_t * ,
factorMtx_t *  )

◆ shrinkDomainDecomposition()

void shrinkDomainDecomposition ( domdec_t * dd1,
PORD_INT scoretype )

Definition at line 898 of file ddcreate.c.

899{ domdec_t *dd2;
900 PORD_INT *msvtxlist, *rep, *key;
901 PORD_INT nvtxdd1, nlist, u;
902
903 nvtxdd1 = dd1->G->nvtx;
904 mymalloc(msvtxlist, nvtxdd1, PORD_INT);
905 mymalloc(rep, nvtxdd1, PORD_INT);
906 mymalloc(key, nvtxdd1, PORD_INT);
907
908 /* ---------------
909 initializations
910 --------------- */
911 nlist = 0;
912 for (u = 0; u < nvtxdd1; u++)
913 { if (dd1->vtype[u] == 2)
914 msvtxlist[nlist++] = u;
915 rep[u] = u;
916 }
917
918 /* -------------------------------------
919 compute priorities and sort multisecs
920 ------------------------------------- */
921 computePriorities(dd1, msvtxlist, key, scoretype);
922 distributionCounting(nlist, msvtxlist, key);
923
924 /* ----------------------------------------------------------
925 eliminate multisecs and build coarser domain decomposition
926 ---------------------------------------------------------- */
927 eliminateMultisecs(dd1, msvtxlist, rep);
928 findIndMultisecs(dd1, msvtxlist, rep);
929 dd2 = coarserDomainDecomposition(dd1, rep);
930
931 /* -----------------------------------
932 append coarser domain decomposition
933 ----------------------------------- */
934 dd1->next = dd2;
935 dd2->prev = dd1;
936
937 free(msvtxlist);
938 free(rep);
939 free(key);
940}
domdec_t * coarserDomainDecomposition(domdec_t *dd1, PORD_INT *rep)
Definition ddcreate.c:778
void eliminateMultisecs(domdec_t *dd, PORD_INT *msvtxlist, PORD_INT *rep)
Definition ddcreate.c:606
void computePriorities(domdec_t *dd, PORD_INT *msvtxlist, PORD_INT *key, PORD_INT scoretype)
Definition ddcreate.c:536
void findIndMultisecs(domdec_t *dd, PORD_INT *msvtxlist, PORD_INT *rep)
Definition ddcreate.c:670

◆ smoothBy2Layers()

PORD_INT smoothBy2Layers ( gbisect_t * Gbisect,
PORD_INT * bipartvertex,
PORD_INT * pnX,
PORD_INT black,
PORD_INT white )

Definition at line 293 of file gbisect.c.

295{ gbipart_t *Gbipart;
296 PORD_INT *xadj, *adjncy, *color, *cwght, *map;
297 PORD_INT *flow, *rc, *matching, *dmflag, dmwght[6];
298 PORD_INT nvtx, smoothed, nX, nX2, nY, x, y, u, i, j, jstart, jstop;
299
300 nvtx = Gbisect->G->nvtx;
301 xadj = Gbisect->G->xadj;
302 adjncy = Gbisect->G->adjncy;
303 color = Gbisect->color;
304 cwght = Gbisect->cwght;
305 nX = *pnX;
306
307 /* ----------------------------------------------------
308 map vector identifies vertices of Gbisect in Gbipart
309 ---------------------------------------------------- */
310 mymalloc(map, nvtx, PORD_INT);
311
312 /* ----------------------------------
313 construct set Y of bipartite graph
314 ---------------------------------- */
315 nY = 0;
316 for (i = 0; i < nX; i++)
317 { x = bipartvertex[i];
318 jstart = xadj[x];
319 jstop = xadj[x+1];
320 for (j = jstart; j < jstop; j++)
321 { y = adjncy[j];
322 if (color[y] == black)
323 { bipartvertex[nX+nY++] = y;
324 color[y] = GRAY;
325 }
326 }
327 }
328 for (i = nX; i < nX+nY; i++)
329 { y = bipartvertex[i];
330 color[y] = black;
331 }
332
333 /* --------------------------------------------
334 compute the Dulmage-Mendelsohn decomposition
335 -------------------------------------------- */
336 Gbipart = setupBipartiteGraph(Gbisect->G, bipartvertex, nX, nY, map);
337
338 mymalloc(dmflag, (nX+nY), PORD_INT);
339 switch(Gbipart->G->type)
340 { case UNWEIGHTED:
341 mymalloc(matching, (nX+nY), PORD_INT);
342 maximumMatching(Gbipart, matching);
343 DMviaMatching(Gbipart, matching, dmflag, dmwght);
344 free(matching);
345 break;
346 case WEIGHTED:
347 mymalloc(flow, Gbipart->G->nedges, PORD_INT);
348 mymalloc(rc, (nX+nY), PORD_INT);
349 maximumFlow(Gbipart, flow, rc);
350 DMviaFlow(Gbipart, flow, rc, dmflag, dmwght);
351 free(flow);
352 free(rc);
353 break;
354 default:
355 fprintf(stderr, "\nError in function smoothSeparator\n"
356 " unrecognized bipartite graph type %d\n", Gbipart->G->type);
357 quit();
358 }
359
360#ifdef DEBUG
361 printf("Dulmage-Mendelsohn decomp. computed\n"
362 "SI %d, SX %d, SR %d, BI %d, BX %d, BR %d\n", dmwght[SI], dmwght[SX],
363 dmwght[SR], dmwght[BI], dmwght[BX], dmwght[BR]);
364#endif
365
366 /* -----------------------------------------------------------------------
367 1st TEST: try to exchange SI with BX, i.e. nodes in SI are moved from
368 the separator into white (white grows), and nodes in BX are moved from
369 black into the separator (black shrinks)
370 ----------------------------------------------------------------------- */
371 smoothed = FALSE;
372 if (F(cwght[GRAY]-dmwght[SI]+dmwght[BX], cwght[black]-dmwght[BX],
373 cwght[white]+dmwght[SI]) + EPS < F(cwght[GRAY], cwght[black],
374 cwght[white]))
375 { smoothed = TRUE;
376
377#ifdef DEBUG
378 printf("exchange SI with BX\n");
379#endif
380
381 cwght[white] += dmwght[SI]; cwght[GRAY] -= dmwght[SI];
382 cwght[black] -= dmwght[BX]; cwght[GRAY] += dmwght[BX];
383 for (i = 0; i < nX+nY; i++)
384 { u = bipartvertex[i];
385 if (dmflag[map[u]] == SI)
386 color[u] = white;
387 if (dmflag[map[u]] == BX)
388 color[u] = GRAY;
389 }
390 }
391
392 /* -----------------------------------------------------------------------
393 2nd TEST: try to exchange SR with BR, i.e. nodes in SR are moved from
394 the separator into white (white grows), and nodes in BR are moved from
395 black into the separator (black shrinks)
396 NOTE: SR is allowed to be exchanged with BR only if SI = BX = 0 or if
397 SI has been exchanged with BX (Adj(SR) is a subset of BX u BR)
398 ----------------------------------------------------------------------- */
399 if ((F(cwght[GRAY]-dmwght[SR]+dmwght[BR], cwght[black]-dmwght[BR],
400 cwght[white]+dmwght[SR]) + EPS < F(cwght[GRAY], cwght[black],
401 cwght[white]))
402 && ((smoothed) || (dmwght[SI] == 0)))
403 { smoothed = TRUE;
404
405#ifdef DEBUG
406 printf("exchange SR with BR\n");
407#endif
408
409 cwght[white] += dmwght[SR]; cwght[GRAY] -= dmwght[SR];
410 cwght[black] -= dmwght[BR]; cwght[GRAY] += dmwght[BR];
411 for (i = 0; i < nX+nY; i++)
412 { u = bipartvertex[i];
413 if (dmflag[map[u]] == SR)
414 color[u] = white;
415 if (dmflag[map[u]] == BR)
416 color[u] = GRAY;
417 }
418 }
419
420 /* -----------------------------------------------------
421 fill bipartvertex with the nodes of the new separator
422 ----------------------------------------------------- */
423 nX2 = 0;
424 for (i = 0; i < nX+nY; i++)
425 { u = bipartvertex[i];
426 if (color[u] == GRAY)
427 bipartvertex[nX2++] = u;
428 }
429 *pnX = nX2;
430
431 /* -------------------------------
432 free working storage and return
433 ------------------------------- */
434 free(map); free(dmflag);
435 freeBipartiteGraph(Gbipart);
436 return(smoothed);
437}
void DMviaMatching(gbipart_t *, PORD_INT *, PORD_INT *, PORD_INT *)
Definition gbipart.c:435
void DMviaFlow(gbipart_t *, PORD_INT *, PORD_INT *, PORD_INT *, PORD_INT *)
Definition gbipart.c:528
void freeBipartiteGraph(gbipart_t *)
Definition gbipart.c:81
gbipart_t * setupBipartiteGraph(graph_t *, PORD_INT *, PORD_INT, PORD_INT, PORD_INT *)
Definition gbipart.c:118
void maximumFlow(gbipart_t *, PORD_INT *, PORD_INT *)
Definition gbipart.c:322
void maximumMatching(gbipart_t *, PORD_INT *)
Definition gbipart.c:195

◆ smoothSeparator()

void smoothSeparator ( gbisect_t * Gbisect,
options_t * options )

Definition at line 443 of file gbisect.c.

444{ PORD_INT *xadj, *adjncy, *vwght, *color, *cwght, *bipartvertex;
445 PORD_INT nvtx, nX, nX2, u, x, y, a, b, i, j, jstart, jstop;
446
447 nvtx = Gbisect->G->nvtx;
448 xadj = Gbisect->G->xadj;
449 adjncy = Gbisect->G->adjncy;
450 vwght = Gbisect->G->vwght;
451 color = Gbisect->color;
452 cwght = Gbisect->cwght;
453
454 mymalloc(bipartvertex, nvtx, PORD_INT);
455
456 /* ----------------------------------------------------------
457 extract the separator (store its vertices in bipartvertex)
458 ---------------------------------------------------------- */
459 nX = 0;
460 for (u = 0; u < nvtx; u++)
461 if (color[u] == GRAY)
462 bipartvertex[nX++] = u;
463
464 do
465 { /* ---------------------------------------------------------------
466 minimize the separator (i.e. minimize set X of bipartite graph)
467 --------------------------------------------------------------- */
468 cwght[GRAY] = nX2 = 0;
469 for (i = 0; i < nX; i++)
470 { x = bipartvertex[i];
471 a = b = FALSE;
472 jstart = xadj[x];
473 jstop = xadj[x+1];
474 for (j = jstart; j < jstop; j++)
475 { y = adjncy[j];
476 if (color[y] == WHITE) a = TRUE;
477 if (color[y] == BLACK) b = TRUE;
478 }
479 if ((a) && (!b))
480 { color[x] = WHITE; cwght[WHITE] += vwght[x]; }
481 else if ((!a) && (b))
482 { color[x] = BLACK; cwght[BLACK] += vwght[x]; }
483 else
484 { bipartvertex[nX2++] = x; cwght[GRAY] += vwght[x]; }
485 }
486 nX = nX2;
487
488#ifdef BE_CAUTIOUS
489 checkSeparator(Gbisect);
490#endif
491
492 /* ------------------------------------------------------------------
493 smooth the unweighted/weighted separator
494 first pair it with the larger set; if unsuccessful try the smaller
495 ------------------------------------------------------------------ */
496 if (cwght[BLACK] >= cwght[WHITE])
497 { a = smoothBy2Layers(Gbisect, bipartvertex, &nX, BLACK, WHITE);
498 if (!a)
499 a = smoothBy2Layers(Gbisect, bipartvertex, &nX, WHITE, BLACK);
500 }
501 else
502 { a = smoothBy2Layers(Gbisect, bipartvertex, &nX, WHITE, BLACK);
503 if (!a)
504 a = smoothBy2Layers(Gbisect, bipartvertex, &nX, BLACK, WHITE);
505 }
506 if ((options[OPTION_MSGLVL] > 2) && (a))
507 printf("\t separator smoothed: S %d, B %d, W %d [cost %7.2f]\n",
508 cwght[GRAY], cwght[BLACK], cwght[WHITE],
509 F(cwght[GRAY], cwght[BLACK], cwght[WHITE]));
510 } while (a);
511
512 free(bipartvertex);
513}
void checkSeparator(gbisect_t *Gbisect)
Definition gbisect.c:117
PORD_INT smoothBy2Layers(gbisect_t *Gbisect, PORD_INT *bipartvertex, PORD_INT *pnX, PORD_INT black, PORD_INT white)
Definition gbisect.c:293

◆ SPACE_cleanup()

void SPACE_cleanup ( topology_t * ,
mask_t *  )

◆ SPACE_mapping()

mapping_t * SPACE_mapping ( graph_t * ,
PORD_INT * ,
options_t * ,
timings_t *  )

◆ SPACE_numFac()

void SPACE_numFac ( factorMtx_t * ,
timings_t *  )

◆ SPACE_numFacPAR()

void SPACE_numFacPAR ( topology_t * ,
mask_t * ,
mapping_t * ,
factorMtx_t * ,
PORD_INT msglvl,
timings_t *  )

◆ SPACE_ordering()

elimtree_t * SPACE_ordering ( graph_t * G,
options_t * options,
timings_t * cpus )

Definition at line 47 of file interface.c.

48{ graph_t *Gc;
49 multisector_t *ms;
50 minprior_t *minprior;
51 elimtree_t *T, *T2;
53 options_t default_options[] = { SPACE_ORDTYPE, SPACE_NODE_SELECTION1,
56 PORD_INT *vtxmap, istage, totnstep, totnzf;
57 FLOAT totops;
58
59 /* --------------------------------------------------
60 set default options, if no other options specified
61 -------------------------------------------------- */
62 if (options == NULL)
63 options = default_options;
64
65 /* ----------------
66 reset all timers
67 ---------------- */
69 pord_resettimer(cpusOrd[TIME_MS]);
80
81 /* ------------------
82 compress the graph
83 ------------------ */
85 mymalloc(vtxmap, G->nvtx, PORD_INT);
86 Gc = compressGraph(G, vtxmap);
88
89 if (Gc != NULL)
90 { if (options[OPTION_MSGLVL] > 0)
91 printf("compressed graph constructed (#nodes %d, #edges %d)\n",
92 Gc->nvtx, Gc->nedges >> 1);
93 }
94 else
95 { Gc = G;
96 free(vtxmap);
97 if (options[OPTION_MSGLVL] > 0)
98 printf("no compressed graph constructed\n");
99 }
100
101 /* -------------------
102 compute multisector
103 ------------------- */
104
105
106 pord_starttimer(cpusOrd[TIME_MS]);
107 ms = constructMultisector(Gc, options, cpusOrd);
108 pord_stoptimer(cpusOrd[TIME_MS]);
109
110
111 if (options[OPTION_MSGLVL] > 0)
112 printf("quality of multisector: #stages %d, #nodes %d, weight %d\n",
113 ms->nstages, ms->nnodes, ms->totmswght);
114
115 /* ---------------------------------
116 compute minimum priority ordering
117 --------------------------------- */
119 minprior = setupMinPriority(ms);
120 T = orderMinPriority(minprior, options, cpusOrd);
122
123 if (options[OPTION_MSGLVL] > 0)
124 { totnstep = totnzf = 0;
125 totops = 0.0;
126 for (istage = 0; istage < ms->nstages; istage++)
127 { totnstep += minprior->stageinfo[istage].nstep;
128 totnzf += minprior->stageinfo[istage].nzf;
129 totops += minprior->stageinfo[istage].ops;
130 }
131 printf("quality of ordering: #steps %d, nzl %d, ops %e\n", totnstep,
132 totnzf, totops);
133 }
134
135 /* -----------------------
136 expand elimination tree
137 ----------------------- */
138 if (Gc != G)
139 { T2 = expandElimTree(T, vtxmap, G->nvtx);
140 freeElimTree(T);
141 freeGraph(Gc);
142 free(vtxmap);
143 }
144 else T2 = T;
145
146 /* --------------------------------------------------
147 pull back timing results, if vector cpus available
148 -------------------------------------------------- */
149 if (cpus != NULL)
150 { cpus[0] = cpusOrd[TIME_COMPRESS];
151 cpus[1] = cpusOrd[TIME_MS];
152 cpus[2] = cpusOrd[TIME_MULTILEVEL];
153 cpus[3] = cpusOrd[TIME_INITDOMDEC];
154 cpus[4] = cpusOrd[TIME_COARSEDOMDEC];
155 cpus[5] = cpusOrd[TIME_INITSEP];
156 cpus[6] = cpusOrd[TIME_REFINESEP];
157 cpus[7] = cpusOrd[TIME_SMOOTH];
158 cpus[8] = cpusOrd[TIME_BOTTOMUP];
159 cpus[9] = cpusOrd[TIME_UPDADJNCY];
160 cpus[10] = cpusOrd[TIME_FINDINODES];
161 cpus[11] = cpusOrd[TIME_UPDSCORE];
162 }
163
164 /* ----------------------
165 free memory and return
166 ---------------------- */
167 freeMultisector(ms);
168 freeMinPriority(minprior);
169 return(T2);
170}
#define TIME_COMPRESS
Definition const.h:89
#define SPACE_MSGLVL
Definition const.h:45
#define SPACE_DOMAIN_SIZE
Definition const.h:44
#define TIME_SMOOTH
Definition const.h:96
#define TIME_MULTILEVEL
Definition const.h:91
#define SPACE_ORDTYPE
Definition const.h:40
#define SPACE_NODE_SELECTION3
Definition const.h:43
#define SPACE_NODE_SELECTION2
Definition const.h:42
#define TIME_BOTTOMUP
Definition const.h:97
#define TIME_MS
Definition const.h:90
#define SPACE_NODE_SELECTION1
Definition const.h:41
#define ORD_TIME_SLOTS
Definition const.h:87
#define pord_resettimer(var)
Definition macros.h:55
elimtree_t * orderMinPriority(minprior_t *, options_t *, timings_t *)
multisector_t * constructMultisector(graph_t *, options_t *, timings_t *)
void freeMultisector(multisector_t *)
Definition multisector.c:86
minprior_t * setupMinPriority(multisector_t *)
graph_t * compressGraph(graph_t *, PORD_INT *)
Definition graph.c:470
elimtree_t * expandElimTree(elimtree_t *, PORD_INT *, PORD_INT)
Definition tree.c:517
void freeMinPriority(minprior_t *)
FLOAT timings_t
Definition types.h:25
PORD_INT options_t
Definition types.h:24

◆ SPACE_setupMask()

mask_t * SPACE_setupMask ( topology_t * ,
PORD_INT  )

◆ SPACE_setupTopology()

topology_t * SPACE_setupTopology ( void )

◆ SPACE_solve()

void SPACE_solve ( inputMtx_t * ,
FLOAT * ,
FLOAT * ,
options_t * ,
timings_t *  )

◆ SPACE_solveTriangular()

void SPACE_solveTriangular ( factorMtx_t * L,
FLOAT * rhs,
FLOAT * xvec )

◆ SPACE_solveTriangularPAR()

void SPACE_solveTriangularPAR ( topology_t * ,
mask_t * ,
mapping_t * ,
factorMtx_t * ,
FLOAT * ,
FLOAT *  )

◆ SPACE_solveWithPerm()

void SPACE_solveWithPerm ( inputMtx_t * ,
PORD_INT * ,
FLOAT * ,
FLOAT * ,
options_t * ,
timings_t *  )

◆ SPACE_solveWithPermPAR()

void SPACE_solveWithPermPAR ( topology_t * top,
mask_t * mask,
inputMtx_t * A,
PORD_INT * perm,
FLOAT * rhs,
FLOAT * xvec,
options_t * options,
timings_t * cpus )

◆ SPACE_symbFac()

factorMtx_t * SPACE_symbFac ( elimtree_t * ,
inputMtx_t *  )

◆ SPACE_symbFacPAR()

factorMtx_t * SPACE_symbFacPAR ( topology_t * ,
mask_t * ,
mapping_t * ,
elimtree_t * ,
inputMtx_t *  )

◆ SPACE_transformElimTree()

elimtree_t * SPACE_transformElimTree ( elimtree_t * ,
PORD_INT  )

◆ split()

void split ( mapping_t * ,
PORD_INT ,
PORD_INT ,
PORD_INT ,
PORD_INT * ,
PORD_INT * ,
FLOAT * ,
PORD_INT  )

◆ splitDenseMtxColumnWise()

void splitDenseMtxColumnWise ( denseMtx_t * ,
mask_t * ,
buffer_t * ,
PORD_INT  )

◆ splitDenseMtxRowWise()

void splitDenseMtxRowWise ( denseMtx_t * ,
mask_t * ,
buffer_t * ,
PORD_INT  )

◆ splitNDnode()

void splitNDnode ( nestdiss_t * nd,
options_t * options,
timings_t * cpus )

Definition at line 125 of file nestdiss.c.

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}
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 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

◆ subtreeFactorOps()

void subtreeFactorOps ( elimtree_t * T,
FLOAT * ops )

Definition at line 935 of file tree.c.

936{ PORD_INT *ncolfactor, *ncolupdate;
937 FLOAT tri, rec;
938 PORD_INT J, K;
939
940 ncolfactor = T->ncolfactor;
941 ncolupdate = T->ncolupdate;
942
943 for (K = firstPostorder(T); K != -1; K = nextPostorder(T, K))
944 { tri = ncolfactor[K];
945 rec = ncolupdate[K];
946 ops[K] = (tri*tri*tri) / 3.0 + (tri*tri) / 2.0 - (5*tri) / 6.0;
947 ops[K] += (tri*tri*rec) + (rec*(rec+1)*tri);
948 for (J = T->firstchild[K]; J != -1; J = T->silbings[J])
949 ops[K] += ops[J];
950 }
951}

◆ trivialMultisector()

multisector_t * trivialMultisector ( graph_t * G)

Definition at line 96 of file multisector.c.

97{ multisector_t *ms;
98 PORD_INT *stage, nvtx, u;
99
100 /* -----------------------------------------------------------------
101 allocate memory for the multisector object and init. stage vector
102 ----------------------------------------------------------------- */
103 nvtx = G->nvtx;
104 ms = newMultisector(G);
105 stage = ms->stage;
106
107 for (u = 0; u < nvtx; u++)
108 stage[u] = 0; /* no vertex belongs to a separator */
109
110 /* -------------------------------
111 finalize the multisector object
112 ------------------------------- */
113 ms->nstages = 1;
114 ms->nnodes = 0;
115 ms->totmswght = 0;
116
117 return(ms);
118}
multisector_t * newMultisector(graph_t *G)
Definition multisector.c:68

◆ updateAdjncy()

void updateAdjncy ( gelim_t * Gelim,
PORD_INT * reachset,
PORD_INT nreach,
PORD_INT * tmp,
PORD_INT * pflag )

Definition at line 495 of file gelim.c.

496{ PORD_INT *xadj, *adjncy, *vwght, *len, *elen, *parent, *score;
497 PORD_INT u, v, e, me, i, j, jj, jdest, jfirstolde, jfirstv, jstart, jstop;
498 PORD_INT covered, marku;
499
500 xadj = Gelim->G->xadj;
501 adjncy = Gelim->G->adjncy;
502 vwght = Gelim->G->vwght;
503 len = Gelim->len;
504 elen = Gelim->elen;
505 parent = Gelim->parent;
506 score = Gelim->score;
507
508 /* -----------------------------------------------------------------
509 build the new element/variable list for each variable in reachset
510 ----------------------------------------------------------------- */
511 for (i = 0; i < nreach; i++)
512 { u = reachset[i];
513 vwght[u] = -vwght[u]; /* mark all variables in reachset */
514 jstart = xadj[u];
515 jstop = xadj[u] + len[u];
516 jdest = jfirstolde = jstart;
517
518#ifdef DEBUG
519 printf("Updating adjacency list of node %d\n", u);
520#endif
521
522 /* --------------------------------------------------------
523 scan the list of elements associated with variable u
524 place newly formed elements at the beginning of the list
525 -------------------------------------------------------- */
526 for (j = jstart; j < jstart + elen[u]; j++)
527 { e = adjncy[j];
528
529#ifdef DEBUG
530 printf(" >> element %d (score %d, parent %d)\n", e,score[e],parent[e]);
531#endif
532
533 if (score[e] == -4) /* e has been absorbed in this elim. step */
534 { me = parent[e]; /* me is the newly formed element */
535 if (tmp[me] < *pflag)
536 { adjncy[jdest++] = adjncy[jfirstolde]; /* move 1st old e to end */
537 adjncy[jfirstolde++] = me; /* append me at the beg. */
538 tmp[me] = *pflag;
539 }
540 }
541 else /* e has not been absorbed, i.e. it is */
542 if (tmp[e] < *pflag) /* an old element */
543 { adjncy[jdest++] = e;
544 tmp[e] = *pflag;
545 }
546 }
547 jfirstv = jdest; /* list of variables starts here */
548
549 /* -------------------------------------------------------
550 scan the list of variables associated with variable u
551 place newly formed elements at the begining of the list
552 ------------------------------------------------------- */
553 for (j = jstart + elen[u]; j < jstop; j++)
554 { v = adjncy[j];
555
556#ifdef DEBUG
557 printf(" >> variable %d (score %d)\n", v, score[v]);
558#endif
559
560 if (score[v] == -3) /* v has been eliminated in this step */
561 { if (tmp[v] < *pflag) /* and, thus, forms a newly created elem. */
562 { adjncy[jdest++] = adjncy[jfirstv]; /* move 1st var. to end */
563 adjncy[jfirstv++] = adjncy[jfirstolde]; /* move 1st old e to end */
564 adjncy[jfirstolde++] = v; /* append v at the beg. */
565 tmp[v] = *pflag;
566 }
567 }
568 else
569 adjncy[jdest++] = v; /* v is still a variable */
570 }
571 elen[u] = jfirstv - jstart;
572 len[u] = jdest - jstart;
573 (*pflag)++; /* clear tmp for next round */
574
575#ifdef DEBUG
576 printf(" node %d: neighboring elements:\n", u);
577 for (j = jstart; j < jstart + elen[u]; j++)
578 printf("%5d", adjncy[j]);
579 printf("\n node %d: neighboring variables:\n", u);
580 for (j = jstart + elen[u]; j < jstart + len[u]; j++)
581 printf("%5d", adjncy[j]);
582 printf("\n");
583#endif
584 }
585
586 /* ---------------------------------------------------------
587 remove from each list all covered edges between variables
588 --------------------------------------------------------- */
589 for (i = 0; i < nreach; i++)
590 { u = reachset[i];
591 jstart = xadj[u];
592 jstop = jstart + len[u];
593 marku = FALSE;
594
595 for (jdest = j = jstart + elen[u]; j < jstop; j++)
596 { v = adjncy[j];
597 if (vwght[v] > 0) /* v does not belong to reachset */
598 adjncy[jdest++] = v; /* edge (u,v) not covered */
599 if (vwght[v] < 0) /* both vertices belong to reachset */
600 { covered = FALSE; /* check for a common element */
601 if (!marku)
602 { for (jj = jstart; jj < jstart + elen[u]; jj++) /* mark elem. */
603 tmp[adjncy[jj]] = *pflag; /* of u */
604 marku = TRUE;
605 }
606 for (jj = xadj[v]; jj < xadj[v] + elen[v]; jj++) /* check elem. */
607 if (tmp[adjncy[jj]] == *pflag) /* of v */
608 { covered = TRUE;
609 break;
610 }
611 if (!covered)
612 adjncy[jdest++] = v;
613 }
614 }
615 len[u] = jdest - jstart;
616 (*pflag)++; /* clear tmp for next round */
617
618#ifdef DEBUG
619 printf(" node %d: neighboring uncovered variables:\n", u);
620 for (j = jstart + elen[u]; j < jstart + len[u]; j++)
621 printf("%5d", adjncy[j]);
622 printf("\n");
623#endif
624 }
625
626 /* --------------------------------
627 unmark all variables in reachset
628 -------------------------------- */
629 for (i = 0; i < nreach; i++)
630 { u = reachset[i];
631 vwght[u] = -vwght[u];
632 }
633}

◆ updateB2W()

void updateB2W ( bucket_t * w_bucket,
bucket_t * b_bucket,
domdec_t * dd,
PORD_INT domain,
PORD_INT * tmp_color,
PORD_INT * deltaW,
PORD_INT * deltaB,
PORD_INT * deltaS )

Definition at line 383 of file ddbisect.c.

385{ PORD_INT *xadj, *adjncy, *vwght, *vtype;
386 PORD_INT weight, u, v, i, istart, istop, j, jstart, jstop;
387
388 xadj = dd->G->xadj;
389 adjncy = dd->G->adjncy;
390 vwght = dd->G->vwght;
391 vtype = dd->vtype;
392
393 istart = xadj[domain];
394 istop = xadj[domain+1];
395 for (i = istart; i < istop; i++)
396 { u = adjncy[i];
397 weight = vwght[u];
398 jstart = xadj[u];
399 jstop = xadj[u+1];
400
401 /* ---------------------------------------------------------------
402 subcase (1): before flipping domain to WHITE there was only one
403 other WHITE domain v. update deltaB[v] and deltaS[v]
404 --------------------------------------------------------------- */
405 if (deltaW[u] < 0)
406 { v = -(deltaW[u]+1);
407 deltaW[u] = 1;
408
409#ifdef DEBUG
410 printf(" B2W case (1): (via multisec %d) removing domain %d from "
411 "w_bucket\n", u, v);
412#endif
413
414 removeBucket(w_bucket, v);
415 deltaB[v] -= weight; deltaS[v] += weight;
416 insertBucket(w_bucket, deltaS[v], v);
417 }
418
419 /* ---------------------------------------------------------------
420 subcase (2): all other domains are BLACK. update deltaB, deltaS
421 of these BLACK domains. NOTE: subcase (3) may directly follow
422 --------------------------------------------------------------- */
423 if (deltaW[u] == 0)
424 { tmp_color[u] = GRAY;
425 for (j = jstart; j < jstop; j++)
426 { v = adjncy[j];
427 if (vtype[v] == 1)
428 {
429#ifdef DEBUG
430 printf(" B2W case (2): (via multisec %d) removing domain %d from "
431 "b_bucket\n", u, v);
432#endif
433
434 removeBucket(b_bucket, v);
435 deltaB[v] += weight; deltaS[v] -= weight;
436 insertBucket(b_bucket, deltaS[v], v);
437 }
438 }
439 }
440
441 if (deltaB[u] < 0) deltaB[u] = 1; /* the unique BLACK dom. flipped */
442 deltaB[u]--; deltaW[u]++;
443
444 /* -------------------------------------------------------------
445 subcase (3): after flipping domain to WHITE there is only one
446 remaining BLACK domain. search it and update deltaW, deltaS
447 furthermore, store the remaining BLACK domain in deltaB[u]
448 ------------------------------------------------------------- */
449 if (deltaB[u] == 1)
450 { for (j = jstart; j < jstop; j++)
451 { v = adjncy[j];
452 if ((tmp_color[v] == BLACK) && (vtype[v] == 1))
453 {
454#ifdef DEBUG
455 printf(" B2W case (3): (via multisec %d) removing domain %d from "
456 "b_bucket\n", u, v);
457#endif
458
459 removeBucket(b_bucket, v);
460 deltaW[v] += weight; deltaS[v] -= weight;
461 deltaB[u] = -(v+1);
462 insertBucket(b_bucket, deltaS[v], v);
463 }
464 }
465 }
466
467 /* -------------------------------------------------------------
468 subcase (4): after flipping domain to WHITE there is no other
469 BLACK domain. update deltaW, deltaS of the WHITE domains
470 ------------------------------------------------------------- */
471 if (deltaB[u] == 0)
472 { tmp_color[u] = WHITE;
473 for (j = jstart; j < jstop; j++)
474 { v = adjncy[j];
475 if (vtype[v] == 1)
476 {
477#ifdef DEBUG
478 printf(" B2W case (4): (via multisec %d) removing domain %d from "
479 "w_bucket\n", u, v);
480#endif
481
482 removeBucket(w_bucket, v);
483 deltaW[v] -= weight; deltaS[v] += weight;
484 insertBucket(w_bucket, deltaS[v], v);
485 }
486 }
487 }
488 }
489}

◆ updateDegree()

void updateDegree ( gelim_t * Gelim,
PORD_INT * reachset,
PORD_INT nreach,
PORD_INT * bin )

Definition at line 761 of file gelim.c.

762{ PORD_INT *xadj, *adjncy, *vwght, *len, *elen, *degree;
763 PORD_INT totvwght, deg, vwghtv, u, v, w, e, me, r, i, istart, istop;
764 PORD_INT j, jstart, jstop;
765
766 totvwght = Gelim->G->totvwght;
767 xadj = Gelim->G->xadj;
768 adjncy = Gelim->G->adjncy;
769 vwght = Gelim->G->vwght;
770 len = Gelim->len;
771 elen = Gelim->elen;
772 degree = Gelim->degree;
773
774 /* -------------------------------------------------------------------
775 degree update only for those vertices in reachset that are adjacent
776 to an element
777 ------------------------------------------------------------------- */
778 for (r = 0; r < nreach; r++)
779 { u = reachset[r];
780 if (elen[u] > 0)
781 bin[u] = 1;
782 }
783
784 /* -----------------------------------------
785 and now do the approximate degree updates
786 ----------------------------------------- */
787 for (r = 0; r < nreach; r++)
788 { u = reachset[r];
789 if (bin[u] == 1) /* me is the most recently formed element */
790 { me = adjncy[xadj[u]]; /* in the neighborhood of u */
791
792#ifdef DEBUG
793 printf("Updating degree of all variables in L(%d) (initiated by %d)\n",
794 me, u);
795#endif
796
797 /* ----------------------------------------------------------------
798 compute in bin[e] the size of Le\Lme for all unabsorbed elements
799 ---------------------------------------------------------------- */
800 istart = xadj[me];
801 istop = istart + len[me]; /* compute in bin[e] the size */
802 for (i = istart; i < istop; i++) /* of Le/Lme for all elements */
803 { v = adjncy[i]; /* e != me that are adjacent */
804 vwghtv = vwght[v]; /* to a principal var. e Lme */
805 if (vwghtv > 0)
806 { jstart = xadj[v];
807 jstop = jstart + elen[v];
808 for (j = jstart; j < jstop; j++)
809 { e = adjncy[j];
810 if (e != me)
811 { if (bin[e] > 0) bin[e] -= vwghtv;
812 else bin[e] = degree[e] - vwghtv;
813 }
814 }
815 }
816 }
817
818#ifdef DEBUG
819 for (i = istart; i < istop; i++)
820 { v = adjncy[i];
821 if (vwght[v] > 0)
822 for (j = xadj[v]; j < xadj[v] + elen[v]; j++)
823 { e = adjncy[j];
824 if (e != me)
825 printf(" >> element %d: degree %d, outer degree %d\n", e,
826 degree[e], bin[e]);
827 }
828 }
829#endif
830
831 /* ------------------------------------------------------
832 update approx. degree for all v in Lme with bin[v] = 1
833 ------------------------------------------------------ */
834 for (i = istart; i < istop; i++)
835 { v = adjncy[i]; /* update the upper bound deg. */
836 vwghtv = vwght[v]; /* of all principal variables */
837 deg = 0; /* in Lme that have not been */
838 if (bin[v] == 1) /* updated yet */
839 { jstart = xadj[v];
840 jstop = jstart + len[v];
841
842 /* scan the element list associated with principal v */
843 for (j = jstart; j < jstart + elen[v]; j++)
844 { e = adjncy[j];
845 if (e != me) deg += bin[e];
846 }
847
848 /* scan the supervariables in the list associated with v */
849 for (j = jstart + elen[v]; j < jstop; j++)
850 { w = adjncy[j];
851 deg += vwght[w];
852 }
853
854 /* compute the external degree of v (add size of Lme) */
855 deg = min(degree[v], deg);
856 degree[v] = max(1, min(deg+degree[me]-vwghtv, totvwght-vwghtv));
857 bin[v] = -1;
858
859#ifdef DEBUG
860 printf(" >> variable %d (totvwght %d, vwght %d): deg %d, "
861 "degme %d, approx degree %d\n", v, totvwght, vwghtv, deg,
862 degree[me], degree[v]);
863#endif
864 }
865 }
866
867 /* ------------------------------------
868 clear bin[e] of all elements e != me
869 ------------------------------------ */
870 for (i = istart; i < istop; i++)
871 { v = adjncy[i];
872 vwghtv = vwght[v];
873 if (vwghtv > 0)
874 { jstart = xadj[v];
875 jstop = jstart + elen[v];
876 for (j = jstart; j < jstop; j++)
877 { e = adjncy[j];
878 if (e != me) bin[e] = -1;
879 }
880 }
881 }
882 }
883 }
884}

◆ updateScore()

void updateScore ( gelim_t * Gelim,
PORD_INT * reachset,
PORD_INT nreach,
PORD_INT scoretype,
PORD_INT * bin )

Definition at line 890 of file gelim.c.

891{ PORD_INT *xadj, *adjncy, *vwght, *len, *elen, *degree, *score;
892 PORD_INT vwghtv, deg, degme, u, v, me, r, i, istart, istop;
893 /* Modified by JYL, 16 march 2005.
894 * scr could overflow for quasi dense rows.
895 * Use a double instead for large degrees
896 * aset it near to MAX_INT in case of problem.
897 */
898 double scr_dbl;
899 PORD_INT scr;
900
901 xadj = Gelim->G->xadj;
902 adjncy = Gelim->G->adjncy;
903 vwght = Gelim->G->vwght;
904 len = Gelim->len;
905 elen = Gelim->elen;
906 degree = Gelim->degree;
907 score = Gelim->score;
908
909 /* ------------------------------------------------------------------
910 score update only for those vertices in reachset that are adjacent
911 to an element
912 ------------------------------------------------------------------ */
913 for (r = 0; r < nreach; r++)
914 { u = reachset[r];
915 if (elen[u] > 0)
916 bin[u] = 1;
917 }
918
919 /* ----------------------------
920 and now do the score updates
921 ---------------------------- */
922 scoretype = scoretype % 10;
923 for (r = 0; r < nreach; r++)
924 { u = reachset[r];
925 if (bin[u] == 1) /* me is the most recently formed element */
926 { me = adjncy[xadj[u]]; /* in the neighborhood of u */
927
928#ifdef DEBUG
929 printf("Updating score of all variables in L(%d) (initiated by %d)\n",
930 me, u);
931#endif
932
933 istart = xadj[me];
934 istop = xadj[me] + len[me];
935 for (i = istart; i < istop; i++)
936 { v = adjncy[i]; /* update score of all principal */
937 if (bin[v] == 1) /* variables in Lme that have not */
938 { vwghtv = vwght[v]; /* been updated yet */
939 deg = degree[v];
940 degme = degree[me] - vwghtv;
941 if (deg > 40000 || degme > 40000)
942 {
943 switch(scoretype)
944 { case AMD:
945 scr_dbl = (double)deg;
946 break;
947 case AMF:
948 scr_dbl = (double)deg*(double)(deg-1)/2 - (double)degme*(double)(degme-1)/2;
949 break;
950 case AMMF:
951 scr_dbl = ((double)deg*(double)(deg-1)/2 - (double)degme*(double)(degme-1)/2) / (double)vwghtv;
952 break;
953 case AMIND:
954 scr_dbl = max(0, ((double)deg*(double)(deg-1)/2 - (double)degme*(double)(degme-1)/2)
955 - (double)deg*(double)vwghtv);
956 break;
957 default:
958 fprintf(stderr, "\nError in function updateScore\n"
959 " unrecognized selection strategy %d\n", scoretype);
960 quit();
961 }
962 /* Some buckets have offset nvtx / 2.
963 * Using MAX_INT - nvtx should then be safe */
964 score[v] = (PORD_INT) (min(scr_dbl,MAX_INT-Gelim->G->nvtx));
965 }
966 else
967 {
968 switch(scoretype)
969 { case AMD:
970 scr = deg;
971 break;
972 case AMF:
973 scr = deg*(deg-1)/2 - degme*(degme-1)/2;
974 break;
975 case AMMF:
976 scr = (deg*(deg-1)/2 - degme*(degme-1)/2) / vwghtv;
977 break;
978 case AMIND:
979 scr = max(0, (deg*(deg-1)/2 - degme*(degme-1)/2)
980 - deg*vwghtv);
981 break;
982 default:
983 fprintf(stderr, "\nError in function updateScore\n"
984 " unrecognized selection strategy %d\n", scoretype);
985 quit();
986 }
987 score[v] = scr;
988 }
989 bin[v] = -1;
990
991#ifdef DEBUG
992 printf(" >> variable %d (me %d): weight %d, (ext)degme %d, "
993 "degree %d, score %d\n", u, me, vwghtv, degme, degree[v],
994 score[v]);
995#endif
996
997 if (score[v] < 0)
998 { fprintf(stderr, "\nError in function updateScore\n"
999 " score[%d] = %d is negative\n", v, score[v]);
1000 quit();
1001 }
1002 }
1003 }
1004 }
1005 }
1006}
#define AMD
Definition const.h:29
#define AMMF
Definition const.h:31
#define AMIND
Definition const.h:32
#define AMF
Definition const.h:30

◆ updateW2B()

void updateW2B ( bucket_t * w_bucket,
bucket_t * b_bucket,
domdec_t * dd,
PORD_INT domain,
PORD_INT * tmp_color,
PORD_INT * deltaW,
PORD_INT * deltaB,
PORD_INT * deltaS )

Definition at line 495 of file ddbisect.c.

497{ PORD_INT *xadj, *adjncy, *vwght, *vtype;
498 PORD_INT weight, u, v, i, istart, istop, j, jstart, jstop;
499
500 xadj = dd->G->xadj;
501 adjncy = dd->G->adjncy;
502 vwght = dd->G->vwght;
503 vtype = dd->vtype;
504
505 istart = xadj[domain];
506 istop = xadj[domain+1];
507 for (i = istart; i < istop; i++)
508 { u = adjncy[i];
509 weight = vwght[u];
510 jstart = xadj[u];
511 jstop = xadj[u+1];
512
513 /* ---------------------------------------------------------------
514 subcase (1): before flipping domain to BLACK there was only one
515 other BLACK domain v. update deltaW[v] and deltaS[v]
516 --------------------------------------------------------------- */
517 if (deltaB[u] < 0)
518 { v = -(deltaB[u]+1);
519 deltaB[u] = 1;
520
521#ifdef DEBUG
522 printf(" W2B case (1): (via multisec %d) removing domain %d from "
523 "b_bucket\n", u, v);
524#endif
525
526 removeBucket(b_bucket, v);
527 deltaW[v] -= weight; deltaS[v] += weight;
528 insertBucket(b_bucket, deltaS[v], v);
529 }
530
531 /* ---------------------------------------------------------------
532 subcase (2): all other domains are WHITE. update deltaW, deltaS
533 of these WHITE domains. NOTE: subcase (3) may directly follow
534 --------------------------------------------------------------- */
535 if (deltaB[u] == 0)
536 { tmp_color[u] = GRAY;
537 for (j = jstart; j < jstop; j++)
538 { v = adjncy[j];
539 if (vtype[v] == 1)
540 {
541#ifdef DEBUG
542 printf(" W2B case (2): (via multisec %d) removing domain %d from "
543 "w_bucket\n", u, v);
544#endif
545
546 removeBucket(w_bucket, v);
547 deltaW[v] += weight; deltaS[v] -= weight;
548 insertBucket(w_bucket, deltaS[v], v);
549 }
550 }
551 }
552
553 if (deltaW[u] < 0) deltaW[u] = 1; /* the unique WHITE dom. flipped */
554 deltaB[u]++; deltaW[u]--;
555
556 /* -------------------------------------------------------------
557 subcase (3): after flipping domain to BLACK there is only one
558 remaining WHITE domain. search it and update deltaB, deltaS
559 furthermore, store the remaining WHITE domain in deltaW[u]
560 ------------------------------------------------------------- */
561 if (deltaW[u] == 1)
562 { for (j = jstart; j < jstop; j++)
563 { v = adjncy[j];
564 if ((tmp_color[v] == WHITE) && (vtype[v] == 1))
565 {
566#ifdef DEBUG
567 printf(" W2B case (3): (via multisec %d) removing domain %d from "
568 "w_bucket\n", u, v);
569#endif
570
571 removeBucket(w_bucket, v);
572 deltaB[v] += weight; deltaS[v] -= weight;
573 deltaW[u] = -(v+1);
574 insertBucket(w_bucket, deltaS[v], v);
575 }
576 }
577 }
578
579 /* ---------------------------------------------------------------
580 subcase (4): after flipping domain to BLACK there is no other
581 WHITE domain. update deltaB, deltaS of the BLACK domains
582 --------------------------------------------------------------- */
583 if (deltaW[u] == 0)
584 { tmp_color[u] = BLACK;
585 for (j = jstart; j < jstop; j++)
586 { v = adjncy[j];
587 if (vtype[v] == 1)
588 {
589#ifdef DEBUG
590 printf(" W2B case (4): (via multisec %d) removing domain %d from "
591 "b_bucket\n", u, v);
592#endif
593
594 removeBucket(b_bucket, v);
595 deltaB[v] -= weight; deltaS[v] += weight;
596 insertBucket(b_bucket, deltaS[v], v);
597 }
598 }
599 }
600 }
601}