Creation of OpenFOAM-dev repository 15/04/2008

This commit is contained in:
OpenFOAM-admin
2008-04-15 18:56:58 +01:00
commit 3170c7c0c9
9896 changed files with 4016171 additions and 0 deletions

View File

@ -0,0 +1,147 @@
include ../Makefile.in
CURBUILDDIR = $(PRGBUILDDIR)
METISSRC = metis.c io.c smbfactor.c
PMETISSRC = pmetis.c io.c cmdline_pmetis.c
KMETISSRC = kmetis.c io.c
OEMETISSRC = oemetis.c io.c smbfactor.c
ONMETISSRC = onmetis.c io.c smbfactor.c
MESH2DUALSRC = mesh2dual.c io.c
MESH2NODALSRC = mesh2nodal.c io.c
PARTDMESHSRC = partdmesh.c io.c
PARTNMESHSRC = partnmesh.c io.c
GRAPHCHKSRC = graphchk.c io.c
KFMETISSRC = kfmetis.c io.c cmdline_kfmetis.c smbfactor.c
CMETISSRC = cmetis.c io.c cmdline_cmetis.c
METISOBJS = $(patsubst %.c, $(CURBUILDDIR)/%$(OBJEXT), $(METISSRC))
PMETISOBJS = $(patsubst %.c, $(CURBUILDDIR)/%$(OBJEXT), $(PMETISSRC))
KMETISOBJS = $(patsubst %.c, $(CURBUILDDIR)/%$(OBJEXT), $(KMETISSRC))
OEMETISOBJS = $(patsubst %.c, $(CURBUILDDIR)/%$(OBJEXT), $(OEMETISSRC))
ONMETISOBJS = $(patsubst %.c, $(CURBUILDDIR)/%$(OBJEXT), $(ONMETISSRC))
MESH2DUALOBJS = $(patsubst %.c, $(CURBUILDDIR)/%$(OBJEXT), $(MESH2DUALSRC))
MESH2NODALOBJS = $(patsubst %.c, $(CURBUILDDIR)/%$(OBJEXT), $(MESH2NODALSRC))
PARTDMESHOBJS = $(patsubst %.c, $(CURBUILDDIR)/%$(OBJEXT), $(PARTDMESHSRC))
PARTNMESHOBJS = $(patsubst %.c, $(CURBUILDDIR)/%$(OBJEXT), $(PARTNMESHSRC))
GRAPHCHKOBJS = $(patsubst %.c, $(CURBUILDDIR)/%$(OBJEXT), $(GRAPHCHKSRC))
KFMETISOBJS = $(patsubst %.c, $(CURBUILDDIR)/%$(OBJEXT), $(KFMETISSRC))
CMETISOBJS = $(patsubst %.c, $(CURBUILDDIR)/%$(OBJEXT), $(CMETISSRC))
ALLOBJS = $(patsubst %.c, $(CURBUILDDIR)/%$(OBJEXT), $(wildcard *.c))
HEADERS = $(wildcard *.h) $(TOPDIR)/include/metis.h $(wildcard $(GKLIBINCDIR)/*.h)
LIBRARIES = $(BUILDDIR)/libmetis$(LIBEXT)
TARGETS = $(BUILDDIR)/metis$(VERNUM)$(EXEEXT) \
$(BUILDDIR)/pmetis$(VERNUM)$(EXEEXT) \
$(BUILDDIR)/kmetis$(VERNUM)$(EXEEXT) \
$(BUILDDIR)/oemetis$(VERNUM)$(EXEEXT) \
$(BUILDDIR)/onmetis$(VERNUM)$(EXEEXT) \
$(BUILDDIR)/mesh2dual$(VERNUM)$(EXEEXT) \
$(BUILDDIR)/mesh2nodal$(VERNUM)$(EXEEXT) \
$(BUILDDIR)/partdmesh$(VERNUM)$(EXEEXT) \
$(BUILDDIR)/partnmesh$(VERNUM)$(EXEEXT) \
$(BUILDDIR)/graphchk$(VERNUM)$(EXEEXT) \
$(BUILDDIR)/kfmetis$(VERNUM)$(EXEEXT) \
$(BUILDDIR)/cmetis$(VERNUM)$(EXEEXT)
default: $(TARGETS)
$(BUILDDIR)/metis$(VERNUM)$(EXEEXT): $(METISOBJS) $(LIBRARIES)
$(LD) $(LDOPTIONS) $(EXEOUTPUTFILE) $(METISOBJS) $(LIBSDIR) $(LIBS)
chmod 744 $@
@if [ "$(BINDIR)" ]; then cp $@* $(BINDIR); fi
$(BUILDDIR)/pmetis$(VERNUM)$(EXEEXT): $(PMETISOBJS) $(LIBRARIES)
$(LD) $(LDOPTIONS) $(EXEOUTPUTFILE) $(PMETISOBJS) $(LIBSDIR) $(LIBS)
chmod 744 $@
@if [ "$(BINDIR)" ]; then cp $@* $(BINDIR); fi
$(BUILDDIR)/kmetis$(VERNUM)$(EXEEXT): $(KMETISOBJS) $(LIBRARIES)
$(LD) $(LDOPTIONS) $(EXEOUTPUTFILE) $(KMETISOBJS) $(LIBSDIR) $(LIBS)
chmod 744 $@
@if [ "$(BINDIR)" ]; then cp $@* $(BINDIR); fi
$(BUILDDIR)/oemetis$(VERNUM)$(EXEEXT): $(OEMETISOBJS) $(LIBRARIES)
$(LD) $(LDOPTIONS) $(EXEOUTPUTFILE) $(OEMETISOBJS) $(LIBSDIR) $(LIBS)
chmod 744 $@
@if [ "$(BINDIR)" ]; then cp $@* $(BINDIR); fi
$(BUILDDIR)/onmetis$(VERNUM)$(EXEEXT): $(ONMETISOBJS) $(LIBRARIES)
$(LD) $(LDOPTIONS) $(EXEOUTPUTFILE) $(ONMETISOBJS) $(LIBSDIR) $(LIBS)
chmod 744 $@
@if [ "$(BINDIR)" ]; then cp $@* $(BINDIR); fi
$(BUILDDIR)/mesh2dual$(VERNUM)$(EXEEXT): $(MESH2DUALOBJS) $(LIBRARIES)
$(LD) $(LDOPTIONS) $(EXEOUTPUTFILE) $(MESH2DUALOBJS) $(LIBSDIR) $(LIBS)
chmod 744 $@
@if [ "$(BINDIR)" ]; then cp $@* $(BINDIR); fi
$(BUILDDIR)/mesh2nodal$(VERNUM)$(EXEEXT): $(MESH2NODALOBJS) $(LIBRARIES)
$(LD) $(LDOPTIONS) $(EXEOUTPUTFILE) $(MESH2NODALOBJS) $(LIBSDIR) $(LIBS)
chmod 744 $@
@if [ "$(BINDIR)" ]; then cp $@* $(BINDIR); fi
$(BUILDDIR)/partdmesh$(VERNUM)$(EXEEXT): $(PARTDMESHOBJS) $(LIBRARIES)
$(LD) $(LDOPTIONS) $(EXEOUTPUTFILE) $(PARTDMESHOBJS) $(LIBSDIR) $(LIBS)
chmod 744 $@
@if [ "$(BINDIR)" ]; then cp $@* $(BINDIR); fi
$(BUILDDIR)/partnmesh$(VERNUM)$(EXEEXT): $(PARTNMESHOBJS) $(LIBRARIES)
$(LD) $(LDOPTIONS) $(EXEOUTPUTFILE) $(PARTNMESHOBJS) $(LIBSDIR) $(LIBS)
chmod 744 $@
@if [ "$(BINDIR)" ]; then cp $@* $(BINDIR); fi
$(BUILDDIR)/graphchk$(VERNUM)$(EXEEXT): $(GRAPHCHKOBJS) $(LIBRARIES)
$(LD) $(LDOPTIONS) $(EXEOUTPUTFILE) $(GRAPHCHKOBJS) $(LIBSDIR) $(LIBS)
chmod 744 $@
@if [ "$(BINDIR)" ]; then cp $@* $(BINDIR); fi
$(BUILDDIR)/kfmetis$(VERNUM)$(EXEEXT): $(KFMETISOBJS) $(LIBRARIES)
$(LD) $(LDOPTIONS) $(EXEOUTPUTFILE) $(KFMETISOBJS) $(LIBSDIR) $(LIBS)
chmod 744 $@
@if [ "$(BINDIR)" ]; then cp $@* $(BINDIR); fi
$(BUILDDIR)/cmetis$(VERNUM)$(EXEEXT): $(CMETISOBJS) $(LIBRARIES)
$(LD) $(LDOPTIONS) $(EXEOUTPUTFILE) $(CMETISOBJS) $(LIBSDIR) $(LIBS)
chmod 744 $@
@if [ "$(BINDIR)" ]; then cp $@* $(BINDIR); fi
$(BUILDDIR)/cepic$(VERNUM)$(EXEEXT): $(CEPICOBJS) $(LIBRARIES)
$(LD) -o $@ $(CEPICOBJ) $(LIBS)
chmod 744 $@
@if [ "$(BINDIR)" ]; then cp $@* $(BINDIR); fi
$(BUILDDIR)/cepic-rcb$(VERNUM)$(EXEEXT): $(CEPICRCBOBJS) $(LIBRARIES)
$(LD) -o $@ $(CEPICRCBOBJ) $(LIBS)
chmod 744 $@
@if [ "$(BINDIR)" ]; then cp $@* $(BINDIR); fi
$(BUILDDIR)/mmetis$(VERNUM)$(EXEEXT): $(MMETISOBJS) $(LIBRARIES)
$(LD) -o $@ $(MMETISOBJS) $(LIBS)
chmod 744 $@
@if [ "$(BINDIR)" ]; then cp $@* $(BINDIR); fi
clean:
rm -f $(ALLOBJS)
realclean:
rm -f $(ALLOBJS) $(TARGETS)
$(ALLOBJS) : $(HEADERS) ../Makefile.in Makefile
$(CURBUILDDIR)/%$(OBJEXT) : %.c
$(CC) $(CFLAGS) $(SOURCEFILE) $(OUTPUTFILE)

View File

@ -0,0 +1,336 @@
/*
* Copyright 2003, Regents of the University of Minnesota
*
* cepic.c
*
* This file contains the driving routine for contact/impact simulations
* for EPIC meshes
*
* Started 4/12/03
* George
*
* $Id: cepic-rcb.c,v 1.3 2003/05/03 16:10:48 karypis Exp $
*
*/
#include <metisbin.h>
#define Flip_int32(type) (((type >>24) & 0x000000ff) | \
((type >> 8) & 0x0000ff00) | \
((type << 8) & 0x00ff0000) | \
((type <<24) & 0xff000000) )
#define Flip_int64(type) (((type >>56) & 0x00000000000000ff) | \
((type >>40) & 0x000000000000ff00) | \
((type >>24) & 0x0000000000ff0000) | \
((type >>8) & 0x00000000ff000000) | \
((type <<8) & 0x000000ff00000000) | \
((type <<24) & 0x0000ff0000000000) | \
((type <<40) & 0x00ff000000000000) | \
((type <<56) & 0xff00000000000000))
int ComputeMapCost(idxtype nvtxs, idxtype nparts, idxtype *fepart, idxtype *cpart);
/*************************************************************************
* Let the game begin
**************************************************************************/
int main(int argc, char *argv[])
{
idxtype i, j, istep, options[10], nn, ne, fstep, lstep, nparts, nboxes, u[3], dim, nchanges, ncomm;
char filename[256];
idxtype *mien, *mrng, *part, *oldpart, *sflag, *bestdims, *fepart;
double *mxyz, *bxyz;
idxtype *xadj, *adjncy, *cntptr, *cntind;
idxtype numflag = 0, wgtflag = 0, edgecut, etype=2;
void *cinfo;
FILE *fpin;
long long int *ltmp;
if (argc != 6) {
mfprintf(stderr, "Usage: %s <nn> <ne> <fstep> <lstep> <nparts>\n", argv[0]);
exit(0);
}
nn = atoi(argv[1]);
ne = atoi(argv[2]);
fstep = atoi(argv[3]);
lstep = atoi(argv[4]);
nparts = atoi(argv[5]);
mprintf("Reading %s, nn: %D, ne: %D, fstep: %D, lstep: %D, nparts: %D\n", filename, nn, ne, fstep, lstep, nparts);
mien = idxmalloc(4*ne, "main: mien");
mxyz = gk_dmalloc(3*nn, "main: mxyz");
mrng = idxmalloc(4*ne, "main: mrng");
bxyz = gk_dmalloc(6*ne*4, "main: bxyz");
fepart = idxmalloc(nn, "main: fepart");
part = idxmalloc(nn, "main: part");
oldpart = idxmalloc(nn, "main: oldpart");
sflag = idxmalloc(nn, "main: sflag");
bestdims = idxsmalloc(2*nparts, -1, "main: bestdims");
xadj = idxmalloc(nn+1, "main: xadj");
adjncy = idxmalloc(50*nn, "main: adjncy");
/*========================================================================
* Read the initial mesh and setup the graph and contact information
*========================================================================*/
msprintf(filename, "mien.%04D", fstep);
fpin = GKfopen(filename, "rb", "main: mien");
fread(mien, sizeof(int), 4*ne, fpin);
for (i=0; i<4*ne; i++)
mien[i] = Flip_int32(mien[i]);
GKfclose(fpin);
msprintf(filename, "mxyz.%04D", fstep);
fpin = GKfopen(filename, "rb", "main: mxyz");
fread(mxyz, sizeof(double), 3*nn, fpin);
for (i=0; i<3*nn; i++) {
ltmp = (long long int *)(mxyz+i);
*ltmp = Flip_int64(*ltmp);
}
GKfclose(fpin);
mprintf("%e %e %e\n", mxyz[3*0+0], mxyz[3*0+1], mxyz[3*0+2]);
msprintf(filename, "mrng.%04D", fstep);
fpin = GKfopen(filename, "rb", "main: mrng");
fread(mrng, sizeof(int), 4*ne, fpin);
for (i=0; i<4*ne; i++)
mrng[i] = Flip_int32(mrng[i]);
GKfclose(fpin);
/*========================================================================
* Determine which nodes are in the surface
*========================================================================*/
iset(nn, 0, sflag);
for (i=0; i<ne; i++) {
if (mrng[4*i+0] > 0) { /* 1, 2, 3 */
sflag[mien[4*i+0]-1] = 1;
sflag[mien[4*i+1]-1] = 1;
sflag[mien[4*i+2]-1] = 1;
}
if (mrng[4*i+1] > 0) { /* 1, 2, 4 */
sflag[mien[4*i+0]-1] = 1;
sflag[mien[4*i+1]-1] = 1;
sflag[mien[4*i+3]-1] = 1;
}
if (mrng[4*i+2] > 0) { /* 2, 3, 4 */
sflag[mien[4*i+1]-1] = 1;
sflag[mien[4*i+2]-1] = 1;
sflag[mien[4*i+3]-1] = 1;
}
if (mrng[4*i+3] > 0) { /* 1, 3, 4 */
sflag[mien[4*i+0]-1] = 1;
sflag[mien[4*i+2]-1] = 1;
sflag[mien[4*i+3]-1] = 1;
}
}
mprintf("Contact Nodes: %D of %D\n", isum(nn, sflag), nn);
/*========================================================================
* Compute the FE partition
*========================================================================*/
numflag = mien[idxargmin(4*ne, mien)];
METIS_MeshToNodal(&ne, &nn, mien, &etype, &numflag, xadj, adjncy);
options[0] = 0;
METIS_PartGraphVKway(&nn, xadj, adjncy, NULL, NULL, &wgtflag, &numflag, &nparts,
options, &edgecut, fepart);
mprintf("K-way partitioning Volume: %D\n", edgecut);
/*========================================================================
* Get into the loop in which you go over the different configurations
*========================================================================*/
for (istep=fstep; istep<=lstep; istep++) {
msprintf(filename, "mxyz.%04D", istep);
mprintf("Reading %s...............................................................\n", filename);
fpin = GKfopen(filename, "rb", "main: mxyz");
fread(mxyz, sizeof(double), 3*nn, fpin);
for (i=0; i<3*nn; i++) {
ltmp = (long long int *)(mxyz+i);
*ltmp = Flip_int64(*ltmp);
}
GKfclose(fpin);
msprintf(filename, "mrng.%04D", istep);
fpin = GKfopen(filename, "rb", "main: mrng");
fread(mrng, sizeof(int), 4*ne, fpin);
for (i=0; i<4*ne; i++)
mrng[i] = Flip_int32(mrng[i]);
GKfclose(fpin);
/* Determine which nodes are in the surface */
iset(nn, 0, sflag);
for (i=0; i<ne; i++) {
if (mrng[4*i+0] > 0) { /* 1, 2, 3 */
sflag[mien[4*i+0]-1] = 1;
sflag[mien[4*i+1]-1] = 1;
sflag[mien[4*i+2]-1] = 1;
}
if (mrng[4*i+1] > 0) { /* 1, 2, 4 */
sflag[mien[4*i+0]-1] = 1;
sflag[mien[4*i+1]-1] = 1;
sflag[mien[4*i+3]-1] = 1;
}
if (mrng[4*i+2] > 0) { /* 2, 3, 4 */
sflag[mien[4*i+1]-1] = 1;
sflag[mien[4*i+2]-1] = 1;
sflag[mien[4*i+3]-1] = 1;
}
if (mrng[4*i+3] > 0) { /* 1, 3, 4 */
sflag[mien[4*i+0]-1] = 1;
sflag[mien[4*i+2]-1] = 1;
sflag[mien[4*i+3]-1] = 1;
}
}
mprintf("Contact Nodes: %D of %D\n", isum(nn, sflag), nn);
/* Determine the bounding boxes of the surface elements */
for (nboxes=0, i=0; i<ne; i++) {
if (mrng[4*i+0] > 0) { /* 1, 2, 3 */
u[0] = mien[4*i+0]-1;
u[1] = mien[4*i+1]-1;
u[2] = mien[4*i+2]-1;
bxyz[6*nboxes+0] = bxyz[6*nboxes+3] = mxyz[3*u[0]+0];
bxyz[6*nboxes+1] = bxyz[6*nboxes+4] = mxyz[3*u[0]+1];
bxyz[6*nboxes+2] = bxyz[6*nboxes+5] = mxyz[3*u[0]+2];
for (j=1; j<3; j++) {
for (dim=0; dim<3; dim++) {
bxyz[6*nboxes+dim] = (bxyz[6*nboxes+dim] > mxyz[3*u[j]+dim] ? mxyz[3*u[j]+dim] : bxyz[6*nboxes+dim]);
bxyz[6*nboxes+3+dim] = (bxyz[6*nboxes+3+dim] < mxyz[3*u[j]+dim] ? mxyz[3*u[j]+dim] : bxyz[6*nboxes+3+dim]);
}
}
nboxes++;
}
if (mrng[4*i+1] > 0) { /* 1, 2, 4 */
u[0] = mien[4*i+0]-1;
u[1] = mien[4*i+1]-1;
u[2] = mien[4*i+3]-1;
bxyz[6*nboxes+0] = bxyz[6*nboxes+3] = mxyz[3*u[0]+0];
bxyz[6*nboxes+1] = bxyz[6*nboxes+4] = mxyz[3*u[0]+1];
bxyz[6*nboxes+2] = bxyz[6*nboxes+5] = mxyz[3*u[0]+2];
for (j=1; j<3; j++) {
for (dim=0; dim<3; dim++) {
bxyz[6*nboxes+dim] = (bxyz[6*nboxes+dim] > mxyz[3*u[j]+dim] ? mxyz[3*u[j]+dim] : bxyz[6*nboxes+dim]);
bxyz[6*nboxes+3+dim] = (bxyz[6*nboxes+3+dim] < mxyz[3*u[j]+dim] ? mxyz[3*u[j]+dim] : bxyz[6*nboxes+3+dim]);
}
}
nboxes++;
}
if (mrng[4*i+2] > 0) { /* 2, 3, 4 */
u[0] = mien[4*i+1]-1;
u[1] = mien[4*i+2]-1;
u[2] = mien[4*i+3]-1;
bxyz[6*nboxes+0] = bxyz[6*nboxes+3] = mxyz[3*u[0]+0];
bxyz[6*nboxes+1] = bxyz[6*nboxes+4] = mxyz[3*u[0]+1];
bxyz[6*nboxes+2] = bxyz[6*nboxes+5] = mxyz[3*u[0]+2];
for (j=1; j<3; j++) {
for (dim=0; dim<3; dim++) {
bxyz[6*nboxes+dim] = (bxyz[6*nboxes+dim] > mxyz[3*u[j]+dim] ? mxyz[3*u[j]+dim] : bxyz[6*nboxes+dim]);
bxyz[6*nboxes+3+dim] = (bxyz[6*nboxes+3+dim] < mxyz[3*u[j]+dim] ? mxyz[3*u[j]+dim] : bxyz[6*nboxes+3+dim]);
}
}
nboxes++;
}
if (mrng[4*i+3] > 0) { /* 1, 3, 4 */
u[0] = mien[4*i+0]-1;
u[1] = mien[4*i+2]-1;
u[2] = mien[4*i+3]-1;
bxyz[6*nboxes+0] = bxyz[6*nboxes+3] = mxyz[3*u[0]+0];
bxyz[6*nboxes+1] = bxyz[6*nboxes+4] = mxyz[3*u[0]+1];
bxyz[6*nboxes+2] = bxyz[6*nboxes+5] = mxyz[3*u[0]+2];
for (j=1; j<3; j++) {
for (dim=0; dim<3; dim++) {
bxyz[6*nboxes+dim] = (bxyz[6*nboxes+dim] > mxyz[3*u[j]+dim] ? mxyz[3*u[j]+dim] : bxyz[6*nboxes+dim]);
bxyz[6*nboxes+3+dim] = (bxyz[6*nboxes+3+dim] < mxyz[3*u[j]+dim] ? mxyz[3*u[j]+dim] : bxyz[6*nboxes+3+dim]);
}
}
nboxes++;
}
}
cinfo = METIS_PartSurfForContactRCB(&nn, mxyz, sflag, &nparts, part, bestdims);
METIS_FindContacts(cinfo, &nboxes, bxyz, &nparts, &cntptr, &cntind);
METIS_FreeContactInfo(cinfo);
nchanges = 0;
if (istep > fstep) {
for (i=0; i<nn; i++)
nchanges += (part[i] != oldpart[i] ? 1 : 0);
}
idxcopy(nn, part, oldpart);
ncomm = ComputeMapCost(nn, nparts, fepart, part);
mprintf("Contacting Elements: %D Indices: %D Nchanges: %D MapCost: %D\n", nboxes, cntptr[nboxes]-nboxes, nchanges, ncomm);
gk_free((void **)&cntptr, &cntind, LTERM);
}
}
/***********************************************************************************
* This function determines the cost of moving data between the two meshes assuming
* that a good matching between the two partitions was done!
************************************************************************************/
int ComputeMapCost(idxtype nvtxs, idxtype nparts, idxtype *fepart, idxtype *cpart)
{
idxtype i, j, k, n, ncomm;
KeyValueType cand[nparts*nparts];
idxtype fmatched[nparts], cmatched[nparts];
/* Compute the overlap */
for (i=0; i<nparts; i++) {
for (j=0; j<nparts; j++) {
cand[i*nparts+j].key = 0;
cand[i*nparts+j].val = i*nparts+j;
}
}
for (k=0, i=0; i<nvtxs; i++) {
if (cpart[i] >= 0) {
cand[(fepart[i]-1)*nparts+(cpart[i]-1)].key++;
k++;
}
}
mprintf("Contact points: %D\n", k);
ikeysort(nparts*nparts, cand);
iset(nparts, -1, fmatched);
iset(nparts, -1, cmatched);
for (ncomm=0, k=nparts*nparts-1; k>=0; k--) {
i = cand[k].val/nparts;
j = cand[k].val%nparts;
if (fmatched[i] == -1 && cmatched[j] == -1) {
fmatched[i] = j;
cmatched[j] = i;
}
else
ncomm += cand[k].key;
}
mprintf("Ncomm: %D\n", ncomm);
return ncomm;
}

