aboutsummaryrefslogtreecommitdiff
path: root/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mmd.c
diff options
context:
space:
mode:
authorTor Aamodt <[email protected]>2010-10-01 08:55:28 -0800
committerTor Aamodt <[email protected]>2010-10-01 08:55:28 -0800
commit11b308e7363e937966b035b4891db32b4eece3bf (patch)
tree50ca4c9ad6f163ac4acb2bf505e64dfebed66947 /benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mmd.c
parentbb820c116764d7a1b8e071137d32b74e7f34dd2f (diff)
integrating recent changes from fermi-test into fermi
(i'll use "fermi" for more disruptive changes to the pipeline model such as updating the MSHRs and getting rid of the warp tracker, ripping out DWF, etc...) [git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 7805]
Diffstat (limited to 'benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mmd.c')
-rw-r--r--benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mmd.c593
1 files changed, 0 insertions, 593 deletions
diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mmd.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mmd.c
deleted file mode 100644
index 1b43618..0000000
--- a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mmd.c
+++ /dev/null
@@ -1,593 +0,0 @@
-/*
- * mmd.c
- *
- * **************************************************************
- * The following C function was developed from a FORTRAN subroutine
- * in SPARSPAK written by Eleanor Chu, Alan George, Joseph Liu
- * and Esmond Ng.
- *
- * The FORTRAN-to-C transformation and modifications such as dynamic
- * memory allocation and deallocation were performed by Chunguang
- * Sun.
- * **************************************************************
- *
- * Taken from SMMS, George 12/13/94
- *
- * The meaning of invperm, and perm vectors is different from that
- * in genqmd_ of SparsPak
- *
- * $Id: mmd.c,v 1.1 2003/07/16 15:55:11 karypis Exp $
- */
-
-#include <metis.h>
-
-
-/*************************************************************************
-* genmmd -- multiple minimum external degree
-* purpose -- this routine implements the minimum degree
-* algorithm. it makes use of the implicit representation
-* of elimination graphs by quotient graphs, and the notion
-* of indistinguishable nodes. It also implements the modifications
-* by multiple elimination and minimum external degree.
-* Caution -- the adjacency vector adjncy will be destroyed.
-* Input parameters --
-* neqns -- number of equations.
-* (xadj, adjncy) -- the adjacency structure.
-* delta -- tolerance value for multiple elimination.
-* maxint -- maximum machine representable (short) integer
-* (any smaller estimate will do) for marking nodes.
-* Output parameters --
-* perm -- the minimum degree ordering.
-* invp -- the inverse of perm.
-* *ncsub -- an upper bound on the number of nonzero subscripts
-* for the compressed storage scheme.
-* Working parameters --
-* head -- vector for head of degree lists.
-* invp -- used temporarily for degree forward link.
-* perm -- used temporarily for degree backward link.
-* qsize -- vector for size of supernodes.
-* list -- vector for temporary linked lists.
-* marker -- a temporary marker vector.
-* Subroutines used -- mmdelm, mmdint, mmdnum, mmdupd.
-**************************************************************************/
-void genmmd(int neqns, idxtype *xadj, idxtype *adjncy, idxtype *invp, idxtype *perm,
- int delta, idxtype *head, idxtype *qsize, idxtype *list, idxtype *marker,
- int maxint, int *ncsub)
-{
- int ehead, i, mdeg, mdlmt, mdeg_node, nextmd, num, tag;
-
- if (neqns <= 0)
- return;
-
- /* Adjust from C to Fortran */
- xadj--; adjncy--; invp--; perm--; head--; qsize--; list--; marker--;
-
- /* initialization for the minimum degree algorithm. */
- *ncsub = 0;
- mmdint(neqns, xadj, adjncy, head, invp, perm, qsize, list, marker);
-
- /* 'num' counts the number of ordered nodes plus 1. */
- num = 1;
-
- /* eliminate all isolated nodes. */
- nextmd = head[1];
- while (nextmd > 0) {
- mdeg_node = nextmd;
- nextmd = invp[mdeg_node];
- marker[mdeg_node] = maxint;
- invp[mdeg_node] = -num;
- num = num + 1;
- }
-
- /* search for node of the minimum degree. 'mdeg' is the current */
- /* minimum degree; 'tag' is used to facilitate marking nodes. */
- if (num > neqns)
- goto n1000;
- tag = 1;
- head[1] = 0;
- mdeg = 2;
-
- /* infinite loop here ! */
- while (1) {
- while (head[mdeg] <= 0)
- mdeg++;
-
- /* use value of 'delta' to set up 'mdlmt', which governs */
- /* when a degree update is to be performed. */
- mdlmt = mdeg + delta;
- ehead = 0;
-
-n500:
- mdeg_node = head[mdeg];
- while (mdeg_node <= 0) {
- mdeg++;
-
- if (mdeg > mdlmt)
- goto n900;
- mdeg_node = head[mdeg];
- };
-
- /* remove 'mdeg_node' from the degree structure. */
- nextmd = invp[mdeg_node];
- head[mdeg] = nextmd;
- if (nextmd > 0)
- perm[nextmd] = -mdeg;
- invp[mdeg_node] = -num;
- *ncsub += mdeg + qsize[mdeg_node] - 2;
- if ((num+qsize[mdeg_node]) > neqns)
- goto n1000;
-
- /* eliminate 'mdeg_node' and perform quotient graph */
- /* transformation. reset 'tag' value if necessary. */
- tag++;
- if (tag >= maxint) {
- tag = 1;
- for (i = 1; i <= neqns; i++)
- if (marker[i] < maxint)
- marker[i] = 0;
- };
-
- mmdelm(mdeg_node, xadj, adjncy, head, invp, perm, qsize, list, marker, maxint, tag);
-
- num += qsize[mdeg_node];
- list[mdeg_node] = ehead;
- ehead = mdeg_node;
- if (delta >= 0)
- goto n500;
-
- n900:
- /* update degrees of the nodes involved in the */
- /* minimum degree nodes elimination. */
- if (num > neqns)
- goto n1000;
- mmdupd( ehead, neqns, xadj, adjncy, delta, &mdeg, head, invp, perm, qsize, list, marker, maxint, &tag);
- }; /* end of -- while ( 1 ) -- */
-
-n1000:
- mmdnum( neqns, perm, invp, qsize );
-
- /* Adjust from Fortran back to C*/
- xadj++; adjncy++; invp++; perm++; head++; qsize++; list++; marker++;
-}
-
-
-/**************************************************************************
-* mmdelm ...... multiple minimum degree elimination
-* Purpose -- This routine eliminates the node mdeg_node of minimum degree
-* from the adjacency structure, which is stored in the quotient
-* graph format. It also transforms the quotient graph representation
-* of the elimination graph.
-* Input parameters --
-* mdeg_node -- node of minimum degree.
-* maxint -- estimate of maximum representable (short) integer.
-* tag -- tag value.
-* Updated parameters --
-* (xadj, adjncy) -- updated adjacency structure.
-* (head, forward, backward) -- degree doubly linked structure.
-* qsize -- size of supernode.
-* marker -- marker vector.
-* list -- temporary linked list of eliminated nabors.
-***************************************************************************/
-void mmdelm(int mdeg_node, idxtype *xadj, idxtype *adjncy, idxtype *head, idxtype *forward,
- idxtype *backward, idxtype *qsize, idxtype *list, idxtype *marker, int maxint,int tag)
-{
- int element, i, istop, istart, j,
- jstop, jstart, link,
- nabor, node, npv, nqnbrs, nxnode,
- pvnode, rlmt, rloc, rnode, xqnbr;
-
- /* find the reachable set of 'mdeg_node' and */
- /* place it in the data structure. */
- marker[mdeg_node] = tag;
- istart = xadj[mdeg_node];
- istop = xadj[mdeg_node+1] - 1;
-
- /* 'element' points to the beginning of the list of */
- /* eliminated nabors of 'mdeg_node', and 'rloc' gives the */
- /* storage location for the next reachable node. */
- element = 0;
- rloc = istart;
- rlmt = istop;
- for ( i = istart; i <= istop; i++ ) {
- nabor = adjncy[i];
- if ( nabor == 0 ) break;
- if ( marker[nabor] < tag ) {
- marker[nabor] = tag;
- if ( forward[nabor] < 0 ) {
- list[nabor] = element;
- element = nabor;
- } else {
- adjncy[rloc] = nabor;
- rloc++;
- };
- }; /* end of -- if -- */
- }; /* end of -- for -- */
-
- /* merge with reachable nodes from generalized elements. */
- while ( element > 0 ) {
- adjncy[rlmt] = -element;
- link = element;
-
-n400:
- jstart = xadj[link];
- jstop = xadj[link+1] - 1;
- for ( j = jstart; j <= jstop; j++ ) {
- node = adjncy[j];
- link = -node;
- if ( node < 0 ) goto n400;
- if ( node == 0 ) break;
- if ((marker[node]<tag)&&(forward[node]>=0)) {
- marker[node] = tag;
- /*use storage from eliminated nodes if necessary.*/
- while ( rloc >= rlmt ) {
- link = -adjncy[rlmt];
- rloc = xadj[link];
- rlmt = xadj[link+1] - 1;
- };
- adjncy[rloc] = node;
- rloc++;
- };
- }; /* end of -- for ( j = jstart; -- */
- element = list[element];
- }; /* end of -- while ( element > 0 ) -- */
- if ( rloc <= rlmt ) adjncy[rloc] = 0;
- /* for each node in the reachable set, do the following. */
- link = mdeg_node;
-
-n1100:
- istart = xadj[link];
- istop = xadj[link+1] - 1;
- for ( i = istart; i <= istop; i++ ) {
- rnode = adjncy[i];
- link = -rnode;
- if ( rnode < 0 ) goto n1100;
- if ( rnode == 0 ) return;
-
- /* 'rnode' is in the degree list structure. */
- pvnode = backward[rnode];
- if (( pvnode != 0 ) && ( pvnode != (-maxint) )) {
- /* then remove 'rnode' from the structure. */
- nxnode = forward[rnode];
- if ( nxnode > 0 ) backward[nxnode] = pvnode;
- if ( pvnode > 0 ) forward[pvnode] = nxnode;
- npv = -pvnode;
- if ( pvnode < 0 ) head[npv] = nxnode;
- };
-
- /* purge inactive quotient nabors of 'rnode'. */
- jstart = xadj[rnode];
- jstop = xadj[rnode+1] - 1;
- xqnbr = jstart;
- for ( j = jstart; j <= jstop; j++ ) {
- nabor = adjncy[j];
- if ( nabor == 0 ) break;
- if ( marker[nabor] < tag ) {
- adjncy[xqnbr] = nabor;
- xqnbr++;
- };
- };
-
- /* no active nabor after the purging. */
- nqnbrs = xqnbr - jstart;
- if ( nqnbrs <= 0 ) {
- /* merge 'rnode' with 'mdeg_node'. */
- qsize[mdeg_node] += qsize[rnode];
- qsize[rnode] = 0;
- marker[rnode] = maxint;
- forward[rnode] = -mdeg_node;
- backward[rnode] = -maxint;
- } else {
- /* flag 'rnode' for degree update, and */
- /* add 'mdeg_node' as a nabor of 'rnode'. */
- forward[rnode] = nqnbrs + 1;
- backward[rnode] = 0;
- adjncy[xqnbr] = mdeg_node;
- xqnbr++;
- if ( xqnbr <= jstop ) adjncy[xqnbr] = 0;
- };
- }; /* end of -- for ( i = istart; -- */
- return;
- }
-
-/***************************************************************************
-* mmdint ---- mult minimum degree initialization
-* purpose -- this routine performs initialization for the
-* multiple elimination version of the minimum degree algorithm.
-* input parameters --
-* neqns -- number of equations.
-* (xadj, adjncy) -- adjacency structure.
-* output parameters --
-* (head, dfrow, backward) -- degree doubly linked structure.
-* qsize -- size of supernode ( initialized to one).
-* list -- linked list.
-* marker -- marker vector.
-****************************************************************************/
-int mmdint(int neqns, idxtype *xadj, idxtype *adjncy, idxtype *head, idxtype *forward,
- idxtype *backward, idxtype *qsize, idxtype *list, idxtype *marker)
-{
- int fnode, ndeg, node;
-
- for ( node = 1; node <= neqns; node++ ) {
- head[node] = 0;
- qsize[node] = 1;
- marker[node] = 0;
- list[node] = 0;
- };
-
- /* initialize the degree doubly linked lists. */
- for ( node = 1; node <= neqns; node++ ) {
- ndeg = xadj[node+1] - xadj[node]/* + 1*/; /* george */
- if (ndeg == 0)
- ndeg = 1;
- fnode = head[ndeg];
- forward[node] = fnode;
- head[ndeg] = node;
- if ( fnode > 0 ) backward[fnode] = node;
- backward[node] = -ndeg;
- };
- return 0;
-}
-
-/****************************************************************************
-* mmdnum --- multi minimum degree numbering
-* purpose -- this routine performs the final step in producing
-* the permutation and inverse permutation vectors in the
-* multiple elimination version of the minimum degree
-* ordering algorithm.
-* input parameters --
-* neqns -- number of equations.
-* qsize -- size of supernodes at elimination.
-* updated parameters --
-* invp -- inverse permutation vector. on input,
-* if qsize[node] = 0, then node has been merged
-* into the node -invp[node]; otherwise,
-* -invp[node] is its inverse labelling.
-* output parameters --
-* perm -- the permutation vector.
-****************************************************************************/
-void mmdnum(int neqns, idxtype *perm, idxtype *invp, idxtype *qsize)
-{
- int father, nextf, node, nqsize, num, root;
-
- for ( node = 1; node <= neqns; node++ ) {
- nqsize = qsize[node];
- if ( nqsize <= 0 ) perm[node] = invp[node];
- if ( nqsize > 0 ) perm[node] = -invp[node];
- };
-
- /* for each node which has been merged, do the following. */
- for ( node = 1; node <= neqns; node++ ) {
- if ( perm[node] <= 0 ) {
-
- /* trace the merged tree until one which has not */
- /* been merged, call it root. */
- father = node;
- while ( perm[father] <= 0 )
- father = - perm[father];
-
- /* number node after root. */
- root = father;
- num = perm[root] + 1;
- invp[node] = -num;
- perm[root] = num;
-
- /* shorten the merged tree. */
- father = node;
- nextf = - perm[father];
- while ( nextf > 0 ) {
- perm[father] = -root;
- father = nextf;
- nextf = -perm[father];
- };
- }; /* end of -- if ( perm[node] <= 0 ) -- */
- }; /* end of -- for ( node = 1; -- */
-
- /* ready to compute perm. */
- for ( node = 1; node <= neqns; node++ ) {
- num = -invp[node];
- invp[node] = num;
- perm[num] = node;
- };
- return;
-}
-
-/****************************************************************************
-* mmdupd ---- multiple minimum degree update
-* purpose -- this routine updates the degrees of nodes after a
-* multiple elimination step.
-* input parameters --
-* ehead -- the beginning of the list of eliminated nodes
-* (i.e., newly formed elements).
-* neqns -- number of equations.
-* (xadj, adjncy) -- adjacency structure.
-* delta -- tolerance value for multiple elimination.
-* maxint -- maximum machine representable (short) integer.
-* updated parameters --
-* mdeg -- new minimum degree after degree update.
-* (head, forward, backward) -- degree doubly linked structure.
-* qsize -- size of supernode.
-* list -- marker vector for degree update.
-* *tag -- tag value.
-****************************************************************************/
-void mmdupd(int ehead, int neqns, idxtype *xadj, idxtype *adjncy, int delta, int *mdeg,
- idxtype *head, idxtype *forward, idxtype *backward, idxtype *qsize, idxtype *list,
- idxtype *marker, int maxint,int *tag)
-{
- int deg, deg0, element, enode, fnode, i, iq2, istop,
- istart, j, jstop, jstart, link, mdeg0, mtag, nabor,
- node, q2head, qxhead;
-
- mdeg0 = *mdeg + delta;
- element = ehead;
-
-n100:
- if ( element <= 0 ) return;
-
- /* for each of the newly formed element, do the following. */
- /* reset tag value if necessary. */
- mtag = *tag + mdeg0;
- if ( mtag >= maxint ) {
- *tag = 1;
- for ( i = 1; i <= neqns; i++ )
- if ( marker[i] < maxint ) marker[i] = 0;
- mtag = *tag + mdeg0;
- };
-
- /* create two linked lists from nodes associated with 'element': */
- /* one with two nabors (q2head) in the adjacency structure, and the*/
- /* other with more than two nabors (qxhead). also compute 'deg0',*/
- /* number of nodes in this element. */
- q2head = 0;
- qxhead = 0;
- deg0 = 0;
- link =element;
-
-n400:
- istart = xadj[link];
- istop = xadj[link+1] - 1;
- for ( i = istart; i <= istop; i++ ) {
- enode = adjncy[i];
- link = -enode;
- if ( enode < 0 ) goto n400;
- if ( enode == 0 ) break;
- if ( qsize[enode] != 0 ) {
- deg0 += qsize[enode];
- marker[enode] = mtag;
-
- /*'enode' requires a degree update*/
- if ( backward[enode] == 0 ) {
- /* place either in qxhead or q2head list. */
- if ( forward[enode] != 2 ) {
- list[enode] = qxhead;
- qxhead = enode;
- } else {
- list[enode] = q2head;
- q2head = enode;
- };
- };
- }; /* enf of -- if ( qsize[enode] != 0 ) -- */
- }; /* end of -- for ( i = istart; -- */
-
- /* for each node in q2 list, do the following. */
- enode = q2head;
- iq2 = 1;
-
-n900:
- if ( enode <= 0 ) goto n1500;
- if ( backward[enode] != 0 ) goto n2200;
- (*tag)++;
- deg = deg0;
-
- /* identify the other adjacent element nabor. */
- istart = xadj[enode];
- nabor = adjncy[istart];
- if ( nabor == element ) nabor = adjncy[istart+1];
- link = nabor;
- if ( forward[nabor] >= 0 ) {
- /* nabor is uneliminated, increase degree count. */
- deg += qsize[nabor];
- goto n2100;
- };
-
- /* the nabor is eliminated. for each node in the 2nd element */
- /* do the following. */
-n1000:
- istart = xadj[link];
- istop = xadj[link+1] - 1;
- for ( i = istart; i <= istop; i++ ) {
- node = adjncy[i];
- link = -node;
- if ( node != enode ) {
- if ( node < 0 ) goto n1000;
- if ( node == 0 ) goto n2100;
- if ( qsize[node] != 0 ) {
- if ( marker[node] < *tag ) {
- /* 'node' is not yet considered. */
- marker[node] = *tag;
- deg += qsize[node];
- } else {
- if ( backward[node] == 0 ) {
- if ( forward[node] == 2 ) {
- /* 'node' is indistinguishable from 'enode'.*/
- /* merge them into a new supernode. */
- qsize[enode] += qsize[node];
- qsize[node] = 0;
- marker[node] = maxint;
- forward[node] = -enode;
- backward[node] = -maxint;
- } else {
- /* 'node' is outmacthed by 'enode' */
- if (backward[node]==0) backward[node] = -maxint;
- };
- }; /* end of -- if ( backward[node] == 0 ) -- */
- }; /* end of -- if ( marker[node] < *tag ) -- */
- }; /* end of -- if ( qsize[node] != 0 ) -- */
- }; /* end of -- if ( node != enode ) -- */
- }; /* end of -- for ( i = istart; -- */
- goto n2100;
-
-n1500:
- /* for each 'enode' in the 'qx' list, do the following. */
- enode = qxhead;
- iq2 = 0;
-
-n1600: if ( enode <= 0 ) goto n2300;
- if ( backward[enode] != 0 ) goto n2200;
- (*tag)++;
- deg = deg0;
-
- /*for each unmarked nabor of 'enode', do the following.*/
- istart = xadj[enode];
- istop = xadj[enode+1] - 1;
- for ( i = istart; i <= istop; i++ ) {
- nabor = adjncy[i];
- if ( nabor == 0 ) break;
- if ( marker[nabor] < *tag ) {
- marker[nabor] = *tag;
- link = nabor;
- if ( forward[nabor] >= 0 )
- /*if uneliminated, include it in deg count.*/
- deg += qsize[nabor];
- else {
-n1700:
- /* if eliminated, include unmarked nodes in this*/
- /* element into the degree count. */
- jstart = xadj[link];
- jstop = xadj[link+1] - 1;
- for ( j = jstart; j <= jstop; j++ ) {
- node = adjncy[j];
- link = -node;
- if ( node < 0 ) goto n1700;
- if ( node == 0 ) break;
- if ( marker[node] < *tag ) {
- marker[node] = *tag;
- deg += qsize[node];
- };
- }; /* end of -- for ( j = jstart; -- */
- }; /* end of -- if ( forward[nabor] >= 0 ) -- */
- }; /* end of -- if ( marker[nabor] < *tag ) -- */
- }; /* end of -- for ( i = istart; -- */
-
-n2100:
- /* update external degree of 'enode' in degree structure, */
- /* and '*mdeg' if necessary. */
- deg = deg - qsize[enode] + 1;
- fnode = head[deg];
- forward[enode] = fnode;
- backward[enode] = -deg;
- if ( fnode > 0 ) backward[fnode] = enode;
- head[deg] = enode;
- if ( deg < *mdeg ) *mdeg = deg;
-
-n2200:
- /* get next enode in current element. */
- enode = list[enode];
- if ( iq2 == 1 ) goto n900;
- goto n1600;
-
-n2300:
- /* get next element in the list. */
- *tag = mtag;
- element = list[element];
- goto n100;
- }