debian/0000775000000000000000000000000012253506725007177 5ustar debian/rules0000775000000000000000000000205411627013116010247 0ustar #!/usr/bin/make -f # This file is public domain. # where sources are DEB_SRCDIR = $(CURDIR)/ # in which directory to build DEB_BUILDDIR = $(DEB_SRCDIR)/ # in which directory to install the sofware DEB_DESTDIR = $(CURDIR)/debian/tmp #DEB_TAR_SRCDIR := parmetis-3.1 DEB_AUTO_CLEANUP_RCS := yes export MACHINE=LINUX DEB_MAKE_CLEAN_TARGET := clean DEB_MAKE_INSTALL_TARGET := #install DESTDIR=$(CURDIR)/debian/tmp/ # no check for this software DEB_MAKE_CHECK_TARGET := DEB_DH_COMPRESS_ARGS := -X pdf include /usr/share/cdbs/1/class/makefile.mk include /usr/share/cdbs/1/rules/debhelper.mk #include /usr/share/cdbs/1/rules/tarball.mk #include /usr/share/cdbs/1/rules/simple-patchsys.mk INSTALL_PROG=install -D INSTALL_DATA=install -m 644 -D #DEB_MAKE_ENVVARS := CFLAGS=-O3 -Wall CXXFLAGS=-O3 -Wall XTRALIBS=-lmpi LIBS=-lmpi LIBDIR= CPPFLAGS=-I. -I.. -I$(DEB_SRCDIR) -I/usr/include/mpi makebuilddir:: -ln -s METISLib metis -ln -s ParMETISLib parmetis clean:: -rm metis parmetis -rm ParMETISLib/ParMETISLib METISLib/METISLib debian/watch0000664000000000000000000000017311627010263010220 0ustar version=3 http://glaros.dtc.umn.edu/gkhome/metis/parmetis/download \ /gkhome/fetch/sw/parmetis/ParMetis-([\d.]+)\.tar\.gz debian/changelog0000664000000000000000000001360612253506725011057 0ustar parmetis (3.1.1-4build1) trusty; urgency=medium * No-change rebuild for libopenmpi1.3 -> libopenmpi1.6 transition. -- Logan Rosen Mon, 16 Dec 2013 00:21:14 -0500 parmetis (3.1.1-4) unstable; urgency=low * Team upload * Package migrated to the Debian Science team * Standards-Version updated to version 3.9.2 * Show compilation warnings at build time * Programs/Makefile: Explicitly link against mpi to resolve FTBFS. Thanks to Daniel T Chen for providing the patch (Closes: #639743) (LP: #832950) * Switch to dpkg-source 3.0 (quilt) format -- Sylvestre Ledru Tue, 30 Aug 2011 00:35:57 +0200 parmetis (3.1.1-3) unstable; urgency=high * Team upload * XS-Autobuild added with high priority to make it to Squeeze. Following Adam D. Barratt advices. -- Sylvestre Ledru Thu, 27 Jan 2011 23:36:35 +0100 parmetis (3.1.1-2) unstable; urgency=low * Team upload * Fix a FTBFS. Thanks to Jakub Wilk for the patch (Closes: #610956) -- Sylvestre Ledru Thu, 27 Jan 2011 09:11:56 +0100 parmetis (3.1.1-1) unstable; urgency=low [ Daniel Leidert (dale) ] * METISLib/Makefile: Link with -lm for missing symbols. * ParMETISLib/Makefile: Ditto. Further link with -lmetis. * debian/control: Added Homepage field. (Vcs-Svn): Fixed. (Depends): Fixed deprecated substvar to be binNMU safe. * debian/copyright: Added missing copyright information to make lintian happy. * debian/parmetis-doc.doc-base (Section): Fixed. * debian/watch: Added. [Christophe Prud'homme] * New upstream release * debian/control: update Standards-Version to 3.8.2 * debian/control: added ${misc:Depends} * deboan/control: use mpi-defaults * debian/rules: use /usr/include/mpi in CPPFLAGS now -- Christophe Prud'homme Wed, 29 Jul 2009 07:11:06 +0200 parmetis (3.1-10) unstable; urgency=low [Christophe Prud'homme] * debian/control,rules: support for all arch -- Christophe Prud'homme Fri, 04 Jan 2008 13:37:39 +0100 parmetis (3.1-9) unstable; urgency=low [Christophe Prud'homme] * Bug fix: "parmetis_3.1-8+b1(unstable/amd64/xenophanes): FTBFS: Doesn't search for mpi.h in right include path", thanks to Marc 'HE' Brockschmidt (Closes: #459025). * Bug fix: "parmetis: rebuild with OpenMPI", thanks to Adam C Powell IV (Closes: #447671). * Bug fix: "parmetis_3.1-8(hppa/experimental): FTBFS: new build-dep removes arch support", thanks to Frank Lichtenheld (Closes: #449018). * Update Standards-Version to 3.7.3 (no change) -- Christophe Prud'homme Fri, 04 Jan 2008 12:13:27 +0100 parmetis (3.1-8) unstable; urgency=low [Christophe Prud'homme] * debian/control: Build-Depends on openmpi, Depends on mpich or openmpi * Bug fix: "Wishlist: lam version.", thanks to Viral Shah (Closes: #200409). * debian/control: XS-Vcs* control fields replaced by their Vcs* counterparts -- Christophe Prud'homme Thu, 01 Nov 2007 10:01:57 +0100 parmetis (3.1-7) unstable; urgency=low [Christophe Prud'homme] * really fix FTBFS -- Christophe Prud'homme Sun, 15 Jul 2007 11:16:13 +0200 parmetis (3.1-6) unstable; urgency=low * Bug fix: "parmetis_3.1-5(hppa/experimental): FTBFS: error: metis/stdheaders.h: No such file or directory", thanks to Frank Lichtenheld (Closes: #432605). -- Christophe Prud'homme Wed, 11 Jul 2007 04:57:37 +0200 parmetis (3.1-5) unstable; urgency=low [ Rafael Laboissiere ] * debian/control: Added XS-Vcs-Svn and XS-Vcs-Browser fields to the Source section [ Christophe Prud'homme ] * METISLib/metis.h, ParMETISLib/parmetislib.h: make metis/parmetis headers usable -- Christophe Prud'homme Mon, 09 Jul 2007 09:38:31 +0200 parmetis (3.1-4) unstable; urgency=low * Install headers from metis and parmetis in there respective subdirectories (/usr/include/metis and /usr/include/parmetis) * Use CDBS * Updated Standards-Version to 3.7.2 (no change) * Taking over parmetis maintenance-ship -- Christophe Prud'homme Thu, 12 Oct 2006 13:49:49 +0200 parmetis (3.1-3) unstable; urgency=low * Rebuild using new mpich library package. * Fixed libparmetis-dev Depends in control. * Switched from mpicc to gcc to get shlib dependencies right. -- Adam C. Powell, IV Tue, 30 Aug 2005 13:18:35 -0400 parmetis (3.1-2) unstable; urgency=low * Declared conflict between parmetis-test and pimppa (closes: #308846). * Changed mpich build dependency to libmpich1.0-dev. * Other minor changes to dependencies. -- Adam C. Powell, IV Wed, 18 May 2005 06:40:33 -0400 parmetis (3.1-1) unstable; urgency=low * New upstream. * Removed redundant data from parmetis-test package which is already in -doc, adjusted the ptest and meshtest man pages accordingly (closes: #233428). -- Adam C. Powell, IV Wed, 18 Feb 2004 11:46:58 -0500 parmetis (3.0-3) unstable; urgency=low * Fixed parmetis.h to work with C++. (closes: #200904) * Added shared library with its very own package. * Changed name of -dev package. * Added -test package with binaries and example files from Test dir. * Added overrides files because lintian mistakenly thinks this is gpl. :-) -- Adam C. Powell, IV Thu, 7 Aug 2003 20:01:45 -0400 parmetis (3.0-2) unstable; urgency=low * New permission from upstream should result in acceptance (closes: #186116). -- Adam C. Powell, IV Tue, 8 Apr 2003 17:54:53 -0400 parmetis (3.0-1) unstable; urgency=low * First packaging attempt, first upload (closes: #186116). * Only static libraries for now, since that's all that upstream generates. -- Adam C. Powell, IV Thu, 27 Mar 2003 20:15:32 -0500 debian/libparmetis-dev.overrides0000664000000000000000000000017211627010263014201 0ustar libparmetis-dev: old-fsf-address-in-copyright-file libparmetis-dev: copyright-should-refer-to-common-license-file-for-gpl debian/compat0000664000000000000000000000000211627010263010364 0ustar 5 debian/rules.old0000664000000000000000000000426011627010263011022 0ustar #!/usr/bin/make -f # based on the sample debian/rules file for GNU hello by Ian Jackson. package=ParMetis export DH_COMPAT=5 build: dh_testdir $(MAKE) touch $@ clean: dh_testdir $(MAKE) clean rm -f build dh_clean binary-indep: dh_testdir -i dh_testroot -i dh_installdirs -i # Overrides file install -d debian/parmetis-doc/usr/share/lintian/overrides install -m 644 debian/parmetis-doc.overrides debian/parmetis-doc/usr/share/lintian/overrides/parmetis-doc dh_installdocs -i dh_installexamples -i dh_installchangelogs -i dh_compress -i dh_fixperms -i dh_installdeb -i dh_gencontrol -i dh_md5sums -i dh_builddeb -i binary-arch: dh_testdir -a dh_testroot -a dh_installdirs -a # I figure manual installation is simple enough with such small pkgs. install -d debian/libparmetis-dev/usr/lib install *.a debian/libparmetis-dev/usr/lib ln -s libmetis.so.3.1 debian/libparmetis-dev/usr/lib/libmetis.so ln -s libparmetis.so.3.1 debian/libparmetis-dev/usr/lib/libparmetis.so install -d debian/libparmetis-dev/usr/include install *.h debian/libparmetis-dev/usr/include chmod 644 debian/libparmetis-dev/usr/include/*.h install -d debian/libparmetis3.1/usr/lib cp -p *.so.* debian/libparmetis3.1/usr/lib install -d debian/parmetis-test/usr/bin install Graphs/ptest Graphs/mtest debian/parmetis-test/usr/bin # Overrides files install -d debian/libparmetis-dev/usr/share/lintian/overrides install -m 644 debian/libparmetis-dev.overrides debian/libparmetis-dev/usr/share/lintian/overrides/libparmetis-dev install -d debian/libparmetis3.1/usr/share/lintian/overrides install -m 644 debian/libparmetis3.1.overrides debian/libparmetis3.1/usr/share/lintian/overrides/libparmetis3.1 install -d debian/parmetis-test/usr/share/lintian/overrides install -m 644 debian/parmetis-test.overrides debian/parmetis-test/usr/share/lintian/overrides/parmetis-test dh_installdocs -a dh_installman -pparmetis-test debian/mtest.1 debian/ptest.1 dh_installchangelogs -a dh_strip -a dh_makeshlibs -a dh_compress -a dh_fixperms -a dh_installdeb -a dh_shlibdeps -a dh_gencontrol -a dh_md5sums -a dh_builddeb -a binary: binary-indep binary-arch .PHONY: binary binary-arch binary-indep clean checkroot debian/parmetis-test.install0000664000000000000000000000016611627010263013362 0ustar Graphs/ptest /usr/bin Graphs/mtest /usr/bin debian/mtest.1 /usr/share/man/man1 debian/ptest.1 /usr/share/man/man1 debian/libparmetis3.1.overrides0000664000000000000000000000017011627010263013645 0ustar libparmetis3.1: old-fsf-address-in-copyright-file libparmetis3.1: copyright-should-refer-to-common-license-file-for-gpl debian/mtest.10000664000000000000000000000100311627010263010376 0ustar .TH mtest 1 "ParMetis mesh partition test" "DEBIAN" \" -*- nroff -*- .SH NAME mtest \- ParMetis mesh partition test .SH SYNOPSIS \fBmtest [MagicNumber]\fP .SH DESCRIPTION This program tests partitioning of the file using the ParMetis libraries. Several sample files are located in the parmetis-doc package in the /usr/share/doc/parmetis-doc/examples directory. .PP For more information, please see the documentation in the parmetis-doc package. .SH AUTHOR Adam Powell debian/copyright0000664000000000000000000002620011627010263011121 0ustar This is non-free software written by George Karypis et al. and copyrighted by the Regents of the University of Minnesota. It was downloaded from http://www-users.cs.umn.edu/~karypis/metis/ and Debianized by Adam Powell on March 10, 2003. The included copyright notice follows, along with the email sent by Dr. Karypis authorizing distribution with Debian. Copyright Notice ---------------- Copyright 1997-2003, Regents of the University of Minnesota The ParMETIS/METIS package is copyrighted by the Regents of the University of Minnesota. It can be freely used for educational and research purposes by non-profit institutions and US government agencies only. Other organizations are allowed to use ParMETIS/METIS only for evaluation purposes, and any further uses will require prior approval. The software may not be sold or redistributed without prior approval. One may make copies of the software for their use provided that the copies, are not sold or distributed, are used under the same terms and conditions. As unestablished research software, this code is provided on an ``as is'' basis without warranty of any kind, either expressed or implied. The downloading, or executing any part of this software constitutes an implicit agreement to these terms. These terms and conditions are subject to change at any time without prior notice. X-UIDL: p0/"!p*Q"!cBh!!$<-"! X-Mozilla-Status: 0013 X-Mozilla-Status2: 00000000 Envelope-to: hazelsct@lyre.mit.edu Received: from fort-point-station.mit.edu ([18.7.7.76]) by lyre.mit.edu with esmtp (Exim 3.35 #1 (Debian)) id 192XKR-0008FG-00 for ; Mon, 07 Apr 2003 10:10:31 -0400 Received: from mhub-w2.tc.umn.edu (mhub-w2.tc.umn.edu [160.94.160.45]) by fort-point-station.mit.edu (8.12.4/8.9.2) with ESMTP id h37EAUal002913 for ; Mon, 7 Apr 2003 10:10:30 -0400 (EDT) Received: from PetrosII (falcon.cs.umn.edu [160.94.179.138] (may be forged)) by mhub-w2.tc.umn.edu with ESMTP for hazelsct@mit.edu; Mon, 7 Apr 2003 09:10:30 -0500 (CDT) From: "George Karypis" To: "'Adam C Powell IV'" Subject: RE: Distributing ParMETIS with Debian Date: Mon, 7 Apr 2003 09:08:07 -0500 Message-ID: <001b01c2fd0f$1d44a550$f88010ac@PetrosII> MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_NextPart_000_001C_01C2FCE5.346E9D50" X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook, Build 10.0.4024 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1106 In-Reply-To: <3E907557.8050800@mit.edu> Importance: Normal X-Umn-Remote-Mta: [N] falcon.cs.umn.edu #+HF+LO X-UIDL: p0/"!p*Q"!cBh!!$<-"! Status: U This is a multi-part message in MIME format. ------=_NextPart_000_001C_01C2FCE5.346E9D50 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit Adam, Yes, you have my permission to include ParMetis's source and binary distributions on Debian's mirror sites. George -----Original Message----- From: Adam C Powell IV [mailto:hazelsct@mit.edu] Sent: Sunday, April 06, 2003 1:44 PM To: George Karypis Cc: James Troup Subject: Re: Distributing ParMETIS with Debian Hello, Thank you again for granting permission to upload ParMETIS into Debian. I successfully built packages and uploaded them, but they were rejected by the archive manager, because we need to make certain of your approval for one thing not mentioned in my original message: Do you approve of the posting of ParMETIS source and binary packages on the 800+ Debian mirror servers around the world, as a means of delivery to our users? Also, I made an error in my original message: because of its non-free status, my ParMETIS packages will not be automatically built for the eleven processor architectures mentioned. I personally have the facilities to build packages for the IA-32, Alpha, PowerPC and ARM architectures, and plan to do so; when a Debian release approaches, I might also use some of the project's machines to built the final release binary packages for other popular computing architectures such as IA-64 (Itanium), Sparc, HP PA-RISC and S/390. And the package source will be available for people to build their own packages on whatever architecture they please. Again, thank you, and I will keep you informed of the package's progress. George Karypis wrote: Adam, Sure, go ahead and include ParMetis in Debian. There are a couple outstanding bugs with the current release of ParMetis that I will be fixing soon, but the changes will be minimal. George -----Original Message----- From: Adam C Powell IV [mailto:hazelsct@mit.edu] Sent: Sunday, March 23, 2003 1:42 PM To: metis@cs.umn.edu Subject: Distributing ParMETIS with Debian Greetings, I am writing to request your permission to distribute ParMETIS with Debian GNU/Linux. Debian (http://www.debian.org/) is an all-volunteer distribution of the Linux kernel with thousands of accompanying software packages, similar to but much larger than RedHat, SuSE, Mandrake, Lindows, etc. (in fact, Lindows is based on Debian's free packages). I am one of the ~850 volunteer maintainers of Debian; I maintain the PETSc and Babel packages among others. Because PETSc can link to ParMETIS, I would like to be able to include it in the Debian distribution. [I am aware of the work of Eray Ozkural to package METIS for Debian, as I was his mentor and sponsor when he was doing that work as part of the process of becoming a Debian maintainer. Unfortunately, for various reasons his application to become a maintainer was rejected, and his packages including METIS removed. This will thus be a new packaging effort by an already-approved maintainer.] Debian packages are grouped according to the "freedom" of software licenses. Since the ParMETIS license is not "free" by Debian standards (http://www.debian.org/intro/free ; basically the same as the Open Source Definition), it would go ino the "non-free" section of Debian, which would alert potential users that copying and usage are restricted, so they should check the copyright file for such terms. (The other two sections are "main", consisting entirely of free software, and "contrib", consisting of free software which depends on non-free software, e.g. when PETSc linking to ParMETIS is uploaded, its dependency on non-free ParMETIS will require moving it into contrib.) In every ParMETIS package (static libs, shared libs, documentation, etc.), your copyright conditions would appear as the file /usr/share/doc/parmetis*/copyright , and users would be bound by those terms just as if they downloaded ParMETIS from your website. When/if I receive your permission, I will upload into the Debian archive the pristine ParMETIS source tarball, together with a gzipped patch containing the Debian packaging, and a third small file with MD5 checksums of the first two and a list of Debian packages required to build ParMETIS binaries; this third file will be GPG-signed by me to guarantee the integrity of all three files. I would thus become the "Debian maintainer" of the ParMETIS package, in the same way as I am the maintainer of packages for PETSc, Babel, Surface Evolver, and installers for the Compaq Alpha Linux compilers. With your permission, I would like to make some small changes, such as building a shared ParMETIS library, and fixing any bugs I might find. I will inform you in advance of any such changes, and you will be able to exercise as much or as little control over these changes as you like. The Debian packaging mentioned above consists of a set of scripts and definition files for the building of binary Debian packages based on the source code. Taken together, these files serve a similar purpose to the spec file for creating RedHat .rpm packages, but with considerably more flexibility. The binary Debian packages will then be built by autobuilder machines for all of the target architectures, which currently include: IA-32, IA-64, Alpha, Sparc, PowerPC, M68K (yes, there are still a bunch of Amiga users around :-), MIPS (big- and little-endian), ARM, S/390 and PA-RISC; support for Hitachi SuperH and alternate kernels on some of these architectures is in the works. This packaging will make ParMETIS and packages which depend on it considerably easier to use, by allowing users to download, say, a parallel fluid dynamics package named "fluids" by typing "apt-get install fluids", which would download and install fluids, the ParMETIS library, and all other support libraries required to run fluids. Users (who run Debian) will not need to compile or link anything, this work will all be done in advance. If you (and the University of Minnesota) agree to the above, I will begin working on the Debian packaging for ParMETIS, and when that packaging is complete, will inform you and upload it into Debian. This will place ParMETIS in the "unstable" distribution immediately, and when it meets several criteria (no build failures on any architecture, no bugs of severity serious or higher, 10 days since upload into unstable), it will be moved into the "testing" distribution. If the package is in the "testing" distribution when a release is made, it will be included in that "stable" distribution release. Independent of your decision regarding Debian, I would like to request that you (U.Mn. etc.) make the METIS family available under a free/open source license of some kind. For example, the Babel SIDL compiler is released under the GNU Lesser General Public license, which among other things, eliminates the need for this sort of permission request for Debian redistribution (though I am in frequent contact with Babel's authors, and consulted them before my initial upload), and also allows me to patch it in various ways important to my users. In your case, you might be more interested in the GNU General Public License, which would not allow linking into proprietary software packages. (As the copyright holder, you could also license *METIS to companies under separate conditions.) As another example, I have simplified linking of the PETSc libraries with C++ code without the extra disk space and build time required by the authors' C++ scheme, and patched a problem in PETSc's timestepping code; both of those patches were sent to the PETSc authors. Thus open source licensing adds value to PETSc, as it does for such well-known software as Linux, Apache, Mozilla, GNOME, OpenOffice, autoconf/automake/libtool, etc., and could do the same for ParMETIS. Thank you for your time and attention. I hope that you will approve of my request to package and distribute ParMETIS with Debian, and that you will give serious consideration to open source licensing of ParMETIS. Sincerely, -- Adam Powell http://lyre.mit.edu/~powell/ Thomas B. King Assistant Professor of Materials Engineering 77 Massachusetts Ave. Rm. 4-117 Phone (617) 452-2086 Cambridge, MA 02139 USA Fax (617) 253-5418 ------=_NextPart_000_001C_01C2FCE5.346E9D50 Content-Type: text/html; charset="US-ASCII" Content-Transfer-Encoding: quoted-printable [removed to avoid having to read "MSHTML" formatted material] ------=_NextPart_000_001C_01C2FCE5.346E9D50-- debian/source/0000775000000000000000000000000011627013614010471 5ustar debian/source/format0000664000000000000000000000001411627012114011671 0ustar 3.0 (quilt) debian/libparmetis-dev.install0000664000000000000000000000031211627010263013641 0ustar *.h /usr/include METISLib/*.h /usr/include/metis ParMETISLib/*.h /usr/include/parmetis libmetis.a /usr/lib libparmetis.a /usr/lib libmetis.so /usr/lib libparmetis.so /usr/lib debian/libparmetis-dev.docs0000664000000000000000000000000711627010263013124 0ustar README debian/ptest.10000664000000000000000000000077111627010263010414 0ustar .TH ptest 1 "ParMetis graph partition test" "DEBIAN" \" -*- nroff -*- .SH NAME ptest \- ParMetis graph partition test .SH SYNOPSIS \fBptest \fP .SH DESCRIPTION This program tests partitioning of the file using the ParMetis libraries. Several sample files are located in the parmetis-doc package in the /usr/share/doc/parmetis-doc/examples directory. .PP For more information, please see the documentation in the parmetis-doc package. .SH AUTHOR Adam Powell debian/parmetis-test.overrides0000664000000000000000000000016611627010263013716 0ustar parmetis-test: old-fsf-address-in-copyright-file parmetis-test: copyright-should-refer-to-common-license-file-for-gpl debian/parmetis-doc.doc-base0000664000000000000000000000072111627010263013154 0ustar Document: parmetis-doc Title: ParMETIS Parallel Graph Partitioning and Sparse Matrix Ordering Author: George Karypis Abstract: ParMETIS is an MPI-based parallel library that implements a variety of algorithms for partitioning unstructured graphs, meshes, and for computing fill-reducing orderings of sparse matrices. Section: Science/Mathematics Format: postscript Files: /usr/share/doc/parmetis-doc/*.ps.gz Format: pdf Files: /usr/share/doc/parmetis-doc/*.pdf debian/parmetis-doc.examples0000664000000000000000000000003711627010263013315 0ustar Graphs/*.graph* Graphs/*.hex3d debian/parmetis-doc.overrides0000664000000000000000000000016411627010263013502 0ustar parmetis-doc: old-fsf-address-in-copyright-file parmetis-doc: copyright-should-refer-to-common-license-file-for-gpl debian/control0000664000000000000000000000560111627010714010574 0ustar Source: parmetis Section: non-free/math Priority: extra Maintainer: Debian Science Team Uploaders: Adam C. Powell IV , Christophe Prud'homme Standards-Version: 3.9.2 Homepage: http://glaros.dtc.umn.edu/gkhome/metis/parmetis/overview Vcs-Svn: svn://svn.debian.org/svn/debian-science/packages/parmetis/trunk/ Vcs-Browser: http://svn.debian.org/viewsvn/debian-science/packages/parmetis/trunk/ Build-Depends: cdbs, debhelper (>> 5), mpi-default-dev, mpi-default-bin XS-Autobuild: yes Package: libparmetis-dev Architecture: any Section: non-free/libdevel Depends: libparmetis3.1 (= ${binary:Version}), ${misc:Depends}, mpi-default-dev Suggests: parmetis-doc Replaces: parmetis-dev Conflicts: parmetis-dev Description: Parallel Graph Partitioning and Sparse Matrix Ordering Libs: Devel ParMetis computes minimal-cut partitions of graphs and meshes in parallel, and orders variables for minimal fill when using direct solvers for sparse matrices. It does all this in parallel, and also can efficiently re-partition a graph or mesh whose connectivity has changed. . This package contains files needed to develop programs using ParMetis. Package: libparmetis3.1 Architecture: any Section: non-free/libs Depends: ${shlibs:Depends}, ${misc:Depends}, mpi-default-dev Description: Parallel Graph Partitioning and Sparse Matrix Ordering Shared Libs ParMetis computes minimal-cut partitions of graphs and meshes in parallel, and orders variables for minimal fill when using direct solvers for sparse matrices. It does all this in parallel, and also can efficiently re-partition a graph or mesh whose connectivity has changed. . This package contains the ParMetis shared libraries. Package: parmetis-test Architecture: any Section: non-free/math Depends: ${shlibs:Depends}, ${misc:Depends}, mpi-default-bin Recommends: parmetis-doc Conflicts: pimppa Description: Parallel Graph Partitioning and Sparse Matrix Ordering Tests ParMetis computes minimal-cut partitions of graphs and meshes in parallel, and orders variables for minimal fill when using direct solvers for sparse matrices. It does all this in parallel, and also can efficiently re-partition a graph or mesh whose connectivity has changed. . This package contains programs which test the ParMetis libraries using files in the parmetis-doc package's examples directory. Package: parmetis-doc Architecture: all Depends: ${misc:Depends} Section: non-free/doc Description: Parallel Graph Partitioning and Sparse Matrix Ordering Lib - Docs ParMetis computes minimal-cut partitions of graphs and meshes in parallel, and orders variables for minimal fill when using direct solvers for sparse matrices. It does all this in parallel, and also can efficiently re-partition a graph or mesh whose connectivity has changed. . This package contains the documentation and example files. debian/parmetis-doc.docs0000664000000000000000000000002011627010263012417 0ustar README Manual/* debian/libparmetis3.1.install0000664000000000000000000000006611627010263013315 0ustar libmetis.so.* /usr/lib libparmetis.so.* /usr/lib debian/patches/0000775000000000000000000000000011627014550010620 5ustar debian/patches/debian-changes-3.1.1-40000664000000000000000000072673311627014550014214 0ustar Description: Upstream changes introduced in version 3.1.1-4 This patch has been created by dpkg-source during the package build. Here's the last changelog entry, hopefully it gives details on why those changes were made: . parmetis (3.1.1-4) unstable; urgency=low . * Team upload * Package migrated to the Debian Science team * Standards-Version updated to version 3.9.2 * Show compilation warnings at build time * Programs/Makefile: Explicitly link against mpi to resolve FTBFS. Thanks to Daniel T Chen for providing the patch (Closes: #639743) (LP: #832950) * Switch to dpkg-source 3.0 (quilt) format . The person named in the Author field signed this changelog entry. Author: Sylvestre Ledru Bug-Debian: http://bugs.debian.org/639743 Bug-Ubuntu: https://bugs.launchpad.net/bugs/832950 --- The information above should follow the Patch Tagging Guidelines, please checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here are templates for supplementary fields that you might want to add: Origin: , Bug: Bug-Debian: http://bugs.debian.org/ Bug-Ubuntu: https://launchpad.net/bugs/ Forwarded: Reviewed-By: Last-Update: --- parmetis-3.1.1.orig/COPYRIGHT +++ parmetis-3.1.1/COPYRIGHT @@ -4,7 +4,7 @@ Copyright Notice The ParMETIS/METIS package is copyrighted by the Regents of the University of Minnesota. It can be freely used for educational and research purposes by non-profit institutions and US government agencies -only. Other organizations are allowed to use ParMETIS/METIS only for +only. Other organizations are allowed to use ParMETIS/METIS only for evaluation purposes, and any further uses will require prior approval. The software may not be sold or redistributed without prior approval. One may make copies of the software for their use provided that the --- parmetis-3.1.1.orig/README +++ parmetis-3.1.1/README @@ -1,4 +1,4 @@ -This is ParMetis version 3.1.1. You can find the manual describing the +This is ParMetis version 3.1. You can find the manual describing the various routines in the directory 'Manual'. Also, the file called INSTALL contains instructions on how to build and test ParMetis. --- parmetis-3.1.1.orig/parmetis.h +++ parmetis-3.1.1/parmetis.h @@ -40,7 +40,6 @@ typedef short idxtype; **************************************************************************/ #define PARMETIS_MAJOR_VERSION 3 #define PARMETIS_MINOR_VERSION 1 -#define PARMETIS_SUBMINOR_VERSION 1 /************************************************************************* @@ -95,6 +94,7 @@ void __cdecl ParMETIS_V3_RefineKway( idxtype *part, MPI_Comm *comm); + /*------------------------------------------------------------------ * Backward compatibility routines with Release 2.0 *-------------------------------------------------------------------*/ @@ -188,16 +188,6 @@ void __cdecl PARDAMETIS( #endif -/************************************************************************* -* Various constants used for the different parameters -**************************************************************************/ -/* Matching types */ -#define PARMETIS_MTYPE_LOCAL 1 -#define PARMETIS_MTYPE_GLOBAL 2 - -/* Refinement types */ -#define PARMETIS_RTYPE_RANDOM 1 -#define PARMETIS_RTYPE_GREEDY 2 -#define PARMETIS_RTYPE_2PHASE 3 + #endif --- parmetis-3.1.1.orig/VERSION +++ parmetis-3.1.1/VERSION @@ -1,4 +1,3 @@ -ParMetis Version 3.1.1 Mon Nov 17 16:41:47 CST 2008 ParMetis Version 3.1.0 Fri Aug 15 13:59:41 CDT 2003 ParMetis Version 3.0.0 Wed Mar 27 23:56:38 CST 2002 ParMetis Version 2.0.0 Tue Sep 22 18:58:31 CDT 1998 --- parmetis-3.1.1.orig/Makefile +++ parmetis-3.1.1/Makefile @@ -6,22 +6,8 @@ default: (cd Programs ; make ) clean: - (cd METISLib ; make clean ) - (cd ParMETISLib ; make clean ) - (cd Programs ; make clean ) - -realclean: (cd METISLib ; make realclean ) (cd ParMETISLib ; make realclean ) (cd Programs ; make realclean ) -checkin: - (cd METISLib ; make checkin ) - (cd ParMETISLib ; make checkin ) - (cd Programs ; make checkin ) - -checkin2: - (cd METISLib ; make checkin2 ) - (cd ParMETISLib ; make checkin2 ) - (cd Programs ; make checkin2 ) --- parmetis-3.1.1.orig/Makefile.in +++ parmetis-3.1.1/Makefile.in @@ -1,22 +1,22 @@ # Which compiler to use -CC = mpicc +CC = gcc # What optimization level to use -OPTFLAGS = -O3 +OPTFLAGS = -O3 # Include directories for the compiler -INCDIR = +INCDIR = # What options to be used by the compiler -COPTIONS = -DNDEBUG +COPTIONS = # Which loader to use -LD = $(CC) +LD = gcc # In which directories to look for any additional libraries -LIBDIR = -L/opt/local/lib -L/usr/lib +LIBDIR = # What additional libraries to link the programs with (eg., -lmpi) #XTRALIBS = -lefence @@ -29,4 +29,4 @@ AR = ar rv #RANLIB = ranlib RANLIB = ar -ts -VERNUM = +VERNUM = --- parmetis-3.1.1.orig/CHANGES +++ parmetis-3.1.1/CHANGES @@ -1,18 +1,4 @@ -Changes in version 3.1.1 -- Fixed a number of bugs that have been reported over the years. - The following tasks correspond to the issues reported at - http://glaros.dtc.umn.edu/flyspray - - Flyspray Task 8: Fixed deallocation of user-supplied vsize - - Flyspray Task 28: Fixed ParMETIS_V3_Mesh2Dual static arrays - - Flyspray Task 30: Fixed 1025 instead of 1024 buckets - - Flyspray Task 34: Fixed writting past wspace->core for certain cases - - Flyspray Task 35: Fixed issues associated with assumed 0-based indexing - - Flyspray Task 36: Fixed mesh 1->0 numbering error -- Fixed non-utilization of the user-supplied seed for the parallel ordering - code - - Changes in version 3.1 - The mesh partitioning and dual creation routines have changed to support mixed element meshes. --- /dev/null +++ parmetis-3.1.1/METISLib/NEW_stats.c @@ -0,0 +1,44 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * stat.c + * + * This file computes various statistics + * + * Started 7/25/97 + * George + * + * $Id: NEW_stats.c,v 1.1 2003/07/16 15:55:15 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function computes the balance of the partitioning +**************************************************************************/ +void Moc_ComputePartitionBalance(GraphType *graph, int nparts, idxtype *where, float *ubvec) +{ + int i, j, nvtxs, ncon; + float *kpwgts, *nvwgt; + float balance; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + nvwgt = graph->nvwgt; + + kpwgts = fmalloc(nparts, "ComputePartitionInfo: kpwgts"); + + for (j=0; jnvtxs; i++) + kpwgts[where[i]] += nvwgt[i*ncon+j]; + + ubvec[j] = (float)nparts*kpwgts[samax(nparts, kpwgts)]/ssum(nparts, kpwgts); + } + + free(kpwgts); + +} + --- /dev/null +++ parmetis-3.1.1/METISLib/NEW_checkgraph.c @@ -0,0 +1,127 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * checkgraph.c + * + * This file contains routines related to I/O + * + * Started 8/28/94 + * George + * + * $Id: NEW_checkgraph.c,v 1.1 2003/07/16 15:55:13 karypis Exp $ + * + */ + +#include + + + +/************************************************************************* +* This function checks if a graph is valid +**************************************************************************/ +int CheckGraph(GraphType *graph) +{ + int i, j, k, l; + int nvtxs, ncon, err=0; + int minedge, maxedge, minewgt, maxewgt; + float minvwgt[MAXNCON], maxvwgt[MAXNCON]; + idxtype *xadj, *adjncy, *adjwgt, *htable; + float *nvwgt, ntvwgts[MAXNCON]; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + htable = idxsmalloc(nvtxs, 0, "htable"); + + if (ncon > 1) { + for (j=0; j 1) { + for (j=0; j maxvwgt[j]) ? nvwgt[i*ncon+j] : maxvwgt[j]; + } + } + + for (j=xadj[i]; j maxedge) ? k : maxedge; + minewgt = (adjwgt[j] < minewgt) ? adjwgt[j] : minewgt; + maxewgt = (adjwgt[j] > maxewgt) ? adjwgt[j] : maxewgt; + + if (i == k) { + printf("Vertex %d contains a self-loop (i.e., diagonal entry in the matrix)!\n", i); + err++; + } + else { + for (l=xadj[k]; l 1) { + for (j=0; j 0.0001) { + printf("Normalized vwgts don't sum to one. Weight %d = %.8f.\n", j, ntvwgts[j]); + err++; + } + } + } + +/* + printf("errs: %d, adjncy: [%d %d], adjwgt: [%d %d]\n", + err, minedge, maxedge, minewgt, maxewgt); + if (ncon > 1) { + for (j=0; j 0) { + printf("A total of %d errors exist in the input file. Correct them, and run again!\n", err); + } + + GKfree(&htable, LTERM); + return (err == 0 ? 1 : 0); +} + --- /dev/null +++ parmetis-3.1.1/METISLib/NEW_mfm.c @@ -0,0 +1,341 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * mfm.c + * + * This file contains code that implements the edge-based FM refinement + * + * Started 7/23/97 + * George + * + * $Id: NEW_mfm.c,v 1.1 2003/07/16 15:55:13 karypis Exp $ + */ + +#include + + +/************************************************************************* +* This function performs an edge-based FM refinement +**************************************************************************/ +void MocFM_2WayEdgeRefine(CtrlType *ctrl, GraphType *graph, float *tpwgts, int npasses) +{ + int i, ii, j, k, l, kwgt, nvtxs, ncon, nbnd, nswaps, from, to, pass, me, limit, tmp, cnum; + idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind; + idxtype *moved, *swaps, *perm, *qnum; + float *nvwgt, *npwgts, mindiff[MAXNCON], origbal, minbal, newbal; + PQueueType parts[MAXNCON][2]; + int higain, oldgain, mincut, initcut, newcut, mincutorder; + float rtpwgts[2]; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + id = graph->id; + ed = graph->ed; + npwgts = graph->npwgts; + bndptr = graph->bndptr; + bndind = graph->bndind; + + moved = idxwspacemalloc(ctrl, nvtxs); + swaps = idxwspacemalloc(ctrl, nvtxs); + perm = idxwspacemalloc(ctrl, nvtxs); + qnum = idxwspacemalloc(ctrl, nvtxs); + + limit = amin(amax(0.01*nvtxs, 25), 150); + + /* Initialize the queues */ + for (i=0; idbglvl&DBG_REFINE) { + printf("Parts: ["); + for (l=0; lnvtxs, graph->nbnd, graph->mincut, origbal); + } + + idxset(nvtxs, -1, moved); + for (pass=0; passmincut; + for (i=0; imincut); + ASSERT(CheckBnd(graph)); + + /* Insert boundary nodes in the priority queues */ + nbnd = graph->nbnd; + RandomPermute(nbnd, perm, 1); + for (ii=0; ii 0 || id[i] == 0); + ASSERT(bndptr[i] != -1); + PQueueInsert(&parts[qnum[i]][where[i]], i, ed[i]-id[i]); + } + + for (nswaps=0; nswaps limit) { /* We hit the limit, undo last move */ + newcut += (ed[higain]-id[higain]); + saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1); + saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); + break; + } + + where[higain] = to; + moved[higain] = nswaps; + swaps[nswaps] = higain; + + if (ctrl->dbglvl&DBG_MOVEINFO) { + printf("Moved %6d from %d(%d). Gain: %5d, Cut: %5d, NPwgts: ", higain, from, cnum, ed[higain]-id[higain], newcut); + for (l=0; l 0) { /* It will now become a boundary vertex */ + BNDInsert(nbnd, bndind, bndptr, k); + if (moved[k] == -1) + PQueueInsert(&parts[qnum[k]][where[k]], k, ed[k]-id[k]); + } + } + } + + } + + + /**************************************************************** + * Roll back computations + *****************************************************************/ + for (i=0; imincutorder; nswaps--) { + higain = swaps[nswaps]; + + to = where[higain] = (where[higain]+1)%2; + SWAP(id[higain], ed[higain], tmp); + if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) + BNDDelete(nbnd, bndind, bndptr, higain); + else if (ed[higain] > 0 && bndptr[higain] == -1) + BNDInsert(nbnd, bndind, bndptr, higain); + + saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); + saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+((to+1)%2)*ncon, 1); + for (j=xadj[higain]; j 0) + BNDInsert(nbnd, bndind, bndptr, k); + } + } + + if (ctrl->dbglvl&DBG_REFINE) { + printf("\tMincut: %6d at %5d, NBND: %6d, NPwgts: [", mincut, mincutorder, nbnd); + for (l=0; lmincut = mincut; + graph->nbnd = nbnd; + + if (mincutorder == -1 || mincut == initcut) + break; + } + + for (i=0; i= maxdiff) { + maxdiff = npwgts[part*ncon+i]-tpwgts[part]; + *from = part; + *cnum = i; + } + } + } + + /* printf("Selected %d(%d) -> %d\n", *from, *cnum, PQueueGetSize(&queues[*cnum][*from])); */ + + if (*from != -1 && PQueueGetSize(&queues[*cnum][*from]) == 0) { + /* The desired queue is empty, select a node from that side anyway */ + for (i=0; i 0) { + max = npwgts[(*from)*ncon + i]; + *cnum = i; + break; + } + } + + for (i++; i max && PQueueGetSize(&queues[i][*from]) > 0) { + max = npwgts[(*from)*ncon + i]; + *cnum = i; + } + } + } + + /* Check to see if you can focus on the cut */ + if (maxdiff <= 0.0 || *from == -1) { + maxgain = -100000; + + for (part=0; part<2; part++) { + for (i=0; i 0 && PQueueGetKey(&queues[i][part]) > maxgain) { + maxgain = PQueueGetKey(&queues[i][part]); + *from = part; + *cnum = i; + } + } + } + } +} + + + + + +/************************************************************************* +* This function checks if the balance achieved is better than the diff +* For now, it uses a 2-norm measure +**************************************************************************/ +int BetterBalance(int ncon, float *npwgts, float *tpwgts, float *diff) +{ + int i; + float ndiff[MAXNCON]; + + for (i=0; i + + +/************************************************************************* +* This function is the entry point for PWMETIS that accepts exact weights +* for the target partitions +**************************************************************************/ +void METIS_mCPartGraphRecursive2(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, + idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, + float *tpwgts, int *options, int *edgecut, idxtype *part) +{ + int i, j; + GraphType graph; + CtrlType ctrl; + float *mytpwgts; +idxtype wgt[2048], minwgt, maxwgt, sumwgt; +float avgwgt; + + if (*numflag == 1) + Change2CNumbering(*nvtxs, xadj, adjncy); + + SetUpGraph(&graph, OP_PMETIS, *nvtxs, *ncon, xadj, adjncy, vwgt, adjwgt, *wgtflag); + graph.npwgts = NULL; + mytpwgts = fmalloc(*nparts, "mytpwgts"); + scopy(*nparts, tpwgts, mytpwgts); + + if (options[0] == 0) { /* Use the default parameters */ + ctrl.CType = McPMETIS_CTYPE; + ctrl.IType = McPMETIS_ITYPE; + ctrl.RType = McPMETIS_RTYPE; + ctrl.dbglvl = McPMETIS_DBGLVL; + } + else { + ctrl.CType = options[OPTION_CTYPE]; + ctrl.IType = options[OPTION_ITYPE]; + ctrl.RType = options[OPTION_RTYPE]; + ctrl.dbglvl = options[OPTION_DBGLVL]; + } + ctrl.optype = OP_PMETIS; + ctrl.CoarsenTo = 100; + + ctrl.nmaxvwgt = 1.5/(1.0*ctrl.CoarsenTo); + + InitRandom(options[7]); + + AllocateWorkSpace(&ctrl, &graph, *nparts); + + IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); + + ASSERT(CheckGraph(&graph)); + *edgecut = MCMlevelRecursiveBisection2(&ctrl, &graph, *nparts, mytpwgts, part, 1.000, 0); +/* +printf("nvtxs: %d, nparts: %d, ncon: %d\n", graph.nvtxs, *nparts, *ncon); +for (i=0; i<(*nparts)*(*ncon); i++) + wgt[i] = 0; +for (i=0; i wgt[maxwgt*(*ncon)+j]) ? i : maxwgt; + sumwgt += wgt[i*(*ncon)+j]; + } + avgwgt = (float)sumwgt / (float)*nparts; + printf("min: %5d, max: %5d, avg: %5.2f, balance: %6.3f\n", wgt[minwgt*(*ncon)+j], wgt[maxwgt*(*ncon)+j], avgwgt, (float)wgt[maxwgt*(*ncon)+j] / avgwgt); +} +printf("\n"); +*/ + + IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); + IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl)); + + FreeWorkSpace(&ctrl, &graph); + GKfree((void *)&mytpwgts, LTERM); + + if (*numflag == 1) + Change2FNumbering(*nvtxs, xadj, adjncy, part); +} + + + +/************************************************************************* +* This function takes a graph and produces a bisection of it +**************************************************************************/ +int MCMlevelRecursiveBisection2(CtrlType *ctrl, GraphType *graph, int nparts, + float *tpwgts, idxtype *part, float ubfactor, int fpart) +{ + int i, nvtxs, cut; + float wsum, tpwgts2[2]; + idxtype *label, *where; + GraphType lgraph, rgraph; + + nvtxs = graph->nvtxs; + if (nvtxs == 0) { +/* printf("\t***Cannot bisect a graph with 0 vertices!\n\t***You are trying to partition a graph into too many parts!\n"); */ + return 0; + } + + /* Determine the weights of the partitions */ + tpwgts2[0] = ssum(nparts/2, tpwgts); + tpwgts2[1] = 1.0-tpwgts2[0]; + + MCMlevelEdgeBisection(ctrl, graph, tpwgts2, ubfactor); + cut = graph->mincut; + + label = graph->label; + where = graph->where; + for (i=0; i 2) + SplitGraphPart(ctrl, graph, &lgraph, &rgraph); + + /* Free the memory of the top level graph */ + GKfree(&graph->gdata, &graph->nvwgt, &graph->rdata, &graph->label, &graph->npwgts, LTERM); + + /* Scale the fractions in the tpwgts according to the true weight */ + wsum = ssum(nparts/2, tpwgts); + sscale(nparts/2, 1.0/wsum, tpwgts); + sscale(nparts-nparts/2, 1.0/(1.0-wsum), tpwgts+nparts/2); + + /* Do the recursive call */ + if (nparts > 3) { + cut += MCMlevelRecursiveBisection2(ctrl, &lgraph, nparts/2, tpwgts, part, ubfactor, fpart); + cut += MCMlevelRecursiveBisection2(ctrl, &rgraph, nparts-nparts/2, tpwgts+nparts/2, part, ubfactor, fpart+nparts/2); + } + else if (nparts == 3) { + cut += MCMlevelRecursiveBisection2(ctrl, &rgraph, nparts-nparts/2, tpwgts+nparts/2, part, ubfactor, fpart+nparts/2); + GKfree(&lgraph.gdata, &lgraph.nvwgt, &lgraph.label, LTERM); + } + + return cut; + +} + + --- /dev/null +++ parmetis-3.1.1/METISLib/NEW_memory.c @@ -0,0 +1,208 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * memory.c + * + * This file contains routines that deal with memory allocation + * + * Started 2/24/96 + * George + * + * $Id: NEW_memory.c,v 1.1 2003/07/16 15:55:13 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function allocates memory for the workspace +**************************************************************************/ +void AllocateWorkSpace(CtrlType *ctrl, GraphType *graph, int nparts) +{ + ctrl->wspace.pmat = NULL; + + if (ctrl->optype == OP_KMETIS) { + ctrl->wspace.edegrees = (EDegreeType *)GKmalloc(graph->nedges*sizeof(EDegreeType), "AllocateWorkSpace: edegrees"); + ctrl->wspace.vedegrees = NULL; + ctrl->wspace.auxcore = (idxtype *)ctrl->wspace.edegrees; + + ctrl->wspace.pmat = idxmalloc(nparts*nparts, "AllocateWorkSpace: pmat"); + + /* Memory requirements for different phases + Coarsening + Matching: 4*nvtxs vectors + Contraction: 2*nvtxs vectors (from the above 4), 1*nparts, 1*Nedges + Total = MAX(4*nvtxs, 2*nvtxs+nparts+nedges) + + Refinement + Random Refinement/Balance: 5*nparts + 1*nvtxs + 2*nedges + Greedy Refinement/Balance: 5*nparts + 2*nvtxs + 2*nedges + 1*PQueue(==Nvtxs) + Total = 5*nparts + 3*nvtxs + 2*nedges + + Total = 5*nparts + 3*nvtxs + 2*nedges + */ + ctrl->wspace.maxcore = 3*(graph->nvtxs+1) + /* Match/Refinement vectors */ + 5*(nparts+1) + /* Partition weights etc */ + graph->nvtxs*(sizeof(ListNodeType)/sizeof(idxtype)) + /* Greedy k-way balance/refine */ + 20 /* padding for 64 bit machines */ + ; + } + else if (ctrl->optype == OP_KVMETIS) { + ctrl->wspace.edegrees = NULL; + ctrl->wspace.vedegrees = (VEDegreeType *)GKmalloc(graph->nedges*sizeof(VEDegreeType), "AllocateWorkSpace: vedegrees"); + ctrl->wspace.auxcore = (idxtype *)ctrl->wspace.vedegrees; + + ctrl->wspace.pmat = idxmalloc(nparts*nparts, "AllocateWorkSpace: pmat"); + + /* Memory requirements for different phases are identical to KMETIS */ + ctrl->wspace.maxcore = 3*(graph->nvtxs+1) + /* Match/Refinement vectors */ + 3*(nparts+1) + /* Partition weights etc */ + graph->nvtxs*(sizeof(ListNodeType)/sizeof(idxtype)) + /* Greedy k-way balance/refine */ + 20 /* padding for 64 bit machines */ + ; + } + else { + ctrl->wspace.edegrees = (EDegreeType *)idxmalloc(graph->nedges, "AllocateWorkSpace: edegrees"); + ctrl->wspace.vedegrees = NULL; + ctrl->wspace.auxcore = (idxtype *)ctrl->wspace.edegrees; + + ctrl->wspace.maxcore = 5*(graph->nvtxs+1) + /* Refinement vectors */ + 4*(nparts+1) + /* Partition weights etc */ + 2*graph->ncon*graph->nvtxs*(sizeof(ListNodeType)/sizeof(idxtype)) + /* 2-way refinement */ + 2*graph->ncon*(NEG_GAINSPAN+PLUS_GAINSPAN+1)*(sizeof(ListNodeType *)/sizeof(idxtype)) + /* 2-way refinement */ + 20 /* padding for 64 bit machines */ + ; + } + + ctrl->wspace.maxcore += HTLENGTH; + ctrl->wspace.core = idxmalloc(ctrl->wspace.maxcore, "AllocateWorkSpace: maxcore"); + ctrl->wspace.ccore = 0; +} + + +/************************************************************************* +* This function allocates memory for the workspace +**************************************************************************/ +void FreeWorkSpace(CtrlType *ctrl, GraphType *graph) +{ + GKfree(&ctrl->wspace.edegrees, &ctrl->wspace.vedegrees, &ctrl->wspace.core, &ctrl->wspace.pmat, LTERM); +} + +/************************************************************************* +* This function returns how may words are left in the workspace +**************************************************************************/ +int WspaceAvail(CtrlType *ctrl) +{ + return ctrl->wspace.maxcore - ctrl->wspace.ccore; +} + + +/************************************************************************* +* This function allocate space from the core +**************************************************************************/ +idxtype *idxwspacemalloc(CtrlType *ctrl, int n) +{ + n += n%2; /* This is a fix for 64 bit machines that require 8-byte pointer allignment */ + + ctrl->wspace.ccore += n; + ASSERT(ctrl->wspace.ccore <= ctrl->wspace.maxcore); + return ctrl->wspace.core + ctrl->wspace.ccore - n; +} + +/************************************************************************* +* This function frees space from the core +**************************************************************************/ +void idxwspacefree(CtrlType *ctrl, int n) +{ + n += n%2; /* This is a fix for 64 bit machines that require 8-byte pointer allignment */ + + ctrl->wspace.ccore -= n; + ASSERT(ctrl->wspace.ccore >= 0); +} + + +/************************************************************************* +* This function allocate space from the core +**************************************************************************/ +float *fwspacemalloc(CtrlType *ctrl, int n) +{ + n += n%2; /* This is a fix for 64 bit machines that require 8-byte pointer allignment */ + + ctrl->wspace.ccore += n; + ASSERT(ctrl->wspace.ccore <= ctrl->wspace.maxcore); + return (float *) (ctrl->wspace.core + ctrl->wspace.ccore - n); +} + +/************************************************************************* +* This function frees space from the core +**************************************************************************/ +void fwspacefree(CtrlType *ctrl, int n) +{ + n += n%2; /* This is a fix for 64 bit machines that require 8-byte pointer allignment */ + + ctrl->wspace.ccore -= n; + ASSERT(ctrl->wspace.ccore >= 0); +} + + + +/************************************************************************* +* This function creates a CoarseGraphType data structure and initializes +* the various fields +**************************************************************************/ +GraphType *CreateGraph(void) +{ + GraphType *graph; + + graph = (GraphType *)GKmalloc(sizeof(GraphType), "CreateCoarseGraph: graph"); + + InitGraph(graph); + + return graph; +} + + +/************************************************************************* +* This function creates a CoarseGraphType data structure and initializes +* the various fields +**************************************************************************/ +void InitGraph(GraphType *graph) +{ + graph->gdata = graph->rdata = NULL; + + graph->nvtxs = graph->nedges = -1; + graph->mincut = graph->minvol = -1; + + graph->xadj = graph->vwgt = graph->adjncy = graph->adjwgt = NULL; + graph->adjwgtsum = NULL; + graph->label = NULL; + graph->cmap = NULL; + + graph->where = graph->pwgts = NULL; + graph->id = graph->ed = NULL; + graph->bndptr = graph->bndind = NULL; + graph->rinfo = NULL; + graph->vrinfo = NULL; + graph->nrinfo = NULL; + + graph->ncon = -1; + graph->nvwgt = NULL; + graph->npwgts = NULL; + + graph->vsize = NULL; + + graph->coarser = graph->finer = NULL; + +} + +/************************************************************************* +* This function deallocates any memory stored in a graph +**************************************************************************/ +void FreeGraph(GraphType *graph) +{ + + GKfree(&graph->gdata, &graph->nvwgt, &graph->rdata, &graph->npwgts, LTERM); + free(graph); +} + --- parmetis-3.1.1.orig/METISLib/parmetis.c +++ parmetis-3.1.1/METISLib/parmetis.c @@ -186,6 +186,7 @@ void METIS_NodeNDP(int nvtxs, idxtype *x } + /************************************************************************* * This function takes a graph and produces a bisection of it **************************************************************************/ @@ -252,6 +253,8 @@ void MlevelNestedDissectionP(CtrlType *c } + + /************************************************************************* * This function is the entry point for ONWMETIS. It requires weights on the * vertices. It is for the case that the matrix has been pre-compressed. @@ -267,24 +270,24 @@ void METIS_NodeComputeSeparator(int *nvt tvwgt = idxsum(*nvtxs, graph.vwgt); if (options[0] == 0) { /* Use the default parameters */ - ctrl.CType = ONMETIS_CTYPE; - ctrl.IType = ONMETIS_ITYPE; - ctrl.RType = ONMETIS_RTYPE; + ctrl.CType = ONMETIS_CTYPE; + ctrl.IType = ONMETIS_ITYPE; + ctrl.RType = ONMETIS_RTYPE; ctrl.dbglvl = ONMETIS_DBGLVL; } else { - ctrl.CType = options[OPTION_CTYPE]; - ctrl.IType = options[OPTION_ITYPE]; - ctrl.RType = options[OPTION_RTYPE]; + ctrl.CType = options[OPTION_CTYPE]; + ctrl.IType = options[OPTION_ITYPE]; + ctrl.RType = options[OPTION_RTYPE]; ctrl.dbglvl = options[OPTION_DBGLVL]; } - ctrl.oflags = 0; - ctrl.pfactor = 0; - ctrl.nseps = 5; - ctrl.optype = OP_ONMETIS; + ctrl.oflags = 0; + ctrl.pfactor = 0; + ctrl.nseps = 1; + ctrl.optype = OP_ONMETIS; ctrl.CoarsenTo = amin(100, *nvtxs-1); - ctrl.maxvwgt = 1.5*tvwgt/ctrl.CoarsenTo; + ctrl.maxvwgt = 1.5*tvwgt/ctrl.CoarsenTo; InitRandom(options[7]); @@ -309,6 +312,7 @@ void METIS_NodeComputeSeparator(int *nvt } + /************************************************************************* * This function is the entry point for ONWMETIS. It requires weights on the * vertices. It is for the case that the matrix has been pre-compressed. @@ -336,12 +340,12 @@ void METIS_EdgeComputeSeparator(int *nvt ctrl.dbglvl = options[OPTION_DBGLVL]; } - ctrl.oflags = 0; - ctrl.pfactor = 0; - ctrl.nseps = 5; - ctrl.optype = OP_OEMETIS; + ctrl.oflags = 0; + ctrl.pfactor = 0; + ctrl.nseps = 1; + ctrl.optype = OP_OEMETIS; ctrl.CoarsenTo = amin(100, *nvtxs-1); - ctrl.maxvwgt = 1.5*tvwgt/ctrl.CoarsenTo; + ctrl.maxvwgt = 1.5*tvwgt/ctrl.CoarsenTo; InitRandom(options[7]); @@ -452,6 +456,7 @@ printf("\n"); } + /************************************************************************* * This function takes a graph and produces a bisection of it **************************************************************************/ --- parmetis-3.1.1.orig/METISLib/Makefile +++ parmetis-3.1.1/METISLib/Makefile @@ -1,5 +1,8 @@ include ../Makefile.in +all: ../libmetis.a ../libmetis.so + +.SUFFIXES: .c .lo .o CFLAGS = $(COPTIONS) $(OPTFLAGS) -I. $(INCDIR) @@ -16,25 +19,35 @@ OBJS = coarsen.o fm.o initpart.o match.o kvmetis.o kwayvolrefine.o kwayvolfm.o subdomains.o \ mfm.o memory.o mrefine.o checkgraph.o +SHLOBJS = $(OBJS:.o=.lo) + .c.o: - $(CC) $(CFLAGS) -c $*.c + $(CC) $(CPPFLAGS) $(CFLAGS) -c $*.c + +.c.lo: + $(CC) $(CPPFLAGS) $(CFLAGS) -fPIC -DPIC -c $< -o $@ ../libmetis.a: $(OBJS) $(AR) $@ $(OBJS) $(RANLIB) $@ +../libmetis.so: $(SHLOBJS) + $(CC) -shared $^ -Wl,-soname,libmetis.so.3.1 -o $@.3.1 \ + $(LIBDIR) -lmpi -lm + ln -s libmetis.so.3.1 $@ + clean: - rm -f *.o + rm -f *.o *.lo realclean: - rm -f *.o ; rm -f ../libmetis.a + rm -f *.o *.lo ../libmetis.* checkin: @for file in *.[c,h]; \ do \ ci -u -m'Maintance' $$file;\ - done + done checkin2: @for file in *.[c,h]; \ --- parmetis-3.1.1.orig/METISLib/ometis.c +++ parmetis-3.1.1/METISLib/ometis.c @@ -433,13 +433,13 @@ void MlevelNodeBisectionMultiple(CtrlTyp bestwhere = idxmalloc(cnvtxs, "MlevelNodeBisection2: bestwhere"); mincut = nvtxs; - for (i=0; inseps; i++) { + for (i=ctrl->nseps; i>0; i--) { ctrl->CType += 20; /* This is a hack. Look at coarsen.c */ MlevelNodeBisection(ctrl, cgraph, tpwgts, ubfactor); /* printf("%5d ", cgraph->mincut); */ - if (i == 0 || cgraph->mincut < mincut) { + if (cgraph->mincut < mincut) { mincut = cgraph->mincut; idxcopy(cnvtxs, cgraph->where, bestwhere); } --- parmetis-3.1.1.orig/METISLib/metis.h +++ parmetis-3.1.1/METISLib/metis.h @@ -10,22 +10,26 @@ * * $Id: metis.h,v 1.3 2003/07/25 13:52:00 karypis Exp $ */ +#ifndef __METIS_H__ +#define __METIS_H__ 1 /* #define DEBUG 1 #define DMALLOC 1 */ -#include +#include #ifdef DMALLOC #include #endif -#include "../parmetis.h" /* Get the idxtype definition */ -#include -#include -#include -#include -#include +#include /* Get the idxtype definition */ +#include +#include +#include +#include +#include + +#endif /* __METIS_H */ --- /dev/null +++ parmetis-3.1.1/METISLib/NEW_mrefine.c @@ -0,0 +1,219 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * refine.c + * + * This file contains the driving routines for multilevel refinement + * + * Started 7/24/97 + * George + * + * $Id: NEW_mrefine.c,v 1.1 2003/07/16 15:55:14 karypis Exp $ + */ + +#include + + +/************************************************************************* +* This function is the entry point of refinement +**************************************************************************/ +void MocRefine2Way(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, float *tpwgts, float ubfactor) +{ + int i; + float tubvec[MAXNCON]; + + for (i=0; incon; i++) + tubvec[i] = 1.0; + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr)); + + /* Compute the parameters of the coarsest graph */ + MocCompute2WayPartitionParams(ctrl, graph); + + for (;;) { + ASSERT(CheckBnd(graph)); + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr)); + switch (ctrl->RType) { + case RTYPE_FM: + MocBalance2Way(ctrl, graph, tpwgts, 1.03); + MocFM_2WayEdgeRefine(ctrl, graph, tpwgts, 8); + break; + case 2: + MocBalance2Way(ctrl, graph, tpwgts, 1.03); + MocFM_2WayEdgeRefine2(ctrl, graph, tpwgts, tubvec, 8); + break; + default: + errexit("Unknown refinement type: %d\n", ctrl->RType); + } + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr)); + + if (graph == orggraph) + break; + + graph = graph->finer; + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr)); + MocProject2WayPartition(ctrl, graph); + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr)); + } + + MocBalance2Way(ctrl, graph, tpwgts, 1.01); + MocFM_2WayEdgeRefine(ctrl, graph, tpwgts, 8); + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr)); +} + + +/************************************************************************* +* This function allocates memory for 2-way edge refinement +**************************************************************************/ +void MocAllocate2WayPartitionMemory(CtrlType *ctrl, GraphType *graph) +{ + int nvtxs, ncon; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + + graph->rdata = idxmalloc(5*nvtxs, "Allocate2WayPartitionMemory: rdata"); + graph->where = graph->rdata; + graph->id = graph->rdata + nvtxs; + graph->ed = graph->rdata + 2*nvtxs; + graph->bndptr = graph->rdata + 3*nvtxs; + graph->bndind = graph->rdata + 4*nvtxs; + + graph->npwgts = fmalloc(2*ncon, "npwgts"); +} + + +/************************************************************************* +* This function computes the initial id/ed +**************************************************************************/ +void MocCompute2WayPartitionParams(CtrlType *ctrl, GraphType *graph) +{ + int i, j, k, l, nvtxs, ncon, nbnd, mincut; + idxtype *xadj, *adjncy, *adjwgt; + float *nvwgt, *npwgts; + idxtype *id, *ed, *where; + idxtype *bndptr, *bndind; + int me, other; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + where = graph->where; + npwgts = sset(2*ncon, 0.0, graph->npwgts); + id = idxset(nvtxs, 0, graph->id); + ed = idxset(nvtxs, 0, graph->ed); + bndptr = idxset(nvtxs, -1, graph->bndptr); + bndind = graph->bndind; + + + /*------------------------------------------------------------ + / Compute now the id/ed degrees + /------------------------------------------------------------*/ + nbnd = mincut = 0; + for (i=0; i= 0 && where[i] <= 1); + me = where[i]; + saxpy(ncon, 1.0, nvwgt+i*ncon, 1, npwgts+me*ncon, 1); + + for (j=xadj[i]; j 0 || xadj[i] == xadj[i+1]) { + mincut += ed[i]; + bndptr[i] = nbnd; + bndind[nbnd++] = i; + } + } + + graph->mincut = mincut/2; + graph->nbnd = nbnd; + +} + + + +/************************************************************************* +* This function projects a partition, and at the same time computes the +* parameters for refinement. +**************************************************************************/ +void MocProject2WayPartition(CtrlType *ctrl, GraphType *graph) +{ + int i, j, k, nvtxs, nbnd, me; + idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum; + idxtype *cmap, *where, *id, *ed, *bndptr, *bndind; + idxtype *cwhere, *cid, *ced, *cbndptr; + GraphType *cgraph; + + cgraph = graph->coarser; + cwhere = cgraph->where; + cid = cgraph->id; + ced = cgraph->ed; + cbndptr = cgraph->bndptr; + + nvtxs = graph->nvtxs; + cmap = graph->cmap; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + adjwgtsum = graph->adjwgtsum; + + MocAllocate2WayPartitionMemory(ctrl, graph); + + where = graph->where; + id = idxset(nvtxs, 0, graph->id); + ed = idxset(nvtxs, 0, graph->ed); + bndptr = idxset(nvtxs, -1, graph->bndptr); + bndind = graph->bndind; + + + /* Go through and project partition and compute id/ed for the nodes */ + for (i=0; i 0 || xadj[i] == xadj[i+1]) { + bndptr[i] = nbnd; + bndind[nbnd++] = i; + } + } + } + } + + graph->mincut = cgraph->mincut; + graph->nbnd = nbnd; + scopy(2*graph->ncon, cgraph->npwgts, graph->npwgts); + + FreeGraph(graph->coarser); + graph->coarser = NULL; + +} + --- parmetis-3.1.1.orig/METISLib/stdheaders.h +++ parmetis-3.1.1/METISLib/stdheaders.h @@ -23,5 +23,4 @@ #include #include #include -#include --- parmetis-3.1.1.orig/Programs/io.c +++ parmetis-3.1.1/Programs/io.c @@ -115,8 +115,10 @@ void ParallelReadGraph(GraphType *graph, /*******************************************/ if (mype == npes-1) { maxnvtxs = 0; - for (i=0; ivtxdist, ograph->xadj, NULL, ograph->adjncy, NULL, 0); - AllocateWSpace(&ctrl, graph, &wspace); + PreAllocateMemory(&ctrl, graph, &wspace); SetUp(&ctrl, graph, &wspace); graph->where = part; graph->ncon = 1; - mgraph = Mc_MoveGraph(&ctrl, graph, &wspace); + mgraph = Moc_MoveGraph(&ctrl, graph, &wspace); omgraph->gnvtxs = mgraph->gnvtxs; omgraph->nvtxs = mgraph->nvtxs; @@ -458,7 +458,7 @@ void TestMoveGraph(GraphType *ograph, Gr FreeGraph(mgraph); graph->where = NULL; - FreeInitialGraphAndRemap(graph, 0, 1); + FreeInitialGraphAndRemap(graph, 0); FreeWSpace(&wspace); } @@ -471,7 +471,7 @@ GraphType *SetUpGraph(CtrlType *ctrl, id int mywgtflag; mywgtflag = wgtflag; - return Mc_SetUpGraph(ctrl, 1, vtxdist, xadj, vwgt, adjncy, adjwgt, &mywgtflag); + return Moc_SetUpGraph(ctrl, 1, vtxdist, xadj, vwgt, adjncy, adjwgt, &mywgtflag); } --- parmetis-3.1.1.orig/Programs/Makefile +++ parmetis-3.1.1/Programs/Makefile @@ -2,27 +2,25 @@ include ../Makefile.in BINDIR = ../Graphs -INCLUDES = -I./ -I../ParMETISLib $(INCDIR) -CFLAGS = $(COPTIONS) $(OPTFLAGS) $(INCLUDES) +#INCLUDES = -I./ -I../ParMETISLib $(INCDIR) +#CFLAGS = $(COPTIONS) $(OPTFLAGS) $(INCLUDES) LIBSDIR = -L.. $(LIBDIR) -LIBS = -lparmetis -lmetis $(XTRALIBS) -lm +LIBS = -lparmetis -lmetis $(XTRALIBS) -lm -lmpi PARMETISLIB = ../libparmetis.a ../libmetis.a PTESTOBJS = ptest.o io.o adaptgraph.o MESHTESTOBJS = mtest.o io.o PARMETISOBJS = parmetis.o io.o adaptgraph.o -POMETISOBJS = pometis.o io.o .c.o: - $(CC) $(CFLAGS) -c $*.c + $(CC) -I./ -I../ParMETISLib $(CPPFLAGS) $(CFLAGS) -c $*.c -default: $(BINDIR)/ptest$(VERNUM) $(BINDIR)/mtest$(VERNUM) $(BINDIR)/parmetis$(VERNUM) \ - $(BINDIR)/pometis$(VERNUM) +default: $(BINDIR)/ptest$(VERNUM) $(BINDIR)/mtest$(VERNUM) $(BINDIR)/mtest$(VERNUM): $(MESHTESTOBJS) $(PARMETISLIB) $(LD) -o $@ $(MESHTESTOBJS) $(LIBSDIR) $(LIBS) @@ -32,26 +30,27 @@ $(BINDIR)/ptest$(VERNUM): $(PTESTOBJS) $ $(LD) -o $@ $(PTESTOBJS) $(LIBSDIR) $(LIBS) chmod 744 $@ -$(BINDIR)/parmetis$(VERNUM): $(PARMETISOBJS) $(PARMETISLIB) - $(LD) -o $@ $(PARMETISOBJS) $(LIBSDIR) $(LIBS) - chmod 744 $@ - -$(BINDIR)/pometis$(VERNUM): $(POMETISOBJS) $(PARMETISLIB) - $(LD) -o $@ $(POMETISOBJS) $(LIBSDIR) $(LIBS) - chmod 744 $@ - - clean: rm -f *.o ;\ rm -f $(BINDIR)/ptest$(VERNUM) rm -f $(BINDIR)/mtest$(VERNUM) - rm -f $(BINDIR)/parmetis$(VERNUM) - rm -f $(BINDIR)/pometis$(VERNUM) realclean: rm -f *.o ;\ rm -f $(BINDIR)/ptest$(VERNUM) rm -f $(BINDIR)/mtest$(VERNUM) - rm -f $(BINDIR)/parmetis$(VERNUM) - rm -f $(BINDIR)/pometis$(VERNUM) + +checkin: + @for file in *.[c,h]; \ + do \ + ci -u -m'Maintance' $$file;\ + done + +checkin2: + @for file in *.[c,h]; \ + do \ + ci $$file;\ + rcs -U $$file;\ + co $$file;\ + done --- parmetis-3.1.1.orig/ParMETISLib/adrivers.c +++ parmetis-3.1.1/ParMETISLib/adrivers.c @@ -51,14 +51,14 @@ void Adaptive_Partition(CtrlType *ctrl, graph->where = idxsmalloc(graph->nvtxs+graph->nrecv, -1, "graph->where"); idxcopy(graph->nvtxs, graph->home, graph->where); - Mc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); lbavg = savg(graph->ncon, lbvec); if (lbavg > ubavg + 0.035 && ctrl->partType != REFINE_PARTITION) Balance_Partition(ctrl, graph, wspace); if (ctrl->dbglvl&DBG_PROGRESS) { - Mc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); rprintf(ctrl, "nvtxs: %10d, balance: ", graph->gnvtxs); for (i=0; incon; i++) rprintf(ctrl, "%.3f ", lbvec[i]); @@ -67,9 +67,9 @@ void Adaptive_Partition(CtrlType *ctrl, /* check if no coarsening took place */ if (graph->finer == NULL) { - Mc_ComputePartitionParams(ctrl, graph, wspace); - Mc_KWayBalance(ctrl, graph, wspace, graph->ncon); - Mc_KWayAdaptiveRefine(ctrl, graph, wspace, NGR_PASSES); + Moc_ComputePartitionParams(ctrl, graph, wspace); + Moc_KWayBalance(ctrl, graph, wspace, graph->ncon); + Moc_KWayAdaptiveRefine(ctrl, graph, wspace, NGR_PASSES); } } else { @@ -82,7 +82,7 @@ void Adaptive_Partition(CtrlType *ctrl, break; case DISCOUPLED: default: - Mc_GlobalMatch_Balance(ctrl, graph, wspace); + Moc_GlobalMatch_Balance(ctrl, graph, wspace); break; } @@ -91,22 +91,22 @@ void Adaptive_Partition(CtrlType *ctrl, /********************************/ /* project partition and refine */ /********************************/ - Mc_ProjectPartition(ctrl, graph, wspace); - Mc_ComputePartitionParams(ctrl, graph, wspace); + Moc_ProjectPartition(ctrl, graph, wspace); + Moc_ComputePartitionParams(ctrl, graph, wspace); if (graph->ncon > 1 && graph->level < 4) { - Mc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); lbavg = savg(graph->ncon, lbvec); if (lbavg > ubavg + 0.025) { - Mc_KWayBalance(ctrl, graph, wspace, graph->ncon); + Moc_KWayBalance(ctrl, graph, wspace, graph->ncon); } } - Mc_KWayAdaptiveRefine(ctrl, graph, wspace, NGR_PASSES); + Moc_KWayAdaptiveRefine(ctrl, graph, wspace, NGR_PASSES); if (ctrl->dbglvl&DBG_PROGRESS) { - Mc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); rprintf(ctrl, "nvtxs: %10d, cut: %8d, balance: ", graph->gnvtxs, graph->mincut); for (i=0; incon; i++) rprintf(ctrl, "%.3f ", lbvec[i]); --- /dev/null +++ parmetis-3.1.1/ParMETISLib/sync @@ -0,0 +1,186 @@ +adrivers.c: ubavg = savg(graph->ncon, ctrl->ubvec); +adrivers.c: ctrl->redist_factor = ctrl->redist_base * ((gtewgt/gtvsize)/ ctrl->edge_size_ratio); +adrivers.c: IFSET(ctrl->dbglvl, DBG_PROGRESS, rprintf(ctrl, "[%6d %8d %5d %5d][%d]\n", +adrivers.c: graph->gnvtxs, GlobalSESum(ctrl, graph->nedges), GlobalSEMin(ctrl, graph->nvtxs), GlobalSEMax(ctrl, graph->nvtxs), ctrl->CoarsenTo)); +adrivers.c: if (graph->gnvtxs < 1.3*ctrl->CoarsenTo || +adrivers.c: if (lbavg > ubavg + 0.035 && ctrl->partType != REFINE_PARTITION) +adrivers.c: if (ctrl->dbglvl&DBG_PROGRESS) { +adrivers.c: switch (ctrl->ps_relation) { +adrivers.c: if (ctrl->dbglvl&DBG_PROGRESS) { +akwayfm.c: int npes = ctrl->npes, mype = ctrl->mype, nparts = ctrl->nparts; +akwayfm.c: IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->KWayTmr)); +akwayfm.c: ubvec = ctrl->ubvec; +akwayfm.c: tpwgts = ctrl->tpwgts; +akwayfm.c: ipc_factor = ctrl->ipc_factor; +akwayfm.c: redist_factor = ctrl->redist_factor; +akwayfm.c: MPI_Bcast((void *)pperm, nparts, IDX_DATATYPE, 0, ctrl->comm); +akwayfm.c: switch (ctrl->ps_relation) { +akwayfm.c: switch (ctrl->ps_relation) { +akwayfm.c: MPI_Allreduce((void *)lnpwgts, (void *)pgnpwgts, nparts*ncon, MPI_FLOAT, MPI_SUM, ctrl->comm); +akwayfm.c: IFSET(ctrl->dbglvl, DBG_RMOVEINFO, rprintf(ctrl, "\t[%d %d], [%.4f], [%d %d %d]\n", +akwayfm.c: MPI_Irecv((void *)(rupdate+sendptr[i]), sendptr[i+1]-sendptr[i], IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->rreq+i); +akwayfm.c: MPI_Isend((void *)(supdate+j), k-j, IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->sreq+i); +akwayfm.c: MPI_Waitall(nnbrs, ctrl->rreq, ctrl->statuses); +akwayfm.c: MPI_Get_count(ctrl->statuses+i, IDX_DATATYPE, nupds_pe+i); +akwayfm.c: MPI_Waitall(nnbrs, ctrl->sreq, ctrl->statuses); +akwayfm.c: MPI_Allreduce((void *)lnpwgts, (void *)gnpwgts, nparts*ncon, MPI_FLOAT, MPI_SUM, ctrl->comm); +akwayfm.c: IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->KWayTmr)); +balancemylink.c: ipc_factor = ctrl->ipc_factor; +balancemylink.c: redist_factor = ctrl->redist_factor; +coarsen.c: int npes=ctrl->npes, mype=ctrl->mype; +coarsen.c: MPI_Allgather((void *)(cvtxdist+npes), 1, IDX_DATATYPE, (void *)cvtxdist, 1, IDX_DATATYPE, ctrl->comm); +coarsen.c: MPI_Irecv((void *)(rsizes+i), 1, IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->rreq+i); +coarsen.c: MPI_Isend((void *)(ssizes+i), 1, IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->sreq+i); +coarsen.c: MPI_Wait(ctrl->rreq+i, &ctrl->status); +coarsen.c: MPI_Wait(ctrl->sreq+i, &ctrl->status); +coarsen.c: MPI_Irecv((void *)(rgraph+l), (4+ncon)*(rlens[i+1]-rlens[i])+2*rsizes[i], IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->rreq+i); +coarsen.c: sgraph[ll++] = (ctrl->partType == STATIC_PARTITION) ? -1 : vsize[ii]; +coarsen.c: sgraph[ll++] = (ctrl->partType == STATIC_PARTITION) ? -1 : home[ii]; +coarsen.c: MPI_Isend((void *)(sgraph+l), ll-l, IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->sreq+i); +coarsen.c: MPI_Wait(ctrl->rreq+i, &ctrl->status); +coarsen.c: MPI_Wait(ctrl->sreq+i, &ctrl->status); +coarsen.c: if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { +coarsen.c: if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { +coarsen.c: if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { +coarsen.c: if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { +coarsen.c: cgraph->nvwgt[j*ncon+h] = (float)(cvwgt[j*ncon+h])/(float)(ctrl->tvwgts[h]); +comm.c: firstvtx = graph->vtxdist[ctrl->mype]; +comm.c: peind[i], 1, ctrl->comm, ctrl->rreq+i); +comm.c: peind[i], 1, ctrl->comm, ctrl->sreq+i); +comm.c: MPI_Waitall(nnbrs, ctrl->rreq, ctrl->statuses); +comm.c: MPI_Waitall(nnbrs, ctrl->sreq, ctrl->statuses); +comm.c: firstvtx = graph->vtxdist[ctrl->mype]; +comm.c: peind[i], 1, ctrl->comm, ctrl->rreq+i); +comm.c: idxcopy(ctrl->npes, sendptr, psendptr); +comm.c: peind[i], 1, ctrl->comm, ctrl->sreq+i); +comm.c: MPI_Isend((void *)(sendpairs), 0, IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->sreq+i); +comm.c: MPI_Wait(ctrl->rreq+i, &(ctrl->status)); +comm.c: MPI_Get_count(&ctrl->status, IDX_DATATYPE, &n); +comm.c: MPI_Waitall(nnbrs, ctrl->sreq, ctrl->statuses); +comm.c: MPI_Allreduce((void *)&value, (void *)&max, 1, MPI_INT, MPI_MAX, ctrl->comm); +comm.c: MPI_Allreduce((void *)&value, (void *)&max, 1, MPI_DOUBLE, MPI_MAX, ctrl->comm); +comm.c: MPI_Allreduce((void *)&value, (void *)&min, 1, MPI_INT, MPI_MIN, ctrl->comm); +comm.c: MPI_Allreduce((void *)&value, (void *)&sum, 1, MPI_INT, MPI_SUM, ctrl->comm); +comm.c: MPI_Allreduce((void *)&value, (void *)&max, 1, MPI_FLOAT, MPI_MAX, ctrl->comm); +comm.c: MPI_Allreduce((void *)&value, (void *)&min, 1, MPI_FLOAT, MPI_MIN, ctrl->comm); +comm.c: MPI_Allreduce((void *)&value, (void *)&sum, 1, MPI_FLOAT, MPI_SUM, ctrl->comm); +debug.c: for (penum=0; penumnpes; penum++) { +debug.c: if (ctrl->mype == penum) { +debug.c: if (ctrl->mype == 0) +debug.c: printf("\t%3d. ", ctrl->mype); +debug.c: MPI_Barrier(ctrl->comm); +debug.c: for (penum=0; penumnpes; penum++) { +debug.c: if (ctrl->mype == penum) { +debug.c: if (ctrl->mype == 0) +debug.c: printf("\t%3d. ", ctrl->mype); +debug.c: MPI_Barrier(ctrl->comm); +debug.c: for (penum=0; penumnpes; penum++) { +debug.c: if (ctrl->mype == penum) { +debug.c: if (ctrl->mype == 0) +debug.c: printf("\t%3d. ", ctrl->mype); +debug.c: MPI_Barrier(ctrl->comm); +debug.c: MPI_Barrier(ctrl->comm); +debug.c: firstvtx = graph->vtxdist[ctrl->mype]; +debug.c: for (penum=0; penumnpes; penum++) { +debug.c: if (ctrl->mype == penum) { +debug.c: MPI_Barrier(ctrl->comm); +debug.c: MPI_Barrier(ctrl->comm); +debug.c: firstvtx = graph->vtxdist[ctrl->mype]; +debug.c: for (penum=0; penumnpes; penum++) { +debug.c: if (ctrl->mype == penum) { +debug.c: MPI_Barrier(ctrl->comm); +debug.c: MPI_Barrier(ctrl->comm); +debug.c: for (penum=0; penumnpes; penum++) { +debug.c: if (ctrl->mype == penum) { +debug.c: printf("PE: %d, nnbrs: %d\n", ctrl->mype, graph->nnbrs); +debug.c: MPI_Barrier(ctrl->comm); +debug.c: MPI_Barrier(ctrl->comm); +debug.c: for (penum=0; penumnpes; penum++) { +debug.c: if (ctrl->mype == penum) { +debug.c: printf("PE: %d, nnbrs: %d", ctrl->mype, nnbrs); +debug.c: MPI_Barrier(ctrl->comm); +diffutil.c: nparts = ctrl->nparts; +diffutil.c: myhome = (ctrl->ps_relation == COUPLED) ? ctrl->mype : graph->home[i]; +diffutil.c: /* PrintVector(ctrl, ctrl->npes, 0, lend, "Lend: "); */ +diffutil.c: MPI_Allreduce((void *)lstart, (void *)gstart, nparts, IDX_DATATYPE, MPI_SUM, ctrl->comm); +diffutil.c: MPI_Allreduce((void *)lleft, (void *)gleft, nparts, IDX_DATATYPE, MPI_SUM, ctrl->comm); +diffutil.c: MPI_Allreduce((void *)lend, (void *)gend, nparts, IDX_DATATYPE, MPI_SUM, ctrl->comm); +grsetup.c: graph->gnvtxs = vtxdist[ctrl->npes]; +grsetup.c: graph->nvtxs = vtxdist[ctrl->mype+1]-vtxdist[ctrl->mype]; +grsetup.c: ctrl->tvwgts[j] = GlobalSESum(ctrl, ltvwgts[j]); +grsetup.c: if (ctrl->tvwgts[i] == 0) { +grsetup.c: graph->nvwgt[i*ncon+j] = (float)(graph->vwgt[i*ncon+j]) / (float)(ctrl->tvwgts[j]); +grsetup.c: srand(ctrl->seed); +grsetup.c: MPI_Comm_dup(comm, &(ctrl->gcomm)); +grsetup.c: MPI_Comm_rank(ctrl->gcomm, &ctrl->mype); +grsetup.c: MPI_Comm_size(ctrl->gcomm, &ctrl->npes); +grsetup.c: ctrl->dbglvl = dbglvl; +grsetup.c: ctrl->nparts = nparts; /* Set the # of partitions is de-coupled from the # of domains */ +grsetup.c: ctrl->comm = ctrl->gcomm; +grsetup.c: ctrl->xyztype = XYZ_SPFILL; +grsetup.c: srand(ctrl->mype); +grsetup.c: lpvtxs = idxsmalloc(ctrl->nparts, 0, "ComputeMoveStatistics: lpvtxs"); +grsetup.c: gpvtxs = idxsmalloc(ctrl->nparts, 0, "ComputeMoveStatistics: gpvtxs"); +grsetup.c: if (where[i] != ctrl->mype) +grsetup.c: /* PrintVector(ctrl, ctrl->npes, 0, lpvtxs, "Lpvtxs: "); */ +grsetup.c: MPI_Allreduce((void *)lpvtxs, (void *)gpvtxs, ctrl->nparts, IDX_DATATYPE, MPI_SUM, ctrl->comm); +grsetup.c: *maxin = GlobalSEMax(ctrl, gpvtxs[ctrl->mype]-(nvtxs-j)); +initbalance.c: IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr)); +initbalance.c: mytpwgts = fsmalloc(ctrl->nparts, 0.0, "mytpwgts"); +initbalance.c: for (i=0; inparts; i++) +initbalance.c: mytpwgts[i] += ctrl->tpwgts[i*ncon+j]; +initbalance.c: for (i=0; inparts; i++) +initbalance.c: if (ctrl->ps_relation == DISCOUPLED) { +initbalance.c: rcounts = imalloc(ctrl->npes, "rcounts"); +initbalance.c: rdispls = imalloc(ctrl->npes+1, "rdispls"); +initbalance.c: for (i=0; inpes; i++) { +initbalance.c: MAKECSR(i, ctrl->npes, rdispls); +initbalance.c: (void *)part, rcounts, rdispls, IDX_DATATYPE, ctrl->comm); +initbalance.c: for (i=0; inpes; i++) +initbalance.c: if (part[i] >= ctrl->nparts) +initbalance.c: part[i] = home[i] = part[i] % ctrl->nparts; +initbalance.c: part[i] = home[i] = (-1*part[i]) % ctrl->nparts; +initbalance.c: IFSET(ctrl->dbglvl, DBG_REFINEINFO, Moc_ComputeSerialBalance(ctrl, agraph, agraph->where, lbvec)); +initbalance.c: IFSET(ctrl->dbglvl, DBG_REFINEINFO, rprintf(ctrl, "input cut: %d, balance: ", ComputeSerialEdgeCut(agraph))); +initbalance.c: IFSET(ctrl->dbglvl, DBG_REFINEINFO, rprintf(ctrl, "%.3f ", lbvec[i])); +initbalance.c: IFSET(ctrl->dbglvl, DBG_REFINEINFO, rprintf(ctrl, "\n")); +initbalance.c: sr = (ctrl->mype % 2 == 0) ? 1 : 0; +initbalance.c: gd = (ctrl->mype % 2 == 1) ? 1 : 0; +initbalance.c: if (graph->ncon > MAX_NCON_FOR_DIFFUSION || ctrl->npes == 1) { +initbalance.c: MPI_Comm_split(ctrl->gcomm, sr, 0, &ipcomm); +initbalance.c: myctrl.sync = ctrl->sync; +initbalance.c: myctrl.seed = ctrl->seed; +initbalance.c: myctrl.nparts = ctrl->nparts; +initbalance.c: myctrl.ipc_factor = ctrl->ipc_factor; +initbalance.c: myctrl.redist_factor = ctrl->redist_base; +initbalance.c: myctrl.tpwgts = ctrl->tpwgts; +initbalance.c: icopy(ncon, ctrl->tvwgts, myctrl.tvwgts); +initbalance.c: icopy(ncon, ctrl->ubvec, myctrl.ubvec); +initbalance.c: moptions[7] = ctrl->sync + (mype % ngroups) + 1; +initbalance.c: lnparts = ctrl->nparts; +initbalance.c: lpecost.rank = ctrl->mype; +initbalance.c: if (ctrl->mype == gpecost.rank && ctrl->mype != sr_pe) { +initbalance.c: MPI_Send((void *)part, nvtxs, IDX_DATATYPE, sr_pe, 1, ctrl->comm); +initbalance.c: if (ctrl->mype != gpecost.rank && ctrl->mype == sr_pe) { +initbalance.c: MPI_Recv((void *)part, nvtxs, IDX_DATATYPE, gpecost.rank, 1, ctrl->comm, &status); +initbalance.c: if (ctrl->mype == sr_pe) { +initbalance.c: SerialRemap(&cgraph, ctrl->nparts, home, lwhere, part, ctrl->tpwgts); +initbalance.c: lpecost.rank = ctrl->mype; +initbalance.c: if (ctrl->mype == gpecost.rank && ctrl->mype != gd_pe) +initbalance.c: MPI_Send((void *)part, nvtxs, IDX_DATATYPE, gd_pe, 1, ctrl->comm); +initbalance.c: if (ctrl->mype != gpecost.rank && ctrl->mype == gd_pe) +initbalance.c: MPI_Recv((void *)part, nvtxs, IDX_DATATYPE, gpecost.rank, 1, ctrl->comm, &status); +initbalance.c: if (ctrl->mype == gd_pe) { +initbalance.c: SerialRemap(&cgraph, ctrl->nparts, home, lwhere, part, ctrl->tpwgts); +initbalance.c: if (ctrl->mype == sr_pe || ctrl->mype == gd_pe) { +initbalance.c: my_cost = ctrl->ipc_factor * my_cut + REDIST_WGT * ctrl->redist_base * my_totalv; +initbalance.c: IFSET(ctrl->dbglvl, DBG_REFINEINFO, printf("%s initial cut: %.1f, totalv: %.1f, balance: %.3f\n", +initbalance.c: (ctrl->mype == sr_pe ? "scratch-remap" : "diffusion"), my_cut, my_totalv, my_balance)); +initbalance.c: if (ctrl->mype == gd_pe) { +initbalance.c: MPI_Send((void *)buffer, 2, MPI_FLOAT, sr_pe, 1, ctrl->comm); +initbalance.c: MPI_Recv((void *)buffer, 2, MPI_FLOAT, gd_pe, 1, ctrl->comm, &status); +initbalance.c: if (ctrl->mype == sr_pe) { +initbalance.c: MPI_Bcast((void *)&who_wins, 1, MPI_INT, sr_pe, ctrl->comm); +initbalance.c: MPI_Bcast((void *)part, nvtxs, IDX_DATATYPE, who_wins, ctrl->comm); +initbalance.c: idxcopy(graph->nvtxs, part+vtxdist[ctrl->mype], graph->where); +initbalance.c: IFSET(ctrl->dbglvl, DBG_TIME, stoptim \ No newline at end of file --- parmetis-3.1.1.orig/ParMETISLib/balancemylink.c +++ parmetis-3.1.1/ParMETISLib/balancemylink.c @@ -108,7 +108,7 @@ MPI_Comm_rank(MPI_COMM_WORLD, &mype); queues = (FPQueueType *)(GKmalloc(sizeof(FPQueueType)*nqueues*2, "queues")); for (i=0; i + /*********************************************************************************** * This function is the entry point of the parallel k-way multilevel partitionioner. * This function assumes nothing about the graph distribution. @@ -50,21 +51,21 @@ void ParMETIS_V3_PartKway(idxtype *vtxdi options, ioptions, part, comm); - /**********************************/ - /* Take care the nparts == 1 case */ - /**********************************/ + /*********************************/ + /* Take care the nparts = 1 case */ + /*********************************/ if (inparts <= 1) { idxset(vtxdist[mype+1]-vtxdist[mype], 0, part); *edgecut = 0; return; } - /*******************************/ - /* Take care of npes == 1 case */ - /*******************************/ - if (npes == 1) { + /******************************/ + /* Take care of npes = 1 case */ + /******************************/ + if (npes == 1 && inparts > 1) { moptions[0] = 0; - nvtxs = vtxdist[1] - vtxdist[0]; + nvtxs = vtxdist[1]; if (incon == 1) { METIS_WPartGraphKway(&nvtxs, xadj, adjncy, vwgt, adjwgt, &iwgtflag, &inumflag, @@ -95,11 +96,11 @@ void ParMETIS_V3_PartKway(idxtype *vtxdi /*****************************/ if (ioptions[0] == 1) { dbglvl = ioptions[PMV3_OPTION_DBGLVL]; - seed = ioptions[PMV3_OPTION_SEED]; + seed = ioptions[PMV3_OPTION_SEED]; } else { dbglvl = GLOBAL_DBGLVL; - seed = GLOBAL_SEED; + seed = GLOBAL_SEED; } SetUpCtrl(&ctrl, inparts, dbglvl, *comm); ctrl.CoarsenTo = amin(vtxdist[npes]+1, 25*incon*amax(npes, inparts)); @@ -110,9 +111,9 @@ void ParMETIS_V3_PartKway(idxtype *vtxdi ctrl.tpwgts = itpwgts; scopy(incon, iubvec, ctrl.ubvec); - graph = Mc_SetUpGraph(&ctrl, incon, vtxdist, xadj, vwgt, adjncy, adjwgt, &iwgtflag); + graph = Moc_SetUpGraph(&ctrl, incon, vtxdist, xadj, vwgt, adjncy, adjwgt, &iwgtflag); - AllocateWSpace(&ctrl, graph, &wspace); + PreAllocateMemory(&ctrl, graph, &wspace); IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); @@ -133,7 +134,7 @@ void ParMETIS_V3_PartKway(idxtype *vtxdi /***********************/ /* Partition the graph */ /***********************/ - Mc_Global_Partition(&ctrl, graph, &wspace); + Moc_Global_Partition(&ctrl, graph, &wspace); ParallelReMapGraph(&ctrl, graph, &wspace); } @@ -163,7 +164,7 @@ void ParMETIS_V3_PartKway(idxtype *vtxdi } GKfree((void **)&itpwgts, (void **)&graph->lnpwgts, (void **)&graph->gnpwgts, (void **)&graph->nvwgt, LTERM); - FreeInitialGraphAndRemap(graph, iwgtflag, 1); + FreeInitialGraphAndRemap(graph, iwgtflag); FreeWSpace(&wspace); FreeCtrl(&ctrl); @@ -177,16 +178,14 @@ void ParMETIS_V3_PartKway(idxtype *vtxdi /************************************************************************* * This function is the driver to the multi-constraint partitioning algorithm. **************************************************************************/ -void Mc_Global_Partition(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +void Moc_Global_Partition(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) { int i, ncon, nparts; float ftmp, ubavg, lbavg, lbvec[MAXNCON]; - AdjustWSpace(ctrl, graph, wspace); - - ncon = graph->ncon; + ncon = graph->ncon; nparts = ctrl->nparts; - ubavg = savg(graph->ncon, ctrl->ubvec); + ubavg = savg(graph->ncon, ctrl->ubvec); SetUp(ctrl, graph, wspace); @@ -207,10 +206,10 @@ void Mc_Global_Partition(CtrlType *ctrl, /* Done with coarsening. Find a partition */ graph->where = idxmalloc(graph->nvtxs+graph->nrecv, "graph->where"); - Mc_InitPartition_RB(ctrl, graph, wspace); + Moc_InitPartition_RB(ctrl, graph, wspace); if (ctrl->dbglvl&DBG_PROGRESS) { - Mc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); rprintf(ctrl, "nvtxs: %10d, balance: ", graph->gnvtxs); for (i=0; incon; i++) rprintf(ctrl, "%.3f ", lbvec[i]); @@ -219,18 +218,17 @@ void Mc_Global_Partition(CtrlType *ctrl, /* In case no coarsening took place */ if (graph->finer == NULL) { - Mc_ComputePartitionParams(ctrl, graph, wspace); - Mc_KWayFM(ctrl, graph, wspace, NGR_PASSES); + Moc_ComputePartitionParams(ctrl, graph, wspace); + Moc_KWayFM(ctrl, graph, wspace, NGR_PASSES); } } else { - Mc_GlobalMatch_Balance(ctrl, graph, wspace); - - Mc_Global_Partition(ctrl, graph->coarser, wspace); + Moc_GlobalMatch_Balance(ctrl, graph, wspace); - Mc_ProjectPartition(ctrl, graph, wspace); + Moc_Global_Partition(ctrl, graph->coarser, wspace); - Mc_ComputePartitionParams(ctrl, graph, wspace); + Moc_ProjectPartition(ctrl, graph, wspace); + Moc_ComputePartitionParams(ctrl, graph, wspace); if (graph->ncon > 1 && graph->level < 3) { for (i=0; i ubavg + 0.035) { if (ctrl->dbglvl&DBG_PROGRESS) { - Mc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); rprintf(ctrl, "nvtxs: %10d, cut: %8d, balance: ", graph->gnvtxs, graph->mincut); for (i=0; incon; i++) rprintf(ctrl, "%.3f ", lbvec[i]); rprintf(ctrl, "\n"); } - Mc_KWayBalance(ctrl, graph, wspace, graph->ncon); + Moc_KWayBalance(ctrl, graph, wspace, graph->ncon); } } - Mc_KWayFM(ctrl, graph, wspace, NGR_PASSES); + Moc_KWayFM(ctrl, graph, wspace, NGR_PASSES); if (ctrl->dbglvl&DBG_PROGRESS) { - Mc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); rprintf(ctrl, "nvtxs: %10d, cut: %8d, balance: ", graph->gnvtxs, graph->mincut); for (i=0; incon; i++) rprintf(ctrl, "%.3f ", lbvec[i]); --- parmetis-3.1.1.orig/ParMETISLib/memory.c +++ parmetis-3.1.1/ParMETISLib/memory.c @@ -15,48 +15,35 @@ #include -/*************************************************************************/ -/*! This function allocate various pools of memory */ -/*************************************************************************/ -void AllocateWSpace(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +/************************************************************************* +* This function allocate various pools of memory +**************************************************************************/ +void PreAllocateMemory(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) { wspace->nlarge = 2*graph->nedges; - wspace->nparts = ctrl->nparts; - wspace->npes = ctrl->npes; wspace->maxcore = 8*graph->nedges+1; - wspace->core = idxmalloc(wspace->maxcore, "AllocateWSpace: wspace->core"); + wspace->core = idxmalloc(wspace->maxcore, "PreAllocateMemory: wspace->core"); wspace->pairs = (KeyValueType *)wspace->core; wspace->indices = (idxtype *)(wspace->pairs + wspace->nlarge); wspace->degrees = (EdgeType *)(wspace->indices + wspace->nlarge); - wspace->pv1 = idxmalloc(ctrl->nparts+ctrl->npes+1, "AllocateWSpace: wspace->pv1"); - wspace->pv2 = idxmalloc(ctrl->nparts+ctrl->npes+1, "AllocateWSpace: wspace->pv2"); - wspace->pv3 = idxmalloc(ctrl->nparts+ctrl->npes+1, "AllocateWSpace: wspace->pv3"); - wspace->pv4 = idxmalloc(ctrl->nparts+ctrl->npes+1, "AllocateWSpace: wspace->pv4"); + wspace->pv1 = idxmalloc(ctrl->nparts+ctrl->npes+1, "PreAllocateMemory: wspace->pv?"); + wspace->pv2 = idxmalloc(ctrl->nparts+ctrl->npes+1, "PreAllocateMemory: wspace->pv?"); + wspace->pv3 = idxmalloc(ctrl->nparts+ctrl->npes+1, "PreAllocateMemory: wspace->pv?"); + wspace->pv4 = idxmalloc(ctrl->nparts+ctrl->npes+1, "PreAllocateMemory: wspace->pv?"); - wspace->pepairs1 = (KeyValueType *)GKmalloc(sizeof(KeyValueType)*(ctrl->nparts+ctrl->npes+1), "AllocateWSpace: wspace->pepairs?"); - wspace->pepairs2 = (KeyValueType *)GKmalloc(sizeof(KeyValueType)*(ctrl->nparts+ctrl->npes+1), "AllocateWSpace: wspace->pepairs?"); + wspace->pepairs1 = (KeyValueType *)GKmalloc(sizeof(KeyValueType)*(ctrl->nparts+ctrl->npes+1), "PreAllocateMemory: wspace->pepairs?"); + wspace->pepairs2 = (KeyValueType *)GKmalloc(sizeof(KeyValueType)*(ctrl->nparts+ctrl->npes+1), "PreAllocateMemory: wspace->pepairs?"); } -/*************************************************************************/ -/*! This function re-allocates the workspace if previous one is not large - enough */ -/*************************************************************************/ -void AdjustWSpace(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) -{ - if (wspace->nlarge < 2*graph->nedges || wspace->nparts < ctrl->nparts || wspace->npes < ctrl->npes) { - FreeWSpace(wspace); - AllocateWSpace(ctrl, graph, wspace); - } -} -/*************************************************************************/ -/*! This function de-allocate various pools of memory */ -/**************************************************************************/ +/************************************************************************* +* This function de-allocate various pools of memory +**************************************************************************/ void FreeWSpace(WorkSpaceType *wspace) { @@ -123,9 +110,8 @@ void InitGraph(GraphType *graph) graph->lnpwgts = graph->gnpwgts = NULL; graph->rinfo = NULL; - graph->nrinfo = NULL; - graph->sepind = NULL; - graph->hmarker = NULL; + graph->nrinfo = NULL; + graph->sepind = NULL; graph->coarser = graph->finer = NULL; @@ -153,7 +139,6 @@ void FreeGraph(GraphType *graph) (void **)&graph->rinfo, (void **)&graph->nrinfo, (void **)&graph->sepind, - (void **)&graph->hmarker, (void **)&graph->lpwgts, (void **)&graph->gpwgts, (void **)&graph->lnpwgts, @@ -180,14 +165,14 @@ void FreeGraph(GraphType *graph) /************************************************************************* * This function deallocates any memory stored in a graph **************************************************************************/ -void FreeInitialGraphAndRemap(GraphType *graph, int wgtflag, int freevsize) +void FreeInitialGraphAndRemap(GraphType *graph, int wgtflag) { int i, nedges; idxtype *adjncy, *imap; nedges = graph->nedges; adjncy = graph->adjncy; - imap = graph->imap; + imap = graph->imap; if (imap != NULL) { for (i=0; ipeadjloc, LTERM); - if (freevsize) - GKfree((void **)&graph->vsize, LTERM); if ((wgtflag&2) == 0) - GKfree((void **)&graph->vwgt, LTERM); + GKfree((void **)&graph->vwgt, (void **)&graph->vsize, LTERM); if ((wgtflag&1) == 0) GKfree((void **)&graph->adjwgt, LTERM); --- /dev/null +++ parmetis-3.1.1/ParMETISLib/coarsen.c @@ -0,0 +1,485 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * mcoarsen.c + * + * This file contains code that performs graph coarsening + * + * Started 2/22/96 + * George + * + * $Id: coarsen.c,v 1.2 2003/07/21 17:18:48 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function creates the coarser graph +**************************************************************************/ +void Moc_Global_CreateCoarseGraph(CtrlType *ctrl, GraphType *graph, + WorkSpaceType *wspace, int cnvtxs) +{ + int h, i, j, k, l, ii, jj, ll, nnbrs, nvtxs, nedges, ncon; + int firstvtx, lastvtx, cfirstvtx, clastvtx, otherlastvtx; + int npes=ctrl->npes, mype=ctrl->mype; + int cnedges, nsend, nrecv, nkeepsize, nrecvsize, nsendsize, v, u; + idxtype *xadj, *ladjncy, *adjwgt, *vwgt, *vsize, *vtxdist, *home; + idxtype *match, *cmap, *rcmap, *scmap; + idxtype *cxadj, *cadjncy, *cadjwgt, *cvwgt, *cvsize = NULL, *chome = NULL, *cvtxdist; + idxtype *rsizes, *ssizes, *rlens, *slens, *rgraph, *sgraph, *perm; + idxtype *peind, *recvptr, *recvind; + float *nvwgt, *cnvwgt; + GraphType *cgraph; + KeyValueType *scand, *rcand; + int mask=(1<<13)-1, htable[8192], htableidx[8192]; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + + vtxdist = graph->vtxdist; + xadj = graph->xadj; + vwgt = graph->vwgt; + vsize = graph->vsize; + nvwgt = graph->nvwgt; + home = graph->home; + ladjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + match = graph->match; + + firstvtx = vtxdist[mype]; + lastvtx = vtxdist[mype+1]; + + cmap = graph->cmap = idxmalloc(nvtxs+graph->nrecv, "CreateCoarseGraph: cmap"); + + nnbrs = graph->nnbrs; + peind = graph->peind; + recvind = graph->recvind; + recvptr = graph->recvptr; + + /* Use wspace->indices as the tmp space for map of the boundary + * vertices that are sent and received */ + scmap = wspace->indices; + rcmap = cmap + nvtxs; + + + /* Initialize the coarser graph */ + cgraph = CreateGraph(); + cgraph->nvtxs = cnvtxs; + cgraph->ncon = ncon; + cgraph->level = graph->level+1; + cgraph->finer = graph; + graph->coarser = cgraph; + + + + /************************************************************* + * Obtain the vtxdist of the coarser graph + **************************************************************/ + cvtxdist = cgraph->vtxdist = idxmalloc(npes+1, "CreateCoarseGraph: cvtxdist"); + cvtxdist[npes] = cnvtxs; /* Use last position in the cvtxdist as a temp buffer */ + + MPI_Allgather((void *)(cvtxdist+npes), 1, IDX_DATATYPE, (void *)cvtxdist, 1, IDX_DATATYPE, ctrl->comm); + + MAKECSR(i, npes, cvtxdist); + + cgraph->gnvtxs = cvtxdist[npes]; + +#ifdef DEBUG_CONTRACT + PrintVector(ctrl, npes+1, 0, cvtxdist, "cvtxdist"); +#endif + + + /************************************************************* + * Construct the cmap vector + **************************************************************/ + cfirstvtx = cvtxdist[mype]; + clastvtx = cvtxdist[mype+1]; + + /* Create the cmap of what you know so far locally */ + cnvtxs = 0; + for (i=0; i= KEEP_BIT) { + k = match[i] - KEEP_BIT; + if (k>=firstvtx && k=firstvtx && knrecv, recvind, match[i])]; + } + } + + CommInterfaceData(ctrl, graph, cmap, scmap, rcmap); + + +#ifdef DEBUG_CONTRACT + PrintVector(ctrl, nvtxs, firstvtx, cmap, "Cmap"); +#endif + + + /************************************************************* + * Determine how many adjcency lists you need to send/receive. + **************************************************************/ + /* Use wspace->pairs as the tmp space for the boundary vertices that are sent and received */ + scand = wspace->pairs; + rcand = graph->rcand = (KeyValueType *)GKmalloc(recvptr[nnbrs]*sizeof(KeyValueType), "CreateCoarseGraph: rcand"); + + nkeepsize = nsend = nrecv = 0; + for (i=0; i=lastvtx) { /* This is comming from afar */ + rcand[nrecv].key = k; + rcand[nrecv].val = cmap[i] - cfirstvtx; /* Set it for use during the partition projection */ + ASSERT(ctrl, rcand[nrecv].val>=0 && rcand[nrecv].valpv1; + ssizes = wspace->pv2; + idxset(nnbrs, 0, ssizes); + idxset(nnbrs, 0, rsizes); + rlens = graph->rlens = idxmalloc(nnbrs+1, "CreateCoarseGraph: graph->rlens"); + slens = graph->slens = idxmalloc(nnbrs+1, "CreateCoarseGraph: graph->slens"); + + /* Take care the sending data first */ + ikeyvalsort(nsend, scand); + slens[0] = 0; + for (k=i=0; i 0) /* Issue a receive only if you are getting something */ + MPI_Irecv((void *)(rsizes+i), 1, IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->rreq+i); + } + + /* Take care the sending data next */ + for (i=0; i 0) /* Issue a send only if you are sending something */ + MPI_Isend((void *)(ssizes+i), 1, IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->sreq+i); + } + + /* OK, now get into the loop waiting for the operations to finish */ + for (i=0; i 0) + MPI_Wait(ctrl->rreq+i, &ctrl->status); + } + for (i=0; i 0) + MPI_Wait(ctrl->sreq+i, &ctrl->status); + } + + +#ifdef DEBUG_CONTRACT + PrintVector(ctrl, nnbrs, 0, rsizes, "rsizes"); + PrintVector(ctrl, nnbrs, 0, ssizes, "ssizes"); +#endif + + /************************************************************* + * Allocate memory for received/sent graphs and start sending + * and receiving data. + * rgraph and sgraph is a different data structure than CSR + * to facilitate single message exchange. + **************************************************************/ + nrecvsize = idxsum(nnbrs, rsizes); + nsendsize = idxsum(nnbrs, ssizes); + if ((4+ncon)*(nrecv+nsend) + 2*(nrecvsize+nsendsize) <= wspace->nlarge) { + rgraph = (idxtype *)wspace->degrees; + sgraph = rgraph + (4+ncon)*nrecv+2*nrecvsize; + } + else { + rgraph = idxmalloc((4+ncon)*nrecv+2*nrecvsize, "CreateCoarseGraph: rgraph"); + sgraph = idxmalloc((4+ncon)*nsend+2*nsendsize, "CreateCoarseGraph: sgraph"); + } + + /* Deal with the received portion first */ + for (l=i=0; i 0) { + MPI_Irecv((void *)(rgraph+l), (4+ncon)*(rlens[i+1]-rlens[i])+2*rsizes[i], IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->rreq+i); + l += (4+ncon)*(rlens[i+1]-rlens[i])+2*rsizes[i]; + } + } + + + /* Deal with the sent portion now */ + for (ll=l=i=0; i 0) { /* Issue a send only if you are sending something */ + for (k=slens[i]; kpartType == STATIC_PARTITION) ? -1 : vsize[ii]; + sgraph[ll++] = (ctrl->partType == STATIC_PARTITION) ? -1 : home[ii]; + for (jj=xadj[ii]; jjcomm, ctrl->sreq+i); + l = ll; + } + } + + /* OK, now get into the loop waiting for the operations to finish */ + for (i=0; i 0) + MPI_Wait(ctrl->rreq+i, &ctrl->status); + } + for (i=0; i 0) + MPI_Wait(ctrl->sreq+i, &ctrl->status); + } + + +#ifdef DEBUG_CONTRACT + rprintf(ctrl, "Graphs were sent!\n"); + PrintTransferedGraphs(ctrl, nnbrs, peind, slens, rlens, sgraph, rgraph); +#endif + + /************************************************************* + * Setup the mapping from indices returned by BSearch to + * those that are actually stored + **************************************************************/ + perm = idxsmalloc(recvptr[nnbrs], -1, "CreateCoarseGraph: perm"); + for (j=i=0; inrecv, recvind, rgraph[j]), j+ncon); */ + perm[BSearch(graph->nrecv, recvind, rgraph[j])] = j+1; + j += (4+ncon)+2*rgraph[j+1]; + } + + /************************************************************* + * Finally, create the coarser graph + **************************************************************/ + /* Allocate memory for the coarser graph, and fire up coarsening */ + cxadj = cgraph->xadj = idxmalloc(cnvtxs+1, "CreateCoarserGraph: cxadj"); + cvwgt = cgraph->vwgt = idxmalloc(cnvtxs*ncon, "CreateCoarserGraph: cvwgt"); + if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { + cvsize = cgraph->vsize = idxmalloc(cnvtxs, "CreateCoarserGraph: cvsize"); + chome = cgraph->home = idxmalloc(cnvtxs, "CreateCoarserGraph: chome"); + } + cnvwgt = cgraph->nvwgt = fmalloc(cnvtxs*ncon, "CreateCoarserGraph: cnvwgt"); + cadjncy = idxmalloc(2*(nkeepsize+nrecvsize), "CreateCoarserGraph: cadjncy"); + cadjwgt = cadjncy + nkeepsize+nrecvsize; + + iset(8192, -1, htable); + + cxadj[0] = cnvtxs = cnedges = 0; + for (i=0; i= KEEP_BIT) { + v = firstvtx+i; + u = match[i]-KEEP_BIT; + + if (u>=firstvtx && u u) + continue; /* I have already collapsed it as (u,v) */ + + /* Collapse the v vertex first, which you know is local */ + for (h=0; hpartType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { + cvsize[cnvtxs] = vsize[i]; + chome[cnvtxs] = home[i]; + } + nedges = 0; + + for (j=xadj[i]; j=firstvtx && upartType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { + cvsize[cnvtxs] += vsize[u]; + /* chome[cnvtxs] = home[u]; */ + } + + for (j=xadj[u]; jnrecv, recvind, u)]; + for (h=0; hpartType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { + cvsize[cnvtxs] += rgraph[u+1+ncon]; + chome[cnvtxs] = rgraph[u+2+ncon]; + } + for (j=0; jnedges = cnedges; + + /* ADD: In order to keep from having to change this too much */ + /* ADD: I kept vwgt array and recomputed nvwgt for each coarser graph */ + for (j=0; jnvwgt[j*ncon+h] = (float)(cvwgt[j*ncon+h])/(float)(ctrl->tvwgts[h]); + + cgraph->adjncy = idxmalloc(cnedges, "CreateCoarserGraph: cadjncy"); + cgraph->adjwgt = idxmalloc(cnedges, "CreateCoarserGraph: cadjwgt"); + idxcopy(cnedges, cadjncy, cgraph->adjncy); + idxcopy(cnedges, cadjwgt, cgraph->adjwgt); + free(cadjncy); + + free(perm); + + if (rgraph != (idxtype *)wspace->degrees) + GKfree((void **)&rgraph, (void **)&sgraph, LTERM); + +} + + --- parmetis-3.1.1.orig/ParMETISLib/kwayfm.c +++ parmetis-3.1.1/ParMETISLib/kwayfm.c @@ -19,7 +19,7 @@ /************************************************************************* * This function performs k-way refinement **************************************************************************/ -void Mc_KWayFM(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace, int npasses) +void Moc_KWayFM(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace, int npasses) { int h, i, ii, iii, j, k, c; int pass, nvtxs, nedges, ncon; @@ -127,7 +127,7 @@ void Mc_KWayFM(CtrlType *ctrl, GraphType oldcut = graph->mincut; /* check to see if the partitioning is imbalanced */ - Mc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); ubavg = savg(ncon, ubvec); lbavg = savg(ncon, lbvec); imbalanced = (lbavg > ubavg) ? 1 : 0; --- parmetis-3.1.1.orig/ParMETISLib/debug.c +++ parmetis-3.1.1/ParMETISLib/debug.c @@ -29,7 +29,7 @@ void PrintVector(CtrlType *ctrl, int n, printf("%s\n", title); printf("\t%3d. ", ctrl->mype); for (i=0; imype); for (i=0; i=KEEP_BIT ? 1 : 0), (vec[i]>=KEEP_BIT ? vec[i]-KEEP_BIT : vec[i])); + printf("[%d %d.%hd] ", first+i, (vec[i]>=KEEP_BIT ? 1 : 0), (vec[i]>=KEEP_BIT ? vec[i]-KEEP_BIT : vec[i])); printf("\n"); fflush(stdout); } @@ -73,7 +73,7 @@ void PrintPairs(CtrlType *ctrl, int n, K printf("%s\n", title); printf("\t%3d. ", ctrl->mype); for (i=0; iwhere = idxmalloc(graph->nvtxs+graph->nrecv, "graph->where"); - Mc_InitPartition_RB(ctrl, graph, wspace); + Moc_InitPartition_RB(ctrl, graph, wspace); if (ctrl->dbglvl&DBG_PROGRESS) { - Mc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); rprintf(ctrl, "nvtxs: %10d, balance: ", graph->gnvtxs); for (i=0; incon; i++) rprintf(ctrl, "%.3f ", lbvec[i]); @@ -60,17 +60,17 @@ void Mc_Global_Partition(CtrlType *ctrl, /* In case no coarsening took place */ if (graph->finer == NULL) { - Mc_ComputePartitionParams(ctrl, graph, wspace); - Mc_KWayFM(ctrl, graph, wspace, NGR_PASSES); + Moc_ComputePartitionParams(ctrl, graph, wspace); + Moc_KWayFM(ctrl, graph, wspace, NGR_PASSES); } } else { - Mc_GlobalMatch_Balance(ctrl, graph, wspace); + Moc_GlobalMatch_Balance(ctrl, graph, wspace); - Mc_Global_Partition(ctrl, graph->coarser, wspace); + Moc_Global_Partition(ctrl, graph->coarser, wspace); - Mc_ProjectPartition(ctrl, graph, wspace); - Mc_ComputePartitionParams(ctrl, graph, wspace); + Moc_ProjectPartition(ctrl, graph, wspace); + Moc_ComputePartitionParams(ctrl, graph, wspace); if (graph->ncon > 1 && graph->level < 3) { for (i=0; i ubavg + 0.035) { if (ctrl->dbglvl&DBG_PROGRESS) { - Mc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); rprintf(ctrl, "nvtxs: %10d, cut: %8d, balance: ", graph->gnvtxs, graph->mincut); for (i=0; incon; i++) rprintf(ctrl, "%.3f ", lbvec[i]); rprintf(ctrl, "\n"); } - Mc_KWayBalance(ctrl, graph, wspace, graph->ncon); + Moc_KWayBalance(ctrl, graph, wspace, graph->ncon); } } - Mc_KWayFM(ctrl, graph, wspace, NGR_PASSES); + Moc_KWayFM(ctrl, graph, wspace, NGR_PASSES); if (ctrl->dbglvl&DBG_PROGRESS) { - Mc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); rprintf(ctrl, "nvtxs: %10d, cut: %8d, balance: ", graph->gnvtxs, graph->mincut); for (i=0; incon; i++) rprintf(ctrl, "%.3f ", lbvec[i]); --- parmetis-3.1.1.orig/ParMETISLib/kwayrefine.c +++ parmetis-3.1.1/ParMETISLib/kwayrefine.c @@ -19,7 +19,7 @@ /************************************************************************* * This function projects a partition. **************************************************************************/ -void Mc_ProjectPartition(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +void Moc_ProjectPartition(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) { int i, nvtxs, nnbrs = -1, firstvtx, cfirstvtx; idxtype *match, *cmap, *where, *cwhere; @@ -30,14 +30,14 @@ void Mc_ProjectPartition(CtrlType *ctrl, IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr)); - cgraph = graph->coarser; - cwhere = cgraph->where; + cgraph = graph->coarser; + cwhere = cgraph->where; cfirstvtx = cgraph->vtxdist[ctrl->mype]; - nvtxs = graph->nvtxs; - match = graph->match; - cmap = graph->cmap; - where = graph->where = idxmalloc(nvtxs+graph->nrecv, "ProjectPartition: graph->where"); + nvtxs = graph->nvtxs; + match = graph->match; + cmap = graph->cmap; + where = graph->where = idxmalloc(nvtxs+graph->nrecv, "ProjectPartition: graph->where"); firstvtx = graph->vtxdist[ctrl->mype]; @@ -128,46 +128,56 @@ void Mc_ProjectPartition(CtrlType *ctrl, /************************************************************************* * This function computes the initial id/ed **************************************************************************/ -void Mc_ComputePartitionParams(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +void Moc_ComputePartitionParams(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) { - int h, i, j, k, nvtxs, ncon, firstvtx, lastvtx; - idxtype *xadj, *ladjncy, *adjwgt, *vtxdist, *where; + int h, i, j, k; + int nvtxs, ncon; + int firstvtx, lastvtx; + idxtype *xadj, *ladjncy, *adjwgt, *vtxdist; float *lnpwgts, *gnpwgts; + idxtype *where, *swhere, *rwhere; RInfoType *rinfo, *myrinfo; EdgeType *edegrees; int me, other; IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->KWayInitTmr)); - nvtxs = graph->nvtxs; - ncon = graph->ncon; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + vtxdist = graph->vtxdist; - xadj = graph->xadj; + xadj = graph->xadj; ladjncy = graph->adjncy; - adjwgt = graph->adjwgt; - where = graph->where; + adjwgt = graph->adjwgt; - rinfo = graph->rinfo = (RInfoType *)GKmalloc(sizeof(RInfoType)*nvtxs, "CPP: rinfo"); - lnpwgts = graph->lnpwgts = fsmalloc(ctrl->nparts*ncon, 0.0, "CPP: lnpwgts"); + where = graph->where; + rinfo = graph->rinfo = (RInfoType *)GKmalloc(sizeof(RInfoType)*nvtxs, "CPP: rinfo"); + lnpwgts = graph->lnpwgts = fmalloc(ctrl->nparts*ncon, "CPP: lnpwgts"); gnpwgts = graph->gnpwgts = fmalloc(ctrl->nparts*ncon, "CPP: gnpwgts"); + sset(ctrl->nparts*ncon, 0, lnpwgts); + firstvtx = vtxdist[ctrl->mype]; - lastvtx = vtxdist[ctrl->mype+1]; + lastvtx = vtxdist[ctrl->mype+1]; /*------------------------------------------------------------ / Send/Receive the where information of interface vertices /------------------------------------------------------------*/ - CommInterfaceData(ctrl, graph, where, wspace->indices, where+nvtxs); + swhere = wspace->indices; + rwhere = where + nvtxs; + + CommInterfaceData(ctrl, graph, where, swhere, rwhere); #ifdef DEBUG_COMPUTEPPARAM PrintVector(ctrl, nvtxs, firstvtx, where, "where"); #endif + ASSERT(ctrl, wspace->nlarge >= xadj[nvtxs]); /*------------------------------------------------------------ / Compute now the id/ed degrees /------------------------------------------------------------*/ - ASSERT(ctrl, wspace->nlarge >= xadj[nvtxs]); graph->lmincut = 0; for (i=0; invwgt[i*ncon+h]; - myrinfo->degrees = wspace->degrees + xadj[i]; + myrinfo->degrees = wspace->degrees + xadj[i]; myrinfo->ndegrees = myrinfo->id = myrinfo->ed = 0; for (j=xadj[i]; jadjncy; firstvtx = vtxdist[mype]; - lastvtx = vtxdist[mype+1]; + lastvtx = vtxdist[mype+1]; pemap = wspace->pv1; idxset(npes, -1, pemap); @@ -65,12 +65,12 @@ void SetUp(CtrlType *ctrl, GraphType *gr adjncy[j] = k-firstvtx; continue; /* local vertex */ } - adjpairs[nadj].key = k; + adjpairs[nadj].key = k; adjpairs[nadj++].val = j; islocal = 0; } if (islocal) { - lperm[i] = lperm[nlocal]; + lperm[i] = lperm[nlocal]; lperm[nlocal++] = i; } } @@ -86,7 +86,7 @@ void SetUp(CtrlType *ctrl, GraphType *gr /* Allocate space for the setup info attached to this level of the graph */ - peind = graph->peind = idxmalloc(npes, "SetUp: peind"); + peind = graph->peind = idxmalloc(npes, "SetUp: peind"); recvptr = graph->recvptr = idxmalloc(npes+1, "SetUp: recvptr"); recvind = graph->recvind = idxmalloc(nrecv, "SetUp: recvind"); @@ -100,12 +100,11 @@ void SetUp(CtrlType *ctrl, GraphType *gr break; } if (j > i) { - peind[nnbrs] = penum; + peind[nnbrs] = penum; recvptr[++nnbrs] = j; i = j; } } - //PrintVector(ctrl, nnbrs+1, 0, recvptr, "recvptr"); /************************************************************* @@ -114,33 +113,28 @@ void SetUp(CtrlType *ctrl, GraphType *gr /* Tell the other processors what they need to send you */ recvrequests = wspace->pepairs1; sendrequests = wspace->pepairs2; - for (i=0; icomm); - //PrintPairs(ctrl, npes, recvrequests, "recvrequests"); - //PrintPairs(ctrl, npes, sendrequests, "sendrequests"); sendptr = graph->sendptr = idxmalloc(npes+1, "SetUp: sendptr"); startsind = wspace->pv2; for (j=i=0; i 0) { - sendptr[j] = sendrequests[i].key; + sendptr[j] = sendrequests[i].key; startsind[j] = sendrequests[i].val; j++; } } + ASSERT(ctrl, nnbrs == j); + MAKECSR(i, j, sendptr); - ASSERT(ctrl, j == nnbrs); - MAKECSR(i, nnbrs, sendptr); - - nsend = sendptr[nnbrs]; + nsend = sendptr[nnbrs]; sendind = graph->sendind = idxmalloc(nsend, "SetUp: sendind"); @@ -162,7 +156,7 @@ void SetUp(CtrlType *ctrl, GraphType *gr /* Create the peadjncy data structure for sparse boundary exchanges */ - pexadj = graph->pexadj = idxsmalloc(nvtxs+1, 0, "SetUp: pexadj"); + pexadj = graph->pexadj = idxsmalloc(nvtxs+1, 0, "SetUp: pexadj"); peadjncy = graph->peadjncy = idxmalloc(nsend, "SetUp: peadjncy"); peadjloc = graph->peadjloc = idxmalloc(nsend, "SetUp: peadjloc"); @@ -186,9 +180,9 @@ void SetUp(CtrlType *ctrl, GraphType *gr pexadj[0] = 0; - graph->nnbrs = nnbrs; - graph->nrecv = nrecv; - graph->nsend = nsend; + graph->nnbrs = nnbrs; + graph->nrecv = nrecv; + graph->nsend = nsend; graph->nlocal = nlocal; --- parmetis-3.1.1.orig/ParMETISLib/akwayfm.c +++ parmetis-3.1.1/ParMETISLib/akwayfm.c @@ -20,7 +20,7 @@ /************************************************************************* * This function performs k-way refinement **************************************************************************/ -void Mc_KWayAdaptiveRefine(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace, int npasses) +void Moc_KWayAdaptiveRefine(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace, int npasses) { int h, i, ii, iii, j, k, c; int pass, nvtxs, nedges, ncon; @@ -152,7 +152,7 @@ void Mc_KWayAdaptiveRefine(CtrlType *ctr FastRandomPermute(nclean, perm+ndirty, 0); /* check to see if the partitioning is imbalanced */ - Mc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); ubavg = savg(ncon, ubvec); lbavg = savg(ncon, lbvec); imbalanced = (lbavg > ubavg) ? 1 : 0; --- parmetis-3.1.1.orig/ParMETISLib/redomylink.c +++ parmetis-3.1.1/ParMETISLib/redomylink.c @@ -118,11 +118,11 @@ MPI_Comm_rank(MPI_COMM_WORLD, &mype); lastseed = (lastseed+1) % nvtxs; where[r] = 0; - Mc_Serial_Compute2WayPartitionParams(graph); - Mc_Serial_Init2WayBalance(graph, tpwgts); - Mc_Serial_FM_2WayRefine(graph, tpwgts, 4); - Mc_Serial_Balance2Way(graph, tpwgts, 1.02); - Mc_Serial_FM_2WayRefine(graph, tpwgts, 4); + Moc_Serial_Compute2WayPartitionParams(graph); + Moc_Serial_Init2WayBalance(graph, tpwgts); + Moc_Serial_FM_2WayRefine(graph, tpwgts, 4); + Moc_Serial_Balance2Way(graph, tpwgts, 1.02); + Moc_Serial_FM_2WayRefine(graph, tpwgts, 4); for (i=0; i= (b) ? (a) : (b)) #define amin(a, b) ((a) >= (b) ? (b) : (a)) @@ -99,45 +98,52 @@ -#ifndef NDEBUG +#ifdef DEBUG # define ASSERT(ctrl, expr) \ if (!(expr)) { \ - myprintf(ctrl, "***ASSERTION failed on line %d of file %s: " #expr "\n", \ - __LINE__, __FILE__); \ - assert(expr); \ + myprintf(ctrl, "***ASSERTION failed on line %d of file %s: " #expr "\n", \ + __LINE__, __FILE__); \ + abort(); \ } +#else +# define ASSERT(ctrl, expr) ; +#endif +#ifdef DEBUG # define ASSERTP(ctrl, expr, msg) \ if (!(expr)) { \ myprintf(ctrl, "***ASSERTION failed on line %d of file %s:" #expr "\n", \ __LINE__, __FILE__); \ myprintf msg ; \ - assert(expr); \ + abort(); \ } +#else +# define ASSERTP(ctrl, expr,msg) ; +#endif +#ifdef DEBUGS # define ASSERTS(expr) \ if (!(expr)) { \ printf("***ASSERTION failed on line %d of file %s: " #expr "\n", \ __LINE__, __FILE__); \ - assert(expr); \ + abort(); \ } +#else +# define ASSERTS(expr) ; +#endif +#ifdef DEBUGS # define ASSERTSP(expr, msg) \ if (!(expr)) { \ printf("***ASSERTION failed on line %d of file %s: " #expr "\n", \ __LINE__, __FILE__); \ printf msg ; \ - assert(expr); \ + abort(); \ } - #else -# define ASSERT(ctrl, expr) ; -# define ASSERTP(ctrl, expr,msg) ; -# define ASSERTS(expr) ; # define ASSERTSP(expr, msg) ; #endif - /************************************************************************* * * These macros insert and remove nodes from the boundary list * **************************************************************************/ --- parmetis-3.1.1.orig/ParMETISLib/parmetislib.h +++ parmetis-3.1.1/ParMETISLib/parmetislib.h @@ -16,16 +16,17 @@ #define DMALLOC 1 */ -#include -#include "../parmetis.h" +#include + #ifdef DMALLOC #include #endif -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include --- parmetis-3.1.1.orig/ParMETISLib/match.c +++ parmetis-3.1.1/ParMETISLib/match.c @@ -18,7 +18,7 @@ /************************************************************************* * This function finds a matching **************************************************************************/ -void Mc_GlobalMatch_Balance(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +void Moc_GlobalMatch_Balance(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) { int h, i, ii, j, k; int nnbrs, nvtxs, ncon, cnvtxs, firstvtx, lastvtx, maxi, maxidx, nkept; @@ -31,8 +31,6 @@ void Mc_GlobalMatch_Balance(CtrlType *ct int *nreqs_pe; KeyValueType *match_requests, *match_granted, *pe_requests; - ASSERT(ctrl, wspace->nlarge > graph->xadj[graph->nvtxs]); - maxnvwgt = 1.0/((float)(ctrl->nparts)*MAXNVWGT_FACTOR); graph->match_type = MATCH_GLOBAL; @@ -40,19 +38,19 @@ void Mc_GlobalMatch_Balance(CtrlType *ct IFSET(ctrl->dbglvl, DBG_TIME, MPI_Barrier(ctrl->comm)); IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr)); - nvtxs = graph->nvtxs; - ncon = graph->ncon; - xadj = graph->xadj; + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; ladjncy = graph->adjncy; - adjwgt = graph->adjwgt; - home = graph->home; - nvwgt = graph->nvwgt; + adjwgt = graph->adjwgt; + home = graph->home; + nvwgt = graph->nvwgt; - vtxdist = graph->vtxdist; + vtxdist = graph->vtxdist; firstvtx = vtxdist[ctrl->mype]; - lastvtx = vtxdist[ctrl->mype+1]; + lastvtx = vtxdist[ctrl->mype+1]; - match = graph->match = idxsmalloc(nvtxs+graph->nrecv, UNMATCHED, "HEM_Match: match"); + match = graph->match = idxsmalloc(nvtxs+graph->nrecv, UNMATCHED, "HEM_Match: match"); myhome = idxsmalloc(nvtxs+graph->nrecv, UNMATCHED, "HEM_Match: myhome"); /*------------------------------------------------------------ @@ -313,485 +311,10 @@ void Mc_GlobalMatch_Balance(CtrlType *ct IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr)); IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ContractTmr)); - Mc_Global_CreateCoarseGraph(ctrl, graph, wspace, cnvtxs); + Moc_Global_CreateCoarseGraph(ctrl, graph, wspace, cnvtxs); IFSET(ctrl->dbglvl, DBG_TIME, MPI_Barrier(ctrl->comm)); IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ContractTmr)); } - -/************************************************************************* -* This function creates the coarser graph -**************************************************************************/ -void Mc_Global_CreateCoarseGraph(CtrlType *ctrl, GraphType *graph, - WorkSpaceType *wspace, int cnvtxs) -{ - int h, i, j, k, l, ii, jj, ll, nnbrs, nvtxs, nedges, ncon; - int firstvtx, lastvtx, cfirstvtx, clastvtx, otherlastvtx; - int npes=ctrl->npes, mype=ctrl->mype; - int cnedges, nsend, nrecv, nkeepsize, nrecvsize, nsendsize, v, u; - idxtype *xadj, *ladjncy, *adjwgt, *vwgt, *vsize, *vtxdist, *home, *where; - idxtype *match, *cmap, *rcmap, *scmap; - idxtype *cxadj, *cadjncy, *cadjwgt, *cvwgt, *cvsize = NULL, *chome = NULL, - *cwhere = NULL, *cvtxdist; - idxtype *rsizes, *ssizes, *rlens, *slens, *rgraph, *sgraph, *perm; - idxtype *peind, *recvptr, *recvind; - float *nvwgt, *cnvwgt; - GraphType *cgraph; - KeyValueType *scand, *rcand; - int mask=(1<<13)-1, htable[8192], htableidx[8192]; - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - - vtxdist = graph->vtxdist; - xadj = graph->xadj; - vwgt = graph->vwgt; - vsize = graph->vsize; - nvwgt = graph->nvwgt; - home = graph->home; - where = graph->where; - ladjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - match = graph->match; - - firstvtx = vtxdist[mype]; - lastvtx = vtxdist[mype+1]; - - cmap = graph->cmap = idxmalloc(nvtxs+graph->nrecv, "CreateCoarseGraph: cmap"); - - nnbrs = graph->nnbrs; - peind = graph->peind; - recvind = graph->recvind; - recvptr = graph->recvptr; - - /* Use wspace->indices as the tmp space for map of the boundary - * vertices that are sent and received */ - scmap = wspace->indices; - rcmap = cmap + nvtxs; - - - /* Initialize the coarser graph */ - cgraph = CreateGraph(); - cgraph->nvtxs = cnvtxs; - cgraph->ncon = ncon; - cgraph->level = graph->level+1; - cgraph->finer = graph; - graph->coarser = cgraph; - - - - /************************************************************* - * Obtain the vtxdist of the coarser graph - **************************************************************/ - cvtxdist = cgraph->vtxdist = idxmalloc(npes+1, "CreateCoarseGraph: cvtxdist"); - cvtxdist[npes] = cnvtxs; /* Use last position in the cvtxdist as a temp buffer */ - - MPI_Allgather((void *)(cvtxdist+npes), 1, IDX_DATATYPE, (void *)cvtxdist, 1, IDX_DATATYPE, ctrl->comm); - - MAKECSR(i, npes, cvtxdist); - - cgraph->gnvtxs = cvtxdist[npes]; - -#ifdef DEBUG_CONTRACT - PrintVector(ctrl, npes+1, 0, cvtxdist, "cvtxdist"); -#endif - - - /************************************************************* - * Construct the cmap vector - **************************************************************/ - cfirstvtx = cvtxdist[mype]; - clastvtx = cvtxdist[mype+1]; - - /* Create the cmap of what you know so far locally */ - cnvtxs = 0; - for (i=0; i= KEEP_BIT) { - k = match[i] - KEEP_BIT; - if (k>=firstvtx && k=firstvtx && knrecv, recvind, match[i])]; - } - } - - CommInterfaceData(ctrl, graph, cmap, scmap, rcmap); - - -#ifdef DEBUG_CONTRACT - PrintVector(ctrl, nvtxs, firstvtx, cmap, "Cmap"); -#endif - - - /************************************************************* - * Determine how many adjcency lists you need to send/receive. - **************************************************************/ - /* Use wspace->pairs as the tmp space for the boundary vertices that are sent and received */ - scand = wspace->pairs; - rcand = graph->rcand = (KeyValueType *)GKmalloc(recvptr[nnbrs]*sizeof(KeyValueType), "CreateCoarseGraph: rcand"); - - nkeepsize = nsend = nrecv = 0; - for (i=0; i=lastvtx) { /* This is comming from afar */ - rcand[nrecv].key = k; - rcand[nrecv].val = cmap[i] - cfirstvtx; /* Set it for use during the partition projection */ - ASSERT(ctrl, rcand[nrecv].val>=0 && rcand[nrecv].valpv1; - ssizes = wspace->pv2; - idxset(nnbrs, 0, ssizes); - idxset(nnbrs, 0, rsizes); - rlens = graph->rlens = idxmalloc(nnbrs+1, "CreateCoarseGraph: graph->rlens"); - slens = graph->slens = idxmalloc(nnbrs+1, "CreateCoarseGraph: graph->slens"); - - /* Take care the sending data first */ - ikeyvalsort(nsend, scand); - slens[0] = 0; - for (k=i=0; i 0) /* Issue a receive only if you are getting something */ - MPI_Irecv((void *)(rsizes+i), 1, IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->rreq+i); - } - - /* Take care the sending data next */ - for (i=0; i 0) /* Issue a send only if you are sending something */ - MPI_Isend((void *)(ssizes+i), 1, IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->sreq+i); - } - - /* OK, now get into the loop waiting for the operations to finish */ - for (i=0; i 0) - MPI_Wait(ctrl->rreq+i, &ctrl->status); - } - for (i=0; i 0) - MPI_Wait(ctrl->sreq+i, &ctrl->status); - } - - -#ifdef DEBUG_CONTRACT - PrintVector(ctrl, nnbrs, 0, rsizes, "rsizes"); - PrintVector(ctrl, nnbrs, 0, ssizes, "ssizes"); -#endif - - /************************************************************* - * Allocate memory for received/sent graphs and start sending - * and receiving data. - * rgraph and sgraph is a different data structure than CSR - * to facilitate single message exchange. - **************************************************************/ - nrecvsize = idxsum(nnbrs, rsizes); - nsendsize = idxsum(nnbrs, ssizes); - if ((4+ncon)*(nrecv+nsend) + 2*(nrecvsize+nsendsize) <= wspace->nlarge) { - rgraph = (idxtype *)wspace->degrees; - sgraph = rgraph + (4+ncon)*nrecv+2*nrecvsize; - } - else { - rgraph = idxmalloc((4+ncon)*nrecv+2*nrecvsize, "CreateCoarseGraph: rgraph"); - sgraph = idxmalloc((4+ncon)*nsend+2*nsendsize, "CreateCoarseGraph: sgraph"); - } - - /* Deal with the received portion first */ - for (l=i=0; i 0) { - MPI_Irecv((void *)(rgraph+l), (4+ncon)*(rlens[i+1]-rlens[i])+2*rsizes[i], IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->rreq+i); - l += (4+ncon)*(rlens[i+1]-rlens[i])+2*rsizes[i]; - } - } - - - /* Deal with the sent portion now */ - for (ll=l=i=0; i 0) { /* Issue a send only if you are sending something */ - for (k=slens[i]; kpartType == STATIC_PARTITION) ? -1 : vsize[ii]; - sgraph[ll++] = (ctrl->partType == STATIC_PARTITION) ? -1 : home[ii]; - for (jj=xadj[ii]; jjcomm, ctrl->sreq+i); - l = ll; - } - } - - /* OK, now get into the loop waiting for the operations to finish */ - for (i=0; i 0) - MPI_Wait(ctrl->rreq+i, &ctrl->status); - } - for (i=0; i 0) - MPI_Wait(ctrl->sreq+i, &ctrl->status); - } - - -#ifdef DEBUG_CONTRACT - rprintf(ctrl, "Graphs were sent!\n"); - PrintTransferedGraphs(ctrl, nnbrs, peind, slens, rlens, sgraph, rgraph); -#endif - - /************************************************************* - * Setup the mapping from indices returned by BSearch to - * those that are actually stored - **************************************************************/ - perm = idxsmalloc(recvptr[nnbrs], -1, "CreateCoarseGraph: perm"); - for (j=i=0; inrecv, recvind, rgraph[j]), j+ncon); */ - perm[BSearch(graph->nrecv, recvind, rgraph[j])] = j+1; - j += (4+ncon)+2*rgraph[j+1]; - } - - /************************************************************* - * Finally, create the coarser graph - **************************************************************/ - /* Allocate memory for the coarser graph, and fire up coarsening */ - cxadj = cgraph->xadj = idxmalloc(cnvtxs+1, "CreateCoarserGraph: cxadj"); - cvwgt = cgraph->vwgt = idxmalloc(cnvtxs*ncon, "CreateCoarserGraph: cvwgt"); - cnvwgt = cgraph->nvwgt = fmalloc(cnvtxs*ncon, "CreateCoarserGraph: cnvwgt"); - cadjncy = idxmalloc(2*(nkeepsize+nrecvsize), "CreateCoarserGraph: cadjncy"); - cadjwgt = cadjncy + nkeepsize+nrecvsize; - if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { - cvsize = cgraph->vsize = idxmalloc(cnvtxs, "CreateCoarserGraph: cvsize"); - chome = cgraph->home = idxmalloc(cnvtxs, "CreateCoarserGraph: chome"); - } - if (where != NULL) /* This is used only by the ordering code for now */ - cwhere = cgraph->where = idxmalloc(cnvtxs, "CreateCoarserGraph: cwhere"); - - iset(8192, -1, htable); - - cxadj[0] = cnvtxs = cnedges = 0; - for (i=0; i= KEEP_BIT) { - v = firstvtx+i; - u = match[i]-KEEP_BIT; - - if (u>=firstvtx && u u) - continue; /* I have already collapsed it as (u,v) */ - - /* Collapse the v vertex first, which you know is local */ - for (h=0; hpartType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { - cvsize[cnvtxs] = vsize[i]; - chome[cnvtxs] = home[i]; - } - if (where != NULL) - cwhere[cnvtxs] = where[i]; - nedges = 0; - - for (j=xadj[i]; j=firstvtx && upartType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { - cvsize[cnvtxs] += vsize[u]; - /* chome[cnvtxs] = home[u]; */ - } - - for (j=xadj[u]; jnrecv, recvind, u)]; - for (h=0; hpartType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { - cvsize[cnvtxs] += rgraph[u+1+ncon]; - chome[cnvtxs] = rgraph[u+2+ncon]; - } - for (j=0; jnedges = cnedges; - - /* ADD: In order to keep from having to change this too much */ - /* ADD: I kept vwgt array and recomputed nvwgt for each coarser graph */ - for (j=0; jnvwgt[j*ncon+h] = (float)(cvwgt[j*ncon+h])/(float)(ctrl->tvwgts[h]); - - cgraph->adjncy = idxmalloc(cnedges, "CreateCoarserGraph: cadjncy"); - cgraph->adjwgt = idxmalloc(cnedges, "CreateCoarserGraph: cadjwgt"); - idxcopy(cnedges, cadjncy, cgraph->adjncy); - idxcopy(cnedges, cadjwgt, cgraph->adjwgt); - - /* Note that graph->where works fine even if it is NULL */ - GKfree((void **)&cadjncy, &graph->where, &perm, LTERM); - - if (rgraph != (idxtype *)wspace->degrees) - GKfree((void **)&rgraph, &sgraph, LTERM); - -} - - --- parmetis-3.1.1.orig/ParMETISLib/order.c +++ parmetis-3.1.1/ParMETISLib/order.c @@ -16,26 +16,19 @@ #include -/*********************************************************************************/ -/*! - This is the top level ordering routine. - \param order is the computed ordering. - \param sizes is the 2*nparts array that will store the sizes of each subdomains - and the sizes of the separators at each level. Note that the - top-level separator is stores at \c sizes[2*nparts-2]. -*/ -/*********************************************************************************/ -void MultilevelOrder(CtrlType *ctrl, GraphType *graph, idxtype *order, idxtype *sizes, - WorkSpaceType *wspace) +/************************************************************************* +* This is the top level ordering routine +**************************************************************************/ +void MultilevelOrder(CtrlType *ctrl, GraphType *graph, idxtype *order, idxtype *sizes, WorkSpaceType *wspace) { int i, nparts, nvtxs, npes; idxtype *perm, *lastnode, *morder, *porder; GraphType *mgraph; - npes = ctrl->npes; + npes = ctrl->npes; nvtxs = graph->nvtxs; - perm = idxmalloc(nvtxs, "MultilevelOrder: perm"); + perm = idxmalloc(nvtxs, "MultilevelOrder: perm"); lastnode = idxsmalloc(4*npes, -1, "MultilevelOrder: lastnode"); for (i=0; i=nparts) - that has not yet been filled in so that the separator sizes of the succesive - levels will be stored correctly. It is used in LabelSeparatos() */ sizes[0] = 2*npes-1; graph->where = idxsmalloc(nvtxs, 0, "MultilevelOrder: graph->where"); @@ -74,8 +64,8 @@ void MultilevelOrder(CtrlType *ctrl, Gra IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MoveTmr)); SetUp(ctrl, graph, wspace); - graph->ncon = 1; /*needed for Mc_MoveGraph */ - mgraph = Mc_MoveGraph(ctrl, graph, wspace); + graph->ncon = 1; /*needed for Moc_MoveGraph */ + mgraph = Moc_MoveGraph(ctrl, graph, wspace); /* Fill in the sizes[] array for the local part. Just the vtxdist of the mgraph */ for (i=0; inparts; - nvtxs = graph->nvtxs; - where = graph->where; + nvtxs = graph->nvtxs; + where = graph->where; lpwgts = graph->lpwgts; gpwgts = graph->gpwgts; /* Compute the local size of the separator. This is required in case the - graph has vertex weights */ + * graph has vertex weights */ idxset(2*nparts, 0, lpwgts); for (i=0; i=0; i-=2) sizes[--sizes[0]] = gpwgts[nparts+i]; - if (ctrl->dbglvl&DBG_INFO) { + if (ctrl->dbglvl&DBG_INFO) { if (ctrl->mype == 0) { printf("SepSizes: "); for (i=0; i= nparts) { sid = where[i]; @@ -176,32 +161,34 @@ void LabelSeparators(CtrlType *ctrl, Gra /* Update lastnode array */ idxcopy(2*nparts, lastnode, sizescan); for (i=0; inparts; - npes = ctrl->npes; + npes = ctrl->npes; - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; + nvtxs = graph->nvtxs; + xadj = graph->xadj; + ladjncy = graph->adjncy; adjwgt = graph->adjwgt; - where = graph->where; + where = graph->where; if (graph->cmap == NULL) graph->cmap = idxmalloc(nvtxs+graph->nrecv, "CompactGraph: cmap"); @@ -214,10 +201,9 @@ void CompactGraph(CtrlType *ctrl, GraphT * that lpwgts stores the local non separator vertices. **************************************************************/ cvtxdist = wspace->pv1; - cnvtxs = idxsum(nparts, graph->lpwgts); + cnvtxs = cvtxdist[npes] = idxsum(nparts, graph->lpwgts); - MPI_Allgather((void *)&cnvtxs, 1, IDX_DATATYPE, (void *)cvtxdist, 1, IDX_DATATYPE, - ctrl->comm); + MPI_Allgather((void *)(cvtxdist+npes), 1, IDX_DATATYPE, (void *)cvtxdist, 1, IDX_DATATYPE, ctrl->comm); MAKECSR(i, npes, cvtxdist); #ifdef DEBUG_ORDER @@ -249,36 +235,37 @@ void CompactGraph(CtrlType *ctrl, GraphT for (i=0; i= nparts); - if (where[i] == where[adjncy[j]]) { - adjncy[l] = cmap[adjncy[j]]; + if (where[i] == where[ladjncy[j]]) { + ladjncy[l] = cmap[ladjncy[j]]; adjwgt[l++] = adjwgt[j]; } +#ifdef DEBUG_ORDER + else if (where[ladjncy[j]] < nparts) + printf("It seems that the separation has failed: %d %d\n", where[i], where[ladjncy[j]]); +#endif } xadj[cnvtxs] = l; graph->vwgt[cnvtxs] = graph->vwgt[i]; - newwhere[cnvtxs] = where[i]; + newwhere[cnvtxs] = where[i]; cnvtxs++; } } - SHIFTCSR(i, cnvtxs, xadj); - - GKfree((void **)&graph->match, (void **)&graph->cmap, (void **)&graph->lperm, - (void **)&graph->where, (void **)&graph->label, (void **)&graph->rinfo, - (void **)&graph->nrinfo, (void **)&graph->lpwgts, (void **)&graph->gpwgts, - (void **)&graph->sepind, (void **)&graph->hmarker, (void **)&graph->peind, - (void **)&graph->sendptr, (void **)&graph->sendind, - (void **)&graph->recvptr, (void **)&graph->recvind, - (void **)&graph->imap, (void **)&graph->rlens, (void **)&graph->slens, - (void **)&graph->rcand, (void **)&graph->pexadj, + for (i=cnvtxs; i>0; i--) + xadj[i] = xadj[i-1]; + xadj[0] = 0; + + GKfree((void **)&graph->match, (void **)&graph->cmap, (void **)&graph->lperm, (void **)&graph->where, (void **)&graph->label, (void **)&graph->rinfo, + (void **)&graph->nrinfo, (void **)&graph->lpwgts, (void **)&graph->gpwgts, (void **)&graph->sepind, (void **)&graph->peind, + (void **)&graph->sendptr, (void **)&graph->sendind, (void **)&graph->recvptr, (void **)&graph->recvind, + (void **)&graph->imap, (void **)&graph->rlens, (void **)&graph->slens, (void **)&graph->rcand, (void **)&graph->pexadj, (void **)&graph->peadjncy, (void **)&graph->peadjloc, LTERM); - graph->nvtxs = cnvtxs; + graph->nvtxs = cnvtxs; graph->nedges = l; graph->gnvtxs = cvtxdist[npes]; - graph->where = newwhere; idxcopy(npes+1, cvtxdist, graph->vtxdist); + graph->where = newwhere; } @@ -294,12 +281,12 @@ void LocalNDOrder(CtrlType *ctrl, GraphT idxtype *perm, *iperm; int numflag=0, options[10]; - nvtxs = graph->nvtxs; - xadj = graph->xadj; + nvtxs = graph->nvtxs; + xadj = graph->xadj; adjncy = graph->adjncy; firstvtx = graph->vtxdist[ctrl->mype]; - lastvtx = graph->vtxdist[ctrl->mype+1]; + lastvtx = graph->vtxdist[ctrl->mype+1]; /* Relabel the vertices so that they are in local index space */ for (i=0; i=0 && iperm[i]ncon = 1; @@ -340,26 +325,23 @@ void Order_Partition(CtrlType *ctrl, Gra GlobalSEMax(ctrl, graph->nvtxs), ctrl->CoarsenTo, GlobalSEMax(ctrl, graph->vwgt[idxamax(graph->nvtxs, graph->vwgt)]))); - if ((graph->gnvtxs < 1.66*ctrl->CoarsenTo) || - (graph->finer != NULL && graph->gnvtxs > graph->finer->gnvtxs*COARSEN_FRACTION)) { + if (graph->gnvtxs < 1.3*ctrl->CoarsenTo || (graph->finer != NULL && graph->gnvtxs > graph->finer->gnvtxs*COARSEN_FRACTION)) { /* Compute the initial npart-way multisection */ InitMultisection(ctrl, graph, wspace); - if (graph->finer == NULL) { /* Do that only if no-coarsening took place */ - AllocateNodePartitionParams(ctrl, graph, wspace); + if (graph->finer == NULL) { /* Do that only of no-coarsening took place */ ComputeNodePartitionParams(ctrl, graph, wspace); - KWayNodeRefine(ctrl, graph, wspace, NGR_PASSES, ORDER_UNBALANCE_FRACTION); + KWayNodeRefine(ctrl, graph, wspace, 2*NGR_PASSES, ORDER_UNBALANCE_FRACTION); } } - else { /* Coarsen it and then partition it */ + else { /* Coarsen it and the partition it */ Mc_LocalMatch_HEM(ctrl, graph, wspace); Order_Partition(ctrl, graph->coarser, wspace); - Mc_ProjectPartition(ctrl, graph, wspace); - AllocateNodePartitionParams(ctrl, graph, wspace); + Moc_ProjectPartition(ctrl, graph, wspace); ComputeNodePartitionParams(ctrl, graph, wspace); - KWayNodeRefine(ctrl, graph, wspace, NGR_PASSES, ORDER_UNBALANCE_FRACTION); + KWayNodeRefine(ctrl, graph, wspace, 2*NGR_PASSES, ORDER_UNBALANCE_FRACTION); } } --- parmetis-3.1.1.orig/ParMETISLib/kwaybalance.c +++ parmetis-3.1.1/ParMETISLib/kwaybalance.c @@ -19,7 +19,7 @@ /************************************************************************* * This function performs k-way refinement **************************************************************************/ -void Mc_KWayBalance(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace, int npasses) +void Moc_KWayBalance(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace, int npasses) { int h, i, ii, iii, j, k, c; int pass, nvtxs, nedges, ncon; @@ -147,7 +147,7 @@ void Mc_KWayBalance(CtrlType *ctrl, Grap */ /* check to see if the partitioning is imbalanced */ - Mc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); ubavg = savg(ncon, ubvec); lbavg = savg(ncon, lbvec); imbalanced = (lbavg > ubavg) ? 1 : 0; --- parmetis-3.1.1.orig/ParMETISLib/initmsection.c +++ parmetis-3.1.1/ParMETISLib/initmsection.c @@ -18,36 +18,17 @@ -/************************************************************************************/ -/*! - The entry point of the algorithm that finds the separators of the coarsest graph. - This algorithm first assembles the graph to all the processors, it then splits the - processors into groups depending on the number of partitions for which we want to - compute the separator. The processors of each group compute the separator of their - corresponding graph and the smallest separator is selected. - - The parameter nparts on calling this routine indicates the number of desired - partitions after the multisection (excluding the nodes that end up on the - separator). The initial bisection is achieved when nparts==2 and upon entry - graph->where[] = 0 for all vertices. Similarly, if nparts==4, it indicates that we - have a graph that is already partitioned into two parts (as specified in - graph->where) and we need to find the separator of each one of these parts. - - The final partitioning is encoded in the graph->where vector as follows. If nparts - is the number of partitions, the left, right, and separator subpartitions of the - original partition i will be labeled 2*i, 2*i+1, and nparts+2*i, respectively. Note - that in the above expressions, i goes from [0...nparts/2]. As a result of this - encoding, the left (i.e., 0th) partition of a node \c i on the separator will be - given by where[i]%nparts. - -*/ -/************************************************************************************/ -void InitMultisection(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) -{ - int i, lpecut[2], gpecut[2], mypart, moptions[10]; - idxtype *vtxdist, *gwhere = NULL, *part, *label; - GraphType *agraph; - int *sendcounts, *displs; +/************************************************************************* +* This function is the entry point of the initial partitioning algorithm. +* This algorithm assembles the graph to all the processors and preceed +* serially. +**************************************************************************/ +void InitMultisection(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +{ + int i, lpecut[2], gpecut[2], mypart, moptions[10]; + idxtype *vtxdist, *gwhere = NULL, *part, *label; + GraphType *agraph; + int *sendcounts, *displs; MPI_Comm newcomm, labelcomm; IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr)); @@ -61,9 +42,9 @@ void InitMultisection(CtrlType *ctrl, Gr mypart = ctrl->mype%(ctrl->nparts/2); MPI_Comm_split(ctrl->comm, mypart, 0, &newcomm); - /* Each processor keeps the graph that it only needs and bisects it */ - agraph->ncon = 1; /* needed for Mc_KeepPart */ - Mc_KeepPart(agraph, wspace, part, mypart); + /* Each processor keeps the graphs that it only needs and bisects it */ + agraph->ncon = 1; /* needed for Moc_KeepPart */ + Moc_KeepPart(agraph, wspace, part, mypart); label = agraph->label; /* Save this because ipart may need it */ agraph->label = NULL; @@ -134,23 +115,22 @@ void InitMultisection(CtrlType *ctrl, Gr agraph->where = part; if (lpecut[1] == 0) { - MPI_Reduce((void *)gwhere, (void *)agraph->where, graph->gnvtxs, IDX_DATATYPE, - MPI_SUM, 0, labelcomm); + MPI_Reduce((void *)gwhere, (void *)agraph->where, graph->gnvtxs, IDX_DATATYPE, MPI_SUM, 0, labelcomm); free(gwhere); } /* The minimum PE performs the Scatter */ vtxdist = graph->vtxdist; ASSERT(ctrl, graph->where != NULL); - GKfree((void **)&graph->where, LTERM); /* Remove the propagated down where info */ + free(graph->where); /* Remove the propagated down where info */ graph->where = idxmalloc(graph->nvtxs+graph->nrecv, "InitPartition: where"); sendcounts = imalloc(ctrl->npes, "InitPartitionNew: sendcounts"); - displs = imalloc(ctrl->npes, "InitPartitionNew: displs"); + displs = imalloc(ctrl->npes, "InitPartitionNew: displs"); for (i=0; inpes; i++) { sendcounts[i] = vtxdist[i+1]-vtxdist[i]; - displs[i] = vtxdist[i]; + displs[i] = vtxdist[i]; } MPI_Scatterv((void *)agraph->where, sendcounts, displs, IDX_DATATYPE, @@ -182,16 +162,16 @@ GraphType *AssembleMultisectedGraph(Ctrl int *recvcounts, *displs, mysize; GraphType *agraph; - gnvtxs = graph->gnvtxs; - nvtxs = graph->nvtxs; - nedges = graph->xadj[nvtxs]; - xadj = graph->xadj; - vwgt = graph->vwgt; - where = graph->where; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; + gnvtxs = graph->gnvtxs; + nvtxs = graph->nvtxs; + nedges = graph->xadj[nvtxs]; + xadj = graph->xadj; + vwgt = graph->vwgt; + where = graph->where; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; vtxdist = graph->vtxdist; - imap = graph->imap; + imap = graph->imap; /* Determine the # of idxtype to receive from each processor */ recvcounts = imalloc(ctrl->npes, "AssembleGraph: recvcounts"); --- parmetis-3.1.1.orig/ParMETISLib/initbalance.c +++ parmetis-3.1.1/ParMETISLib/initbalance.c @@ -42,7 +42,7 @@ void Balance_Partition(CtrlType *ctrl, G IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr)); vtxdist = graph->vtxdist; - agraph = Mc_AssembleAdaptiveGraph(ctrl, graph, wspace); + agraph = Moc_AssembleAdaptiveGraph(ctrl, graph, wspace); nvtxs = cgraph.nvtxs = agraph->nvtxs; nedges = cgraph.nedges = agraph->nedges; ncon = cgraph.ncon = agraph->ncon; @@ -106,7 +106,7 @@ void Balance_Partition(CtrlType *ctrl, G /****************************************/ /****************************************/ - IFSET(ctrl->dbglvl, DBG_REFINEINFO, Mc_ComputeSerialBalance(ctrl, agraph, agraph->where, lbvec)); + IFSET(ctrl->dbglvl, DBG_REFINEINFO, Moc_ComputeSerialBalance(ctrl, agraph, agraph->where, lbvec)); IFSET(ctrl->dbglvl, DBG_REFINEINFO, rprintf(ctrl, "input cut: %d, balance: ", ComputeSerialEdgeCut(agraph))); for (i=0; incon; i++) IFSET(ctrl->dbglvl, DBG_REFINEINFO, rprintf(ctrl, "%.3f ", lbvec[i])); @@ -185,12 +185,12 @@ void Balance_Partition(CtrlType *ctrl, G /* I'm picking the left branch */ if (srmype < fpe+lnpes/2) { - Mc_KeepPart(agraph, wspace, part, 0); + Moc_KeepPart(agraph, wspace, part, 0); lnpes = lnpes/2; lnparts = lnparts/2; } else { - Mc_KeepPart(agraph, wspace, part, 1); + Moc_KeepPart(agraph, wspace, part, 1); fpart = fpart + lnparts/2; fpe = fpe + lnpes/2; lnpes = lnpes - lnpes/2; @@ -224,7 +224,7 @@ void Balance_Partition(CtrlType *ctrl, G MPI_Allreduce((void *)lwhere, (void *)part, nvtxs, IDX_DATATYPE, MPI_SUM, srcomm); edgecut = ComputeSerialEdgeCut(&cgraph); - Mc_ComputeSerialBalance(ctrl, &cgraph, part, lbvec); + Moc_ComputeSerialBalance(ctrl, &cgraph, part, lbvec); lbsum = ssum(ncon, lbvec); MPI_Allreduce((void *)&edgecut, (void *)&max_cut, 1, MPI_INT, MPI_MAX, ipcomm); MPI_Allreduce((void *)&lbsum, (void *)&min_lbsum, 1, MPI_FLOAT, MPI_MIN, ipcomm); @@ -264,7 +264,7 @@ void Balance_Partition(CtrlType *ctrl, G if (ncon == 1) { rating = WavefrontDiffusion(&myctrl, agraph, home); - Mc_ComputeSerialBalance(ctrl, &cgraph, part, lbvec); + Moc_ComputeSerialBalance(ctrl, &cgraph, part, lbvec); lbsum = ssum(ncon, lbvec); /* Determine which PE computed the best partitioning */ @@ -295,7 +295,7 @@ void Balance_Partition(CtrlType *ctrl, G } } else { - Mc_Diffusion(&myctrl, agraph, graph->vtxdist, agraph->where, home, wspace, N_MOC_GD_PASSES); + Moc_Diffusion(&myctrl, agraph, graph->vtxdist, agraph->where, home, wspace, N_MOC_GD_PASSES); } } @@ -306,7 +306,7 @@ void Balance_Partition(CtrlType *ctrl, G /********************************************************************/ my_cut = (float) ComputeSerialEdgeCut(&cgraph); my_totalv = (float) Mc_ComputeSerialTotalV(&cgraph, home); - Mc_ComputeSerialBalance(ctrl, &cgraph, part, lbvec); + Moc_ComputeSerialBalance(ctrl, &cgraph, part, lbvec); my_balance = ssum(cgraph.ncon, lbvec); my_balance /= (float) cgraph.ncon; my_cost = ctrl->ipc_factor * my_cut + REDIST_WGT * ctrl->redist_base * my_totalv; @@ -363,7 +363,7 @@ void Balance_Partition(CtrlType *ctrl, G /************************************************************************* * This function assembles the graph into a single processor **************************************************************************/ -GraphType *Mc_AssembleAdaptiveGraph(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +GraphType *Moc_AssembleAdaptiveGraph(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) { int i, j, k, l, gnvtxs, nvtxs, ncon, gnedges, nedges, gsize; idxtype *xadj, *vwgt, *vsize, *adjncy, *adjwgt, *vtxdist, *imap; --- parmetis-3.1.1.orig/ParMETISLib/rmetis.c +++ parmetis-3.1.1/ParMETISLib/rmetis.c @@ -91,7 +91,7 @@ void ParMETIS_V3_RefineKway(idxtype *vtx ctrl.ps_relation = ps_relation; ctrl.tpwgts = itpwgts; - graph = Mc_SetUpGraph(&ctrl, incon, vtxdist, xadj, vwgt, adjncy, adjwgt, &iwgtflag); + graph = Moc_SetUpGraph(&ctrl, incon, vtxdist, xadj, vwgt, adjncy, adjwgt, &iwgtflag); graph->vsize = idxsmalloc(graph->nvtxs, 1, "vsize"); graph->home = idxmalloc(graph->nvtxs, "home"); @@ -107,7 +107,7 @@ void ParMETIS_V3_RefineKway(idxtype *vtx ctrl.edge_size_ratio = gtewgt/gtvsize; scopy(incon, iubvec, ctrl.ubvec); - AllocateWSpace(&ctrl, graph, &wspace); + PreAllocateMemory(&ctrl, graph, &wspace); /***********************/ /* Partition and Remap */ @@ -149,10 +149,10 @@ void ParMETIS_V3_RefineKway(idxtype *vtx /*************************************/ /* Free memory, renumber, and return */ /*************************************/ - GKfree((void **)&graph->lnpwgts, &graph->gnpwgts, &graph->nvwgt, &graph->home, - &graph->vsize, &itpwgts, LTERM); + GKfree((void **)&graph->lnpwgts, (void **)&graph->gnpwgts, (void **)&graph->nvwgt, (void **)(&graph->home), (void **)(&graph->vsize), LTERM); - FreeInitialGraphAndRemap(graph, iwgtflag, 1); + GKfree((void **)&itpwgts, LTERM); + FreeInitialGraphAndRemap(graph, iwgtflag); FreeWSpace(&wspace); FreeCtrl(&ctrl); --- parmetis-3.1.1.orig/ParMETISLib/stat.c +++ parmetis-3.1.1/ParMETISLib/stat.c @@ -19,7 +19,7 @@ /************************************************************************* * This function computes the balance of the partitioning **************************************************************************/ -void Mc_ComputeSerialBalance(CtrlType *ctrl, GraphType *graph, idxtype *where, float *ubvec) +void Moc_ComputeSerialBalance(CtrlType *ctrl, GraphType *graph, idxtype *where, float *ubvec) { int i, j, nvtxs, ncon, nparts; idxtype *pwgts, *tvwgts, *vwgt; @@ -56,7 +56,7 @@ void Mc_ComputeSerialBalance(CtrlType *c /************************************************************************* * This function computes the balance of the partitioning **************************************************************************/ -void Mc_ComputeParallelBalance(CtrlType *ctrl, GraphType *graph, idxtype *where, float *ubvec) +void Moc_ComputeParallelBalance(CtrlType *ctrl, GraphType *graph, idxtype *where, float *ubvec) { int i, j, nvtxs, ncon, nparts; float *nvwgt, *lnpwgts, *gnpwgts; @@ -103,7 +103,7 @@ void Mc_ComputeParallelBalance(CtrlType /************************************************************************* * This function prints a matrix **************************************************************************/ -void Mc_PrintThrottleMatrix(CtrlType *ctrl, GraphType *graph, float *matrix) +void Moc_PrintThrottleMatrix(CtrlType *ctrl, GraphType *graph, float *matrix) { int i, j; @@ -130,7 +130,7 @@ void Mc_PrintThrottleMatrix(CtrlType *ct /************************************************************************* * This function computes stats for refinement **************************************************************************/ -void Mc_ComputeRefineStats(CtrlType *ctrl, GraphType *graph, float *ubvec) +void Moc_ComputeRefineStats(CtrlType *ctrl, GraphType *graph, float *ubvec) { int h, i, j, k; int nvtxs, ncon; --- parmetis-3.1.1.orig/ParMETISLib/gkmetis.c +++ parmetis-3.1.1/ParMETISLib/gkmetis.c @@ -117,10 +117,10 @@ void ParMETIS_V3_PartGeomKway(idxtype *v uwgtflag = iwgtflag|2; uvwgt = idxsmalloc(vtxdist[mype+1]-vtxdist[mype], 1, "uvwgt"); - graph = Mc_SetUpGraph(&ctrl, 1, vtxdist, xadj, uvwgt, adjncy, adjwgt, &uwgtflag); + graph = Moc_SetUpGraph(&ctrl, 1, vtxdist, xadj, uvwgt, adjncy, adjwgt, &uwgtflag); free(graph->nvwgt); graph->nvwgt = NULL; - AllocateWSpace(&ctrl, graph, &wspace); + PreAllocateMemory(&ctrl, graph, &wspace); /*================================================================= * Compute the initial npes-way partitioning geometric partitioning @@ -146,11 +146,11 @@ void ParMETIS_V3_PartGeomKway(idxtype *v graph->ncon = incon; j = ctrl.nparts; ctrl.nparts = ctrl.npes; - mgraph = Mc_MoveGraph(&ctrl, graph, &wspace); + mgraph = Moc_MoveGraph(&ctrl, graph, &wspace); ctrl.nparts = j; /**********************************************************/ - /* Do the same functionality as Mc_SetUpGraph for mgraph */ + /* Do the same functionality as Moc_SetUpGraph for mgraph */ /**********************************************************/ /* compute tvwgts */ for (j=0; jwhere = idxmalloc(graph->nvtxs+graph->nrecv, "PartitionSmallGraph: where"); - agraph = Mc_AssembleAdaptiveGraph(ctrl, graph, wspace); + agraph = Moc_AssembleAdaptiveGraph(ctrl, graph, wspace); mypart = idxmalloc(agraph->nvtxs, "mypart"); moptions[0] = 0; --- parmetis-3.1.1.orig/ParMETISLib/rename.h +++ parmetis-3.1.1/ParMETISLib/rename.h @@ -1,29 +1,29 @@ /* kmetis.c */ -#define Mc_Global_Partition Mc_Global_Partition__ +#define Moc_Global_Partition Moc_Global_Partition__ /* mmetis.c */ /* gkmetis.c */ /* match.c */ -#define Mc_GlobalMatch_Balance Mc_GlobalMatch_Balance__ +#define Moc_GlobalMatch_Balance Moc_GlobalMatch_Balance__ /* coarsen.c */ -#define Mc_Global_CreateCoarseGraph Mc_Global_CreateCoarseGraph__ +#define Moc_Global_CreateCoarseGraph Moc_Global_CreateCoarseGraph__ /* initpart.c */ -#define Mc_InitPartition_RB Mc_InitPartition_RB__ -#define Mc_KeepPart Mc_KeepPart__ +#define Moc_InitPartition_RB Moc_InitPartition_RB__ +#define Moc_KeepPart Moc_KeepPart__ /* kwayrefine.c */ -#define Mc_ProjectPartition Mc_ProjectPartition__ -#define Mc_ComputePartitionParams Mc_ComputePartitionParams__ +#define Moc_ProjectPartition Moc_ProjectPartition__ +#define Moc_ComputePartitionParams Moc_ComputePartitionParams__ /* kwayfm.c */ -#define Mc_KWayFM Mc_KWayFM__ +#define Moc_KWayFM Moc_KWayFM__ /* kwaybalance.c */ -#define Mc_KWayBalance Mc_KWayBalance__ +#define Moc_KWayBalance Moc_KWayBalance__ /* remap.c */ #define ParallelReMapGraph ParallelReMapGraph__ @@ -31,7 +31,7 @@ #define SimilarTpwgts SimilarTpwgts__ /* move.c */ -#define Mc_MoveGraph Mc_MoveGraph__ +#define Moc_MoveGraph Moc_MoveGraph__ #define CheckMGraph CheckMGraph__ #define ProjectInfoBack ProjectInfoBack__ #define FindVtxPerm FindVtxPerm__ @@ -69,10 +69,10 @@ /* initbalance.c */ #define Balance_Partition Balance_Partition__ -#define Mc_AssembleAdaptiveGraph Mc_AssembleAdaptiveGraph__ +#define Moc_AssembleAdaptiveGraph Moc_AssembleAdaptiveGraph__ /* mdiffusion.c */ -#define Mc_Diffusion Mc_Diffusion__ +#define Moc_Diffusion Moc_Diffusion__ #define ExtractGraph ExtractGraph__ /* diffutil.c */ @@ -87,31 +87,31 @@ #define ComputeSerialTotalV ComputeSerialTotalV__ /* akwayfm.c */ -#define Mc_KWayAdaptiveRefine Mc_KWayAdaptiveRefine__ +#define Moc_KWayAdaptiveRefine Moc_KWayAdaptiveRefine__ /* selectq.c */ -#define Mc_DynamicSelectQueue Mc_DynamicSelectQueue__ -#define Mc_HashVwgts Mc_HashVwgts__ -#define Mc_HashVRank Mc_HashVRank__ +#define Moc_DynamicSelectQueue Moc_DynamicSelectQueue__ +#define Moc_HashVwgts Moc_HashVwgts__ +#define Moc_HashVRank Moc_HashVRank__ /* csrmatch.c */ #define CSR_Match_SHEM CSR_Match_SHEM__ /* serial.c */ -#define Mc_SerialKWayAdaptRefine Mc_SerialKWayAdaptRefine__ -#define Mc_ComputeSerialPartitionParams Mc_ComputeSerialPartitionParams__ +#define Moc_SerialKWayAdaptRefine Moc_SerialKWayAdaptRefine__ +#define Moc_ComputeSerialPartitionParams Moc_ComputeSerialPartitionParams__ #define AreAllHVwgtsBelow AreAllHVwgtsBelow__ #define ComputeHKWayLoadImbalance ComputeHKWayLoadImbalance__ #define SerialRemap SerialRemap__ #define SSMIncKeyCmp SSMIncKeyCmp__ -#define Mc_Serial_FM_2WayRefine Mc_Serial_FM_2WayRefine__ +#define Moc_Serial_FM_2WayRefine Moc_Serial_FM_2WayRefine__ #define Serial_SelectQueue Serial_SelectQueue__ #define Serial_BetterBalance Serial_BetterBalance__ #define Serial_Compute2WayHLoadImbalance Serial_Compute2WayHLoadImbalance__ -#define Mc_Serial_Balance2Way Mc_Serial_Balance2Way__ -#define Mc_Serial_Init2WayBalance Mc_Serial_Init2WayBalance__ +#define Moc_Serial_Balance2Way Moc_Serial_Balance2Way__ +#define Moc_Serial_Init2WayBalance Moc_Serial_Init2WayBalance__ #define Serial_SelectQueueOneWay Serial_SelectQueueOneWay__ -#define Mc_Serial_Compute2WayPartitionParams Mc_Serial_Compute2WayPartitionParams__ +#define Moc_Serial_Compute2WayPartitionParams Moc_Serial_Compute2WayPartitionParams__ #define Serial_AreAnyVwgtsBelow Serial_AreAnyVwgtsBelow__ /* weird.c */ @@ -180,10 +180,10 @@ #define CheckHeapFloat CheckHeapFloat__ /* stat.c */ -#define Mc_ComputeSerialBalance Mc_ComputeSerialBalance__ -#define Mc_ComputeParallelBalance Mc_ComputeParallelBalance__ -#define Mc_PrintThrottleMatrix Mc_PrintThrottleMatrix__ -#define Mc_ComputeRefineStats Mc_ComputeRefineStats__ +#define Moc_ComputeSerialBalance Moc_ComputeSerialBalance__ +#define Moc_ComputeParallelBalance Moc_ComputeParallelBalance__ +#define Moc_PrintThrottleMatrix Moc_PrintThrottleMatrix__ +#define Moc_ComputeRefineStats Moc_ComputeRefineStats__ /* debug.c */ #define PrintVector PrintVector__ @@ -271,7 +271,7 @@ #define ikeyvalsort ikeyvalsort__ /* grsetup.c */ -#define Mc_SetUpGraph Mc_SetUpGraph__ +#define Moc_SetUpGraph Moc_SetUpGraph__ #define SetUpCtrl SetUpCtrl__ #define ChangeNumbering ChangeNumbering__ #define ChangeNumberingMesh ChangeNumberingMesh__ --- parmetis-3.1.1.orig/ParMETISLib/move.c +++ parmetis-3.1.1/ParMETISLib/move.c @@ -19,7 +19,7 @@ * This routine can be called with or without performing refinement. * In the latter case it allocates and computes lpwgts itself. **************************************************************************/ -GraphType *Mc_MoveGraph(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +GraphType *Moc_MoveGraph(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) { int h, i, ii, j, jj, nvtxs, ncon, nparts; idxtype *xadj, *vwgt, *adjncy, *adjwgt, *mvtxdist; @@ -28,26 +28,24 @@ GraphType *Mc_MoveGraph(CtrlType *ctrl, KeyValueType *sinfo, *rinfo; GraphType *mgraph; - /* this routine only works when nparts == npes */ - ASSERT(ctrl, ctrl->nparts == ctrl->npes); - nparts = ctrl->nparts; + ASSERT(ctrl, nparts == ctrl->npes); - nvtxs = graph->nvtxs; - ncon = graph->ncon; - xadj = graph->xadj; - vwgt = graph->vwgt; + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + vwgt = graph->vwgt; adjncy = graph->adjncy; adjwgt = graph->adjwgt; - where = graph->where; + where = graph->where; mvtxdist = idxmalloc(nparts+1, "MoveGraph: mvtxdist"); /* Let's do a prefix scan to determine the labeling of the nodes given */ lpwgts = wspace->pv1; gpwgts = wspace->pv2; - sinfo = wspace->pepairs1; - rinfo = wspace->pepairs2; + sinfo = wspace->pepairs1; + rinfo = wspace->pepairs2; for (i=0; i wspace->maxcore) { /* Adjust core memory, incase the graph was originally very memory unbalanced */ - GKfree((void **)&wspace->core, LTERM); + free(wspace->core); wspace->maxcore = lpwgts[nparts]+4*gpwgts[nparts]; /* In spirit of the 8*nedges */ - wspace->core = idxmalloc(wspace->maxcore, "Mc_MoveGraph: wspace->core"); + wspace->core = idxmalloc(wspace->maxcore, "Moc_MoveGraph: wspace->core"); } sgraph = wspace->core; @@ -101,14 +100,12 @@ GraphType *Mc_MoveGraph(CtrlType *ctrl, for (i=0; i 0) MPI_Irecv((void *)(rgraph+gpwgts[i]), gpwgts[i+1]-gpwgts[i], IDX_DATATYPE, i, 1, ctrl->comm, ctrl->rreq+i); - else { + else ASSERT(ctrl, gpwgts[i+1]-gpwgts[i] == 0); - } } /* Assemble the graph to be sent and send it */ for (i=0; i= 0 && where[i] < nparts); ii = lpwgts[where[i]]; sgraph[ii++] = xadj[i+1]-xadj[i]; for (h=0; h0; i--) + lpwgts[i] = lpwgts[i-1]; + lpwgts[0] = 0; for (i=0; i 0) MPI_Isend((void *)(sgraph+lpwgts[i]), lpwgts[i+1]-lpwgts[i], IDX_DATATYPE, i, 1, ctrl->comm, ctrl->sreq+i); - else { + else ASSERT(ctrl, lpwgts[i+1]-lpwgts[i] == 0); - } } /* @@ -148,21 +146,20 @@ GraphType *Mc_MoveGraph(CtrlType *ctrl, /* OK, now go and put the graph into GraphType Format */ mgraph = CreateGraph(); - - mgraph->vtxdist = mvtxdist; - mgraph->gnvtxs = graph->gnvtxs; - mgraph->ncon = ncon; - mgraph->level = 0; - mgraph->nvtxs = mgraph->nedges = 0; + mgraph->gnvtxs = graph->gnvtxs; + mgraph->ncon = ncon; + mgraph->level = 0; + mgraph->nvtxs = mgraph->nedges = 0; for (i=0; invtxs += rinfo[i].key; + mgraph->nvtxs += rinfo[i].key; mgraph->nedges += rinfo[i].val; } - nvtxs = mgraph->nvtxs; - xadj = mgraph->xadj = idxmalloc(nvtxs+1, "MMG: mgraph->xadj"); - vwgt = mgraph->vwgt = idxmalloc(nvtxs*ncon, "MMG: mgraph->vwgt"); + nvtxs = mgraph->nvtxs; + xadj = mgraph->xadj = idxmalloc(nvtxs+1, "MMG: mgraph->xadj"); + vwgt = mgraph->vwgt = idxmalloc(nvtxs*ncon, "MMG: mgraph->vwgt"); adjncy = mgraph->adjncy = idxmalloc(mgraph->nedges, "MMG: mgraph->adjncy"); adjwgt = mgraph->adjwgt = idxmalloc(mgraph->nedges, "MMG: mgraph->adjwgt"); + mgraph->vtxdist = mvtxdist; for (jj=ii=i=0; inedges); - ASSERT(ctrl, ii == gpwgts[nparts]); ASSERTP(ctrl, jj == mgraph->nedges, (ctrl, "%d %d\n", jj, mgraph->nedges)); ASSERTP(ctrl, ii == gpwgts[nparts], (ctrl, "%d %d %d %d %d\n", ii, gpwgts[nparts], jj, mgraph->nedges, nvtxs)); - GKfree((void **)&newlabel, LTERM); + free(newlabel); #ifdef DEBUG IFSET(ctrl->dbglvl, DBG_INFO, rprintf(ctrl, "Checking moved graph...\n")); @@ -315,19 +310,17 @@ void CheckMGraph(CtrlType *ctrl, GraphTy idxtype *xadj, *adjncy, *vtxdist; - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; vtxdist = graph->vtxdist; firstvtx = vtxdist[ctrl->mype]; - lastvtx = vtxdist[ctrl->mype+1]; + lastvtx = vtxdist[ctrl->mype+1]; for (i=0; i= firstvtx && adjncy[j] < lastvtx) { k = adjncy[j]-firstvtx; for (jj=xadj[k]; jjvsize = (vsize == NULL ? idxsmalloc(graph->nvtxs, 1, "vsize") : vsize); graph->home = idxmalloc(graph->nvtxs, "home"); @@ -114,7 +113,7 @@ void ParMETIS_V3_AdaptiveRepart(idxtype ctrl.edge_size_ratio = gtewgt/gtvsize; scopy(incon, iubvec, ctrl.ubvec); - AllocateWSpace(&ctrl, graph, &wspace); + PreAllocateMemory(&ctrl, graph, &wspace); /***********************/ /* Partition and Remap */ @@ -156,10 +155,11 @@ void ParMETIS_V3_AdaptiveRepart(idxtype /*************************************/ /* Free memory, renumber, and return */ /*************************************/ - GKfree((void **)&graph->lnpwgts, &graph->gnpwgts, &graph->nvwgt, &graph->home, - &itpwgts, LTERM); - - FreeInitialGraphAndRemap(graph, iwgtflag, vsize == NULL); + GKfree((void **)&graph->lnpwgts, (void **)&graph->gnpwgts, (void **)&graph->nvwgt, (void **)(&graph->home), LTERM); + if (vsize == NULL) + GKfree((void **)(&graph->vsize), LTERM); + GKfree((void **)&itpwgts, LTERM); + FreeInitialGraphAndRemap(graph, iwgtflag); FreeWSpace(&wspace); FreeCtrl(&ctrl); @@ -182,8 +182,6 @@ void Adaptive_Partition(CtrlType *ctrl, float gtewgt, gtvsize; float ubavg, lbavg, lbvec[MAXNCON]; - AdjustWSpace(ctrl, graph, wspace); - /************************************/ /* Set up important data structures */ /************************************/ @@ -208,14 +206,14 @@ void Adaptive_Partition(CtrlType *ctrl, graph->where = idxsmalloc(graph->nvtxs+graph->nrecv, -1, "graph->where"); idxcopy(graph->nvtxs, graph->home, graph->where); - Mc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); lbavg = savg(graph->ncon, lbvec); if (lbavg > ubavg + 0.035 && ctrl->partType != REFINE_PARTITION) Balance_Partition(ctrl, graph, wspace); if (ctrl->dbglvl&DBG_PROGRESS) { - Mc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); rprintf(ctrl, "nvtxs: %10d, balance: ", graph->gnvtxs); for (i=0; incon; i++) rprintf(ctrl, "%.3f ", lbvec[i]); @@ -224,9 +222,9 @@ void Adaptive_Partition(CtrlType *ctrl, /* check if no coarsening took place */ if (graph->finer == NULL) { - Mc_ComputePartitionParams(ctrl, graph, wspace); - Mc_KWayBalance(ctrl, graph, wspace, graph->ncon); - Mc_KWayAdaptiveRefine(ctrl, graph, wspace, NGR_PASSES); + Moc_ComputePartitionParams(ctrl, graph, wspace); + Moc_KWayBalance(ctrl, graph, wspace, graph->ncon); + Moc_KWayAdaptiveRefine(ctrl, graph, wspace, NGR_PASSES); } } else { @@ -239,7 +237,7 @@ void Adaptive_Partition(CtrlType *ctrl, break; case DISCOUPLED: default: - Mc_GlobalMatch_Balance(ctrl, graph, wspace); + Moc_GlobalMatch_Balance(ctrl, graph, wspace); break; } @@ -248,22 +246,22 @@ void Adaptive_Partition(CtrlType *ctrl, /********************************/ /* project partition and refine */ /********************************/ - Mc_ProjectPartition(ctrl, graph, wspace); - Mc_ComputePartitionParams(ctrl, graph, wspace); + Moc_ProjectPartition(ctrl, graph, wspace); + Moc_ComputePartitionParams(ctrl, graph, wspace); if (graph->ncon > 1 && graph->level < 4) { - Mc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); lbavg = savg(graph->ncon, lbvec); if (lbavg > ubavg + 0.025) { - Mc_KWayBalance(ctrl, graph, wspace, graph->ncon); + Moc_KWayBalance(ctrl, graph, wspace, graph->ncon); } } - Mc_KWayAdaptiveRefine(ctrl, graph, wspace, NGR_PASSES); + Moc_KWayAdaptiveRefine(ctrl, graph, wspace, NGR_PASSES); if (ctrl->dbglvl&DBG_PROGRESS) { - Mc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); rprintf(ctrl, "nvtxs: %10d, cut: %8d, balance: ", graph->gnvtxs, graph->mincut); for (i=0; incon; i++) rprintf(ctrl, "%.3f ", lbvec[i]); --- parmetis-3.1.1.orig/ParMETISLib/grsetup.c +++ parmetis-3.1.1/ParMETISLib/grsetup.c @@ -19,7 +19,7 @@ /************************************************************************* * This function setsup the CtrlType structure **************************************************************************/ -GraphType *Mc_SetUpGraph(CtrlType *ctrl, int ncon, idxtype *vtxdist, idxtype *xadj, +GraphType *Moc_SetUpGraph(CtrlType *ctrl, int ncon, idxtype *vtxdist, idxtype *xadj, idxtype *vwgt, idxtype *adjncy, idxtype *adjwgt, int *wgtflag) { int i, j; @@ -103,28 +103,33 @@ void SetUpCtrl(CtrlType *ctrl, int npart **************************************************************************/ void ChangeNumbering(idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *part, int npes, int mype, int from) { - int i, nvtxs; - - nvtxs = vtxdist[mype+1]-vtxdist[mype]; + int i, nvtxs, nedges; if (from == 1) { /* Change it from 1 to 0 */ for (i=0; i +#include --- parmetis-3.1.1.orig/ParMETISLib/Makefile +++ parmetis-3.1.1/ParMETISLib/Makefile @@ -1,5 +1,8 @@ include ../Makefile.in +all: ../libparmetis.a ../libparmetis.so + +.SUFFIXES: .c .lo .o CFLAGS = $(COPTIONS) $(OPTFLAGS) -I. $(INCDIR) @@ -9,35 +12,44 @@ OBJS = comm.o util.o debug.o setup.o grs xyzpart.o pspases.o frename.o \ iintsort.o iidxsort.o ikeysort.o ikeyvalsort.o \ kmetis.o gkmetis.o ometis.o \ - initpart.o match.o \ + initpart.o match.o coarsen.o \ kwayfm.o kwayrefine.o kwaybalance.o \ remap.o stat.o fpqueue.o \ ametis.o rmetis.o lmatch.o initbalance.o \ mdiffusion.o diffutil.o wave.o \ csrmatch.o redomylink.o balancemylink.o \ selectq.o akwayfm.o serial.o move.o \ - mmetis.o mesh.o memory.o weird.o backcompat.o + mmetis.o mesh.o memory.o weird.o backcompat.o + +SHLOBJS = $(OBJS:.o=.lo) .c.o: - $(CC) $(CFLAGS) -c $*.c + $(CC) $(CPPFLAGS) $(CFLAGS) -c $*.c +.c.lo: + $(CC) $(CPPFLAGS) $(CFLAGS) -fPIC -DPIC -c $< -o $@ ../libparmetis.a: $(OBJS) $(AR) $@ $(OBJS) $(RANLIB) $@ +../libparmetis.so: $(SHLOBJS) + $(CC) -shared $^ -Wl,-soname,libparmetis.so.3.1 -o $@.3.1 \ + $(LIBDIR) -lmpi -lm -L../ -lmetis + ln -s libparmetis.so.3.1 $@ + clean: - rm -f *.o + rm -f *.o *.lo realclean: - rm -f *.o ; rm -f ../libparmetis.a + rm -f *.o *.lo ../libparmetis.* checkin: @for file in *.[c,h]; \ do \ ci -u -m'Maintance' $$file;\ - done + done checkin2: @for file in *.[c,h]; \ --- parmetis-3.1.1.orig/ParMETISLib/lmatch.c +++ parmetis-3.1.1/ParMETISLib/lmatch.c @@ -26,26 +26,24 @@ void Mc_LocalMatch_HEM(CtrlType *ctrl, G idxtype *perm, *match; float maxnvwgt, *nvwgt; - ASSERT(ctrl, wspace->nlarge > graph->xadj[graph->nvtxs]); - graph->match_type = MATCH_LOCAL; maxnvwgt = 1.0/((float)(ctrl->nparts)*MAXVWGT_FACTOR); IFSET(ctrl->dbglvl, DBG_TIME, MPI_Barrier(ctrl->comm)); IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr)); - nvtxs = graph->nvtxs; - ncon = graph->ncon; - xadj = graph->xadj; - nvwgt = graph->nvwgt; + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; ladjncy = graph->adjncy; - adjwgt = graph->adjwgt; - home = graph->home; + adjwgt = graph->adjwgt; + home = graph->home; - vtxdist = graph->vtxdist; + vtxdist = graph->vtxdist; firstvtx = vtxdist[ctrl->mype]; - match = graph->match = idxmalloc(nvtxs+graph->nrecv, "HEM_Match: match"); + match = graph->match = idxmalloc(nvtxs+graph->nrecv, "HEM_Match: match"); myhome = idxsmalloc(nvtxs+graph->nrecv, UNMATCHED, "HEM_Match: myhome"); idxset(nvtxs, UNMATCHED, match); @@ -77,7 +75,7 @@ void Mc_LocalMatch_HEM(CtrlType *ctrl, G if (nvwgt[i*ncon+h] > maxnvwgt) break; - if (h == ncon && iinvtxs; - ncon = graph->ncon; + ncon = graph->ncon; vtxdist = graph->vtxdist; - xadj = graph->xadj; - vwgt = graph->vwgt; - home = graph->home; - vsize = graph->vsize; + xadj = graph->xadj; + vwgt = graph->vwgt; + home = graph->home; + vsize = graph->vsize; ladjncy = graph->adjncy; - adjwgt = graph->adjwgt; - where = graph->where; - match = graph->match; + adjwgt = graph->adjwgt; + where = graph->where; + match = graph->match; firstvtx = vtxdist[mype]; @@ -358,9 +357,7 @@ void Mc_Local_CreateCoarseGraph(CtrlType cgraph->adjwgt = idxmalloc(cnedges, "CreateCoarserGraph: cadjwgt"); idxcopy(cnedges, cadjncy, cgraph->adjncy); idxcopy(cnedges, cadjwgt, cgraph->adjwgt); - - /* Note that graph->where works fine even if it is NULL */ - GKfree((void **)&cadjncy, (void **)&graph->where, LTERM); + GKfree((void **)&cadjncy, (void **)&graph->where, LTERM); /* Note that graph->where works fine even if it is NULL */ } --- parmetis-3.1.1.orig/ParMETISLib/initpart.c +++ parmetis-3.1.1/ParMETISLib/initpart.c @@ -25,7 +25,7 @@ * This algorithm assembles the graph to all the processors and preceeds * by parallelizing the recursive bisection step. **************************************************************************/ -void Mc_InitPartition_RB(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +void Moc_InitPartition_RB(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) { int i, j; int ncon, mype, npes, gnvtxs, ngroups; @@ -48,12 +48,12 @@ void Mc_InitPartition_RB(CtrlType *ctrl, IFSET(ctrl->dbglvl, DBG_TIME, MPI_Barrier(ctrl->comm)); IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr)); - agraph = Mc_AssembleAdaptiveGraph(ctrl, graph, wspace); - part = idxmalloc(agraph->nvtxs, "Mc_IP_RB: part"); - xadj = idxmalloc(agraph->nvtxs+1, "Mc_IP_RB: xadj"); - adjncy = idxmalloc(agraph->nedges, "Mc_IP_RB: adjncy"); - adjwgt = idxmalloc(agraph->nedges, "Mc_IP_RB: adjwgt"); - vwgt = idxmalloc(agraph->nvtxs*ncon, "Mc_IP_RB: vwgt"); + agraph = Moc_AssembleAdaptiveGraph(ctrl, graph, wspace); + part = idxmalloc(agraph->nvtxs, "Moc_IP_RB: part"); + xadj = idxmalloc(agraph->nvtxs+1, "Moc_IP_RB: xadj"); + adjncy = idxmalloc(agraph->nedges, "Moc_IP_RB: adjncy"); + adjwgt = idxmalloc(agraph->nedges, "Moc_IP_RB: adjwgt"); + vwgt = idxmalloc(agraph->nvtxs*ncon, "Moc_IP_RB: vwgt"); idxcopy(agraph->nvtxs*ncon, agraph->vwgt, vwgt); idxcopy(agraph->nvtxs+1, agraph->xadj, xadj); @@ -66,8 +66,8 @@ void Mc_InitPartition_RB(CtrlType *ctrl, gnvtxs = agraph->nvtxs; - gwhere0 = idxsmalloc(gnvtxs, 0, "Mc_IP_RB: gwhere0"); - gwhere1 = idxmalloc(gnvtxs, "Mc_IP_RB: gwhere1"); + gwhere0 = idxsmalloc(gnvtxs, 0, "Moc_IP_RB: gwhere0"); + gwhere1 = idxmalloc(gnvtxs, "Moc_IP_RB: gwhere1"); /* ADD: this assumes that tpwgts for all constraints is the same */ /* ADD: this is necessary because serial metis does not support the general case */ @@ -107,12 +107,12 @@ void Mc_InitPartition_RB(CtrlType *ctrl, /* I'm picking the left branch */ if (mype < fpe+lnpes/2) { - Mc_KeepPart(agraph, wspace, part, 0); + Moc_KeepPart(agraph, wspace, part, 0); lnpes = lnpes/2; lnparts = lnparts/2; } else { - Mc_KeepPart(agraph, wspace, part, 1); + Moc_KeepPart(agraph, wspace, part, 1); fpart = fpart + lnparts/2; fpe = fpe + lnpes/2; lnpes = lnpes - lnpes/2; @@ -158,7 +158,7 @@ void Mc_InitPartition_RB(CtrlType *ctrl, agraph->where = gwhere1; agraph->vwgt = vwgt; agraph->nvtxs = gnvtxs; - Mc_ComputeSerialBalance(ctrl, agraph, gwhere1, lbvec); + Moc_ComputeSerialBalance(ctrl, agraph, gwhere1, lbvec); lbsum = ssum(ncon, lbvec); edgecut = ComputeSerialEdgeCut(agraph); @@ -199,7 +199,7 @@ void Mc_InitPartition_RB(CtrlType *ctrl, /************************************************************************* * This function keeps one parts **************************************************************************/ -void Mc_KeepPart(GraphType *graph, WorkSpaceType *wspace, idxtype *part, int mypart) +void Moc_KeepPart(GraphType *graph, WorkSpaceType *wspace, idxtype *part, int mypart) { int h, i, j, k; int nvtxs, ncon, mynvtxs, mynedges; @@ -214,7 +214,7 @@ void Mc_KeepPart(GraphType *graph, WorkS adjwgt = graph->adjwgt; label = graph->label; - rename = idxmalloc(nvtxs, "Mc_KeepPart: rename"); + rename = idxmalloc(nvtxs, "Moc_KeepPart: rename"); for (mynvtxs=0, i=0; invtxs; i++) - graph->where[i] = graph->where[i]%npes; - ctrl.nparts = nparts = npes; + IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); + + Moc_Global_Partition(&ctrl, graph, &wspace); + + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); + IFSET(ctrl.dbglvl, DBG_TIME, PrintTimingInfo(&ctrl)); /*======================================================= * Move the graph according to the partitioning =======================================================*/ - IFSET(dbglvl_original, DBG_TIME, MPI_Barrier(ctrl.gcomm)); - IFSET(dbglvl_original, DBG_TIME, starttimer(ctrl.MoveTmr)); + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.MoveTmr)); MALLOC_CHECK(NULL); graph->ncon = 1; - mgraph = Mc_MoveGraph(&ctrl, graph, &wspace); + mgraph = Moc_MoveGraph(&ctrl, graph, &wspace); MALLOC_CHECK(NULL); - IFSET(dbglvl_original, DBG_TIME, MPI_Barrier(ctrl.gcomm)); - IFSET(dbglvl_original, DBG_TIME, stoptimer(ctrl.MoveTmr)); - - /* restore the user supplied dbglvl */ - ctrl.dbglvl = dbglvl_original; + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.MoveTmr)); /*======================================================= * Now compute an ordering of the moved graph =======================================================*/ - AdjustWSpace(&ctrl, mgraph, &wspace); + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); + + FreeWSpace(&wspace); + PreAllocateMemory(&ctrl, mgraph, &wspace); ctrl.ipart = ISEP_NODE; ctrl.CoarsenTo = amin(vtxdist[npes]+1, amax(20*npes, 1000)); @@ -158,14 +145,15 @@ void ParMETIS_V3_NodeND(idxtype *vtxdist MALLOC_CHECK(NULL); - IFSET(dbglvl_original, DBG_TIME, MPI_Barrier(ctrl.gcomm)); - IFSET(dbglvl_original, DBG_TIME, stoptimer(ctrl.TotalTmr)); - IFSET(dbglvl_original, DBG_TIME, PrintTimingInfo(&ctrl)); - IFSET(dbglvl_original, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); + IFSET(ctrl.dbglvl, DBG_TIME, PrintTimingInfo(&ctrl)); + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); - GKfree((void **)&ctrl.tpwgts, &morder, LTERM); + free(ctrl.tpwgts); + free(morder); FreeGraph(mgraph); - FreeInitialGraphAndRemap(graph, 0, 1); + FreeInitialGraphAndRemap(graph, 0); FreeWSpace(&wspace); FreeCtrl(&ctrl); --- parmetis-3.1.1.orig/ParMETISLib/mesh.c +++ parmetis-3.1.1/ParMETISLib/mesh.c @@ -32,7 +32,7 @@ void ParMETIS_V3_Mesh2Dual(idxtype *elmd idxtype *gnptr, *gnind, *nptr, *nind, *myxadj, *myadjncy = NULL; idxtype *sbuffer, *rbuffer, *htable; KeyValueType *nodelist, *recvbuffer; - idxtype maxcount, *ind, *wgt; + idxtype ind[200], wgt[200]; int gmaxnode, gminnode; CtrlType ctrl; @@ -45,7 +45,7 @@ void ParMETIS_V3_Mesh2Dual(idxtype *elmd nelms = elmdist[mype+1]-elmdist[mype]; if (*numflag == 1) - ChangeNumberingMesh(elmdist, eptr, eind, NULL, NULL, NULL, npes, mype, 1); + ChangeNumberingMesh2(elmdist, eptr, eind, NULL, NULL, NULL, npes, mype, 1); mask = (1<<11)-1; @@ -258,10 +258,6 @@ void ParMETIS_V3_Mesh2Dual(idxtype *elmd firstelm = elmdist[mype]; /* Two passes -- in first pass, simply find out the memory requirements */ - maxcount = 200; - ind = idxmalloc(maxcount, "ParMETIS_V3_Mesh2Dual: ind"); - wgt = idxmalloc(maxcount, "ParMETIS_V3_Mesh2Dual: wgt"); - for (pass=0; pass<2; pass++) { for (i=0; i 0) { *qnum = hash; return; @@ -290,7 +290,7 @@ MPI_Comm_rank(MPI_COMM_WORLD, &mype); /************************************************************************* * This function sorts the nvwgts of a vertex and returns a hashed value **************************************************************************/ -int Mc_HashVwgts(int ncon, float *nvwgt) +int Moc_HashVwgts(int ncon, float *nvwgt) { int i; int multiplier, retval; @@ -322,7 +322,7 @@ int Mc_HashVwgts(int ncon, float *nvwgt) /************************************************************************* * This function sorts the vwgts of a vertex and returns a hashed value **************************************************************************/ -int Mc_HashVRank(int ncon, int *vwgt) +int Moc_HashVRank(int ncon, int *vwgt) { int i, multiplier, retval; --- parmetis-3.1.1.orig/ParMETISLib/mdiffusion.c +++ parmetis-3.1.1/ParMETISLib/mdiffusion.c @@ -19,7 +19,7 @@ * This algorithm assembles the graph to all the processors and preceed * serially. **************************************************************************/ -int Mc_Diffusion(CtrlType *ctrl, GraphType *graph, idxtype *vtxdist, +int Moc_Diffusion(CtrlType *ctrl, GraphType *graph, idxtype *vtxdist, idxtype *where, idxtype *home, WorkSpaceType *wspace, int npasses) { int h, i, j; @@ -81,7 +81,7 @@ int Mc_Diffusion(CtrlType *ctrl, GraphTy ehome = pack + 7*nvtxs; wsize = amax(sizeof(float)*nparts*6, sizeof(idxtype)*(nvtxs+nparts*2+1)); - workspace = (float *)GKmalloc(wsize, "Mc_Diffusion: workspace"); + workspace = (float *)GKmalloc(wsize, "Moc_Diffusion: workspace"); degrees = GKmalloc(nedges*sizeof(EdgeType), "Mc_Diffusion: degrees"); rinfo = graph->rinfo = GKmalloc(nvtxs*sizeof(RInfoType), "Mc_Diffusion: rinfo"); @@ -292,8 +292,8 @@ int Mc_Diffusion(CtrlType *ctrl, GraphTy /*****************************/ /* perform serial refinement */ /*****************************/ - Mc_ComputeSerialPartitionParams(graph, nparts, degrees); - Mc_SerialKWayAdaptRefine(graph, nparts, home, ctrl->ubvec, 10); + Moc_ComputeSerialPartitionParams(graph, nparts, degrees); + Moc_SerialKWayAdaptRefine(graph, nparts, home, ctrl->ubvec, 10); /****************************/ @@ -332,7 +332,7 @@ int Mc_Diffusion(CtrlType *ctrl, GraphTy me = idxamin(nparts, match); if (match[me] == 0) { -if (ctrl->mype == PE) printf("WARNING: empty subdomain %d in Mc_Diffusion\n", me); +if (ctrl->mype == PE) printf("WARNING: empty subdomain %d in Moc_Diffusion\n", me); you = idxamax(nparts, match); for (i=0; i +#define PackWeightWhereInfo(a, b) (((a)<<10) + (b)) +#define SelectWhere(a) ((a)%1024) +#define SelectWeight(a) (((a)>>10)) -/************************************************************************************/ -/*! - This function allocates the memory required for the nodeND refinement code. - The only refinement-related information that is has is the \c graph->where vector - and allocates the memory for the remaining of the refinement-related data-structures. - -*/ -/************************************************************************************/ -void AllocateNodePartitionParams(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) -{ - int nparts, nvtxs; - idxtype *vwgt; - NRInfoType *rinfo, *myrinfo; - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->KWayInitTmr)); - - nvtxs = graph->nvtxs; - nparts = ctrl->nparts; - - graph->nrinfo = (NRInfoType *)GKmalloc(sizeof(NRInfoType)*nvtxs, "AllocateNodePartitionParams: rinfo"); - graph->lpwgts = idxmalloc(2*nparts, "AllocateNodePartitionParams: lpwgts"); - graph->gpwgts = idxmalloc(2*nparts, "AllocateNodePartitionParams: gpwgts"); - graph->sepind = idxmalloc(nvtxs, "AllocateNodePartitionParams: sepind"); - graph->hmarker = idxmalloc(nvtxs, "AllocateNodePartitionParams: hmarker"); - - /* Allocate additional memory for graph->vwgt in order to store the weights - of the remote vertices */ - vwgt = graph->vwgt; - graph->vwgt = idxmalloc(nvtxs+graph->nrecv, "AllocateNodePartitionParams: graph->vwgt"); - idxcopy(nvtxs, vwgt, graph->vwgt); - GKfree((void **)&vwgt, LTERM); - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->KWayInitTmr)); -} - -/************************************************************************************/ -/*! - This function computes the initial node refinment information for the parallel - nodeND code. It requires that the required data-structures have already been - allocated via a call to AllocateNodePartitionParams. - -*/ -/************************************************************************************/ +/************************************************************************* +* This function computes the initial id/ed +**************************************************************************/ void ComputeNodePartitionParams(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) { int i, j, nparts, nvtxs, nsep, firstvtx, lastvtx; - idxtype *xadj, *adjncy, *adjwgt, *vtxdist, *vwgt, *lpwgts, *gpwgts, *sepind, *hmarker; - idxtype *where; + idxtype *xadj, *ladjncy, *adjwgt, *vtxdist, *vwgt, *lpwgts, *gpwgts, *sepind; + idxtype *where, *swhere, *rwhere; NRInfoType *rinfo, *myrinfo; int me, other, otherwgt; IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->KWayInitTmr)); - nvtxs = graph->nvtxs; + nvtxs = graph->nvtxs; nparts = ctrl->nparts; vtxdist = graph->vtxdist; - xadj = graph->xadj; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - vwgt = graph->vwgt; - - where = graph->where; - rinfo = graph->nrinfo; - lpwgts = graph->lpwgts; - gpwgts = graph->gpwgts; - sepind = graph->sepind; - hmarker = graph->hmarker; + xadj = graph->xadj; + ladjncy = graph->adjncy; + adjwgt = graph->adjwgt; + vwgt = graph->vwgt; + + where = graph->where; + rinfo = graph->nrinfo = (NRInfoType *)GKmalloc(sizeof(NRInfoType)*nvtxs, "ComputeNodePartitionParams: rinfo"); + lpwgts = graph->lpwgts = idxsmalloc(2*nparts, 0, "ComputePartitionParams: lpwgts"); + gpwgts = graph->gpwgts = idxmalloc(2*nparts, "ComputePartitionParams: gpwgts"); + sepind = graph->sepind = idxmalloc(nvtxs, "ComputePartitionParams: sepind"); firstvtx = vtxdist[ctrl->mype]; - lastvtx = vtxdist[ctrl->mype+1]; + lastvtx = vtxdist[ctrl->mype+1]; - /* Reset refinement data structures */ - idxset(2*nparts, 0, lpwgts); - idxset(nvtxs, 0, hmarker); - - /* Send/Receive the where and vwgt information of interface vertices. */ - CommInterfaceData(ctrl, graph, where, wspace->indices, where+nvtxs); - CommInterfaceData(ctrl, graph, vwgt, wspace->indices, vwgt+nvtxs); + /*------------------------------------------------------------ + / Send/Receive the where information of interface vertices. + / Also use this to also encode the vwgt information of this + / vertex. This is a hack, but it should work for now! + /------------------------------------------------------------*/ + swhere = wspace->indices; + rwhere = where + nvtxs; + for (i=0; i= 0 && where[i] < 2*nparts, (ctrl, "%d\n", where[i]) ); + where[i] = PackWeightWhereInfo(vwgt[i], where[i]); + } + + CommInterfaceData(ctrl, graph, where, swhere, rwhere); /*------------------------------------------------------------ / Compute now the degrees /------------------------------------------------------------*/ for (nsep=i=0; i= 0 && me < 2*nparts); lpwgts[me] += vwgt[i]; if (me >= nparts) { /* If it is a separator vertex */ sepind[nsep++] = i; - lpwgts[2*nparts-1] += vwgt[i]; /* Keep track of total separator weight */ + lpwgts[2*nparts-1] += vwgt[i]; myrinfo = rinfo+i; myrinfo->edegrees[0] = myrinfo->edegrees[1] = 0; for (j=xadj[i]; jedegrees[other%2] += vwgt[adjncy[j]]; + myrinfo->edegrees[other%2] += otherwgt; } } } @@ -124,19 +94,6 @@ void ComputeNodePartitionParams(CtrlType MPI_Allreduce((void *)lpwgts, (void *)gpwgts, 2*nparts, IDX_DATATYPE, MPI_SUM, ctrl->comm); graph->mincut = gpwgts[2*nparts-1]; - - /* Mark the halo vertices by determining how many non-local vertices they are - * connected to. */ - idxset(nvtxs, 0, hmarker); - for (i=0; i= nvtxs) { - hmarker[i]++; - } - } - } - - #ifdef XX /* Print Weight information */ if (ctrl->mype == 0) { @@ -150,22 +107,16 @@ void ComputeNodePartitionParams(CtrlType } -/************************************************************************************/ -/*! - This function performs k-way node-based refinement. The refinement is done - concurrently for all the different partitions. It works because each of the - partitions is disconnected from each other due to the removal of the previous level - separators. - -*/ -/************************************************************************************/ -void KWayNodeRefine(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace, - int npasses, float ubfraction) + +/************************************************************************* +* This function performs k-way refinement +**************************************************************************/ +void KWayNodeRefine(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace, int npasses, float ubfraction) { - int i, ii, iii, j, k, pass, nvtxs, firstvtx, lastvtx, otherlastvtx, c, nmoves, + int i, ii, j, k, pass, nvtxs, firstvtx, lastvtx, otherlastvtx, c, nmoves, nlupd, nsupd, nnbrs, nchanged, nsep; int npes = ctrl->npes, mype = ctrl->mype, nparts = ctrl->nparts; - idxtype *xadj, *adjncy, *adjwgt, *vtxdist, *vwgt; + idxtype *xadj, *ladjncy, *adjwgt, *vtxdist, *vwgt; idxtype *where, *lpwgts, *gpwgts, *sepind; idxtype *peind, *recvptr, *sendptr; idxtype *update, *supdate, *rupdate, *pe_updates, *htable, *changed; @@ -173,41 +124,41 @@ void KWayNodeRefine(CtrlType *ctrl, Grap KeyValueType *swchanges, *rwchanges; int *nupds_pe; NRInfoType *rinfo, *myrinfo; - int from, to, me, other, oldcut; + int from, me, other, otherwgt, oldcut; IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->KWayTmr)); nvtxs = graph->nvtxs; vtxdist = graph->vtxdist; - xadj = graph->xadj; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - vwgt = graph->vwgt; + xadj = graph->xadj; + ladjncy = graph->adjncy; + adjwgt = graph->adjwgt; + vwgt = graph->vwgt; firstvtx = vtxdist[mype]; - lastvtx = vtxdist[mype+1]; + lastvtx = vtxdist[mype+1]; - where = graph->where; - rinfo = graph->nrinfo; + where = graph->where; + rinfo = graph->nrinfo; lpwgts = graph->lpwgts; gpwgts = graph->gpwgts; - nsep = graph->nsep; + nsep = graph->nsep; sepind = graph->sepind; - nnbrs = graph->nnbrs; - peind = graph->peind; + nnbrs = graph->nnbrs; + peind = graph->peind; recvptr = graph->recvptr; sendptr = graph->sendptr; - changed = idxmalloc(nvtxs, "KWayRefine: changed"); + changed = idxmalloc(nvtxs, "KWayRefine: changed"); rwchanges = wspace->pairs; swchanges = rwchanges + recvptr[nnbrs]; - update = idxmalloc(nvtxs, "KWayRefine: update"); - supdate = wspace->indices; - rupdate = supdate + recvptr[nnbrs]; + update = idxmalloc(nvtxs, "KWayRefine: update"); + supdate = wspace->indices; + rupdate = supdate + recvptr[nnbrs]; nupds_pe = imalloc(npes, "KWayRefine: nupds_pe"); htable = idxsmalloc(nvtxs+graph->nrecv, 0, "KWayRefine: lhtable"); @@ -219,10 +170,8 @@ void KWayNodeRefine(CtrlType *ctrl, Grap badminpwgt[i] = badminpwgt[i+1] = (1.0/ubfraction)*(gpwgts[i]+gpwgts[i+1])/2; badmaxpwgt[i] = badmaxpwgt[i+1] = ubfraction*(gpwgts[i]+gpwgts[i+1])/2; } - //myprintf(ctrl, "%6d %6d %6d %6d %6d %6d %6d\n", lpwgts[0], lpwgts[1], lpwgts[2], gpwgts[0], gpwgts[1], gpwgts[2], badmaxpwgt[0]); - IFSET(ctrl->dbglvl, DBG_REFINEINFO, - PrintNodeBalanceInfo(ctrl, nparts, gpwgts, badminpwgt, badmaxpwgt, 1)); + IFSET(ctrl->dbglvl, DBG_REFINEINFO, PrintNodeBalanceInfo(ctrl, nparts, gpwgts, badminpwgt, badmaxpwgt, 1)); for (pass=0; passmincut; @@ -236,42 +185,39 @@ void KWayNodeRefine(CtrlType *ctrl, Grap nlupd = nsupd = nmoves = nchanged = 0; for (ii=0; ii= nparts); - /* Go through the loop to see if gain is possible for the separator vertex */ + /* Go through the loop if gain is possible for the separator vertex */ if (rinfo[i].edegrees[(c+1)%2] <= vwgt[i]) { - /* It is a one-sded move so it will go to the other partition. - Look at the comments in InitMultisection to understand the meaning - of from%nparts */ - to = from%nparts+c; + other = from%nparts+c; /* It is one-sided move so we know where it goes */ - if (gpwgts[to]+vwgt[i] > badmaxpwgt[to]) { + if (gpwgts[other]+vwgt[i] > badmaxpwgt[other]) { /* printf("Skip because of weight! %d\n", vwgt[i]-rinfo[i].edegrees[(c+1)%2]); */ continue; /* We cannot move it there because it gets too heavy */ } - /* Update the where information of the vertex you moved */ - where[i] = to; + /* Update where, weight, and ID/ED information of the vertex you moved */ + where[i] = PackWeightWhereInfo(vwgt[i], other); - /* Remove this vertex from the sepind. Note the trick for looking at - the sepind[ii] again */ + /* Remove this vertex from the sepind. Note the trick for looking at the sepind[ii] again */ sepind[ii--] = sepind[--nsep]; - /* myprintf(ctrl, "Vertex %d [%d %d] is moving to %d from %d [%d]\n", - i+firstvtx, vwgt[i], rinfo[i].edegrees[(c+1)%2], to, from, where[i]); */ + /* myprintf(ctrl, "Vertex %d [%d %d] is moving to %d from %d [%d]\n", i+firstvtx, vwgt[i], rinfo[i].edegrees[(c+1)%2], other, from, SelectWhere(where[i])); */ - lpwgts[from] -= vwgt[i]; + lpwgts[from] -= vwgt[i]; lpwgts[2*nparts-1] -= vwgt[i]; - lpwgts[to] += vwgt[i]; - gpwgts[to] += vwgt[i]; + lpwgts[other] += vwgt[i]; + gpwgts[other] += vwgt[i]; - /* Put the vertices adjacent to i that belong to either the separator or - the (c+1)%2 partition into the update array */ + /* + * Put the vertices adjacent to i that belong to either the separator or + * the (c+1)%2 partition into the update array + */ for (j=xadj[i]; jpv4); + CommChangedInterfaceData(ctrl, graph, nchanged, changed, where, swchanges, rwchanges, wspace->pv4); IFSET(ctrl->dbglvl, DBG_RMOVEINFO, rprintf(ctrl, "\t[%d %d], [%d %d %d]\n", - pass, c, GlobalSESum(ctrl, nmoves), GlobalSESum(ctrl, nsupd), - GlobalSESum(ctrl, nlupd))); + pass, c, GlobalSESum(ctrl, nmoves), GlobalSESum(ctrl, nsupd), GlobalSESum(ctrl, nlupd))); - /*----------------------------------------------------------------------- - / Time to communicate with processors to send the vertices whose degrees - / need to be updated. - /-----------------------------------------------------------------------*/ + /*------------------------------------------------------------- + / Time to communicate with processors to send the vertices + / whose degrees need to be update. + /-------------------------------------------------------------*/ /* Issue the receives first */ for (i=0; icomm, - ctrl->sreq+i); + MPI_Isend((void *)(supdate+j), k-j, IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->sreq+i); j = k; } @@ -351,24 +294,22 @@ void KWayNodeRefine(CtrlType *ctrl, Grap nchanged = 0; for (ii=0; iipexadj[i+1]-graph->pexadj[i] > 0) changed[nchanged++] = i; - lpwgts[where[i]] += vwgt[i]; + lpwgts[SelectWhere(where[i])] += vwgt[i]; lpwgts[2*nparts-1] += vwgt[i]; - /* myprintf(ctrl, "Vertex %d moves into the separator from %d to %d\n", - i+firstvtx, me, where[i]); */ + /* myprintf(ctrl, "Vertex %d moves into the separator from %d to %d\n", i+firstvtx, me, SelectWhere(where[i])); */ } } /* Tell everybody interested what the new where[] info is for the interface vertices */ - CommChangedInterfaceData(ctrl, graph, nchanged, changed, where, swchanges, - rwchanges, wspace->pv4); + CommChangedInterfaceData(ctrl, graph, nchanged, changed, where, swchanges, rwchanges, wspace->pv4); /*------------------------------------------------------------- @@ -380,7 +321,7 @@ void KWayNodeRefine(CtrlType *ctrl, Grap htable[i] = 0; - me = where[i]; + me = SelectWhere(where[i]); if (me >= nparts) { /* If it is a separator vertex */ /* myprintf(ctrl, "Updating %d %d\n", i+firstvtx, me); */ @@ -388,39 +329,42 @@ void KWayNodeRefine(CtrlType *ctrl, Grap myrinfo->edegrees[0] = myrinfo->edegrees[1] = 0; for (j=xadj[i]; jedegrees[other%2] += vwgt[adjncy[j]]; + myrinfo->edegrees[other%2] += otherwgt; } } } /* Finally, sum-up the partition weights */ - MPI_Allreduce((void *)lpwgts, (void *)gpwgts, 2*nparts, IDX_DATATYPE, MPI_SUM, - ctrl->comm); + MPI_Allreduce((void *)lpwgts, (void *)gpwgts, 2*nparts, IDX_DATATYPE, MPI_SUM, ctrl->comm); graph->mincut = gpwgts[2*nparts-1]; - IFSET(ctrl->dbglvl, DBG_REFINEINFO, PrintNodeBalanceInfo(ctrl, nparts, gpwgts, - badminpwgt, badmaxpwgt, 0)); + IFSET(ctrl->dbglvl, DBG_REFINEINFO, PrintNodeBalanceInfo(ctrl, nparts, gpwgts, badminpwgt, badmaxpwgt, 0)); } if (graph->mincut == oldcut) break; } - GKfree((void **)&update, &nupds_pe, &htable, &changed, LTERM); + /* Go and clear-up the where array */ + for (i=0; inrecv; i++) + where[i] = SelectWhere(where[i]); + + GKfree((void **)&update, (void **)&nupds_pe, (void **)&htable, (void **)&changed, LTERM); IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->KWayTmr)); } + /************************************************************************* * This function prints balance information for the parallel k-section * refinement algorithm **************************************************************************/ -void PrintNodeBalanceInfo(CtrlType *ctrl, int nparts, idxtype *gpwgts, idxtype *badminpwgt, - idxtype *badmaxpwgt, int title) +void PrintNodeBalanceInfo(CtrlType *ctrl, int nparts, idxtype *gpwgts, idxtype *badminpwgt, idxtype *badmaxpwgt, int title) { int i; @@ -431,8 +375,7 @@ void PrintNodeBalanceInfo(CtrlType *ctrl printf("\tTotalSep: %d, ", gpwgts[2*nparts-1]); for (i=0; icomm); --- parmetis-3.1.1.orig/ParMETISLib/stdheaders.h +++ parmetis-3.1.1/ParMETISLib/stdheaders.h @@ -21,6 +21,5 @@ #include #include #include -#include #include --- parmetis-3.1.1.orig/ParMETISLib/xyzpart.c +++ parmetis-3.1.1/ParMETISLib/xyzpart.c @@ -31,8 +31,9 @@ void Coordinate_Partition(CtrlType *ctrl else graph->nrecv = 0; - nvtxs = graph->nvtxs; - vtxdist = graph->vtxdist; + nvtxs = graph->nvtxs; + vtxdist = graph->vtxdist; + firstvtx = vtxdist[ctrl->mype]; cand = (KeyValueType *)GKmalloc(nvtxs*sizeof(KeyValueType), "Coordinate_Partition: cand"); @@ -76,9 +77,8 @@ void Coordinate_Partition(CtrlType *ctrl break; case XYZ_SPFILL: for (i=0; i=0; j--) { for (k=0; knpes, mype=ctrl->mype, firstvtx, lastvtx; --- parmetis-3.1.1.orig/ParMETISLib/comm.c +++ parmetis-3.1.1/ParMETISLib/comm.c @@ -22,12 +22,12 @@ void CommInterfaceData(CtrlType *ctrl, G idxtype *peind, *sendptr, *sendind, *recvptr, *recvind; firstvtx = graph->vtxdist[ctrl->mype]; - nnbrs = graph->nnbrs; - peind = graph->peind; - sendptr = graph->sendptr; - sendind = graph->sendind; - recvptr = graph->recvptr; - recvind = graph->recvind; + nnbrs = graph->nnbrs; + peind = graph->peind; + sendptr = graph->sendptr; + sendind = graph->sendind; + recvptr = graph->recvptr; + recvind = graph->recvind; /* Issue the receives first */ for (i=0; i