View File

@ -0,0 +1,256 @@
/*
* Copyright 2003, Regents of the University of Minnesota
*
* cepic.c
*
* This file contains the driving routine for contact/impact simulations
* for EPIC meshes
*
* Started 4/12/03
* George
*
* $Id: cepic.c,v 1.15 2003/05/03 16:10:48 karypis Exp $
*
*/
#include <metisbin.h>
#define Flip_int32(type) (((type >>24) & 0x000000ff) | \
((type >> 8) & 0x0000ff00) | \
((type << 8) & 0x00ff0000) | \
((type <<24) & 0xff000000) )
#define Flip_int64(type) (((type >>56) & 0x00000000000000ff) | \
((type >>40) & 0x000000000000ff00) | \
((type >>24) & 0x0000000000ff0000) | \
((type >>8) & 0x00000000ff000000) | \
((type <<8) & 0x000000ff00000000) | \
((type <<24) & 0x0000ff0000000000) | \
((type <<40) & 0x00ff000000000000) | \
((type <<56) & 0xff00000000000000))
/*************************************************************************
* Let the game begin
**************************************************************************/
main(int argc, char *argv[])
{
idxtype i, j, k, istep, options[10], nn, ne, fstep, lstep, nparts, nboxes, u[3], dim, nsplit, flags=0, NSKIP=1;
char filename[256];
idxtype *mien, *mrng, *part, *sflag;
double *mxyz, *bxyz;
idxtype *xadj, *adjncy, *cntptr, *cntind;
idxtype numflag = 0, wgtflag = 0, edgecut, etype=2;
void *cinfo=NULL;
FILE *fpin;
long long int *ltmp;
if (argc <= 6) {
mfprintf(stderr, "Usage: %s <nn> <ne> <fstep> <lstep> <nparts> [flags] [NSKIP]\n", argv[0]);
exit(0);
}
nn = atoi(argv[1]);
ne = atoi(argv[2]);
fstep = atoi(argv[3]);
lstep = atoi(argv[4]);
nparts = atoi(argv[5]);
if (argc > 6)
flags = atoi(argv[6]);
if (argc > 7)
NSKIP = atoi(argv[7]);
mprintf("\n\n------------------------------------------------------------------------------------------\n");
mprintf("Reading nn: %D, ne: %D, fstep: %D, lstep: %D, nparts: %D\n", nn, ne, fstep, lstep, nparts);
mien = idxmalloc(4*ne, "main: mien");
mxyz = gk_dmalloc(3*nn, "main: mxyz");
mrng = idxmalloc(4*ne, "main: mrng");
bxyz = gk_dmalloc(6*ne*4, "main: bxyz");
part = idxmalloc(nn, "main: part");
sflag = idxmalloc(nn, "main: sflag");
xadj = idxmalloc(nn+1, "main: xadj");
adjncy = idxmalloc(50*nn, "main: adjncy");
/*========================================================================
* Read the initial mesh and setup the graph and contact information
*========================================================================*/
msprintf(filename, "mien.%04D", fstep);
fpin = GKfopen(filename, "rb", "main: mien");
fread(mien, sizeof(int), 4*ne, fpin);
for (i=0; i<4*ne; i++)
mien[i] = Flip_int32(mien[i]);
GKfclose(fpin);
/*========================================================================
* Create the nodal graph
*========================================================================*/
numflag = mien[idxargmin(4*ne, mien)];
METIS_MeshToNodal(&ne, &nn, mien, &etype, &numflag, xadj, adjncy);
/*========================================================================
* Get into the loop in which you go over the different configurations
*========================================================================*/
for (k=0, istep=fstep; istep<=lstep; istep++, k++) {
msprintf(filename, "mxyz.%04D", istep);
mprintf("Reading %s...............................................................\n", filename);
fpin = GKfopen(filename, "rb", "main: mxyz");
fread(mxyz, sizeof(double), 3*nn, fpin);
for (i=0; i<3*nn; i++) {
ltmp = (long long int *)(mxyz+i);
*ltmp = Flip_int64(*ltmp);
}
GKfclose(fpin);
msprintf(filename, "mrng.%04D", istep);
fpin = GKfopen(filename, "rb", "main: mrng");
fread(mrng, sizeof(int), 4*ne, fpin);
for (i=0; i<4*ne; i++)
mrng[i] = Flip_int32(mrng[i]);
GKfclose(fpin);
/* Determine which nodes are in the surface */
iset(nn, 0, sflag);
for (i=0; i<ne; i++) {
if (mrng[4*i+0] > 0) { /* 1, 2, 3 */
sflag[mien[4*i+0]-1] = 1;
sflag[mien[4*i+1]-1] = 1;
sflag[mien[4*i+2]-1] = 1;
}
if (mrng[4*i+1] > 0) { /* 1, 2, 4 */
sflag[mien[4*i+0]-1] = 1;
sflag[mien[4*i+1]-1] = 1;
sflag[mien[4*i+3]-1] = 1;
}
if (mrng[4*i+2] > 0) { /* 2, 3, 4 */
sflag[mien[4*i+1]-1] = 1;
sflag[mien[4*i+2]-1] = 1;
sflag[mien[4*i+3]-1] = 1;
}
if (mrng[4*i+3] > 0) { /* 1, 3, 4 */
sflag[mien[4*i+0]-1] = 1;
sflag[mien[4*i+2]-1] = 1;
sflag[mien[4*i+3]-1] = 1;
}
}
mprintf("Contact Nodes: %D of %D\n", isum(nn, sflag), nn);
/* Compute/Update the partitioning */
if (k%NSKIP == 0) {
if (cinfo != NULL)
METIS_FreeContactInfo(cinfo);
options[0] = 0;
cinfo = METIS_PartGraphForContact(&nn, xadj, adjncy, mxyz, sflag, &numflag, &nparts,
options, &edgecut, part);
for (i=0; i<nn; i++)
part[i]--;
}
switch (flags) {
case 1:
if (cinfo != NULL)
METIS_FreeContactInfo(cinfo);
cinfo = METIS_SetupContact(&nn, mxyz, sflag, &nparts, part);
break;
case 2:
if (cinfo != NULL)
METIS_FreeContactInfo(cinfo);
cinfo = METIS_SetupContact0(&nn, mxyz, sflag, &nparts, part);
break;
default:
METIS_UpdateContactInfo(cinfo, &nn, mxyz, sflag);
}
/* Determine the bounding boxes of the surface elements */
for (nsplit=0, nboxes=0, i=0; i<ne; i++) {
if (mrng[4*i+0] > 0) { /* 1, 2, 3 */
u[0] = mien[4*i+0]-1;
u[1] = mien[4*i+1]-1;
u[2] = mien[4*i+2]-1;
bxyz[6*nboxes+0] = bxyz[6*nboxes+3] = mxyz[3*u[0]+0];
bxyz[6*nboxes+1] = bxyz[6*nboxes+4] = mxyz[3*u[0]+1];
bxyz[6*nboxes+2] = bxyz[6*nboxes+5] = mxyz[3*u[0]+2];
for (j=1; j<3; j++) {
for (dim=0; dim<3; dim++) {
bxyz[6*nboxes+dim] = (bxyz[6*nboxes+dim] > mxyz[3*u[j]+dim] ? mxyz[3*u[j]+dim] : bxyz[6*nboxes+dim]);
bxyz[6*nboxes+3+dim] = (bxyz[6*nboxes+3+dim] < mxyz[3*u[j]+dim] ? mxyz[3*u[j]+dim] : bxyz[6*nboxes+3+dim]);
}
}
nboxes++;
if (part[u[0]] != part[u[1]] || part[u[0]] != part[u[2]])
nsplit++;
}
if (mrng[4*i+1] > 0) { /* 1, 2, 4 */
u[0] = mien[4*i+0]-1;
u[1] = mien[4*i+1]-1;
u[2] = mien[4*i+3]-1;
bxyz[6*nboxes+0] = bxyz[6*nboxes+3] = mxyz[3*u[0]+0];
bxyz[6*nboxes+1] = bxyz[6*nboxes+4] = mxyz[3*u[0]+1];
bxyz[6*nboxes+2] = bxyz[6*nboxes+5] = mxyz[3*u[0]+2];
for (j=1; j<3; j++) {
for (dim=0; dim<3; dim++) {
bxyz[6*nboxes+dim] = (bxyz[6*nboxes+dim] > mxyz[3*u[j]+dim] ? mxyz[3*u[j]+dim] : bxyz[6*nboxes+dim]);
bxyz[6*nboxes+3+dim] = (bxyz[6*nboxes+3+dim] < mxyz[3*u[j]+dim] ? mxyz[3*u[j]+dim] : bxyz[6*nboxes+3+dim]);
}
}
nboxes++;
if (part[u[0]] != part[u[1]] || part[u[0]] != part[u[2]])
nsplit++;
}
if (mrng[4*i+2] > 0) { /* 2, 3, 4 */
u[0] = mien[4*i+1]-1;
u[1] = mien[4*i+2]-1;
u[2] = mien[4*i+3]-1;
bxyz[6*nboxes+0] = bxyz[6*nboxes+3] = mxyz[3*u[0]+0];
bxyz[6*nboxes+1] = bxyz[6*nboxes+4] = mxyz[3*u[0]+1];
bxyz[6*nboxes+2] = bxyz[6*nboxes+5] = mxyz[3*u[0]+2];
for (j=1; j<3; j++) {
for (dim=0; dim<3; dim++) {
bxyz[6*nboxes+dim] = (bxyz[6*nboxes+dim] > mxyz[3*u[j]+dim] ? mxyz[3*u[j]+dim] : bxyz[6*nboxes+dim]);
bxyz[6*nboxes+3+dim] = (bxyz[6*nboxes+3+dim] < mxyz[3*u[j]+dim] ? mxyz[3*u[j]+dim] : bxyz[6*nboxes+3+dim]);
}
}
nboxes++;
if (part[u[0]] != part[u[1]] || part[u[0]] != part[u[2]])
nsplit++;
}
if (mrng[4*i+3] > 0) { /* 1, 3, 4 */
u[0] = mien[4*i+0]-1;
u[1] = mien[4*i+2]-1;
u[2] = mien[4*i+3]-1;
bxyz[6*nboxes+0] = bxyz[6*nboxes+3] = mxyz[3*u[0]+0];
bxyz[6*nboxes+1] = bxyz[6*nboxes+4] = mxyz[3*u[0]+1];
bxyz[6*nboxes+2] = bxyz[6*nboxes+5] = mxyz[3*u[0]+2];
for (j=1; j<3; j++) {
for (dim=0; dim<3; dim++) {
bxyz[6*nboxes+dim] = (bxyz[6*nboxes+dim] > mxyz[3*u[j]+dim] ? mxyz[3*u[j]+dim] : bxyz[6*nboxes+dim]);
bxyz[6*nboxes+3+dim] = (bxyz[6*nboxes+3+dim] < mxyz[3*u[j]+dim] ? mxyz[3*u[j]+dim] : bxyz[6*nboxes+3+dim]);
}
}
nboxes++;
if (part[u[0]] != part[u[1]] || part[u[0]] != part[u[2]])
nsplit++;
}
}
METIS_FindContacts(cinfo, &nboxes, bxyz, &nparts, &cntptr, &cntind);
mprintf("Contacting Elements: %D Indices: %D Nsplit: %D\n", nboxes, cntptr[nboxes]-nboxes, nsplit);
gk_free((void **)&cntptr, &cntind, LTERM);
}
}

View File

@ -0,0 +1,208 @@
/*
* cmdline_cpmetis.c
*
* This file parses the command line arguments
*
* Started 3/25/03
* George
*
* $Id: cmdline_cmetis.c,v 1.1 2003/04/04 23:22:47 karypis Exp $
*
*/
#include <metisbin.h>
/*-------------------------------------------------------------------
* Command-line options
*-------------------------------------------------------------------*/
static struct gk_option long_options[] = {
{"mtype", 1, 0, CMD_MTYPE},
{"itype", 1, 0, CMD_ITYPE},
{"rtype", 1, 0, CMD_RTYPE},
{"balanced", 0, 0, CMD_BALANCE},
{"niter", 1, 0, CMD_NITER},
{"tpwgts", 1, 0, CMD_TPWGTS},
{"seed", 1, 0, CMD_SEED},
{"dbglvl", 1, 0, CMD_DBGLVL},
{"help", 0, 0, CMD_HELP},
{0, 0, 0, 0}
};
/*-------------------------------------------------------------------
* Mappings for the various parameter values
*-------------------------------------------------------------------*/
static gk_StringMap_t mtype_options[] = {
{"rm", MTYPE_RM},
{"hem", MTYPE_HEM},
{"shem", MTYPE_SHEM},
{"shebm", MTYPE_SHEBM_ONENORM},
{"sbhem", MTYPE_SBHEM_ONENORM},
{NULL, 0}
};
static gk_StringMap_t itype_options[] = {
{"greedy", ITYPE_GGPKL},
{"random", ITYPE_RANDOM},
{NULL, 0}
};
static gk_StringMap_t rtype_options[] = {
{"fm", RTYPE_FM},
{NULL, 0}
};
/*-------------------------------------------------------------------
* Mini help
*-------------------------------------------------------------------*/
static char helpstr[][100] =
{
" ",
"Usage: cpmetis [options] <graph filename> <coord filename> <nparts>",
" ",
" Required parameters",
" filename Stores the graph to be partitioned.",
" nparts The number of partitions to split the graph.",
" ",
" Optional parameters",
" -mtyep=string",
" Specifies the scheme to be used to match the vertices of the graph",
" during the coarsening.",
" The possible values are:",
" rm - Random matching",
" hem - Heavy-edge matching",
" shem - Sorted heavy-edge matching [default]",
" shebm - Combination of shem and balanced matching for",
" multi-constraint.",
" sbhem - Similar as shebm but priority is given to balance",
" ",
" -itype=string",
" Specifies the scheme to be used to compute the initial partitioning",
" of the graph.",
" The possible values are:",
" greedy - Grow a bisection using a greedy strategy [default]",
" random - Compute a bisection at random",
" ",
" -rtype=string",
" Specifies the scheme to be used for refinement",
" The possible values are:",
" fm - FM refinement",
" ",
" -balance",
" Specifies that the final partitioning should contain nparts-1 equal",
" size partitions with the last partition having upto nparts-1 fewer",
" vertices.",
" ",
" -seed=int ",
" Selects the seed of the random number generator. ",
" ",
" -dbglvl=int ",
" Selects the dbglvl. ",
" ",
" -help",
" Prints this message.",
""
};
static char shorthelpstr[][100] = {
" ",
" Usage: cpmetis [options] <graph filename> <coord filename> <nparts>",
" use 'cpmetis -help' for a summary of the options.",
""
};
/*************************************************************************
* This is the entry point of the command-line argument parser
**************************************************************************/
void parse_cmdline(ParamType *params, int argc, char *argv[])
{
int i, j, k;
int c, option_index;
/* initialize the params data structure */
params->mtype = PMETIS_CTYPE;
params->itype = PMETIS_ITYPE;
params->rtype = PMETIS_RTYPE;
params->dbglvl = PMETIS_DBGLVL;
params->balance = 0;
params->seed = -1;
params->dbglvl = 0;
params->filename = NULL;
params->xyzfilename = NULL;
params->nparts = 1;
/* Parse the command line arguments */
while ((c = gk_getopt_long_only(argc, argv, "", long_options, &option_index)) != -1) {
switch (c) {
case CMD_MTYPE:
if (gk_optarg)
if ((params->mtype = gk_GetStringID(mtype_options, gk_optarg)) == -1)
errexit("Invalid option -%s=%s\n", long_options[option_index].name, gk_optarg);
break;
case CMD_ITYPE:
if (gk_optarg)
if ((params->itype = gk_GetStringID(itype_options, gk_optarg)) == -1)
errexit("Invalid option -%s=%s\n", long_options[option_index].name, gk_optarg);
break;
case CMD_RTYPE:
if (gk_optarg)
if ((params->rtype = gk_GetStringID(rtype_options, gk_optarg)) == -1)
errexit("Invalid option -%s=%s\n", long_options[option_index].name, gk_optarg);
break;
case CMD_BALANCE:
params->balance = 1;
break;
case CMD_SEED:
if (gk_optarg) params->seed = atoi(gk_optarg);
break;
case CMD_DBGLVL:
if (gk_optarg) params->dbglvl = atoi(gk_optarg);
break;
case CMD_HELP:
for (i=0; strlen(helpstr[i]) > 0; i++)
mprintf("%s\n", helpstr[i]);
exit(0);
break;
case '?':
default:
mprintf("Illegal command-line option(s)\nUse %s -help for a summary of the options.\n", argv[0]);
exit(0);
}
}
if (argc-gk_optind != 3) {
mprintf("Missing parameters.");
for (i=0; strlen(shorthelpstr[i]) > 0; i++)
mprintf("%s\n", shorthelpstr[i]);
exit(0);
}
params->filename = strdup(argv[gk_optind++]);
params->xyzfilename = strdup(argv[gk_optind++]);
params->nparts = atoi(argv[gk_optind++]);
}

View File

@ -0,0 +1,206 @@
/*
* cmdline_kfmetis.c
*
* This file parses the command line arguments
*
* Started 8/9/02
* George
*
* $Id: cmdline_kfmetis.c,v 1.1 2002/08/12 15:20:50 karypis Exp $
*
*/
#include <metisbin.h>
/*-------------------------------------------------------------------
* Command-line options
*-------------------------------------------------------------------*/
static struct gk_option long_options[] = {
{"mtype", 1, 0, CMD_MTYPE},
{"itype", 1, 0, CMD_ITYPE},
{"rtype", 1, 0, CMD_RTYPE},
{"balanced", 0, 0, CMD_BALANCE},
{"niter", 1, 0, CMD_NITER},
{"tpwgts", 1, 0, CMD_TPWGTS},
{"seed", 1, 0, CMD_SEED},
{"dbglvl", 1, 0, CMD_DBGLVL},
{"help", 0, 0, CMD_HELP},
{0, 0, 0, 0}
};
/*-------------------------------------------------------------------
* Mappings for the various parameter values
*-------------------------------------------------------------------*/
static gk_StringMap_t mtype_options[] = {
{"rm", MTYPE_RM},
{"hem", MTYPE_HEM},
{"shem", MTYPE_SHEM},
{"shebm", MTYPE_SHEBM_ONENORM},
{"sbhem", MTYPE_SBHEM_ONENORM},
{NULL, 0}
};
static gk_StringMap_t itype_options[] = {
{"greedy", ITYPE_GGPKL},
{"random", ITYPE_RANDOM},
{NULL, 0}
};
static gk_StringMap_t rtype_options[] = {
{"fm", RTYPE_FM},
{NULL, 0}
};
/*-------------------------------------------------------------------
* Mini help
*-------------------------------------------------------------------*/
static char helpstr[][100] =
{
" ",
"Usage: pmetis [options] <filename> <nparts>",
" ",
" Required parameters",
" filename Stores the graph to be partitioned.",
" nparts The number of partitions to split the graph.",
" ",
" Optional parameters",
" -mtyep=string",
" Specifies the scheme to be used to match the vertices of the graph",
" during the coarsening.",
" The possible values are:",
" rm - Random matching",
" hem - Heavy-edge matching",
" shem - Sorted heavy-edge matching [default]",
" shebm - Combination of shem and balanced matching for",
" multi-constraint.",
" sbhem - Similar as shebm but priority is given to balance",
" ",
" -itype=string",
" Specifies the scheme to be used to compute the initial partitioning",
" of the graph.",
" The possible values are:",
" greedy - Grow a bisection using a greedy strategy [default]",
" random - Compute a bisection at random",
" ",
" -rtype=string",
" Specifies the scheme to be used for refinement",
" The possible values are:",
" fm - FM refinement",
" ",
" -balance",
" Specifies that the final partitioning should contain nparts-1 equal",
" size partitions with the last partition having upto nparts-1 fewer",
" vertices.",
" ",
" -seed=int ",
" Selects the seed of the random number generator. ",
" ",
" -dbglvl=int ",
" Selects the dbglvl. ",
" ",
" -help",
" Prints this message.",
""
};
static char shorthelpstr[][100] = {
" ",
" Usage: pmetis [options] <filename> <nparts>",
" use 'pmetis -help' for a summary of the options.",
""
};
/*************************************************************************
* This is the entry point of the command-line argument parser
**************************************************************************/
void parse_cmdline(ParamType *params, int argc, char *argv[])
{
int i, j, k;
int c, option_index;
/* initialize the params data structure */
params->mtype = PMETIS_CTYPE;
params->itype = PMETIS_ITYPE;
params->rtype = PMETIS_RTYPE;
params->dbglvl = PMETIS_DBGLVL;
params->balance = 0;
params->seed = -1;
params->dbglvl = 0;
params->filename = NULL;
params->nparts = 1;
/* Parse the command line arguments */
while ((c = gk_getopt_long_only(argc, argv, "", long_options, &option_index)) != -1) {
switch (c) {
case CMD_MTYPE:
if (gk_optarg)
if ((params->mtype = gk_GetStringID(mtype_options, gk_optarg)) == -1)
errexit("Invalid option -%s=%s\n", long_options[option_index].name, gk_optarg);
break;
case CMD_ITYPE:
if (gk_optarg)
if ((params->itype = gk_GetStringID(itype_options, gk_optarg)) == -1)
errexit("Invalid option -%s=%s\n", long_options[option_index].name, gk_optarg);
break;
case CMD_RTYPE:
if (gk_optarg)
if ((params->rtype = gk_GetStringID(rtype_options, gk_optarg)) == -1)
errexit("Invalid option -%s=%s\n", long_options[option_index].name, gk_optarg);
break;
case CMD_BALANCE:
params->balance = 1;
break;
case CMD_SEED:
if (gk_optarg) params->seed = atoi(gk_optarg);
break;
case CMD_DBGLVL:
if (gk_optarg) params->dbglvl = atoi(gk_optarg);
break;
case CMD_HELP:
for (i=0; strlen(helpstr[i]) > 0; i++)
mprintf("%s\n", helpstr[i]);
exit(0);
break;
case '?':
default:
mprintf("Illegal command-line option(s)\nUse %s -help for a summary of the options.\n", argv[0]);
exit(0);
}
}
if (argc-gk_optind != 2) {
mprintf("Missing parameters.");
for (i=0; strlen(shorthelpstr[i]) > 0; i++)
mprintf("%s\n", shorthelpstr[i]);
exit(0);
}
params->filename = strdup(argv[gk_optind++]);
params->nparts = atoi(argv[gk_optind++]);
}

View File

@ -0,0 +1,206 @@
/*
* cmdline_pmetis.c
*
* This file parses the command line arguments
*
* Started 8/9/02
* George
*
* $Id: cmdline_pmetis.c,v 1.4 2002/08/12 15:20:51 karypis Exp $
*
*/
#include <metisbin.h>
/*-------------------------------------------------------------------
* Command-line options
*-------------------------------------------------------------------*/
static struct gk_option long_options[] = {
{"mtype", 1, 0, CMD_MTYPE},
{"itype", 1, 0, CMD_ITYPE},
{"rtype", 1, 0, CMD_RTYPE},
{"balanced", 0, 0, CMD_BALANCE},
{"niter", 1, 0, CMD_NITER},
{"tpwgts", 1, 0, CMD_TPWGTS},
{"seed", 1, 0, CMD_SEED},
{"dbglvl", 1, 0, CMD_DBGLVL},
{"help", 0, 0, CMD_HELP},
{0, 0, 0, 0}
};
/*-------------------------------------------------------------------
* Mappings for the various parameter values
*-------------------------------------------------------------------*/
static gk_StringMap_t mtype_options[] = {
{"rm", MTYPE_RM},
{"hem", MTYPE_HEM},
{"shem", MTYPE_SHEM},
{"shebm", MTYPE_SHEBM_ONENORM},
{"sbhem", MTYPE_SBHEM_ONENORM},
{NULL, 0}
};
static gk_StringMap_t itype_options[] = {
{"greedy", ITYPE_GGPKL},
{"random", ITYPE_RANDOM},
{NULL, 0}
};
static gk_StringMap_t rtype_options[] = {
{"fm", RTYPE_FM},
{NULL, 0}
};
/*-------------------------------------------------------------------
* Mini help
*-------------------------------------------------------------------*/
static char helpstr[][100] =
{
" ",
"Usage: pmetis [options] <filename> <nparts>",
" ",
" Required parameters",
" filename Stores the graph to be partitioned.",
" nparts The number of partitions to split the graph.",
" ",
" Optional parameters",
" -mtyep=string",
" Specifies the scheme to be used to match the vertices of the graph",
" during the coarsening.",
" The possible values are:",
" rm - Random matching",
" hem - Heavy-edge matching",
" shem - Sorted heavy-edge matching [default]",
" shebm - Combination of shem and balanced matching for",
" multi-constraint.",
" sbhem - Similar as shebm but priority is given to balance",
" ",
" -itype=string",
" Specifies the scheme to be used to compute the initial partitioning",
" of the graph.",
" The possible values are:",
" greedy - Grow a bisection using a greedy strategy [default]",
" random - Compute a bisection at random",
" ",
" -rtype=string",
" Specifies the scheme to be used for refinement",
" The possible values are:",
" fm - FM refinement",
" ",
" -balance",
" Specifies that the final partitioning should contain nparts-1 equal",
" size partitions with the last partition having upto nparts-1 fewer",
" vertices.",
" ",
" -seed=int ",
" Selects the seed of the random number generator. ",
" ",
" -dbglvl=int ",
" Selects the dbglvl. ",
" ",
" -help",
" Prints this message.",
""
};
static char shorthelpstr[][100] = {
" ",
" Usage: pmetis [options] <filename> <nparts>",
" use 'pmetis -help' for a summary of the options.",
""
};
/*************************************************************************
* This is the entry point of the command-line argument parser
**************************************************************************/
void parse_cmdline(ParamType *params, int argc, char *argv[])
{
int i, j, k;
int c, option_index;
/* initialize the params data structure */
params->mtype = PMETIS_CTYPE;
params->itype = PMETIS_ITYPE;
params->rtype = PMETIS_RTYPE;
params->dbglvl = PMETIS_DBGLVL;
params->balance = 0;
params->seed = -1;
params->dbglvl = 0;
params->filename = NULL;
params->nparts = 1;
/* Parse the command line arguments */
while ((c = gk_getopt_long_only(argc, argv, "", long_options, &option_index)) != -1) {
switch (c) {
case CMD_MTYPE:
if (gk_optarg)
if ((params->mtype = gk_GetStringID(mtype_options, gk_optarg)) == -1)
errexit("Invalid option -%s=%s\n", long_options[option_index].name, gk_optarg);
break;
case CMD_ITYPE:
if (gk_optarg)
if ((params->itype = gk_GetStringID(itype_options, gk_optarg)) == -1)
errexit("Invalid option -%s=%s\n", long_options[option_index].name, gk_optarg);
break;
case CMD_RTYPE:
if (gk_optarg)
if ((params->rtype = gk_GetStringID(rtype_options, gk_optarg)) == -1)
errexit("Invalid option -%s=%s\n", long_options[option_index].name, gk_optarg);
break;
case CMD_BALANCE:
params->balance = 1;
break;
case CMD_SEED:
if (gk_optarg) params->seed = atoi(gk_optarg);
break;
case CMD_DBGLVL:
if (gk_optarg) params->dbglvl = atoi(gk_optarg);
break;
case CMD_HELP:
for (i=0; strlen(helpstr[i]) > 0; i++)
mprintf("%s\n", helpstr[i]);
exit(0);
break;
case '?':
default:
mprintf("Illegal command-line option(s)\nUse %s -help for a summary of the options.\n", argv[0]);
exit(0);
}
}
if (argc-gk_optind != 2) {
mprintf("Missing parameters.");
for (i=0; strlen(shorthelpstr[i]) > 0; i++)
mprintf("%s\n", shorthelpstr[i]);
exit(0);
}
params->filename = strdup(argv[gk_optind++]);
params->nparts = atoi(argv[gk_optind++]);
}

View File

@ -0,0 +1,97 @@
/*
* Copyright 2003, Regents of the University of Minnesota
*
* cmetis.c
*
* This file contains the driving routine for partitioning for
* sub-domain direct factorization.
*
* Started 3/25/03
* George
*
* $Id: cmetis.c,v 1.5 2003/04/08 12:52:59 karypis Exp $
*
*/
#include <metisbin.h>
/*************************************************************************
* Let the game begin
**************************************************************************/
int main(int argc, char *argv[])
{
idxtype i, options[10], nnodes, nclean, naclean, ndirty, maxdepth;
idxtype *part, *sflag;
float lbvec[MAXNCON];
GraphType graph;
idxtype numflag = 0, wgtflag = 0, edgecut;
ParamType params;
void *cinfo;
double TOTALTmr, METISTmr, IOTmr;
parse_cmdline(&params, argc, argv);
if (params.nparts < 2) {
mprintf("The number of partitions should be greater than 1!\n");
exit(0);
}
gk_clearcputimer(TOTALTmr);
gk_clearcputimer(METISTmr);
gk_clearcputimer(IOTmr);
gk_startcputimer(TOTALTmr);
gk_startcputimer(IOTmr);
ReadGraph(&graph, params.filename, &wgtflag);
if (graph.nvtxs <= 0) {
mprintf("Empty graph. Nothing to do.\n");
exit(0);
}
ReadCoordinates(&graph, params.xyzfilename);
gk_stopcputimer(IOTmr);
mprintf("**********************************************************************\n");
mprintf("%s", METISTITLE);
mprintf("Graph Information ---------------------------------------------------\n");
mprintf(" Name: %s, #Vertices: %D, #Edges: %D, #Parts: %D\n", params.filename, graph.nvtxs, graph.nedges/2, params.nparts);
if (graph.ncon > 1)
mprintf(" Balancing Constraints: %D\n", graph.ncon);
mprintf("\nRecursive Partitioning... -------------------------------------------\n");
part = idxmalloc(graph.nvtxs, "main: part");
sflag = idxsmalloc(graph.nvtxs, 1, "main: sflag");
options[0] = 0;
gk_startcputimer(METISTmr);
cinfo = METIS_PartGraphForContact(&graph.nvtxs, graph.xadj, graph.adjncy, graph.coords, sflag,
&numflag, &(params.nparts), options, &edgecut, part);
METIS_UpdateContactInfo(cinfo, &graph.nvtxs, graph.coords, sflag);
gk_stopcputimer(METISTmr);
ComputePartitionBalance(&graph, params.nparts, part, lbvec);
graph.vwgt = idxsmalloc(graph.nvtxs, 1, "main: graph->vwgt");
mprintf(" %D-way Edge-Cut: %7D, Volume: %7D, Balance: ", params.nparts, edgecut,
ComputeVolume(&graph, part));
for (i=0; i<graph.ncon; i++)
mprintf("%5.2f ", lbvec[i]);
mprintf("\n");
gk_startcputimer(IOTmr);
WritePartition(params.filename, part, graph.nvtxs, params.nparts);
gk_stopcputimer(IOTmr);
gk_stopcputimer(TOTALTmr);
mprintf("\nTiming Information --------------------------------------------------\n");
mprintf(" I/O: \t\t %7.3f\n", gk_getcputimer(IOTmr));
mprintf(" Partitioning: \t\t %7.3f (CMETIS time)\n", gk_getcputimer(METISTmr));
mprintf(" Total: \t\t %7.3f\n", gk_getcputimer(TOTALTmr));
mprintf("**********************************************************************\n");
gk_free((void **)&graph.xadj, &graph.adjncy, &graph.vwgt, &graph.adjwgt, &graph.coords, &part, &sflag, LTERM);
}

View File

@ -0,0 +1,45 @@
/*
* defs.h
*
* This file contains various constant definitions
*
* Started 8/9/02
* George
*
*/
#define CMD_MTYPE 1
#define CMD_ITYPE 2
#define CMD_RTYPE 3
#define CMD_BALANCE 10
#define CMD_NITER 20
#define CMD_NTRIALS 21
#define CMD_TPWGTS 30
#define CMD_SEED 50
#define CMD_OUTPUT 100
#define CMD_NOOUTPUT 101
#define CMD_DBGLVL 1000
#define CMD_HELP 1001
/* The text labels for MTypes */
static char mtypenames[][10] = {"", "None", "MAXTF", "SQRT", "LOG", "IDF"};
/* The text labels for ITypes */
static char itypenames[][10] = {"", "None", "IDF"};
/* The text labels for RTypes */
static char rtypenames[][20] = {"", "I1", "I2", "E1", "G1", "G1'", "H1", "H2", "SLINK",
"SLINK_W", "CLINK", "CLINK_W", "UPGMA", "UPGMA_W",
"UPGMA_W2", "Cut", "RCut", "NCut", "MMCut"};

View File

@ -0,0 +1,58 @@
/*
* Copyright 1997, Regents of the University of Minnesota
*
* graphchk.c
*
* This file checks the validity of a graph
*
* Started 8/28/94
* George
*
* $Id: graphchk.c,v 1.2 2002/08/10 06:02:53 karypis Exp $
*
*/
#include <metisbin.h>
/*************************************************************************
* Let the game begin
**************************************************************************/
int main(int argc, char *argv[])
{
GraphType graph;
char filename[256];
idxtype wgtflag;
if (argc != 2) {
mprintf("Usage: %s <GraphFile>\n", argv[0]);
exit(0);
}
strcpy(filename, argv[1]);
ReadGraph(&graph, filename, &wgtflag);
if (graph.nvtxs == 0) {
mprintf("Empty graph!\n");
exit(0);
}
mprintf("**********************************************************************\n");
mprintf("%s", METISTITLE);
mprintf("Graph Information ---------------------------------------------------\n");
mprintf(" Name: %s, #Vertices: %D, #Edges: %D\n\n", filename, graph.nvtxs, graph.nedges/2);
mprintf("Checking Graph... ---------------------------------------------------\n");
if (CheckGraph(&graph))
mprintf(" The format of the graph is correct!\n");
else
mprintf(" The format of the graph is incorrect!\n");
mprintf("\n**********************************************************************\n");
gk_free((void **)&graph.xadj, &graph.adjncy, &graph.vwgt, &graph.adjwgt, LTERM);
}

View File

@ -0,0 +1,690 @@
/*
* Copyright 1997, Regents of the University of Minnesota
*
* io.c
*
* This file contains routines related to I/O
*
* Started 8/28/94
* George
*
* $Id: io.c,v 1.7 2003/04/13 04:45:14 karypis Exp $
*
*/
#include <metisbin.h>
/*************************************************************************
* This function reads the spd matrix
**************************************************************************/
void ReadGraph(GraphType *graph, char *filename, idxtype *wgtflag)
{
idxtype i, j, k, l, fmt, readew, readvw, ncon, edge, ewgt;
idxtype *xadj, *adjncy, *vwgt, *adjwgt;
char *line, *oldstr, *newstr;
FILE *fpin;
InitGraph(graph);
line = gk_cmalloc(MAXLINE+1, "ReadGraph: line");
fpin = gk_fopen(filename, "r", __func__);
do {
fgets(line, MAXLINE, fpin);
} while (line[0] == '%' && !feof(fpin));
if (feof(fpin)) {
graph->nvtxs = 0;
gk_free((void **)&line, LTERM);
return;
}
fmt = ncon = 0;
msscanf(line, "%D %D %D %D", &(graph->nvtxs), &(graph->nedges), &fmt, &ncon);
readew = (fmt%10 > 0);
readvw = ((fmt/10)%10 > 0);
if (fmt >= 100) {
mprintf("Cannot read this type of file format!");
exit(0);
}
*wgtflag = 0;
if (readew)
*wgtflag += 1;
if (readvw)
*wgtflag += 2;
if (ncon > 0 && !readvw) {
mprintf("------------------------------------------------------------------------------\n");
mprintf("*** I detected an error in your input file ***\n\n");
mprintf("You specified ncon=%D, but the fmt parameter does not specify vertex weights\n", ncon);
mprintf("Make sure that the fmt parameter is set to either 10 or 11.\n");
mprintf("------------------------------------------------------------------------------\n");
exit(0);
}
graph->nedges *=2;
ncon = graph->ncon = (ncon == 0 ? 1 : ncon);
/*mprintf("%D %D %D %D %D [%D %D]\n", fmt, fmt%10, (fmt/10)%10, ncon, graph->ncon, readew, readvw);*/
if (graph->nvtxs > MAXIDX)
errexit("\nThe matrix is too big: %d [%d %d]\n", graph->nvtxs, MAXIDX, sizeof(idxtype));
xadj = graph->xadj = idxsmalloc(graph->nvtxs+1, 0, "ReadGraph: xadj");
adjncy = graph->adjncy = idxmalloc(graph->nedges, "ReadGraph: adjncy");
vwgt = graph->vwgt = (readvw ? idxmalloc(ncon*graph->nvtxs, "ReadGraph: vwgt") : NULL);
adjwgt = graph->adjwgt = (readew ? idxmalloc(graph->nedges, "ReadGraph: adjwgt") : NULL);
/* Start reading the graph file */
for (xadj[0]=0, k=0, i=0; i<graph->nvtxs; i++) {
do {
fgets(line, MAXLINE, fpin);
} while (line[0] == '%' && !feof(fpin));
oldstr = line;
newstr = NULL;
if (strlen(line) == MAXLINE)
errexit("\nBuffer for fgets not big enough!\n");
if (readvw) {
for (l=0; l<ncon; l++) {
vwgt[i*ncon+l] = strtoidx(oldstr, &newstr, 10);
oldstr = newstr;
}
}
for (;;) {
edge = strtoidx(oldstr, &newstr, 10) -1;
oldstr = newstr;
if (readew) {
ewgt = strtoidx(oldstr, &newstr, 10);
oldstr = newstr;
}
if (edge < 0)
break;
adjncy[k] = edge;
if (readew)
adjwgt[k] = ewgt;
k++;
}
xadj[i+1] = k;
}
gk_fclose(fpin);
if (k != graph->nedges) {
mprintf("------------------------------------------------------------------------------\n");
mprintf("*** I detected an error in your input file ***\n\n");
mprintf("In the first line of the file, you specified that the graph contained\n%D edges. However, I only found %D edges in the file.\n", graph->nedges/2, k/2);
if (2*k == graph->nedges) {
mprintf("\n *> I detected that you specified twice the number of edges that you have in\n");
mprintf(" the file. Remember that the number of edges specified in the first line\n");
mprintf(" counts each edge between vertices v and u only once.\n\n");
}
mprintf("Please specify the correct number of edges in the first line of the file.\n");
mprintf("------------------------------------------------------------------------------\n");
exit(0);
}
gk_free((void **)&line, LTERM);
}
/*************************************************************************
* This function reads the spd matrix
**************************************************************************/
void ReadCoordinates(GraphType *graph, char *filename)
{
idxtype i, j, k, l, nvtxs, fmt, readew, readvw, ncon, edge, ewgt;
FILE *fpin;
char *line;
fpin = gk_fopen(filename, "r", __func__);
nvtxs = graph->nvtxs;
graph->coords = gk_dsmalloc(3*nvtxs, 0.0, "ReadCoordinates: coords");
line = gk_cmalloc(MAXLINE+1, "ReadCoordinates: line");
for (i=0; i<nvtxs; i++) {
fgets(line, MAXLINE, fpin);
msscanf(line, "%lf %lf %lf", graph->coords+3*i+0, graph->coords+3*i+1, graph->coords+3*i+2);
}
gk_fclose(fpin);
gk_free((void **)&line, LTERM);
}
/*************************************************************************
* This function writes out the partition vector
**************************************************************************/
void WritePartition(char *fname, idxtype *part, idxtype n, idxtype nparts)
{
FILE *fpout;
idxtype i;
char filename[256];
msprintf(filename,"%s.part.%D",fname, nparts);
fpout = gk_fopen(filename, "w", __func__);
for (i=0; i<n; i++)
fprintf(fpout,"%" PRIIDX "\n", part[i]);
gk_fclose(fpout);
}
/*************************************************************************
* This function writes out the partition vectors for a mesh
**************************************************************************/
void WriteMeshPartition(char *fname, idxtype nparts, idxtype ne, idxtype *epart,
idxtype nn, idxtype *npart)
{
FILE *fpout;
idxtype i;
char filename[256];
msprintf(filename,"%s.epart.%D",fname, nparts);
fpout = gk_fopen(filename, "w", __func__);
for (i=0; i<ne; i++)
fprintf(fpout,"%" PRIIDX "\n", epart[i]);
gk_fclose(fpout);
msprintf(filename,"%s.npart.%D",fname, nparts);
fpout = gk_fopen(filename, "w", __func__);
for (i=0; i<nn; i++)
fprintf(fpout, "%" PRIIDX "\n", npart[i]);
gk_fclose(fpout);
}
/*************************************************************************
* This function writes out the partition vector
**************************************************************************/
void WritePermutation(char *fname, idxtype *iperm, idxtype n)
{
FILE *fpout;
idxtype i;
char filename[256];
msprintf(filename,"%s.iperm",fname);
fpout = gk_fopen(filename, "w", __func__);
for (i=0; i<n; i++)
fprintf(fpout, "%" PRIIDX "\n", iperm[i]);
gk_fclose(fpout);
}
/*************************************************************************
* This function checks if a graph is valid
**************************************************************************/
int CheckGraph(GraphType *graph)
{
idxtype i, j, k, l, nvtxs, err=0;
idxtype *xadj, *adjncy, *adjwgt;
nvtxs = graph->nvtxs;
xadj = graph->xadj;
adjncy = graph->adjncy;
adjwgt = graph->adjwgt;
for (i=0; i<nvtxs; i++) {
for (j=xadj[i]; j<xadj[i+1]; j++) {
k = adjncy[j];
if (i == k) {
mprintf("Vertex %D contains a self-loop (i.e., diagonal entry in the matrix)!\n", i);
err++;
}
else {
for (l=xadj[k]; l<xadj[k+1]; l++) {
if (adjncy[l] == i) {
if (adjwgt != NULL && adjwgt[l] != adjwgt[j]) {
mprintf("Edges (%D %D) and (%D %D) do not have the same weight! %D %D\n", i,k,k,i, adjwgt[l], adjwgt[adjncy[j]]);
err++;
}
break;
}
}
if (l == xadj[k+1]) {
mprintf("Missing edge: (%D %D)!\n", k, i);
err++;
}
}
}
}
if (err > 0)
mprintf("A total of %D errors exist in the input file. Correct them, and run again!\n", err);
return (err == 0 ? 1 : 0);
}
/****************************************************************************
* This function detect the input mesh type
***************************************************************************/
int MeshType(char *filename)
{
int i, j, k, l, len, cnt=0;
FILE *fpin;
char temp[40], inpt[80];
int firstline[3];
fpin = gk_fopen(filename, "r", __func__);
mfscanf(fpin,"%[^\n]s", inpt);
gk_fclose(fpin);
len = strlen(inpt);
i=0;k=0;
while (inpt[i]==' ') i++;
while (i<=len) {
if (inpt[i]==' ' || i==len) {
l=0;
for (j=k; j<i;j++ )
temp[l++]=inpt[j];
temp[l]='\0';
firstline[cnt++] = atoi(temp);
while (inpt[i]==' ') i++;
k=i;
if (i==len) break;
}
else
i++;
}
if (cnt==1)
return 0; /*Mixed element without weight */
else if (cnt==2 && firstline[1]>0)
return 1; /*Fixed element without weight*/
else if (cnt==2 && firstline[1]==-1)
return 2; /*Mixed element with weight*/
else if (cnt==3 && firstline[2]==-1)
return 3; /*Fixed element with weight*/
}
/*************************************************************************
* This function reads the element node array of a mesh
**************************************************************************/
idxtype *ReadMesh(char *filename, idxtype *ne, idxtype *nn, idxtype *etype)
{
idxtype i, j, k, esize;
idxtype *elmnts;
FILE *fpin;
fpin = gk_fopen(filename, "r", __func__);
mfscanf(fpin, "%D %D", ne, etype);
switch (*etype) {
case 1:
esize = 3;
break;
case 2:
esize = 4;
break;
case 3:
esize = 8;
break;
case 4:
esize = 4;
break;
case 5:
esize = 2;
break;
default:
errexit("Unknown mesh-element type: %d\n", *etype);
}
elmnts = idxmalloc(esize*(*ne), "ReadMesh: elmnts");
for (j=esize*(*ne), i=0; i<j; i++) {
mfscanf(fpin, "%D", elmnts+i);
elmnts[i]--;
}
gk_fclose(fpin);
*nn = elmnts[idxargmax(j, elmnts)]+1;
return elmnts;
}
/*************************************************************************
* This function reads the element node array of a mesh with weight
**************************************************************************/
idxtype *ReadMeshWgt(char *filename, idxtype *ne, idxtype *nn, idxtype *etype,
idxtype *vwgt)
{
idxtype i, j, k, esize;
idxtype *elmnts;
FILE *fpin;
fpin = gk_fopen(filename, "r", __func__);
mfscanf(fpin, "%D %D", ne, etype);
mfscanf(fpin, "%D", &i);
switch (*etype) {
case 1:
esize = 3;
break;
case 2:
esize = 4;
break;
case 3:
esize = 8;
break;
case 4:
esize = 4;
break;
case 5:
esize = 2;
break;
default:
errexit("Unknown mesh-element type: %d\n", *etype);
}
elmnts = idxmalloc(esize*(*ne), "ReadMeshWgt: elmnts");
for (j=0, i=0; i<*ne; i++) {
mfscanf(fpin, "%D", vwgt+i);
for (k=0; k<esize; k++) {
mfscanf(fpin, "%D", elmnts+j);
elmnts[j++]--;
}
}
gk_fclose(fpin);
*nn = elmnts[idxargmax(j, elmnts)]+1;
return elmnts;
}
/*************************************************************************
* This function reads the weights of each elements
**************************************************************************/
idxtype *ReadWgt(char *filename, idxtype *ne, idxtype *nn, idxtype *etype)
{
idxtype i, j, k, l, esize;
idxtype *vwgt;
FILE *fpin;
fpin = gk_fopen(filename, "r", __func__);
mfscanf(fpin, "%D %D", ne, etype);
mfscanf(fpin, "%D", &i);
switch (*etype) {
case 1:
esize = 3;
break;
case 2:
esize = 4;
break;
case 3:
esize = 8;
break;
case 4:
esize = 4;
break;
case 5:
esize = 2;
break;
default:
errexit("Unknown mesh-element type: %d\n", *etype);
}
vwgt = idxmalloc(*ne, "ReadWgt: vwgt");
for (j=0, i=0; i<*ne; i++) {
mfscanf(fpin, "%D", vwgt+i);
for (k=0; k<esize; k++) {
mfscanf(fpin, "%D", &l);
j++;
}
}
gk_fclose(fpin);
return vwgt;
}
/*************************************************************************
* This function reads # of element of a mixed mesh
**************************************************************************/
idxtype MixedElements(char *filename)
{
idxtype ne;
FILE *fpin;
fpin = gk_fopen(filename, "r", __func__);
mfscanf(fpin, "%D", &ne);
gk_fclose(fpin);
return ne;
}
/*************************************************************************
* This function reads the element node array of a i Mixed mesh
**************************************************************************/
idxtype *ReadMixedMesh(char *filename, idxtype *ne, idxtype *nn, idxtype *etype)
{
idxtype i, j, k, esize;
idxtype *elmnts;
FILE *fpin;
idxtype sizes[]={-1,3,4,8,4,2};
fpin = gk_fopen(filename, "r", __func__);
mfscanf(fpin, "%D", ne);
elmnts = idxmalloc(8*(*ne), "ReadMixedMesh: elmnts");
for (j=0, i=0; i<*ne; i++) {
mfscanf(fpin, "%D", etype+i);
for (k=0;k<sizes[etype[i]];k++) {
mfscanf(fpin, "%D", elmnts+j);
elmnts[j++]--;
}
}
gk_fclose(fpin);
*nn = elmnts[idxargmax(j, elmnts)]+1;
return elmnts;
}
/*************************************************************************
* This function reads the element node array of a Mixed mesh with weight
**************************************************************************/
idxtype *ReadMixedMeshWgt(char *filename, idxtype *ne, idxtype *nn,
idxtype *etype, idxtype *vwgt)
{
idxtype i, j, k, esize;
idxtype *elmnts;
FILE *fpin;
idxtype sizes[]={-1,3,4,8,4,2};
fpin = gk_fopen(filename, "r", __func__);
mfscanf(fpin, "%D", ne);
mfscanf(fpin, "%D", nn);
elmnts = idxmalloc(8*(*ne), "ReadMixedMeshWgt: elmnts");
for (j=0, i=0; i<*ne; i++) {
mfscanf(fpin, "%D",etype+i);
mfscanf(fpin, "%D",vwgt+i);
for (k=0;k<sizes[etype[i]];k++) {
mfscanf(fpin, "%D", elmnts+j);
elmnts[j++]--;
}
}
gk_fclose(fpin);
*nn = elmnts[idxargmax(j, elmnts)]+1;
return elmnts;
}
/************************************************************************
* This function reads the element node array of a i Mixed mesh
**************************************************************************/
idxtype *ReadMgcnums(char *filename)
{
idxtype i;
idxtype *mgc;
FILE *fpin;
fpin = gk_fopen(filename, "r", __func__);
mgc = idxmalloc(36, "Readmgcnums: mgcnums");
for (i=0; i<36; i++) {
if (i<6 || i%6==0)
mgc[i]=-1;
else
mfscanf(fpin, "%D", mgc+i);
}
gk_fclose(fpin);
return mgc;
}
/*************************************************************************
* This function writes a graphs into a file
**************************************************************************/
void WriteGraph(char *filename, idxtype nvtxs, idxtype *xadj, idxtype *adjncy)
{
idxtype i, j;
FILE *fpout;
fpout = gk_fopen(filename, "w", __func__);
mfprintf(fpout, "%D %D", nvtxs, xadj[nvtxs]/2);
for (i=0; i<nvtxs; i++) {
mfprintf(fpout, "\n");
for (j=xadj[i]; j<xadj[i+1]; j++)
fprintf(fpout, " %" PRIIDX, adjncy[j]+1);
}
gk_fclose(fpout);
}
/*************************************************************************
* This function writes weighted graph into a file
**************************************************************************/
void WriteWgtGraph(char *filename, idxtype nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt)
{
idxtype i, j;
FILE *fpout;
fpout = gk_fopen(filename, "w", __func__);
mfprintf(fpout, "%D %D", nvtxs, xadj[nvtxs]/2);
mfprintf(fpout, " %D", 10);
for (i=0; i<nvtxs; i++) {
fprintf(fpout, "\n");
fprintf(fpout, "%" PRIIDX, vwgt[i]);
for (j=xadj[i]; j<xadj[i+1]; j++)
fprintf(fpout, " %" PRIIDX, adjncy[j]+1);
}
gk_fclose(fpout);
}
/*************************************************************************
* This function writes a graphs into a file
**************************************************************************/
void WriteMocGraph(GraphType *graph)
{
idxtype i, j, nvtxs, ncon;
idxtype *xadj, *adjncy;
float *nvwgt;
char filename[256];
FILE *fpout;
nvtxs = graph->nvtxs;
ncon = graph->ncon;
xadj = graph->xadj;
adjncy = graph->adjncy;
nvwgt = graph->nvwgt;
msprintf(filename, "moc.graph.%D.%D", nvtxs, ncon);
fpout = gk_fopen(filename, "w", __func__);
mfprintf(fpout, "%D %D 10 1 %D", nvtxs, xadj[nvtxs]/2, ncon);
for (i=0; i<nvtxs; i++) {
mfprintf(fpout, "\n");
for (j=0; j<ncon; j++)
fprintf(fpout, "%" PRIIDX " ", (int)((float)10e6*nvwgt[i*ncon+j]));
for (j=xadj[i]; j<xadj[i+1]; j++)
fprintf(fpout, " %" PRIIDX, adjncy[j]+1);
}
gk_fclose(fpout);
}

View File

@ -0,0 +1,95 @@
/*
* Copyright 1997, Regents of the University of Minnesota
*
* kfmetis.c
*
* This file contains the driving routine for partitioning for
* sub-domain direct factorization.
*
* Started 8/11/02
* George
*
* $Id: kfmetis.c,v 1.2 2002/08/13 16:40:14 karypis Exp $
*
*/
#include <metisbin.h>
/*************************************************************************
* Let the game begin
**************************************************************************/
int main(int argc, char *argv[])
{
idxtype i, options[10];
idxtype *part;
float lbvec[MAXNCON];
GraphType graph;
idxtype numflag = 0, wgtflag = 0, edgecut;
ParamType params;
double TOTALTmr, METISTmr, IOTmr;
parse_cmdline(&params, argc, argv);
if (params.nparts < 2) {
mprintf("The number of partitions should be greater than 1!\n");
exit(0);
}
gk_clearcputimer(TOTALTmr);
gk_clearcputimer(METISTmr);
gk_clearcputimer(IOTmr);
gk_startcputimer(TOTALTmr);
gk_startcputimer(IOTmr);
ReadGraph(&graph, params.filename, &wgtflag);
if (graph.nvtxs <= 0) {
mprintf("Empty graph. Nothing to do.\n");
exit(0);
}
gk_stopcputimer(IOTmr);
mprintf("**********************************************************************\n");
mprintf("%s", METISTITLE);
mprintf("Graph Information ---------------------------------------------------\n");
mprintf(" Name: %s, #Vertices: %D, #Edges: %D, #Parts: %D\n", params.filename, graph.nvtxs, graph.nedges/2, params.nparts);
if (graph.ncon > 1)
mprintf(" Balancing Constraints: %D\n", graph.ncon);
mprintf("\nRecursive Partitioning... -------------------------------------------\n");
part = idxmalloc(graph.nvtxs, "main: part");
options[0] = 0;
gk_startcputimer(METISTmr);
METIS_PartFillGraph(&graph.nvtxs, graph.xadj, graph.adjncy, graph.vwgt, graph.adjwgt,
&wgtflag, &numflag, &(params.nparts), options, &edgecut, part);
gk_stopcputimer(METISTmr);
ComputePartitionBalance(&graph, params.nparts, part, lbvec);
mprintf(" %D-way Edge-Cut: %7D, Balance: ", params.nparts, edgecut);
for (i=0; i<graph.ncon; i++)
mprintf("%5.2f ", lbvec[i]);
mprintf("\n");
gk_startcputimer(IOTmr);
// WritePartition(params.filename, part, graph.nvtxs, params.nparts);
gk_stopcputimer(IOTmr);
gk_stopcputimer(TOTALTmr);
mprintf("\nTiming Information --------------------------------------------------\n");
mprintf(" I/O: \t\t %7.3f\n", gk_getcputimer(IOTmr));
mprintf(" Partitioning: \t\t %7.3f (PMETIS time)\n", gk_getcputimer(METISTmr));
mprintf(" Total: \t\t %7.3f\n", gk_getcputimer(TOTALTmr));
mprintf("**********************************************************************\n");
gk_free((void **)&graph.xadj, &graph.adjncy, &graph.vwgt, &graph.adjwgt, &part, LTERM);
}

View File

@ -0,0 +1,111 @@
/*
* Copyright 1997, Regents of the University of Minnesota
*
* kmetis.c
*
* This file contains the driving routine for kmetis
*
* Started 8/28/94
* George
*
* $Id: kmetis.c,v 1.6 2003/07/31 16:15:50 karypis Exp $
*
*/
#include <metisbin.h>
/*************************************************************************
* Let the game begin
**************************************************************************/
int main(int argc, char *argv[])
{
idxtype i, nparts, options[10];
idxtype *part;
float rubvec[MAXNCON], lbvec[MAXNCON];
GraphType graph;
char filename[256];
idxtype numflag = 0, wgtflag = 0, edgecut;
double TOTALTmr, METISTmr, IOTmr;
if (argc != 3) {
mprintf("Usage: %s <GraphFile> <Nparts>\n",argv[0]);
exit(0);
}
strcpy(filename, argv[1]);
nparts = atoi(argv[2]);
if (nparts < 2) {
mprintf("The number of partitions should be greater than 1!\n");
exit(0);
}
gk_clearcputimer(TOTALTmr);
gk_clearcputimer(METISTmr);
gk_clearcputimer(IOTmr);
gk_startcputimer(TOTALTmr);
gk_startcputimer(IOTmr);
ReadGraph(&graph, filename, &wgtflag);
/* The following is for debuging empty graphs...
graph.nedges = 0;
idxset(graph.nvtxs+1, 0, graph.xadj);
*/
if (graph.nvtxs <= 0) {
mprintf("Empty graph. Nothing to do.\n");
exit(0);
}
gk_stopcputimer(IOTmr);
mprintf("**********************************************************************\n");
mprintf("%s", METISTITLE);
mprintf("Graph Information ---------------------------------------------------\n");
mprintf(" Name: %s, #Vertices: %D, #Edges: %D, #Parts: %D\n", filename, graph.nvtxs, graph.nedges/2, nparts);
if (graph.ncon > 1)
mprintf(" Balancing Constraints: %D\n", graph.ncon);
mprintf("\nK-way Partitioning... -----------------------------------------------\n");
part = idxmalloc(graph.nvtxs, "main: part");
options[0] = 0;
gk_startcputimer(METISTmr);
if (graph.ncon == 1) {
METIS_PartGraphKway(&graph.nvtxs, graph.xadj, graph.adjncy, graph.vwgt, graph.adjwgt,
&wgtflag, &numflag, &nparts, options, &edgecut, part);
}
else {
for (i=0; i<graph.ncon; i++)
rubvec[i] = HORIZONTAL_IMBALANCE;
METIS_mCPartGraphKway(&graph.nvtxs, &graph.ncon, graph.xadj, graph.adjncy, graph.vwgt,
graph.adjwgt, &wgtflag, &numflag, &nparts, rubvec, options, &edgecut, part);
}
gk_stopcputimer(METISTmr);
ComputePartitionBalance(&graph, nparts, part, lbvec);
mprintf(" %D-way Edge-Cut: %7D, Balance: ", nparts, edgecut);
for (i=0; i<graph.ncon; i++)
mprintf("%5.2f ", lbvec[i]);
mprintf("\n");
gk_startcputimer(IOTmr);
WritePartition(filename, part, graph.nvtxs, nparts);
gk_stopcputimer(IOTmr);
gk_stopcputimer(TOTALTmr);
mprintf("\nTiming Information --------------------------------------------------\n");
mprintf(" I/O: \t\t %7.3f\n", gk_getcputimer(IOTmr));
mprintf(" Partitioning: \t\t %7.3f (KMETIS time)\n", gk_getcputimer(METISTmr));
mprintf(" Total: \t\t %7.3f\n", gk_getcputimer(TOTALTmr));
mprintf("**********************************************************************\n");
gk_free((void **)&graph.xadj, &graph.adjncy, &graph.vwgt, &graph.adjwgt, &part, LTERM);
}

View File

@ -0,0 +1,158 @@
/*
* Copyright 1997, Regents of the University of Minnesota
*
* mesh2dual.c
*
* This file reads in the element node connectivity array of a mesh and writes
* out its dual in the format suitable for Metis.
*
* Started 9/29/97
* George
*
* $Id: mesh2dual.c,v 1.2 2002/08/10 06:02:53 karypis Exp $
*
*/
#include <metisbin.h>
/*************************************************************************
* Let the game begin
**************************************************************************/
int main(int argc, char *argv[])
{
idxtype i, j, ne, nn, etype, mtype, cnt, numflag=0;
idxtype *elmnts, *xadj, *adjncy, *metype;
idxtype *conmat, *elms, *weights;
double IOTmr, DUALTmr;
char fileout[256], etypestr[5][5] = {"TRI", "TET", "HEX", "QUAD", "LINE"};
if (argc <2) {
mprintf("Usage: %s <meshfile> [confile]\n",argv[0]);
exit(0);
}
mtype=MeshType(argv[1]);
ne=MixedElements(argv[1]);
metype = idxmalloc(ne, "main: metype");
weights = idxmalloc(ne, "main: weights");
if (mtype==1 || mtype==3){
gk_clearcputimer(IOTmr);
gk_clearcputimer(DUALTmr);
gk_startcputimer(IOTmr);
if (mtype==1)
elmnts = ReadMesh(argv[1], &ne, &nn, &etype);
else
elmnts = ReadMeshWgt(argv[1], &ne, &nn, &etype, weights);
gk_stopcputimer(IOTmr);
mprintf("**********************************************************************\n");
mprintf("%s", METISTITLE);
mprintf("Mesh Information ----------------------------------------------------\n");
mprintf(" Name: %s, #Elements: %D, #Nodes: %D, Etype: %s\n\n", argv[1], ne, nn, etypestr[etype-1]);
mprintf("Forming Dual Graph... -----------------------------------------------\n");
xadj = idxmalloc(ne+1, "main: xadj");
elms = idxsmalloc(ne+1, 0, "main: elms");
gk_startcputimer(DUALTmr);
cnt=METIS_MeshToDualCount(&ne, &nn, elmnts, elms, &etype, &numflag);
adjncy = idxmalloc(cnt+1, "main: adjncy");
METIS_MeshToDual(&ne, &nn, elmnts, elms, &etype, &numflag, xadj, adjncy);
gk_stopcputimer(DUALTmr);
mprintf(" Dual Information: #Vertices: %D, #Edges: %D\n", ne, xadj[ne]/2);
msprintf(fileout, "%s.dgraph", argv[1]);
gk_startcputimer(IOTmr);
if (mtype==1)
WriteGraph(fileout, ne, xadj, adjncy);
else
WriteWgtGraph(fileout, ne, xadj, adjncy, weights);
gk_stopcputimer(IOTmr);
mprintf("\nTiming Information --------------------------------------------------\n");
mprintf(" I/O: \t\t %7.3f\n", gk_getcputimer(IOTmr));
mprintf(" Dual Creation:\t\t %7.3f\n", gk_getcputimer(DUALTmr));
mprintf("**********************************************************************\n");
}
else {
gk_clearcputimer(IOTmr);
gk_clearcputimer(DUALTmr);
gk_startcputimer(IOTmr);
if(mtype==0)
elmnts = ReadMixedMesh(argv[1], &ne, &nn, metype);
else
elmnts = ReadMixedMeshWgt(argv[1], &ne, &nn, metype, weights);
if (argc==3)
conmat = ReadMgcnums(argv[2]);
gk_stopcputimer(IOTmr);
mprintf("**********************************************************************\n");
mprintf("%s", METISTITLE);
mprintf("Mesh Information ----------------------------------------------------\n");
mprintf(" Name: %s, #Elements: %D, #Nodes: %D, Etype: %s\n\n", argv[1], ne, nn, "Mixed");
mprintf("Forming Dual Graph... ----------------------------------------------\n");
xadj = idxmalloc(ne+1, "main: xadj");
elms = idxsmalloc(ne+1, 0, "main: elms");
gk_startcputimer(DUALTmr);
if (argc==3){
cnt=METIS_MixedMeshToDualCount(&ne, &nn, elmnts, elms, metype, &numflag,
conmat, 1);
adjncy = idxmalloc(cnt+1, "main: adjncy");
METIS_MixedMeshToDual(&ne, &nn, elmnts, elms, metype, &numflag, xadj, adjncy,
conmat, 1);
}
else{
cnt=METIS_MixedMeshToDualCount(&ne, &nn, elmnts, elms, metype, &numflag,
conmat, 0);
adjncy = idxmalloc(cnt+1, "main: adjncy");
METIS_MixedMeshToDual(&ne, &nn, elmnts, elms, metype, &numflag, xadj, adjncy, conmat, 0);
}
gk_stopcputimer(DUALTmr);
mprintf(" Dual Information: #Vertices: %D, #Edges: %D\n", ne, xadj[ne]/2);
msprintf(fileout, "%s.dgraph", argv[1]);
gk_startcputimer(IOTmr);
if (mtype==0)
WriteGraph(fileout, ne, xadj, adjncy);
else
WriteWgtGraph(fileout, ne, xadj, adjncy, weights);
gk_stopcputimer(IOTmr);
mprintf("\nTiming Information --------------------------------------------------\n");
mprintf(" I/O: \t\t %7.3f\n", gk_getcputimer(IOTmr));
mprintf(" Dual Creation:\t\t %7.3f\n", gk_getcputimer(DUALTmr));
mprintf("**********************************************************************\n");
}
gk_free((void **)&elmnts, &xadj, &adjncy, &metype, &weights, &elms, LTERM);
}

View File

@ -0,0 +1,129 @@
/*
* Copyright 1997, Regents of the University of Minnesota
*
* mesh2nodal.c
*
* This file reads in the element node connectivity array of a mesh and writes
* out its dual in the format suitable for Metis.
*
* Started 9/29/97
* George
*
* $Id: mesh2nodal.c,v 1.2 2002/08/10 06:02:53 karypis Exp $
*
*/
#include <metisbin.h>
/*************************************************************************
* Let the game begin
**************************************************************************/
int main(int argc, char *argv[])
{
idxtype i, j, ne, nn, etype, mtype, numflag=0;
idxtype *elmnts, *xadj, *adjncy, *metype, *weights;
double IOTmr, DUALTmr;
char fileout[256], etypestr[5][5] = {"TRI", "TET", "HEX", "QUAD", "LINE"};
if (argc != 2) {
mprintf("Usage: %s <meshfile>\n",argv[0]);
exit(0);
}
mtype=MeshType(argv[1]);
ne=MixedElements(argv[1]);
metype = idxmalloc(ne, "main: metype");
weights = idxmalloc(ne, "main: weights");
if (mtype==1 || mtype==3){
gk_clearcputimer(IOTmr);
gk_clearcputimer(DUALTmr);
gk_startcputimer(IOTmr);
if (mtype==1)
elmnts = ReadMesh(argv[1], &ne, &nn, &etype);
else
elmnts = ReadMeshWgt(argv[1], &ne, &nn, &etype, weights);
gk_stopcputimer(IOTmr);
mprintf("**********************************************************************\n");
mprintf("%s", METISTITLE);
mprintf("Mesh Information ----------------------------------------------------\n");
mprintf(" Name: %s, #Elements: %D, #Nodes: %D, Etype: %s\n\n", argv[1], ne, nn, etypestr[etype-1]);
mprintf("Forming Nodal Graph... ----------------------------------------------\n");
xadj = idxmalloc(nn+1, "main: xadj");
adjncy = idxmalloc(20*nn, "main: adjncy");
gk_startcputimer(DUALTmr);
METIS_MeshToNodal(&ne, &nn, elmnts, &etype, &numflag, xadj, adjncy);
gk_stopcputimer(DUALTmr);
mprintf(" Nodal Information: #Vertices: %D, #Edges: %D\n", nn, xadj[nn]/2);
msprintf(fileout, "%s.ngraph", argv[1]);
gk_startcputimer(IOTmr);
WriteGraph(fileout, nn, xadj, adjncy);
gk_stopcputimer(IOTmr);
mprintf("\nTiming Information --------------------------------------------------\n");
mprintf(" I/O: \t\t %7.3f\n", gk_getcputimer(IOTmr));
mprintf(" Nodal Creation:\t\t %7.3f\n", gk_getcputimer(DUALTmr));
mprintf("**********************************************************************\n");
}
else{
gk_clearcputimer(IOTmr);
gk_clearcputimer(DUALTmr);
gk_startcputimer(IOTmr);
if(mtype==0)
elmnts = ReadMixedMesh(argv[1], &ne, &nn, metype);
else
elmnts = ReadMixedMeshWgt(argv[1], &ne, &nn, metype, weights);
gk_stopcputimer(IOTmr);
mprintf("**********************************************************************\n");
mprintf("%s", METISTITLE);
mprintf("Mesh Information ----------------------------------------------------\n");
mprintf(" Name: %s, #Elements: %D, #Nodes: %D, Etype: %s\n\n", argv[1], ne, nn, "Mixed");
mprintf("Forming Nodal Graph... ----------------------------------------------\n");
xadj = idxmalloc(nn+1, "main: xadj");
adjncy = idxmalloc(20*nn, "main: adjncy");
gk_startcputimer(DUALTmr);
METIS_MixedMeshToNodal(&ne, &nn, elmnts, metype, &numflag, xadj, adjncy);
gk_stopcputimer(DUALTmr);
mprintf(" Nodal Information: #Vertices: %D, #Edges: %D\n", nn, xadj[nn]/2);
msprintf(fileout, "%s.ngraph", argv[1]);
gk_startcputimer(IOTmr);
WriteGraph(fileout, nn, xadj, adjncy);
gk_stopcputimer(IOTmr);
mprintf("\nTiming Information --------------------------------------------------\n");
mprintf(" I/O: \t\t %7.3f\n", gk_getcputimer(IOTmr));
mprintf(" Nodal Creation:\t\t %7.3f\n", gk_getcputimer(DUALTmr));
mprintf("**********************************************************************\n");
}
gk_free((void **)&elmnts, &xadj, &adjncy, &metype, &weights, LTERM);
}

View File

@ -0,0 +1,196 @@
/*
* Copyright 1997, Regents of the University of Minnesota
*
* metis.c
*
* This file contains the driving routine for multilevel method
*
* Started 8/28/94
* George
*
* $Id: metis.c,v 1.2 2002/08/10 06:02:53 karypis Exp $
*
*/
#include <metisbin.h>
/*************************************************************************
* Let the game begin
**************************************************************************/
int main(int argc, char *argv[])
{
idxtype i, nparts, OpType, options[10], nbytes;
idxtype *part, *perm, *iperm, *sizes;
GraphType graph;
char filename[256];
idxtype numflag = 0, wgtflag = 0, edgecut;
if (argc != 11) {
mprintf("Usage: %s <GraphFile> <Nparts> <Mtype> <Rtype> <IPtype> <Oflags> <Pfactor> <Nseps> <OPtype> <Options> \n",argv[0]);
exit(0);
}
strcpy(filename, argv[1]);
nparts = atoi(argv[2]);
options[OPTION_CTYPE] = atoi(argv[3]);
options[OPTION_RTYPE] = atoi(argv[4]);
options[OPTION_ITYPE] = atoi(argv[5]);
options[OPTION_OFLAGS] = atoi(argv[6]);
options[OPTION_PFACTOR] = atoi(argv[7]);
options[OPTION_NSEPS] = atoi(argv[8]);
OpType = atoi(argv[9]);
options[OPTION_DBGLVL] = atoi(argv[10]);
ReadGraph(&graph, filename, &wgtflag);
if (graph.nvtxs <= 0) {
mprintf("Empty graph. Nothing to do.\n");
exit(0);
}
mprintf("Partitioning a graph with %D vertices and %D edges\n", graph.nvtxs, graph.nedges/2);
METIS_EstimateMemory(&graph.nvtxs, graph.xadj, graph.adjncy, &numflag, &OpType, &nbytes);
mprintf("Metis will need %D Mbytes\n", nbytes/(1024*1024));
part = perm = iperm = NULL;
options[0] = 1;
switch (OpType) {
case OP_PMETIS:
mprintf("Recursive Partitioning... ------------------------------------------\n");
part = idxmalloc(graph.nvtxs, "main: part");
METIS_PartGraphRecursive(&graph.nvtxs, graph.xadj, graph.adjncy, graph.vwgt, graph.adjwgt,
&wgtflag, &numflag, &nparts, options, &edgecut, part);
IFSET(options[OPTION_DBGLVL], DBG_OUTPUT, WritePartition(filename, part, graph.nvtxs, nparts));
mprintf(" %D-way Edge-Cut: %7D\n", nparts, edgecut);
ComputePartitionInfo(&graph, nparts, part);
gk_free((void **)&part, LTERM);
break;
case OP_KMETIS:
mprintf("K-way Partitioning... -----------------------------------------------\n");
part = idxmalloc(graph.nvtxs, "main: part");
METIS_PartGraphKway(&graph.nvtxs, graph.xadj, graph.adjncy, graph.vwgt, graph.adjwgt,
&wgtflag, &numflag, &nparts, options, &edgecut, part);
IFSET(options[OPTION_DBGLVL], DBG_OUTPUT, WritePartition(filename, part, graph.nvtxs, nparts));
mprintf(" %D-way Edge-Cut: %7D\n", nparts, edgecut);
ComputePartitionInfo(&graph, nparts, part);
gk_free((void **)&part, LTERM);
break;
case OP_OEMETIS:
gk_free((void **)&graph.vwgt, &graph.adjwgt, LTERM);
mprintf("Edge-based Nested Dissection Ordering... ----------------------------\n");
perm = idxmalloc(graph.nvtxs, "main: perm");
iperm = idxmalloc(graph.nvtxs, "main: iperm");
METIS_EdgeND(&graph.nvtxs, graph.xadj, graph.adjncy, &numflag, options, perm, iperm);
IFSET(options[OPTION_DBGLVL], DBG_OUTPUT, WritePartition(filename, iperm, graph.nvtxs, 0));
ComputeFillIn(&graph, iperm);
gk_free((void **)&perm, &iperm, LTERM);
break;
case OP_ONMETIS:
gk_free((void **)&graph.vwgt, &graph.adjwgt, LTERM);
mprintf("Node-based Nested Dissection Ordering... ----------------------------\n");
perm = idxmalloc(graph.nvtxs, "main: perm");
iperm = idxmalloc(graph.nvtxs, "main: iperm");
METIS_NodeND(&graph.nvtxs, graph.xadj, graph.adjncy, &numflag, options, perm, iperm);
IFSET(options[OPTION_DBGLVL], DBG_OUTPUT, WritePartition(filename, iperm, graph.nvtxs, 0));
ComputeFillIn(&graph, iperm);
gk_free((void **)&perm, &iperm, LTERM);
break;
case OP_ONWMETIS:
gk_free((void **)&graph.adjwgt, LTERM);
mprintf("WNode-based Nested Dissection Ordering... ---------------------------\n");
perm = idxmalloc(graph.nvtxs, "main: perm");
iperm = idxmalloc(graph.nvtxs, "main: iperm");
METIS_NodeWND(&graph.nvtxs, graph.xadj, graph.adjncy, graph.vwgt, &numflag, options, perm, iperm);
IFSET(options[OPTION_DBGLVL], DBG_OUTPUT, WritePartition(filename, iperm, graph.nvtxs, 0));
ComputeFillIn(&graph, iperm);
gk_free((void **)&perm, &iperm, LTERM);
break;
case 6:
gk_free((void **)&graph.vwgt, &graph.adjwgt, LTERM);
mprintf("Node-based Nested Dissection Ordering... ----------------------------\n");
perm = idxmalloc(graph.nvtxs, "main: perm");
iperm = idxmalloc(graph.nvtxs, "main: iperm");
sizes = idxmalloc(2*nparts, "main: sizes");
METIS_NodeNDP(graph.nvtxs, graph.xadj, graph.adjncy, nparts, options, perm, iperm, sizes);
IFSET(options[OPTION_DBGLVL], DBG_OUTPUT, WritePartition(filename, iperm, graph.nvtxs, 0));
ComputeFillIn(&graph, iperm);
for (i=0; i<2*nparts-1; i++)
mprintf("%D ", sizes[i]);
mprintf("\n");
gk_free((void **)&perm, &iperm, &sizes, LTERM);
break;
case 7:
mprintf("K-way Vol Partitioning... -------------------------------------------\n");
part = idxmalloc(graph.nvtxs, "main: part");
METIS_PartGraphVKway(&graph.nvtxs, graph.xadj, graph.adjncy, graph.vwgt, NULL,
&wgtflag, &numflag, &nparts, options, &edgecut, part);
IFSET(options[OPTION_DBGLVL], DBG_OUTPUT, WritePartition(filename, part, graph.nvtxs, nparts));
mprintf(" %D-way Volume: %7D\n", nparts, edgecut);
ComputePartitionInfo(&graph, nparts, part);
gk_free((void **)&part, LTERM);
break;
case 9:
mprintf("K-way Partitioning (with vwgts)... ----------------------------------\n");
part = idxmalloc(graph.nvtxs, "main: part");
graph.vwgt = idxmalloc(graph.nvtxs, "main: graph.vwgt");
for (i=0; i<graph.nvtxs; i++)
graph.vwgt[i] = graph.xadj[i+1]-graph.xadj[i]+1;
wgtflag = 2;
METIS_PartGraphKway(&graph.nvtxs, graph.xadj, graph.adjncy, graph.vwgt, graph.adjwgt,
&wgtflag, &numflag, &nparts, options, &edgecut, part);
IFSET(options[OPTION_DBGLVL], DBG_OUTPUT, WritePartition(filename, part, graph.nvtxs, nparts));
mprintf(" %D-way Edge-Cut: %7D\n", nparts, edgecut);
ComputePartitionInfo(&graph, nparts, part);
gk_free((void **)&part, LTERM);
break;
case 10:
break;
default:
errexit("Unknown");
}
gk_free((void **)&graph.xadj, &graph.adjncy, &graph.vwgt, &graph.adjwgt, LTERM);
}

View File

@ -0,0 +1,49 @@
/*
* metisbin.h
*
* This file contains the various header inclusions
*
* Started 8/9/02
* George
*/
#include <GKlib.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <time.h>
#include <string.h>
#include <limits.h>
#include <signal.h>
#include <setjmp.h>
#include <assert.h>
#if defined(ENABLE_OPENMP)
#include <omp.h>
#endif
#include <metis.h>
#include "../libmetis/defs.h"
#include "../libmetis/struct.h"
#include "../libmetis/rename.h"
#include "../libmetis/macros.h"
#include "../libmetis/proto.h"
#include "defs.h"
#include "struct.h"
#include "proto.h"
#if defined(COMPILER_MSC)
#define rint(x) ((idxtype)((x)+0.5)) /* MSC does not have rint() function */
#endif
#if defined(COMPILER_GCC)
extern char* strdup (const char *);
#endif

View File

@ -0,0 +1,146 @@
/*
* Copyright 1997, Regents of the University of Minnesota
*
* metis.c
*
* This file contains the driving routine for multilevel method
*
* Started 8/28/94
* George
*
* $Id: mmetis.c,v 1.2 2002/08/10 06:02:53 karypis Exp $
*
*/
#include <metisbin.h>
/*************************************************************************
* Let the game begin
**************************************************************************/
int main(int argc, char *argv[])
{
idxtype i, j, nparts, OpType, options[10], nbytes;
idxtype *part, *perm, *iperm, *sizes;
GraphType graph;
char filename[256];
idxtype numflag = 0, wgtflag = 0, edgecut;
idxtype *mvwgt, *vwgt, *vsize;
float rubvec[MAXNCON];
if (argc < 8) {
mprintf("Usage: %s <GraphFile> <Nparts> <Mtype> <Rtype> <IPtype> <OpType> <Options> \n",argv[0]);
exit(0);
}
strcpy(filename, argv[1]);
nparts = atoi(argv[2]);
options[OPTION_CTYPE] = atoi(argv[3]);
options[OPTION_RTYPE] = atoi(argv[4]);
options[OPTION_ITYPE] = atoi(argv[5]);
OpType = atoi(argv[6]);
options[OPTION_DBGLVL] = atoi(argv[7]);
ReadGraph(&graph, filename, &wgtflag);
if (graph.nvtxs <= 0) {
mprintf("Empty graph. Nothing to do.\n");
exit(0);
}
mprintf("Partitioning a graph with %D vertices and %D edges. Constraints: %D\n", graph.nvtxs, graph.nedges/2, graph.ncon);
part = perm = iperm = NULL;
vsize = NULL;
options[0] = 1;
switch (OpType) {
case OP_PMETIS:
mprintf("Recursive Partitioning... ------------------------------------------\n");
part = idxmalloc(graph.nvtxs, "main: part");
METIS_mCPartGraphRecursive(&graph.nvtxs, &graph.ncon, graph.xadj, graph.adjncy,
graph.vwgt, graph.adjwgt, &wgtflag, &numflag, &nparts, options, &edgecut, part);
IFSET(options[OPTION_DBGLVL], DBG_OUTPUT, WritePartition(filename, part, graph.nvtxs, nparts));
mprintf(" %D-way Edge-Cut: %7D\n", nparts, edgecut);
ComputePartitionInfo(&graph, nparts, part);
gk_free((void **)&part, LTERM);
break;
case OP_KMETIS:
mprintf("K-way Partitioning... ----------------------------------------------\n");
part = idxmalloc(graph.nvtxs, "main: part");
if (argc != 8+graph.ncon)
errexit("You must supply %d ub constraints!\n", graph.ncon);
for (i=0; i<graph.ncon; i++)
rubvec[i] = atof(argv[8+i]);
METIS_mCPartGraphKway(&graph.nvtxs, &graph.ncon, graph.xadj, graph.adjncy, graph.vwgt,
graph.adjwgt, &wgtflag, &numflag, &nparts, rubvec, options, &edgecut, part);
IFSET(options[OPTION_DBGLVL], DBG_OUTPUT, WritePartition(filename, part, graph.nvtxs, nparts));
mprintf(" %D-way Edge-Cut: %7D \tUBVec: ", nparts, edgecut);
for (i=0; i<graph.ncon; i++)
mprintf("%.3f ", rubvec[i]);
mprintf("\n");
ComputePartitionInfo(&graph, nparts, part);
if (options[OPTION_DBGLVL]&1024) {
/* Partition each objective separately and see the results */
vwgt = idxmalloc(graph.nvtxs, "vwgt");
for (j=0; j<graph.ncon; j++) {
for (i=0; i<graph.nvtxs; i++)
vwgt[i] = graph.vwgt[i*graph.ncon+j];
options[0] = 0;
METIS_PartGraphKway(&graph.nvtxs, graph.xadj, graph.adjncy, vwgt, graph.adjwgt,
&wgtflag, &numflag, &nparts, options, &edgecut, part);
mprintf("Partitioning using constrain %D ------------------------------------\n", j);
ComputePartitionInfo(&graph, nparts, part);
}
gk_free((void **)&vwgt, LTERM);
}
gk_free((void **)&part, LTERM);
break;
case 3:
mprintf("Recursive Partitioning... -----------------------------------------\n");
part = idxmalloc(graph.nvtxs, "main: part");
if (argc != 8+graph.ncon)
errexit("You must supply %d ub constraints!\n", graph.ncon);
for (i=0; i<graph.ncon; i++)
rubvec[i] = atof(argv[8+i]);
METIS_mCHPartGraphRecursive(&graph.nvtxs, &graph.ncon, graph.xadj, graph.adjncy,
graph.vwgt, graph.adjwgt, &wgtflag, &numflag, &nparts, rubvec, options, &edgecut, part);
IFSET(options[OPTION_DBGLVL], DBG_OUTPUT, WritePartition(filename, part, graph.nvtxs, nparts));
mprintf(" %D-way Edge-Cut: %7D \tUBVec: ", nparts, edgecut);
for (i=0; i<graph.ncon; i++)
mprintf("%.3f ", rubvec[i]);
mprintf("\n");
ComputePartitionInfo(&graph, nparts, part);
gk_free((void **)&part, LTERM);
break;
default:
errexit("Unknown");
}
gk_free((void **)&graph.xadj, &graph.adjncy, &graph.vwgt, &graph.adjwgt, LTERM);
}

View File

@ -0,0 +1,95 @@
/*
* Copyright 1997, Regents of the University of Minnesota
*
* oemetis.c
*
* This file contains the driving routine for multilevel method
*
* Started 8/28/94
* George
*
* $Id: oemetis.c,v 1.2 2002/08/10 06:02:53 karypis Exp $
*
*/
#include <metisbin.h>
/*************************************************************************
* Let the game begin
**************************************************************************/
int main(int argc, char *argv[])
{
idxtype i, options[10];
idxtype *perm, *iperm;
GraphType graph;
char filename[256];
idxtype numflag = 0, wgtflag;
double TOTALTmr, METISTmr, IOTmr, SMBTmr;
if (argc != 2) {
mprintf("Usage: %s <GraphFile>\n",argv[0]);
exit(0);
}
strcpy(filename, argv[1]);
gk_clearcputimer(TOTALTmr);
gk_clearcputimer(METISTmr);
gk_clearcputimer(IOTmr);
gk_clearcputimer(SMBTmr);
gk_startcputimer(TOTALTmr);
gk_startcputimer(IOTmr);
ReadGraph(&graph, filename, &wgtflag);
if (graph.nvtxs <= 0) {
mprintf("Empty graph. Nothing to do.\n");
exit(0);
}
if (graph.ncon != 1) {
mprintf("Ordering can only be applied to graphs with one constraint.\n");
exit(0);
}
gk_stopcputimer(IOTmr);
/* Ordering does not use weights! */
gk_free((void **)&graph.vwgt, &graph.adjwgt, LTERM);
mprintf("**********************************************************************\n");
mprintf("%s", METISTITLE);
mprintf("Graph Information ---------------------------------------------------\n");
mprintf(" Name: %s, #Vertices: %D, #Edges: %D\n\n", filename, graph.nvtxs, graph.nedges/2);
mprintf("Edge-Based Ordering... ----------------------------------------------\n");
perm = idxmalloc(graph.nvtxs, "main: perm");
iperm = idxmalloc(graph.nvtxs, "main: iperm");
options[0] = 0;
gk_startcputimer(METISTmr);
METIS_EdgeND(&graph.nvtxs, graph.xadj, graph.adjncy, &numflag, options, perm, iperm);
gk_stopcputimer(METISTmr);
gk_startcputimer(IOTmr);
WritePermutation(filename, iperm, graph.nvtxs);
gk_stopcputimer(IOTmr);
gk_startcputimer(SMBTmr);
ComputeFillIn(&graph, iperm);
gk_stopcputimer(SMBTmr);
gk_stopcputimer(TOTALTmr);
mprintf("\nTiming Information --------------------------------------------------\n");
mprintf(" I/O: \t %7.3f\n", gk_getcputimer(IOTmr));
mprintf(" Ordering: \t %7.3f (OEMETIS time)\n", gk_getcputimer(METISTmr));
mprintf(" Symbolic Factorization: \t %7.3f\n", gk_getcputimer(SMBTmr));
mprintf(" Total: \t %7.3f\n", gk_getcputimer(TOTALTmr));
mprintf("**********************************************************************\n");
gk_free((void **)&graph.xadj, &graph.adjncy, &perm, &iperm, LTERM);
}

View File

@ -0,0 +1,95 @@
/*
* Copyright 1997, Regents of the University of Minnesota
*
* onmetis.c
*
* This file contains the driving routine for multilevel method
*
* Started 8/28/94
* George
*
* $Id: onmetis.c,v 1.2 2002/08/10 06:02:53 karypis Exp $
*
*/
#include <metisbin.h>
/*************************************************************************
* Let the game begin
**************************************************************************/
int main(int argc, char *argv[])
{
idxtype i, options[10];
idxtype *perm, *iperm;
GraphType graph;
char filename[256];
idxtype numflag = 0, wgtflag;
double TOTALTmr, METISTmr, IOTmr, SMBTmr;
if (argc != 2) {
mprintf("Usage: %s <GraphFile>\n",argv[0]);
exit(0);
}
strcpy(filename, argv[1]);
gk_clearcputimer(TOTALTmr);
gk_clearcputimer(METISTmr);
gk_clearcputimer(IOTmr);
gk_clearcputimer(SMBTmr);
gk_startcputimer(TOTALTmr);
gk_startcputimer(IOTmr);
ReadGraph(&graph, filename, &wgtflag);
if (graph.nvtxs <= 0) {
mprintf("Empty graph. Nothing to do.\n");
exit(0);
}
if (graph.ncon != 1) {
mprintf("Ordering can only be applied to graphs with one constraint.\n");
exit(0);
}
gk_stopcputimer(IOTmr);
/* Ordering does not use weights! */
gk_free((void **)&graph.vwgt, &graph.adjwgt, LTERM);
mprintf("**********************************************************************\n");
mprintf("%s", METISTITLE);
mprintf("Graph Information ---------------------------------------------------\n");
mprintf(" Name: %s, #Vertices: %D, #Edges: %D\n\n", filename, graph.nvtxs, graph.nedges/2);
mprintf("Node-Based Ordering... ----------------------------------------------\n");
perm = idxmalloc(graph.nvtxs, "main: perm");
iperm = idxmalloc(graph.nvtxs, "main: iperm");
options[0] = 0;
gk_startcputimer(METISTmr);
METIS_NodeND(&graph.nvtxs, graph.xadj, graph.adjncy, &numflag, options, perm, iperm);
gk_stopcputimer(METISTmr);
gk_startcputimer(IOTmr);
WritePermutation(filename, iperm, graph.nvtxs);
gk_stopcputimer(IOTmr);
gk_startcputimer(SMBTmr);
ComputeFillIn(&graph, iperm);
gk_stopcputimer(SMBTmr);
gk_stopcputimer(TOTALTmr);
mprintf("\nTiming Information --------------------------------------------------\n");
mprintf(" I/O: \t %7.3f\n", gk_getcputimer(IOTmr));
mprintf(" Ordering: \t %7.3f (ONMETIS time)\n", gk_getcputimer(METISTmr));
mprintf(" Symbolic Factorization: \t %7.3f\n", gk_getcputimer(SMBTmr));
mprintf(" Total: \t %7.3f\n", gk_getcputimer(TOTALTmr));
mprintf("**********************************************************************\n");
gk_free((void **)&graph.xadj, &graph.adjncy, &perm, &iperm, LTERM);
}

View File

@ -0,0 +1,122 @@
/*
* Copyright 1997, Regents of the University of Minnesota
*
* partdmesh.c
*
* This file reads in the element node connectivity array of a mesh and
* partitions both the elements and the nodes using KMETIS on the dual graph.
*
* Started 9/29/97
* George
*
* $Id: partdmesh.c,v 1.2 2002/08/10 06:02:54 karypis Exp $
*
*/
#include <metisbin.h>
/*************************************************************************
* Let the game begin
**************************************************************************/
int main(int argc, char *argv[])
{
idxtype i, j, ne, nn, etype, mtype, numflag=0, nparts, edgecut, custom=0;
idxtype *elmnts, *epart, *npart, *metype, *conmat, *weights;
double IOTmr, DUALTmr;
char etypestr[5][5] = {"TRI", "TET", "HEX", "QUAD", "LINE"};
GraphType graph;
if (argc < 3) {
mprintf("Usage: %s <meshfile> <nparts> [confile]\n",argv[0]);
exit(0);
}
nparts = atoi(argv[2]);
if (nparts < 2) {
mprintf("nparts must be greater than one.\n");
exit(0);
}
mtype=MeshType(argv[1]);
ne=MixedElements(argv[1]);
metype = idxmalloc(ne, "main: metype");
weights = idxmalloc(ne, "main: weights");
gk_clearcputimer(IOTmr);
gk_clearcputimer(DUALTmr);
gk_startcputimer(IOTmr);
if(mtype==1)
elmnts = ReadMesh(argv[1], &ne, &nn, &etype);
else if(mtype==3)
elmnts = ReadMeshWgt(argv[1], &ne, &nn, &etype, weights);
else if(mtype==0)
elmnts = ReadMixedMesh(argv[1], &ne, &nn, metype);
else
elmnts = ReadMixedMeshWgt(argv[1], &ne, &nn, metype, weights);
if (argc==4){
conmat = ReadMgcnums(argv[2]);
custom=1;
}
gk_stopcputimer(IOTmr);
epart = idxmalloc(ne, "main: epart");
npart = idxmalloc(nn, "main: npart");
mprintf("**********************************************************************\n");
mprintf("%s", METISTITLE);
mprintf("Mesh Information ----------------------------------------------------\n");
if (mtype==1)
mprintf(" Name: %s, #Elements: %D, #Nodes: %D, Etype: %s\n\n", argv[1], ne, nn, etypestr[etype-1]);
else
mprintf(" Name: %s, #Elements: %D, #Nodes: %D, Etype: %s\n\n", argv[1], ne, nn, "Mixed");
mprintf("Partitioning Dual Graph... ------------------------------------------\n");
gk_startcputimer(DUALTmr);
if (mtype==1)
METIS_PartMeshDual(&ne, &nn, elmnts, &etype, &numflag, &nparts, &edgecut, epart, npart, 0, NULL);
else if (mtype==3)
METIS_PartMeshDual(&ne, &nn, elmnts, &etype, &numflag, &nparts, &edgecut, epart, npart, 2, weights);
else if (mtype==0)
METIS_PartMixedMeshDual(&ne, &nn, elmnts, metype, &numflag, &nparts, &edgecut, epart, npart, conmat, custom, 0, NULL);
else
METIS_PartMixedMeshDual(&ne, &nn, elmnts, metype, &numflag, &nparts, &edgecut, epart, npart, conmat, custom, 2, weights);
gk_stopcputimer(DUALTmr);
mprintf(" %D-way Edge-Cut: %7D, Balance: %5.2f\n", nparts, edgecut, ComputeElementBalance(ne, nparts, epart));
gk_startcputimer(IOTmr);
WriteMeshPartition(argv[1], nparts, ne, epart, nn, npart);
gk_stopcputimer(IOTmr);
mprintf("\nTiming Information --------------------------------------------------\n");
mprintf(" I/O: \t\t %7.3f\n", gk_getcputimer(IOTmr));
mprintf(" Partitioning: \t\t %7.3f\n", gk_getcputimer(DUALTmr));
mprintf("**********************************************************************\n");
/*
graph.nvtxs = nn;
graph.xadj = idxmalloc(nn+1, "xadj");
graph.vwgt = idxsmalloc(nn, 1, "vwgt");
graph.adjncy = idxmalloc(20*nn, "adjncy");
graph.adjwgt = idxsmalloc(20*nn, 1, "adjncy");
METIS_MeshToNodal(&ne, &nn, elmnts, &etype, &numflag, graph.xadj, graph.adjncy);
ComputePartitionInfo(&graph, nparts, npart);
gk_free((void **)&graph.xadj, &graph.adjncy, &graph.vwgt, &graph.adjwgt, LTERM);
*/
gk_free((void **)&elmnts, &epart, &npart, &metype, &weights, LTERM);
}

View File

@ -0,0 +1,117 @@
/*
* Copyright 1997, Regents of the University of Minnesota
*
* partnmesh.c
*
* This file reads in the element node connectivity array of a mesh and
* partitions both the elements and the nodes using KMETIS on the dual graph.
*
* Started 9/29/97
* George
*
* $Id: partnmesh.c,v 1.2 2002/08/10 06:02:54 karypis Exp $
*
*/
#include <metisbin.h>
/*************************************************************************
* Let the game begin
**************************************************************************/
int main(int argc, char *argv[])
{
idxtype i, j, ne, nn, etype, mtype, numflag=0, nparts, edgecut;
idxtype *elmnts, *epart, *npart, *metype, *weights;
double IOTmr, DUALTmr;
char etypestr[5][5] = {"TRI", "TET", "HEX", "QUAD", "LINE"};
GraphType graph;
if (argc != 3) {
mprintf("Usage: %s <meshfile> <nparts>\n",argv[0]);
exit(0);
}
nparts = atoi(argv[2]);
if (nparts < 2) {
mprintf("nparts must be greater than one.\n");
exit(0);
}
gk_clearcputimer(IOTmr);
gk_clearcputimer(DUALTmr);
mtype=MeshType(argv[1]);
ne=MixedElements(argv[1]);
metype = idxmalloc(ne, "main: metype");
weights = idxmalloc(ne, "main: weights");
gk_startcputimer(IOTmr);
if(mtype==1)
elmnts = ReadMesh(argv[1], &ne, &nn, &etype);
else if(mtype==3)
elmnts = ReadMeshWgt(argv[1], &ne, &nn, &etype, weights);
else if(mtype==0)
elmnts = ReadMixedMesh(argv[1], &ne, &nn, metype);
else
elmnts = ReadMixedMeshWgt(argv[1], &ne, &nn, metype, weights);
gk_stopcputimer(IOTmr);
epart = idxmalloc(ne, "main: epart");
npart = idxmalloc(nn, "main: npart");
mprintf("**********************************************************************\n");
mprintf("%s", METISTITLE);
mprintf("Mesh Information ----------------------------------------------------\n");
if (mtype==1)
mprintf(" Name: %s, #Elements: %D, #Nodes: %D, Etype: %s\n\n", argv[1], ne, nn, etypestr[etype-1]);
else
mprintf(" Name: %s, #Elements: %D, #Nodes: %D, Etype: %s\n\n", argv[1], ne, nn, "Mixed");
mprintf("Partitioning Nodal Graph... -----------------------------------------\n");
gk_startcputimer(DUALTmr);
if (mtype==1 || mtype==3)
METIS_PartMeshNodal(&ne, &nn, elmnts, &etype, &numflag, &nparts, &edgecut, epart, npart);
else
METIS_PartMixedMeshNodal(&ne, &nn, elmnts, metype, &numflag, &nparts, &edgecut, epart, npart);
gk_stopcputimer(DUALTmr);
mprintf(" %D-way Edge-Cut: %7D, Balance: %5.2f\n", nparts, edgecut, ComputeElementBalance(ne, nparts, epart));
gk_startcputimer(IOTmr);
WriteMeshPartition(argv[1], nparts, ne, epart, nn, npart);
gk_stopcputimer(IOTmr);
mprintf("\nTiming Information --------------------------------------------------\n");
mprintf(" I/O: \t\t %7.3f\n", gk_getcputimer(IOTmr));
mprintf(" Partitioning: \t\t %7.3f\n", gk_getcputimer(DUALTmr));
mprintf("**********************************************************************\n");
/*
graph.nvtxs = ne;
graph.xadj = idxmalloc(ne+1, "xadj");
graph.vwgt = idxsmalloc(ne, 1, "vwgt");
graph.adjncy = idxmalloc(10*ne, "adjncy");
graph.adjwgt = idxsmalloc(10*ne, 1, "adjncy");
METIS_MeshToDual(&ne, &nn, elmnts, &etype, &numflag, graph.xadj, graph.adjncy);
ComputePartitionInfo(&graph, nparts, epart);
gk_free((void **)&graph.xadj, &graph.adjncy, &graph.vwgt, &graph.adjwgt, LTERM);
*/
gk_free((void **)&elmnts, &epart, &npart, &metype, &weights, LTERM);
}

View File

@ -0,0 +1,105 @@
/*
* Copyright 1997, Regents of the University of Minnesota
*
* pmetis.c
*
* This file contains the driving routine for multilevel method
*
* Started 8/28/94
* George
*
* $Id: pmetis.c,v 1.3 2002/08/10 06:57:51 karypis Exp $
*
*/
#include <metisbin.h>
/*************************************************************************
* Let the game begin
**************************************************************************/
int main(int argc, char *argv[])
{
idxtype i, options[10];
idxtype *part;
float lbvec[MAXNCON];
GraphType graph;
idxtype numflag = 0, wgtflag = 0, edgecut;
ParamType params;
double TOTALTmr, METISTmr, IOTmr;
parse_cmdline(&params, argc, argv);
if (params.nparts < 2) {
mprintf("The number of partitions should be greater than 1!\n");
exit(0);
}
gk_clearcputimer(TOTALTmr);
gk_clearcputimer(METISTmr);
gk_clearcputimer(IOTmr);
gk_startcputimer(TOTALTmr);
gk_startcputimer(IOTmr);
ReadGraph(&graph, params.filename, &wgtflag);
if (graph.nvtxs <= 0) {
mprintf("Empty graph. Nothing to do.\n");
exit(0);
}
gk_stopcputimer(IOTmr);
mprintf("**********************************************************************\n");
mprintf("%s", METISTITLE);
mprintf("Graph Information ---------------------------------------------------\n");
mprintf(" Name: %s, #Vertices: %D, #Edges: %D, #Parts: %D\n", params.filename, graph.nvtxs, graph.nedges/2, params.nparts);
if (graph.ncon > 1)
mprintf(" Balancing Constraints: %D\n", graph.ncon);
mprintf("\nRecursive Partitioning... -------------------------------------------\n");
part = idxmalloc(graph.nvtxs, "main: part");
options[0] = 0;
options[0] = 1;
options[OPTION_CTYPE] = params.mtype;
options[OPTION_ITYPE] = params.itype;
options[OPTION_RTYPE] = params.rtype;
options[OPTION_DBGLVL] = params.dbglvl;
gk_startcputimer(METISTmr);
if (graph.ncon == 1) {
METIS_PartGraphRecursive(&graph.nvtxs, graph.xadj, graph.adjncy, graph.vwgt, graph.adjwgt,
&wgtflag, &numflag, &(params.nparts), options, &edgecut, part);
}
else {
METIS_mCPartGraphRecursive(&graph.nvtxs, &graph.ncon, graph.xadj, graph.adjncy, graph.vwgt,
graph.adjwgt, &wgtflag, &numflag, &(params.nparts), options, &edgecut, part);
}
gk_stopcputimer(METISTmr);
ComputePartitionBalance(&graph, params.nparts, part, lbvec);
mprintf(" %D-way Edge-Cut: %7D, Balance: ", params.nparts, edgecut);
for (i=0; i<graph.ncon; i++)
mprintf("%5.2f ", lbvec[i]);
mprintf("\n");
gk_startcputimer(IOTmr);
WritePartition(params.filename, part, graph.nvtxs, params.nparts);
gk_stopcputimer(IOTmr);
gk_stopcputimer(TOTALTmr);
mprintf("\nTiming Information --------------------------------------------------\n");
mprintf(" I/O: \t\t %7.3f\n", gk_getcputimer(IOTmr));
mprintf(" Partitioning: \t\t %7.3f (PMETIS time)\n", gk_getcputimer(METISTmr));
mprintf(" Total: \t\t %7.3f\n", gk_getcputimer(TOTALTmr));
mprintf("**********************************************************************\n");
gk_free((void **)&graph.xadj, &graph.adjncy, &graph.vwgt, &graph.adjwgt, &part, LTERM);
}

View File

@ -0,0 +1,47 @@
/*
* proto.h
*
* This file contains function prototypes
*
* Started 11/1/99
* George
*
* $Id: proto.h,v 1.15 2003/04/04 23:22:49 karypis Exp $
*
*/
#ifndef _PROTOBIN_H_
#define _PROTOBIN_H_
/* io.c */
void ReadGraph(GraphType *, char *, idxtype *);
void ReadCoordinates(GraphType *, char *);
void WritePartition(char *, idxtype *, idxtype, idxtype);
void WriteMeshPartition(char *, idxtype, idxtype, idxtype *, idxtype, idxtype *);
void WritePermutation(char *, idxtype *, idxtype);
int CheckGraph(GraphType *);
int MeshType(char *);
idxtype *ReadWgt(char *, idxtype *, idxtype *, idxtype *);
idxtype *ReadMesh(char *, idxtype *, idxtype *, idxtype *);
idxtype *ReadMeshWgt(char *, idxtype *, idxtype *, idxtype *, idxtype *);
idxtype *ReadMixedMesh(char *, idxtype *, idxtype *, idxtype *);
idxtype *ReadMixedMeshWgt(char *, idxtype *, idxtype *, idxtype *, idxtype *);
void WriteGraph(char *, idxtype, idxtype *, idxtype *);
idxtype MixedElements(char *);
idxtype *ReadMgcnums(char *);
void WriteWgtGraph(char *, idxtype , idxtype *, idxtype *, idxtype *);
/* smbfactor.c */
void ComputeFillIn(GraphType *, idxtype *);
idxtype ComputeFillIn2(GraphType *, idxtype *);
idxtype smbfct(idxtype, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *);
/* cmdline.c */
void parse_cmdline(ParamType *params, int argc, char *argv[]);
/* cpmetis.c */
#endif

View File

@ -0,0 +1,385 @@
/*
* Copyright 1997, Regents of the University of Minnesota
*
* smbfactor.c
*
* This file performs the symbolic factorization of a matrix
*
* Started 8/1/97
* George
*
* $Id: smbfactor.c,v 1.2 2002/08/10 06:02:55 karypis Exp $
*
*/
#include <metisbin.h>
/*************************************************************************
* This function sets up data structures for fill-in computations
**************************************************************************/
void ComputeFillIn(GraphType *graph, idxtype *iperm)
{
idxtype i, j, k, nvtxs, maxlnz, maxsub;
idxtype *xadj, *adjncy;
idxtype *perm, *xlnz, *xnzsub, *nzsub;
double opc;
/*
mprintf("\nSymbolic factorization... --------------------------------------------\n");
*/
nvtxs = graph->nvtxs;
xadj = graph->xadj;
adjncy = graph->adjncy;
maxsub = 4*xadj[nvtxs];
/* Relabel the vertices so that it starts from 1 */
k = xadj[nvtxs];
for (i=0; i<k; i++)
adjncy[i]++;
for (i=0; i<nvtxs+1; i++)
xadj[i]++;
/* Allocate the required memory */
perm = idxmalloc(nvtxs+1, "ComputeFillIn: perm");
xlnz = idxmalloc(nvtxs+1, "ComputeFillIn: xlnz");
xnzsub = idxmalloc(nvtxs+1, "ComputeFillIn: xnzsub");
nzsub = idxmalloc(maxsub, "ComputeFillIn: nzsub");
/* Construct perm from iperm and change the numbering of iperm */
for (i=0; i<nvtxs; i++)
perm[iperm[i]] = i;
for (i=0; i<nvtxs; i++) {
iperm[i]++;
perm[i]++;
}
/*
* Call sparspak routine.
*/
if (smbfct(nvtxs, xadj, adjncy, perm, iperm, xlnz, &maxlnz, xnzsub, nzsub, &maxsub)) {
gk_free((void **)&nzsub, LTERM);
maxsub = 4*maxsub;
nzsub = idxmalloc(maxsub, "ComputeFillIn: nzsub");
if (smbfct(nvtxs, xadj, adjncy, perm, iperm, xlnz, &maxlnz, xnzsub, nzsub, &maxsub))
errexit("MAXSUB is too small!");
}
opc = 0;
for (i=0; i<nvtxs; i++)
xlnz[i]--;
for (i=0; i<nvtxs; i++)
opc += (xlnz[i+1]-xlnz[i])*(xlnz[i+1]-xlnz[i]) - (xlnz[i+1]-xlnz[i]);
mprintf(" Nonzeros: %D, \tOperation Count: %6.4le\n", maxlnz, opc);
gk_free((void **)&perm, &xlnz, &xnzsub, &nzsub, LTERM);
/* Relabel the vertices so that it starts from 0 */
for (i=0; i<nvtxs; i++)
iperm[i]--;
for (i=0; i<nvtxs+1; i++)
xadj[i]--;
k = xadj[nvtxs];
for (i=0; i<k; i++)
adjncy[i]--;
}
/*************************************************************************
* This function sets up data structures for fill-in computations
**************************************************************************/
idxtype ComputeFillIn2(GraphType *graph, idxtype *iperm)
{
idxtype i, j, k, nvtxs, maxlnz, maxsub;
idxtype *xadj, *adjncy;
idxtype *perm, *xlnz, *xnzsub, *nzsub;
double opc;
nvtxs = graph->nvtxs;
xadj = graph->xadj;
adjncy = graph->adjncy;
maxsub = 4*xadj[nvtxs];
/* Relabel the vertices so that it starts from 1 */
k = xadj[nvtxs];
for (i=0; i<k; i++)
adjncy[i]++;
for (i=0; i<nvtxs+1; i++)
xadj[i]++;
/* Allocate the required memory */
perm = idxmalloc(nvtxs+1, "ComputeFillIn: perm");
xlnz = idxmalloc(nvtxs+1, "ComputeFillIn: xlnz");
xnzsub = idxmalloc(nvtxs+1, "ComputeFillIn: xnzsub");
nzsub = idxmalloc(maxsub, "ComputeFillIn: nzsub");
/* Construct perm from iperm and change the numbering of iperm */
for (i=0; i<nvtxs; i++)
perm[iperm[i]] = i;
for (i=0; i<nvtxs; i++) {
iperm[i]++;
perm[i]++;
}
/*
* Call sparspak routine.
*/
if (smbfct(nvtxs, xadj, adjncy, perm, iperm, xlnz, &maxlnz, xnzsub, nzsub, &maxsub)) {
gk_free((void **)&nzsub, LTERM);
maxsub = 4*maxsub;
nzsub = idxmalloc(maxsub, "ComputeFillIn: nzsub");
if (smbfct(nvtxs, xadj, adjncy, perm, iperm, xlnz, &maxlnz, xnzsub, nzsub, &maxsub))
errexit("MAXSUB is too small!");
}
opc = 0;
for (i=0; i<nvtxs; i++)
xlnz[i]--;
for (i=0; i<nvtxs; i++)
opc += (xlnz[i+1]-xlnz[i])*(xlnz[i+1]-xlnz[i]) - (xlnz[i+1]-xlnz[i]);
gk_free((void **)&perm, &xlnz, &xnzsub, &nzsub, LTERM);
/* Relabel the vertices so that it starts from 0 */
for (i=0; i<nvtxs; i++)
iperm[i]--;
for (i=0; i<nvtxs+1; i++)
xadj[i]--;
k = xadj[nvtxs];
for (i=0; i<k; i++)
adjncy[i]--;
return maxlnz;
}
/*****************************************************************
********** SMBFCT ..... SYMBOLIC FACTORIZATION *********
******************************************************************
* PURPOSE - THIS ROUTINE PERFORMS SYMBOLIC FACTORIZATION
* ON A PERMUTED LINEAR SYSTEM AND IT ALSO SETS UP THE
* COMPRESSED DATA STRUCTURE FOR THE SYSTEM.
*
* INPUT PARAMETERS -
* NEQNS - NUMBER OF EQUATIONS.
* (XADJ, ADJNCY) - THE ADJACENCY STRUCTURE.
* (PERM, INVP) - THE PERMUTATION VECTOR AND ITS INVERSE.
*
* UPDATED PARAMETERS -
* MAXSUB - SIZE OF THE SUBSCRIPT ARRAY NZSUB. ON RETURN,
* IT CONTAINS THE NUMBER OF SUBSCRIPTS USED
*
* OUTPUT PARAMETERS -
* XLNZ - INDEX INTO THE NONZERO STORAGE VECTOR LNZ.
* (XNZSUB, NZSUB) - THE COMPRESSED SUBSCRIPT VECTORS.
* MAXLNZ - THE NUMBER OF NONZEROS FOUND.
*
*******************************************************************/
idxtype smbfct(idxtype neqns, idxtype *xadj, idxtype *adjncy, idxtype *perm, idxtype *invp,
idxtype *xlnz, idxtype *maxlnz, idxtype *xnzsub, idxtype *nzsub, idxtype *maxsub)
{
/* Local variables */
idxtype node, rchm, mrgk, lmax, i, j, k, m, nabor, nzbeg, nzend;
idxtype kxsub, jstop, jstrt, mrkflg, inz, knz, flag;
idxtype *mrglnk, *marker, *rchlnk;
rchlnk = idxmalloc(neqns+1, "smbfct: rchlnk");
marker = idxsmalloc(neqns+1, 0, "smbfct: marker");
mrglnk = idxsmalloc(neqns+1, 0, "smbfct: mgrlnk");
/* Parameter adjustments */
--marker;
--mrglnk;
--rchlnk;
--nzsub;
--xnzsub;
--xlnz;
--invp;
--perm;
--adjncy;
--xadj;
/* Function Body */
flag = 0;
nzbeg = 1;
nzend = 0;
xlnz[1] = 1;
/* FOR EACH COLUMN KNZ COUNTS THE NUMBER OF NONZEROS IN COLUMN K ACCUMULATED IN RCHLNK. */
for (k = 1; k <= neqns; ++k) {
knz = 0;
mrgk = mrglnk[k];
mrkflg = 0;
marker[k] = k;
if (mrgk != 0)
marker[k] = marker[mrgk];
xnzsub[k] = nzend;
node = perm[k];
if (xadj[node] >= xadj[node+1]) {
xlnz[k+1] = xlnz[k];
continue;
}
/* USE RCHLNK TO LINK THROUGH THE STRUCTURE OF A(*,K) BELOW DIAGONAL */
rchlnk[k] = neqns+1;
for (j=xadj[node]; j<xadj[node+1]; j++) {
nabor = invp[adjncy[j]];
if (nabor <= k)
continue;
rchm = k;
do {
m = rchm;
rchm = rchlnk[m];
} while (rchm <= nabor);
knz++;
rchlnk[m] = nabor;
rchlnk[nabor] = rchm;
if (marker[nabor] != marker[k])
mrkflg = 1;
}
/* TEST FOR MASS SYMBOLIC ELIMINATION */
lmax = 0;
if (mrkflg != 0 || mrgk == 0 || mrglnk[mrgk] != 0)
goto L350;
xnzsub[k] = xnzsub[mrgk] + 1;
knz = xlnz[mrgk + 1] - (xlnz[mrgk] + 1);
goto L1400;
/* LINK THROUGH EACH COLUMN I THAT AFFECTS L(*,K) */
L350:
i = k;
while ((i = mrglnk[i]) != 0) {
inz = xlnz[i+1] - (xlnz[i]+1);
jstrt = xnzsub[i] + 1;
jstop = xnzsub[i] + inz;
if (inz > lmax) {
lmax = inz;
xnzsub[k] = jstrt;
}
/* MERGE STRUCTURE OF L(*,I) IN NZSUB INTO RCHLNK. */
rchm = k;
for (j = jstrt; j <= jstop; ++j) {
nabor = nzsub[j];
do {
m = rchm;
rchm = rchlnk[m];
} while (rchm < nabor);
if (rchm != nabor) {
knz++;
rchlnk[m] = nabor;
rchlnk[nabor] = rchm;
rchm = nabor;
}
}
}
/* CHECK IF SUBSCRIPTS DUPLICATE THOSE OF ANOTHER COLUMN */
if (knz == lmax)
goto L1400;
/* OR IF TAIL OF K-1ST COLUMN MATCHES HEAD OF KTH */
if (nzbeg > nzend)
goto L1200;
i = rchlnk[k];
for (jstrt = nzbeg; jstrt <= nzend; ++jstrt) {
if (nzsub[jstrt] < i)
continue;
if (nzsub[jstrt] == i)
goto L1000;
else
goto L1200;
}
goto L1200;
L1000:
xnzsub[k] = jstrt;
for (j = jstrt; j <= nzend; ++j) {
if (nzsub[j] != i)
goto L1200;
i = rchlnk[i];
if (i > neqns)
goto L1400;
}
nzend = jstrt - 1;
/* COPY THE STRUCTURE OF L(*,K) FROM RCHLNK TO THE DATA STRUCTURE (XNZSUB, NZSUB) */
L1200:
nzbeg = nzend + 1;
nzend += knz;
if (nzend > *maxsub) {
flag = 1; /* Out of memory */
break;
}
i = k;
for (j=nzbeg; j<=nzend; ++j) {
i = rchlnk[i];
nzsub[j] = i;
marker[i] = k;
}
xnzsub[k] = nzbeg;
marker[k] = k;
/*
* UPDATE THE VECTOR MRGLNK. NOTE COLUMN L(*,K) JUST FOUND
* IS REQUIRED TO DETERMINE COLUMN L(*,J), WHERE
* L(J,K) IS THE FIRST NONZERO IN L(*,K) BELOW DIAGONAL.
*/
L1400:
if (knz > 1) {
kxsub = xnzsub[k];
i = nzsub[kxsub];
mrglnk[k] = mrglnk[i];
mrglnk[i] = k;
}
xlnz[k + 1] = xlnz[k] + knz;
}
if (flag == 0) {
*maxlnz = xlnz[neqns] - 1;
*maxsub = xnzsub[neqns];
xnzsub[neqns + 1] = xnzsub[neqns];
}
marker++;
mrglnk++;
rchlnk++;
nzsub++;
xnzsub++;
xlnz++;
invp++;
perm++;
adjncy++;
xadj++;
gk_free((void **)&rchlnk, &mrglnk, &marker, LTERM);
return flag;
}

View File

@ -0,0 +1,54 @@
/*
* struct.h
*
* This file contains data structures for the various programs of METIS.
*
* Started 8/9/02
* George
*
* $Id: struct.h,v 1.8 2003/04/04 23:22:50 karypis Exp $
*/
#ifndef _STRUCTBIN_H_
#define _STRUCTBIN_H_
/*************************************************************************
* The following data structure implements a string-2-idxtype mapping
* table used for parsing command-line options
**************************************************************************/
typedef struct {
char *name;
idxtype id;
} StringMapType;
/*************************************************************************
* This data structure stores the various command line arguments
**************************************************************************/
typedef struct {
idxtype mtype;
idxtype itype;
idxtype rtype;
idxtype balance;
idxtype ntrials;
idxtype niter;
idxtype seed;
idxtype dbglvl;
idxtype nparts;
char *filename;
char *xyzfilename;
char *tpwgts;
float iotimer;
float clustertimer;
float reporttimer;
} ParamType;
#endif