Zoltan is added as thirdParty package

This commit is contained in:
Hamidreza
2025-05-15 21:58:43 +03:30
parent 83a6e4baa1
commit d7479cf1bd
3392 changed files with 318142 additions and 1 deletions

View File

@ -0,0 +1,68 @@
TRIBITS_INCLUDE_DIRECTORIES(REQUIRED_DURING_INSTALLATION_TESTING ${PACKAGE_SOURCE_DIR}/src/zz)
TRIBITS_INCLUDE_DIRECTORIES(REQUIRED_DURING_INSTALLATION_TESTING ${PACKAGE_SOURCE_DIR}/src/lb)
TRIBITS_INCLUDE_DIRECTORIES(REQUIRED_DURING_INSTALLATION_TESTING ${PACKAGE_SOURCE_DIR}/src/Utilities/shared)
TRIBITS_INCLUDE_DIRECTORIES(REQUIRED_DURING_INSTALLATION_TESTING ${PACKAGE_SOURCE_DIR}/src/params)
TRIBITS_INCLUDE_DIRECTORIES(REQUIRED_DURING_INSTALLATION_TESTING ${PACKAGE_SOURCE_DIR}/src/order)
TRIBITS_INCLUDE_DIRECTORIES(REQUIRED_DURING_INSTALLATION_TESTING ${PACKAGE_SOURCE_DIR}/src/par)
TRIBITS_INCLUDE_DIRECTORIES(REQUIRED_DURING_INSTALLATION_TESTING ${PACKAGE_SOURCE_DIR}/src/tpls)
TRIBITS_ADD_EXECUTABLE_AND_TEST(
simpleHIER
SOURCES simpleHIER.c
ARGS
COMM mpi
NUM_MPI_PROCS 1-4
)
TRIBITS_ADD_EXECUTABLE_AND_TEST(
simpleBLOCK
SOURCES simpleBLOCK.c
ARGS
COMM serial mpi
NUM_MPI_PROCS 1-4
)
TRIBITS_ADD_EXECUTABLE_AND_TEST(
simpleRCB
SOURCES simpleRCB.c
ARGS
COMM serial mpi
NUM_MPI_PROCS 1-4
)
TRIBITS_ADD_EXECUTABLE_AND_TEST(
simpleGRAPH
SOURCES simpleGRAPH.c
ARGS
COMM serial mpi
NUM_MPI_PROCS 1-4
)
TRIBITS_ADD_EXECUTABLE_AND_TEST(
simplePHG
SOURCES simplePHG.c
ARGS
COMM serial mpi
NUM_MPI_PROCS 1-4
)
TRIBITS_ADD_EXECUTABLE_AND_TEST(
migrateGRAPH
SOURCES migrateGRAPH.c
ARGS
COMM serial mpi
NUM_MPI_PROCS 1-4
)
TRIBITS_ADD_EXECUTABLE_AND_TEST(
problemGRAPH
SOURCES problemGRAPH.c
ARGS
COMM serial mpi
NUM_MPI_PROCS 1-4
)
TRIBITS_COPY_FILES_TO_BINARY_DIR(CExamplesCopyFiles
SOURCE_FILES hypergraph.txt mesh.txt objects.txt graph.txt
)

85
thirdParty/Zoltan/example/C/Makefile.am vendored Normal file
View File

@ -0,0 +1,85 @@
# @HEADER
#
########################################################################
#
# Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
# Copyright 2012 Sandia Corporation
#
# Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
# the U.S. Government retains certain rights in this software.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the Corporation nor the names of the
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Questions? Contact Karen Devine kddevin@sandia.gov
# Erik Boman egboman@sandia.gov
#
########################################################################
#
# @HEADER
# The following line helps the test harness recover from build errors.
all-local:
include $(top_builddir)/Makefile.export.zoltan
EXEEXT = .exe
noinst_PROGRAMS = simpleBLOCK simpleRCB simpleGRAPH simplePHG problemGRAPH
simpleBLOCK_SOURCES = simpleBLOCK.c
simpleBLOCK_DEPENDENCIES = $(ZOLTAN_DEPS)
simpleBLOCK_CFLAGS = $(ZOLTAN_INCLUDES)
simpleBLOCK_LDADD = $(ZOLTAN_LIBS)
simpleRCB_SOURCES = simpleRCB.c
simpleRCB_DEPENDENCIES = $(ZOLTAN_DEPS)
simpleRCB_CFLAGS = $(ZOLTAN_INCLUDES)
simpleRCB_LDADD = $(ZOLTAN_LIBS)
simpleGRAPH_SOURCES = simpleGRAPH.c
simpleGRAPH_DEPENDENCIES = $(ZOLTAN_DEPS)
simpleGRAPH_CFLAGS = $(ZOLTAN_LIBRARY_INCLUDES)
simpleGRAPH_LDADD = $(ZOLTAN_LIBS)
simplePHG_SOURCES = simplePHG.c
simplePHG_DEPENDENCIES = $(ZOLTAN_DEPS)
simplePHG_CFLAGS = $(ZOLTAN_INCLUDES)
simplePHG_LDADD = $(ZOLTAN_LIBS)
problemGRAPH_SOURCES = problemGRAPH.c
problemGRAPH_DEPENDENCIES = $(ZOLTAN_DEPS)
problemGRAPH_CFLAGS = $(ZOLTAN_LIBRARY_INCLUDES)
problemGRAPH_LDADD = $(ZOLTAN_LIBS)
EXTRA_DIST = classicMakefile objects.txt hypergraph.txt graph.txt mesh.txt
FNAMES=$(EXTRA_DIST:%=$(srcdir)/%)
all-local:
if test -e Makefile.am ; then : ; else cp $(FNAMES) $(builddir); fi

656
thirdParty/Zoltan/example/C/Makefile.in vendored Normal file
View File

@ -0,0 +1,656 @@
# Makefile.in generated by automake 1.11.3 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
# Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
# @HEADER
#
########################################################################
#
# Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
# Copyright 2012 Sandia Corporation
#
# Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
# the U.S. Government retains certain rights in this software.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the Corporation nor the names of the
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Questions? Contact Karen Devine kddevin@sandia.gov
# Erik Boman egboman@sandia.gov
#
########################################################################
#
# @HEADER
# The following line helps the test harness recover from build errors.
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
noinst_PROGRAMS = simpleBLOCK$(EXEEXT) simpleRCB$(EXEEXT) \
simpleGRAPH$(EXEEXT) simplePHG$(EXEEXT) problemGRAPH$(EXEEXT)
subdir = example/C
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/config/ax_f90_module_case.m4 \
$(top_srcdir)/config/ax_f90_module_flag.m4 \
$(top_srcdir)/config/tac_arg_check_mpi.m4 \
$(top_srcdir)/config/tac_arg_enable_export-makefiles.m4 \
$(top_srcdir)/config/tac_arg_enable_feature.m4 \
$(top_srcdir)/config/tac_arg_enable_feature_sub.m4 \
$(top_srcdir)/config/tac_arg_enable_feature_sub_check.m4 \
$(top_srcdir)/config/tac_arg_enable_option.m4 \
$(top_srcdir)/config/tac_arg_with_3pl_sub.m4 \
$(top_srcdir)/config/tac_arg_with_ar.m4 \
$(top_srcdir)/config/tac_arg_with_flags.m4 \
$(top_srcdir)/config/tac_arg_with_incdirs.m4 \
$(top_srcdir)/config/tac_arg_with_libdirs.m4 \
$(top_srcdir)/config/tac_arg_with_libs.m4 \
$(top_srcdir)/config/tac_arg_with_package.m4 \
$(top_srcdir)/config/tac_arg_with_perl.m4 \
$(top_srcdir)/config/wk_fc_get_vendor.m4 \
$(top_srcdir)/config/zac_arg_config_mpi.m4 \
$(top_srcdir)/config/zac_arg_with_id.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/src/include/Zoltan_config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
PROGRAMS = $(noinst_PROGRAMS)
am_problemGRAPH_OBJECTS = problemGRAPH-problemGRAPH.$(OBJEXT)
problemGRAPH_OBJECTS = $(am_problemGRAPH_OBJECTS)
problemGRAPH_LINK = $(CCLD) $(problemGRAPH_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
am_simpleBLOCK_OBJECTS = simpleBLOCK-simpleBLOCK.$(OBJEXT)
simpleBLOCK_OBJECTS = $(am_simpleBLOCK_OBJECTS)
simpleBLOCK_LINK = $(CCLD) $(simpleBLOCK_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
am_simpleGRAPH_OBJECTS = simpleGRAPH-simpleGRAPH.$(OBJEXT)
simpleGRAPH_OBJECTS = $(am_simpleGRAPH_OBJECTS)
simpleGRAPH_LINK = $(CCLD) $(simpleGRAPH_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
am_simplePHG_OBJECTS = simplePHG-simplePHG.$(OBJEXT)
simplePHG_OBJECTS = $(am_simplePHG_OBJECTS)
simplePHG_LINK = $(CCLD) $(simplePHG_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
am_simpleRCB_OBJECTS = simpleRCB-simpleRCB.$(OBJEXT)
simpleRCB_OBJECTS = $(am_simpleRCB_OBJECTS)
simpleRCB_LINK = $(CCLD) $(simpleRCB_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src/include
depcomp = $(SHELL) $(top_srcdir)/config/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(problemGRAPH_SOURCES) $(simpleBLOCK_SOURCES) \
$(simpleGRAPH_SOURCES) $(simplePHG_SOURCES) \
$(simpleRCB_SOURCES)
DIST_SOURCES = $(problemGRAPH_SOURCES) $(simpleBLOCK_SOURCES) \
$(simpleGRAPH_SOURCES) $(simplePHG_SOURCES) \
$(simpleRCB_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALTERNATE_AR = @ALTERNATE_AR@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EXEEXT = .exe
FC = @FC@
FCFLAGS = @FCFLAGS@
FCFLAGS_f = @FCFLAGS_f@
FCFLAGS_f90 = @FCFLAGS_f90@
FCLIBS = @FCLIBS@
FC_MAJOR_VERSION = @FC_MAJOR_VERSION@
FC_MODNAME = @FC_MODNAME@
FC_MODNAME_Q = @FC_MODNAME_Q@
FC_VENDOR = @FC_VENDOR@
FC_VERSION = @FC_VERSION@
FC_VERSION_STRING = @FC_VERSION_STRING@
HAVE_PERL = @HAVE_PERL@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
MPI_CC = @MPI_CC@
MPI_CXX = @MPI_CXX@
MPI_FC = @MPI_FC@
MPI_RECV_LIMIT_FLAG = @MPI_RECV_LIMIT_FLAG@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL_EXE = @PERL_EXE@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_aux_dir = @ac_aux_dir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_FC = @ac_ct_FC@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
simpleBLOCK_SOURCES = simpleBLOCK.c
simpleBLOCK_DEPENDENCIES = $(ZOLTAN_DEPS)
simpleBLOCK_CFLAGS = $(ZOLTAN_INCLUDES)
simpleBLOCK_LDADD = $(ZOLTAN_LIBS)
simpleRCB_SOURCES = simpleRCB.c
simpleRCB_DEPENDENCIES = $(ZOLTAN_DEPS)
simpleRCB_CFLAGS = $(ZOLTAN_INCLUDES)
simpleRCB_LDADD = $(ZOLTAN_LIBS)
simpleGRAPH_SOURCES = simpleGRAPH.c
simpleGRAPH_DEPENDENCIES = $(ZOLTAN_DEPS)
simpleGRAPH_CFLAGS = $(ZOLTAN_LIBRARY_INCLUDES)
simpleGRAPH_LDADD = $(ZOLTAN_LIBS)
simplePHG_SOURCES = simplePHG.c
simplePHG_DEPENDENCIES = $(ZOLTAN_DEPS)
simplePHG_CFLAGS = $(ZOLTAN_INCLUDES)
simplePHG_LDADD = $(ZOLTAN_LIBS)
problemGRAPH_SOURCES = problemGRAPH.c
problemGRAPH_DEPENDENCIES = $(ZOLTAN_DEPS)
problemGRAPH_CFLAGS = $(ZOLTAN_LIBRARY_INCLUDES)
problemGRAPH_LDADD = $(ZOLTAN_LIBS)
EXTRA_DIST = classicMakefile objects.txt hypergraph.txt graph.txt mesh.txt
FNAMES = $(EXTRA_DIST:%=$(srcdir)/%)
all: all-am
.SUFFIXES:
.SUFFIXES: .c .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu example/C/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu example/C/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
clean-noinstPROGRAMS:
-test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
problemGRAPH$(EXEEXT): $(problemGRAPH_OBJECTS) $(problemGRAPH_DEPENDENCIES) $(EXTRA_problemGRAPH_DEPENDENCIES)
@rm -f problemGRAPH$(EXEEXT)
$(problemGRAPH_LINK) $(problemGRAPH_OBJECTS) $(problemGRAPH_LDADD) $(LIBS)
simpleBLOCK$(EXEEXT): $(simpleBLOCK_OBJECTS) $(simpleBLOCK_DEPENDENCIES) $(EXTRA_simpleBLOCK_DEPENDENCIES)
@rm -f simpleBLOCK$(EXEEXT)
$(simpleBLOCK_LINK) $(simpleBLOCK_OBJECTS) $(simpleBLOCK_LDADD) $(LIBS)
simpleGRAPH$(EXEEXT): $(simpleGRAPH_OBJECTS) $(simpleGRAPH_DEPENDENCIES) $(EXTRA_simpleGRAPH_DEPENDENCIES)
@rm -f simpleGRAPH$(EXEEXT)
$(simpleGRAPH_LINK) $(simpleGRAPH_OBJECTS) $(simpleGRAPH_LDADD) $(LIBS)
simplePHG$(EXEEXT): $(simplePHG_OBJECTS) $(simplePHG_DEPENDENCIES) $(EXTRA_simplePHG_DEPENDENCIES)
@rm -f simplePHG$(EXEEXT)
$(simplePHG_LINK) $(simplePHG_OBJECTS) $(simplePHG_LDADD) $(LIBS)
simpleRCB$(EXEEXT): $(simpleRCB_OBJECTS) $(simpleRCB_DEPENDENCIES) $(EXTRA_simpleRCB_DEPENDENCIES)
@rm -f simpleRCB$(EXEEXT)
$(simpleRCB_LINK) $(simpleRCB_OBJECTS) $(simpleRCB_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/problemGRAPH-problemGRAPH.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simpleBLOCK-simpleBLOCK.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simpleGRAPH-simpleGRAPH.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simplePHG-simplePHG.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simpleRCB-simpleRCB.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
problemGRAPH-problemGRAPH.o: problemGRAPH.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(problemGRAPH_CFLAGS) $(CFLAGS) -MT problemGRAPH-problemGRAPH.o -MD -MP -MF $(DEPDIR)/problemGRAPH-problemGRAPH.Tpo -c -o problemGRAPH-problemGRAPH.o `test -f 'problemGRAPH.c' || echo '$(srcdir)/'`problemGRAPH.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/problemGRAPH-problemGRAPH.Tpo $(DEPDIR)/problemGRAPH-problemGRAPH.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='problemGRAPH.c' object='problemGRAPH-problemGRAPH.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(problemGRAPH_CFLAGS) $(CFLAGS) -c -o problemGRAPH-problemGRAPH.o `test -f 'problemGRAPH.c' || echo '$(srcdir)/'`problemGRAPH.c
problemGRAPH-problemGRAPH.obj: problemGRAPH.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(problemGRAPH_CFLAGS) $(CFLAGS) -MT problemGRAPH-problemGRAPH.obj -MD -MP -MF $(DEPDIR)/problemGRAPH-problemGRAPH.Tpo -c -o problemGRAPH-problemGRAPH.obj `if test -f 'problemGRAPH.c'; then $(CYGPATH_W) 'problemGRAPH.c'; else $(CYGPATH_W) '$(srcdir)/problemGRAPH.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/problemGRAPH-problemGRAPH.Tpo $(DEPDIR)/problemGRAPH-problemGRAPH.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='problemGRAPH.c' object='problemGRAPH-problemGRAPH.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(problemGRAPH_CFLAGS) $(CFLAGS) -c -o problemGRAPH-problemGRAPH.obj `if test -f 'problemGRAPH.c'; then $(CYGPATH_W) 'problemGRAPH.c'; else $(CYGPATH_W) '$(srcdir)/problemGRAPH.c'; fi`
simpleBLOCK-simpleBLOCK.o: simpleBLOCK.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simpleBLOCK_CFLAGS) $(CFLAGS) -MT simpleBLOCK-simpleBLOCK.o -MD -MP -MF $(DEPDIR)/simpleBLOCK-simpleBLOCK.Tpo -c -o simpleBLOCK-simpleBLOCK.o `test -f 'simpleBLOCK.c' || echo '$(srcdir)/'`simpleBLOCK.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/simpleBLOCK-simpleBLOCK.Tpo $(DEPDIR)/simpleBLOCK-simpleBLOCK.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='simpleBLOCK.c' object='simpleBLOCK-simpleBLOCK.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simpleBLOCK_CFLAGS) $(CFLAGS) -c -o simpleBLOCK-simpleBLOCK.o `test -f 'simpleBLOCK.c' || echo '$(srcdir)/'`simpleBLOCK.c
simpleBLOCK-simpleBLOCK.obj: simpleBLOCK.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simpleBLOCK_CFLAGS) $(CFLAGS) -MT simpleBLOCK-simpleBLOCK.obj -MD -MP -MF $(DEPDIR)/simpleBLOCK-simpleBLOCK.Tpo -c -o simpleBLOCK-simpleBLOCK.obj `if test -f 'simpleBLOCK.c'; then $(CYGPATH_W) 'simpleBLOCK.c'; else $(CYGPATH_W) '$(srcdir)/simpleBLOCK.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/simpleBLOCK-simpleBLOCK.Tpo $(DEPDIR)/simpleBLOCK-simpleBLOCK.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='simpleBLOCK.c' object='simpleBLOCK-simpleBLOCK.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simpleBLOCK_CFLAGS) $(CFLAGS) -c -o simpleBLOCK-simpleBLOCK.obj `if test -f 'simpleBLOCK.c'; then $(CYGPATH_W) 'simpleBLOCK.c'; else $(CYGPATH_W) '$(srcdir)/simpleBLOCK.c'; fi`
simpleGRAPH-simpleGRAPH.o: simpleGRAPH.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simpleGRAPH_CFLAGS) $(CFLAGS) -MT simpleGRAPH-simpleGRAPH.o -MD -MP -MF $(DEPDIR)/simpleGRAPH-simpleGRAPH.Tpo -c -o simpleGRAPH-simpleGRAPH.o `test -f 'simpleGRAPH.c' || echo '$(srcdir)/'`simpleGRAPH.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/simpleGRAPH-simpleGRAPH.Tpo $(DEPDIR)/simpleGRAPH-simpleGRAPH.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='simpleGRAPH.c' object='simpleGRAPH-simpleGRAPH.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simpleGRAPH_CFLAGS) $(CFLAGS) -c -o simpleGRAPH-simpleGRAPH.o `test -f 'simpleGRAPH.c' || echo '$(srcdir)/'`simpleGRAPH.c
simpleGRAPH-simpleGRAPH.obj: simpleGRAPH.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simpleGRAPH_CFLAGS) $(CFLAGS) -MT simpleGRAPH-simpleGRAPH.obj -MD -MP -MF $(DEPDIR)/simpleGRAPH-simpleGRAPH.Tpo -c -o simpleGRAPH-simpleGRAPH.obj `if test -f 'simpleGRAPH.c'; then $(CYGPATH_W) 'simpleGRAPH.c'; else $(CYGPATH_W) '$(srcdir)/simpleGRAPH.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/simpleGRAPH-simpleGRAPH.Tpo $(DEPDIR)/simpleGRAPH-simpleGRAPH.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='simpleGRAPH.c' object='simpleGRAPH-simpleGRAPH.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simpleGRAPH_CFLAGS) $(CFLAGS) -c -o simpleGRAPH-simpleGRAPH.obj `if test -f 'simpleGRAPH.c'; then $(CYGPATH_W) 'simpleGRAPH.c'; else $(CYGPATH_W) '$(srcdir)/simpleGRAPH.c'; fi`
simplePHG-simplePHG.o: simplePHG.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simplePHG_CFLAGS) $(CFLAGS) -MT simplePHG-simplePHG.o -MD -MP -MF $(DEPDIR)/simplePHG-simplePHG.Tpo -c -o simplePHG-simplePHG.o `test -f 'simplePHG.c' || echo '$(srcdir)/'`simplePHG.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/simplePHG-simplePHG.Tpo $(DEPDIR)/simplePHG-simplePHG.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='simplePHG.c' object='simplePHG-simplePHG.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simplePHG_CFLAGS) $(CFLAGS) -c -o simplePHG-simplePHG.o `test -f 'simplePHG.c' || echo '$(srcdir)/'`simplePHG.c
simplePHG-simplePHG.obj: simplePHG.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simplePHG_CFLAGS) $(CFLAGS) -MT simplePHG-simplePHG.obj -MD -MP -MF $(DEPDIR)/simplePHG-simplePHG.Tpo -c -o simplePHG-simplePHG.obj `if test -f 'simplePHG.c'; then $(CYGPATH_W) 'simplePHG.c'; else $(CYGPATH_W) '$(srcdir)/simplePHG.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/simplePHG-simplePHG.Tpo $(DEPDIR)/simplePHG-simplePHG.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='simplePHG.c' object='simplePHG-simplePHG.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simplePHG_CFLAGS) $(CFLAGS) -c -o simplePHG-simplePHG.obj `if test -f 'simplePHG.c'; then $(CYGPATH_W) 'simplePHG.c'; else $(CYGPATH_W) '$(srcdir)/simplePHG.c'; fi`
simpleRCB-simpleRCB.o: simpleRCB.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simpleRCB_CFLAGS) $(CFLAGS) -MT simpleRCB-simpleRCB.o -MD -MP -MF $(DEPDIR)/simpleRCB-simpleRCB.Tpo -c -o simpleRCB-simpleRCB.o `test -f 'simpleRCB.c' || echo '$(srcdir)/'`simpleRCB.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/simpleRCB-simpleRCB.Tpo $(DEPDIR)/simpleRCB-simpleRCB.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='simpleRCB.c' object='simpleRCB-simpleRCB.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simpleRCB_CFLAGS) $(CFLAGS) -c -o simpleRCB-simpleRCB.o `test -f 'simpleRCB.c' || echo '$(srcdir)/'`simpleRCB.c
simpleRCB-simpleRCB.obj: simpleRCB.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simpleRCB_CFLAGS) $(CFLAGS) -MT simpleRCB-simpleRCB.obj -MD -MP -MF $(DEPDIR)/simpleRCB-simpleRCB.Tpo -c -o simpleRCB-simpleRCB.obj `if test -f 'simpleRCB.c'; then $(CYGPATH_W) 'simpleRCB.c'; else $(CYGPATH_W) '$(srcdir)/simpleRCB.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/simpleRCB-simpleRCB.Tpo $(DEPDIR)/simpleRCB-simpleRCB.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='simpleRCB.c' object='simpleRCB-simpleRCB.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simpleRCB_CFLAGS) $(CFLAGS) -c -o simpleRCB-simpleRCB.obj `if test -f 'simpleRCB.c'; then $(CYGPATH_W) 'simpleRCB.c'; else $(CYGPATH_W) '$(srcdir)/simpleRCB.c'; fi`
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(PROGRAMS) all-local
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-noinstPROGRAMS mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am:
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am all-local check check-am clean \
clean-generic clean-noinstPROGRAMS ctags distclean \
distclean-compile distclean-generic distclean-tags distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
uninstall-am
all-local:
include $(top_builddir)/Makefile.export.zoltan
all-local:
if test -e Makefile.am ; then : ; else cp $(FNAMES) $(builddir); fi
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -0,0 +1,78 @@
##
## a basic makefile to build examples
##
##
## The default type for a Zoltan global ID is "int". This can be changed
## with compile-time flags like:
##
## -DZOLTAN_ID_TYPE_LONG_LONG
##
## See src/include/zoltan_types.h for the valid id type macros. If Zoltan was compiled
## with one of these flags, then these examples need to be compiled with the same flag.
##
ID_TYPE_FLAG=-DZOLTAN_ID_TYPE_LONG_LONG
##
## Location of zoltan library, also location of Zoltan_config.h if
## using the autoconf build
BLD=../../build/src
##
## Location of zoltan "src" directory (for header files)
##
SRC=../../src
# Location of zoltan header files
ZOLTAN_INCLUDE=-I$(SRC)/include
##
## For an autoconf build, the location of Zoltan_config.h
##
ZOLTAN_CONFIG_INCLUDE=-I$(BLD)/include
##
## Headers for zoltan utilities, not often used by applications
## Needed for use of Zoltan_Hash in simpleGRAPH.c
##
ZOLTAN_UTIL_INCLUDE=-I$(SRC)/zz \
-I$(SRC)/par \
-I$(SRC)/order \
-I$(SRC)/tpls \
-I$(SRC)/lb \
-I$(SRC)/params \
-I$(SRC)/Utilities/shared
##
## If Zoltan was built with a third party library, provide the information required
## to link with that library.
##
SCOTCH=/home/lriesen/system/scotch_5.1.10a-32
PARMETIS=/home/lafisk/system/parmetis/ParMetis-3.1
TPL_LIB_DIR=-L$(PARMETIS) -L$(SCOTCH)/lib
TPL_INCLUDE=-I$(PARMETIS) -I$(SCOTCH)/include
TPL_LIBS=-lparmetis -lmetis -lptscotch -lscotch -lptscotcherr -lscotcherr
CC=mpicc
CFLAGS =$(ID_TYPE_FLAG)
EXAMPLE_NAMES= simpleBLOCK simpleRCB simpleGRAPH simplePHG migrateGRAPH simpleHIER problemGRAPH
all: $(EXAMPLE_NAMES)
%: %.c
$(CC) $(CFLAGS) $(TPL_LIB_DIR) \
-I$(BLD)/include $(TPL_INCLUDE) $(ZOLTAN_INCLUDE) $(ZOLTAN_UTIL_INCLUDE) \
-o $@ $< $(BLD)/libzoltan.a $(TPL_LIBS) -lm
clean:
@rm -rf $(EXAMPLE_NAMES)

View File

@ -0,0 +1,6 @@
These examples show how coloring can be done, but
unfortunately the coloring computed is not always valid
(in parallel). The reason is unclear.
TODO: These examples should either be fixed or removed.

View File

@ -0,0 +1,77 @@
# @HEADER
#
########################################################################
#
# Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
# Copyright 2012 Sandia Corporation
#
# Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
# the U.S. Government retains certain rights in this software.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the Corporation nor the names of the
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Questions? Contact Karen Devine kddevin@sandia.gov
# Erik Boman egboman@sandia.gov
#
########################################################################
#
# @HEADER
CC = mpicc
CFLAGS = -Wall -Wstrict-prototypes -O3 -m64
# CFLAGS = -Wall -Wstrict-prototypes -g -m64 -DZOLTANV31
# CFLAGS = -Wall -Wstrict-prototypes -g -m64 -D_DEBUG
BUILD = linux
ZOLTAN31 = ../../../Zoltan_v3.1_Release
ZOLTAN32 = ../../../Zoltan_v3.2_buggy
INC31 = -I$(ZOLTAN31)/src/include
LIBP31 = $(ZOLTAN31)/src/Obj_$(BUILD)
LIBS31 = -L$(LIBP31) -lzoltan -lm
INC32 = -I$(ZOLTAN32)/src/include
LIBP32 = $(ZOLTAN32)/src/Obj_$(BUILD)
LIBS32 = -L$(LIBP32) -lzoltan -lm
all: zcol zcoldriver zcoldriver-v3.1
zcol : zcol.c $(LIBP31)/libzoltan.a makefile
$(CC) $(CFLAGS) -DZOLTANV31 -o $@ zcol.c $(INC31) $(LIBS31)
zcoldriver-v3.1 : zcoldriver.c $(LIBP31)/libzoltan.a makefile
$(CC) $(CFLAGS) -DZOLTANV31 -o $@ zcoldriver.c $(INC31) $(LIBS31)
zcoldriver : zcoldriver.c $(LIBP32)/libzoltan.a makefile
$(CC) $(CFLAGS) -o $@ zcoldriver.c $(INC32) $(LIBS32)
clean:
rm -f *.o zcoldriver zcoldriver-v3.1 zcol

View File

@ -0,0 +1,689 @@
/*
* @HEADER
*
* ***********************************************************************
*
* Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
* Copyright 2012 Sandia Corporation
*
* Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
* the U.S. Government retains certain rights in this software.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Corporation nor the names of the
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Questions? Contact Karen Devine kddevin@sandia.gov
* Erik Boman egboman@sandia.gov
*
* ***********************************************************************
*
* @HEADER
*/
/***************************************************************
File : zcoldrive.c
Date :
Author : Umit V. Catalyurek
Descr : based on Zoltan simpleGraph example, a driver
for coloring codes that generates 5, 7 or 9
point stencil on the fly and colors them.
***************************************************************/
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>
#include "zoltan.h"
/*
#define _DEBUG
#define ZOLTANV31
*/
#define pID(i, j) ((i)*uz->procC + (j))
#define gID(i, j) ((i)*uz->meshC + (j))
#define lID(i, j) (((i)-uz->_sr)*(uz->_ec-uz->_sc) + ((j)-uz->_sc))
#define getR(id) ((id) / uz->meshC)
#define getC(id) ((id) % uz->meshC)
#define pIDfRC(r, c) pID(r/(uz->meshR/uz->procR), c/(uz->meshC/uz->procC))
#define pIDfGID(gid) pIDfRC(getR(gid), getC(gid))
#define lIDfGID(gid) lID(getR(gid), getC(gid))
#define gIDfLID(lid) gID(uz->_sr+(lid/(uz->_ec-uz->_sc)), uz->_sc+(lid%(uz->_ec-uz->_sc)))
static int *xadj=NULL, *adj=NULL, *adjTemp=NULL;
struct edge {
int c, r;
};
struct edge neig[8] = {
{0, -1}, {1, 0}, {0, 1}, {-1, 0},
{-1, -1}, {1, 1}, {1, -1}, {-1, 1}
};
typedef struct {
int stencil; /* for 5, 7 and 9-point, 4, 6 and 8 edges will be created, respectively,
hence stencil value will be 4, 6 or 8 */
int procR, procC; /* proc mesh is R x C */
int meshR, meshC; /* input mesh is R x C */
int _sr, _er, _sc, _ec; /* proc's start (inclusive) and end (exclusive) rows/cols of input mesh */
int myRank, myR, myC;
int numProcs;
double beta;
int numredge;
int *redgeto; /* if beta>0; contains end point of my random edges;
redgeto[lID(i,j)] = -1 means no random edge,
>= 0 points to end point */
} UZData;
extern unsigned int Zoltan_Rand_InRange(unsigned int *, unsigned int);
double u_wseconds(void)
{
struct timeval tp;
gettimeofday(&tp, NULL);
return (double) tp.tv_sec + (double) tp.tv_usec / 1000000.0;
}
static int get_number_of_objects(void *data, int *ierr)
{
UZData *uz = (UZData *) data;
*ierr = ZOLTAN_OK;
return (uz->_er-uz->_sr) * (uz->_ec-uz->_sc);
}
static void get_object_list(void *data, int sizeGID, int sizeLID,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int wgt_dim, float *obj_wgts, int *ierr)
{
UZData *uz = (UZData *) data;
int i, j, next=0;
/* By setting parameters, I previously gave the Zoltan library
* the length of my global IDs, local IDs, and object weights.
*/
if (sizeGID != 1 || sizeLID !=1 ){ /* My global/local IDs are 1 integer */
*ierr = ZOLTAN_FATAL;
return;
}
for (i=uz->_sr; i<uz->_er; ++i)
for (j=uz->_sc; j<uz->_ec; ++j) {
globalID[next] = gID(i, j); /* application wide global ID */
localID[next] = lID(i, j); /* process specific local ID */
/* sanity check */
if (lID(i, j)!=next) {
fprintf(stderr, "umit something is wrong lID(%d, %d) is %d but next is %d\n", i, j, lID(i, j), next);
exit(1);
}
#if 0
if (wgt_dim>0)
obj_wgts[next] = uz->stencil; /* weight */
#endif
++next;
}
*ierr = ZOLTAN_OK;
}
/* let's keep this in the code for now; may be we'll use it later */
#if 0
/*
**************************************************************
* Prototype: ZOLTAN_NUM_GEOM_FN
* Return the dimension of a vertex, for geometric methods
**************************************************************
*/
static int get_num_geometry(void *data, int *ierr)
{
*ierr = ZOLTAN_OK;
return 2;
}
/*
**************************************************************
* Prototype: ZOLTAN_GEOM_MULTI_FN
* Return the coordinates of my objects (vertices), for
* geometric methods.
**************************************************************
*/
static void get_geometry_list(void *data, int sizeGID, int sizeLID,
int num_obj,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int num_dim, double *geom_vec, int *ierr)
{
UZData *uz = (UZData *) data;
int i, j, next=0;
if ( (sizeGID != 1) || (sizeLID != 1) || (num_dim != 2)){
*ierr = ZOLTAN_FATAL;
return;
}
for (i=uz->_sr; i<uz->_er; ++i)
for (j=uz->_sc; j<uz->_ec; ++j) {
geom_vec[next++] = (double) i;
geom_vec[next++] = (double) j;
}
*ierr = ZOLTAN_OK;
}
#endif
static int filledges(int lid, int *adjID, int *adjProc, UZData *uz)
{
int *nextID = adjID, *ptr;
int *nextProc = adjProc;
int gid = gIDfLID(lid);
int r = getR(gid), r2;
int c = getC(gid), c2, e, j;
/* printf(" %d (%d,%d) : ", id, r, c); */
for (e=0; e<uz->stencil; ++e) {
r2 = r+neig[e].r;
c2 = c+neig[e].c;
if (r2>=0 && r2<uz->meshR &&
c2>=0 && c2<uz->meshC) {
*nextID++ = gID(r2, c2);
if (adjProc)
*nextProc++ = pID(r2/(uz->meshR/uz->procR), c2/(uz->meshC/uz->procC));
/* printf(" %d (%d, %d) [%d] ", *(nextID-1), r2, c2, *(nextProc-1)); */
}
}
if (uz->redgeto && (uz->redgeto[lid]>=0)) {
for (ptr=adjID; ptr<nextID && *ptr!=uz->redgeto[lid]; ++ptr);
if (ptr>=nextID) {
r2 = getR(uz->redgeto[lid]);
c2 = getC(uz->redgeto[lid]);
*nextID++ = uz->redgeto[lid];
if (adjProc)
*nextProc++ = pID(r2/(uz->meshR/uz->procR), c2/(uz->meshC/uz->procC));
/* printf(" %d (%d, %d) [%d] ", *(nextID-1), r2, c2, *(nextProc-1)); */
}
}
if (xadj) {
for (j=xadj[lid]; j<xadj[lid+1]; ++j) {
for (ptr=adjID; ptr<nextID && *ptr!=uz->redgeto[lid]; ++ptr);
if (ptr>=nextID) {
*nextID++ = adj[j];
if (adjProc)
*nextProc++ = pIDfGID(adj[j]);
}
}
}
/* printf("\n"); */
return nextID-adjID;
}
static void get_num_edges_list(void *data, int sizeGID, int sizeLID,
int num_obj,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int *numEdges, int *ierr)
{
UZData *uz = (UZData *) data;
int i, lid;
if ( (sizeGID != 1) || (sizeLID != 1)){
*ierr = ZOLTAN_FATAL;
return;
}
for (i=0; i < num_obj ; ++i){
lid = lIDfGID(globalID[i]);
numEdges[i] = filledges(lid, adjTemp, NULL, uz);
}
*ierr = ZOLTAN_OK;
}
static void get_edge_list(void *data, int sizeGID, int sizeLID,
int num_obj, ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int *num_edges,
ZOLTAN_ID_PTR nborGID, int *nborProc,
int wgt_dim, float *ewgts, int *ierr)
{
UZData *uz = (UZData *) data;
int i;
ZOLTAN_ID_PTR nextID;
int *nextProc;
if ( (sizeGID != 1) || (sizeLID != 1) ||
(wgt_dim != 0)) { /* we are not using edge weights */
*ierr = ZOLTAN_FATAL;
return;
}
nextID = nborGID;
nextProc = nborProc;
/* printf("querying %d vertices\n", num_obj); */
for (i=0; i < num_obj ; ++i) {
int lid = lIDfGID(globalID[i]), ne;
ne = filledges(lid, (int *) nextID, nextProc, uz);
nextID += ne;
nextProc += ne;
}
*ierr = ZOLTAN_OK;
}
void computeProcMesh(UZData *uz)
{
int i = (int) sqrt((double)uz->numProcs+0.1);
while (uz->numProcs % i)
--i;
uz->procR = i;
uz->procC = uz->numProcs / i;
}
void printStats(char *st, int val, int myRank, int nProc)
{
int *allval=NULL, minv, maxv, totv, i;
if (!myRank)
allval = (int *) malloc(sizeof(int)*nProc);
MPI_Gather(&val, 1, MPI_INT, allval, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (!myRank) {
minv = maxv = totv = allval[0];
for (i=1; i<nProc; ++i) {
if (allval[i]>maxv)
maxv = allval[i];
if (allval[i]<minv)
minv = allval[i];
totv += allval[i];
}
printf("%-15s Min: %10d Max: %10d Avg: %10.1lf Tot: %10d\n", st, minv, maxv, (double) totv/(double)nProc, totv);
free(allval);
}
}
#ifdef _DEBUG
void saveColor(char *exename, UZData *uz, int *gid_list, int *color, int ngids)
{
char fname[2048];
FILE *fp;
int i;
sprintf(fname, "%s.%dx%d.%d-point.%d.Of.%dx%d.txt", exename,
uz->meshR, uz->meshC, uz->stencil+1, uz->myRank, uz->procR, uz->procC);
if (!uz->myRank)
printf("Saving the colors in file '%s'\n", fname);
fp = fopen(fname, "w");
for (i=0; i<ngids; ++i)
fprintf(fp, "%d %d\n", gid_list[i], color[i]);
fclose(fp);
}
#endif
int main(int argc, char *argv[])
{
int rc, i, ngids, maxcol, ncolors;
float ver;
struct Zoltan_Struct *zz=NULL;
#ifdef ZOLTANV31
int numGidEntries, numLidEntries;
#else
ZOLTAN_GRAPH_EVAL graph;
#endif
int *color;
ZOLTAN_ID_PTR gid_list;
UZData guz, *uz=&guz;
int msg_tag = 9999;
int nlvtx, next, maxdeg=0;
double times[9]={0.,0.,0.,0.,0.,0.,0.,0.}; /* Used for timing measurements */
double gtimes[9]={0.,0.,0.,0.,0.,0.,0.,0.}; /* Used for timing measurements */
/******************************************************************
** Initialize MPI and Zoltan
******************************************************************/
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &uz->myRank);
MPI_Comm_size(MPI_COMM_WORLD, &uz->numProcs);
MPI_Barrier(MPI_COMM_WORLD);
times[0] = u_wseconds();
rc = Zoltan_Initialize(argc, argv, &ver);
if (rc != ZOLTAN_OK){
fprintf(stderr, "Sorry Zoltan initialize failed...\n");
goto End;
}
zz = Zoltan_Create(MPI_COMM_WORLD);
if (argc<3 && !uz->myRank) {
fprintf(stderr, "usage: %s [meshR] [meshC] [X-point stencil] [procR] [procC] [ws-beta] [<ZoltanParam>=<Val>] ...\n\n", argv[0]);
fprintf(stderr, "ws-beta: is the probablity of adding an edge to a vertex to generate Watts-Strogatz graphs\n");
fprintf(stderr, "Valid values for Stencil are 5, 7 and 9\n");
fprintf(stderr, "Zoltan Coloring Parameters and values are\n");
fprintf(stderr, "\tDISTANCE : 1 or 2\n");
fprintf(stderr, "\tSUPERSTEP_SIZE : suggested >= 100\n");
fprintf(stderr, "\tCOMM_PATTERN : S or A\n");
fprintf(stderr, "\tCOLOR_ORDER : I, B, U\n");
fprintf(stderr, "\tCOLORING_METHOD : F (for now)\n");
fprintf(stderr, "\n");
}
uz->procR = uz->procC = 0;
uz->meshR = uz->meshC = 1024;
uz->stencil = 9;
if (argc>1)
uz->meshR = atoi(argv[1]);
if (argc>2)
uz->meshC = atoi(argv[2]);
if (argc>3)
uz->stencil = atoi(argv[3]);
if (uz->stencil!=5 && uz->stencil!=7 && uz->stencil!=9) {
fprintf(stderr, "\t invalid stencil value. Valid values are 5, 7 and 9. Assumed 9.\n");
uz->stencil = 9;
}
--uz->stencil;
if (argc>4)
uz->procR = atoi(argv[4]);
if (argc>5)
uz->procC = atoi(argv[5]);
if (uz->procR <= 0 || uz->procC <= 0)
computeProcMesh(uz);
if (uz->procR*uz->procC!=uz->numProcs) {
fprintf(stderr, "#Procs=%d but requested %dx%d Proc Mesh Partitioning...\n", uz->numProcs, uz->procR, uz->procC);
goto End;
}
if (argc>6)
uz->beta = atof(argv[6]);
else
uz->beta = 0.0;
/* compute which part of mesh I will compute */
uz->myR = uz->myRank / uz->procC;
uz->myC = uz->myRank % uz->procC;
uz->_sr = uz->myR * (uz->meshR / uz->procR);
uz->_er = (uz->myR+1) * (uz->meshR / uz->procR);
if (uz->_er>uz->meshR)
uz->_er = uz->meshR;
uz->_sc = uz->myC * (uz->meshC / uz->procC);
uz->_ec = (uz->myC+1) * (uz->meshC / uz->procC);
if (uz->_ec>uz->meshC)
uz->_ec = uz->meshC;
if ( (uz->meshR % uz->procR) !=0 || (uz->meshC % uz->procC)!=0) {
printf("Mesh dimensions are not divisible with proc mesh.\nRequested mesh is %dx%d and proc mesh is %d x %d\n", uz->meshR, uz->meshC, uz->procR, uz->procC);
exit(1);
}
nlvtx= (uz->_er-uz->_sr) * (uz->_ec-uz->_sc);
if (uz->myRank==0)
printf("Running %s on %d x %d processor mesh, generating %d-point %d x %d mesh with beta=%.3lf\n", argv[0], uz->procR, uz->procC, uz->stencil+1, uz->meshR, uz->meshC, uz->beta);
times[1] = u_wseconds();
uz->numredge = 0;
uz->redgeto = NULL;
if (uz->beta>0) { /* create random edges for WS graph */
int ngvtx=uz->meshC*uz->meshR, trsh=(int) (uz->beta*100.0);
int ierr=0;
int *edges=NULL, *redges=NULL, *proclist=NULL, nedge;
ZOLTAN_COMM_OBJ *plan;
uz->redgeto = (int *) malloc(nlvtx*sizeof(int));
for (i=0; i<nlvtx; ++i) {
int rv = Zoltan_Rand_InRange(NULL, 100);
if ( rv < trsh) {
if ((uz->redgeto[i] = Zoltan_Rand_InRange(NULL, ngvtx))==gIDfLID(i)) /* is it a self edge */
uz->redgeto[i] = -1;
else
++uz->numredge;
} else
uz->redgeto[i] = -1;
}
edges = (int *) malloc(sizeof(int)*2*uz->numredge);
proclist = (int *) malloc(sizeof(int)*uz->numredge);
next = 0;
for (i=0; i<nlvtx; ++i)
if (uz->redgeto[i]>0) {
edges[2*next] = uz->redgeto[i];
edges[2*next+1] = gIDfLID(i);
proclist[next] = pIDfGID(uz->redgeto[i]);
++next;
}
ierr = Zoltan_Comm_Create(&plan, uz->numredge, proclist, MPI_COMM_WORLD,
msg_tag, &nedge);
redges = (int *) malloc(sizeof(int)*2*nedge);
--msg_tag;
ierr |= Zoltan_Comm_Do(plan, msg_tag, (char *) edges, 2*sizeof(int),
(char *) redges);
ierr |= Zoltan_Comm_Destroy(&plan);
free(proclist);
free(edges);
if (ierr) {
printf("error while communicating edges!\n");
exit(1);
}
xadj = (int *) calloc(1+nlvtx, sizeof(int));
adj = (int *) malloc(sizeof(int)*nedge);
for (i=0; i<nedge; ++i) {
if (redges[2*i] < gID(uz->_sr, uz->_sc) || redges[2*i] >= gID(uz->_er, uz->_ec)) {
printf("[%d/%d] received gid=%d doesn't blong to processor range [%d, %d) should go to proc %d\n", uz->myRank, uz->numProcs, redges[2*i], gID(uz->_sr, uz->_sc), gID(uz->_er, uz->_ec), pIDfGID(redges[2*i]));
}
++xadj[lIDfGID(redges[2*i])];
}
xadj[nlvtx] = nedge;
maxdeg = xadj[0];
for (i=1; i<nlvtx; ++i) {
maxdeg = xadj[i]>maxdeg ? xadj[i] : maxdeg;
xadj[i] += xadj[i-1];
}
for (i=0; i<nedge; ++i) {
int u = lIDfGID(redges[2*i]);
int v = redges[2*i+1];
adj[--xadj[u]] = v;
}
free(redges);
}
maxdeg += uz->stencil+1;
adjTemp = (int *) malloc(sizeof(int)*2*maxdeg);
times[2] = u_wseconds();
/*
printf("My rank %d/%d at proc-mesh loc (%d, %d) generating [%d, %d) x [%d, %d) + %d random edges TotEdge=%d\n", uz->myRank, uz->numProcs, uz->myR, uz->myC, uz->_sr, uz->_er, uz->_sc, uz->_ec, uz->numredge, xadj[nlvtx]); */
printStats("Number of Vertices ", nlvtx, uz->myRank, uz->numProcs);
if (xadj)
printStats("Number of Rand Edges", xadj[nlvtx], uz->myRank, uz->numProcs);
/* General parameters */
#ifndef ZOLTANV31
Zoltan_Set_Param(zz, "GRAPH_BUILD_TYPE", "FAST_NO_DUP");
#endif
/* General parameters */
Zoltan_Set_Param(zz, "DEBUG_LEVEL", "3");
Zoltan_Set_Param(zz, "NUM_GID_ENTRIES", "1");
Zoltan_Set_Param(zz, "NUM_LID_ENTRIES", "1");
Zoltan_Set_Param(zz, "OBJ_WEIGHT_DIM", "0");
/* coloring parameters */
Zoltan_Set_Param(zz, "SUPERSTEP_SIZE", "500"); /* let's make S=500 default */
for (i=7; i<argc; ++i) {
char param[256], *eq;
if (!uz->myRank)
printf("processing argv[%d]='%s'\n", i, argv[i]);
strncpy(param, argv[i], sizeof(param));
eq = strchr(param, '=');
if (!eq) {
fprintf(stderr, "invalid argument '%s', Zoltan Paramters should be in the format <ZoltanParam>=<Val>\n", param);
goto End;
}
*eq = 0;
Zoltan_Set_Param(zz, param, eq+1);
}
#if 0
/* Graph parameters */
Zoltan_Set_Param(zz, "CHECK_GRAPH", "2");
#endif
/* set call backs */
Zoltan_Set_Num_Obj_Fn(zz, get_number_of_objects, uz);
Zoltan_Set_Obj_List_Fn(zz, get_object_list, uz);
Zoltan_Set_Num_Edges_Multi_Fn(zz, get_num_edges_list, uz);
Zoltan_Set_Edge_List_Multi_Fn(zz, get_edge_list, uz);
#if 0
#ifndef ZOLTANV31
Zoltan_LB_Eval_Graph(zz, 0, &graph);
if (!uz->myRank) {
printf("EdgeCut Min=%8.0f Max=%8.0f Sum=%8.0f\n", graph.cuts[EVAL_GLOBAL_MIN], graph.cuts[EVAL_GLOBAL_MAX], graph.cuts[EVAL_GLOBAL_SUM]);
printf("#Vertices Min=%8.0f Max=%8.0f Sum=%8.0f imbal=%.2f\n", graph.nobj[EVAL_GLOBAL_MIN], graph.nobj[EVAL_GLOBAL_MAX], graph.nobj[EVAL_GLOBAL_SUM], graph.obj_imbalance);
}
#endif
#endif
/* now color */
ngids = get_number_of_objects(uz, &rc);
gid_list = (ZOLTAN_ID_PTR) malloc(sizeof(ZOLTAN_ID_TYPE) * ngids);
#ifndef ZOLTANV31
next = 0;
for (i=uz->_sr; i<uz->_er; ++i) {
int j;
for (j=uz->_sc; j<uz->_ec; ++j) {
gid_list[next++] = i*uz->meshC + j;
}
}
#endif
color = (int *) malloc(sizeof(int) * ngids);
MPI_Barrier(MPI_COMM_WORLD);
times[3] = u_wseconds();
#ifdef ZOLTANV31
rc = Zoltan_Color(zz, /* input (all remaining fields are output) */
&numGidEntries, /* Number of integers used for a global ID */
&numLidEntries, /* Number of integers used for a local ID */
ngids, /* #objects to color in this proc */
gid_list, /* global ids of colored vertices */
NULL, /* we ignore local ids */
color); /* result color */
#else
rc = Zoltan_Color(zz, /* input (all remaining fields are output) */
1, /* Number of integers used for a global ID */
ngids, /* #objects to color in this proc */
gid_list, /* global ids of colored vertices */
color); /* result color */
#endif
MPI_Barrier(MPI_COMM_WORLD);
times[4] = u_wseconds();
MPI_Reduce(times, gtimes, 5, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
if (rc != ZOLTAN_OK)
fprintf(stderr, "Zoltan_Color failed with return code %d...\n", rc);
for (maxcol=i=0; i<ngids; ++i)
if (color[i] > maxcol)
maxcol = color[i];
MPI_Reduce(&maxcol, &ncolors, 1, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD);
if (uz->myRank==0) {
struct rusage usage;
printf("%s setup Proc-0: %8.2lf Max: %8.2lf\n", argv[0], times[1]-times[0], gtimes[1]-gtimes[0]);
printf("%s gen rand edges Proc-0: %8.2lf Max: %8.2lf\n", argv[0], times[2]-times[1], gtimes[2]-gtimes[1]);
printf("%s set gids Proc-0: %8.2lf Max: %8.2lf\n", argv[0], times[3]-times[2], gtimes[3]-gtimes[2]);
printf("%s Zoltan_Color call Proc-0: %8.2lf Max: %8.2lf\n", argv[0], times[4]-times[3], gtimes[4]-gtimes[3]);
printf("%s Coloring Time : %.2lf # Colors used : %d\n", argv[0], gtimes[4]-gtimes[0], ncolors);
getrusage(RUSAGE_SELF, &usage);
printf("%s maxrss=%ld minflt=%ld majflt=%ld nswap=%ld\n", argv[0], usage.ru_maxrss, usage.ru_minflt, usage.ru_majflt, usage.ru_nswap);
}
#ifdef _DEBUG
saveColor(argv[0], uz, (int *) gid_list, color, ngids);
#endif
/******************************************************************
** Clean up
******************************************************************/
if (gid_list)
free(gid_list);
if (color)
free(color);
if (xadj)
free(xadj);
if (adj)
free(adj);
if (adjTemp)
free(adjTemp);
if (uz->redgeto)
free(uz->redgeto);
End:
Zoltan_Destroy(&zz);
MPI_Finalize();
return 0;
}

View File

@ -0,0 +1,602 @@
/*
* @HEADER
*
* ***********************************************************************
*
* Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
* Copyright 2012 Sandia Corporation
*
* Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
* the U.S. Government retains certain rights in this software.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Corporation nor the names of the
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Questions? Contact Karen Devine kddevin@sandia.gov
* Erik Boman egboman@sandia.gov
*
* ***********************************************************************
*
* @HEADER
*/
/***************************************************************
File : zcoldrive.c
Date :
Author : Umit V. Catalyurek
Descr : based on Zoltan simpleGraph example, a driver
for coloring codes that generates 5, 7 or 9
point stencil on the fly and colors them.
***************************************************************/
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>
#include "zoltan.h"
/*
#define _DEBUG
#define ZOLTANV31
*/
#define pID(i, j) ((i)*uz->procC + (j))
#define gID(i, j) ((i)*uz->meshC + (j))
#define lID(i, j) (((i)-uz->_sr)*(uz->_ec-uz->_sc) + ((j)-uz->_sc))
#define getR(id) ((id) / uz->meshC)
#define getC(id) ((id) % uz->meshC)
struct edge {
int c, r;
};
struct edge neig[8] = {
{0, -1}, {1, 0}, {0, 1}, {-1, 0},
{-1, -1}, {1, 1}, {1, -1}, {-1, 1}
};
typedef struct {
int stencil; /* for 5, 7 and 9-point, 4, 6 and 8 edges will be created, respectively,
hence stencil value will be 4, 6 or 8 */
int procR, procC; /* proc mesh is R x C */
int meshR, meshC; /* input mesh is R x C */
int _sr, _er, _sc, _ec; /* proc's start (inclusive) and end (exclusive) rows/cols of input mesh */
int myRank, myR, myC;
int numProcs;
double beta;
int numredge;
int *redgeto; /* if beta>0; contains end point of my random edges;
redgeto[lID(i,j)] = -1 means no random edge,
>= 0 points to end point */
} UZData;
extern unsigned int Zoltan_Rand_InRange(unsigned int *, unsigned int);
double u_wseconds(void)
{
struct timeval tp;
gettimeofday(&tp, NULL);
return (double) tp.tv_sec + (double) tp.tv_usec / 1000000.0;
}
static int get_number_of_objects(void *data, int *ierr)
{
UZData *uz = (UZData *) data;
*ierr = ZOLTAN_OK;
return (uz->_er-uz->_sr) * (uz->_ec-uz->_sc);
}
static void get_object_list(void *data, int sizeGID, int sizeLID,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int wgt_dim, float *obj_wgts, int *ierr)
{
UZData *uz = (UZData *) data;
int i, j, next=0;
/* By setting parameters, I previously gave the Zoltan library
* the length of my global IDs, local IDs, and object weights.
*/
if (sizeGID != 1 || sizeLID !=1 ){ /* My global/local IDs are 1 integer */
*ierr = ZOLTAN_FATAL;
return;
}
for (i=uz->_sr; i<uz->_er; ++i)
for (j=uz->_sc; j<uz->_ec; ++j) {
globalID[next] = gID(i, j); /* application wide global ID */
localID[next] = lID(i, j); /* process specific local ID */
/* sanity check */
if (lID(i, j)!=next) {
fprintf(stderr, "umit something is wrong lID(%d, %d) is %d but next is %d\n", i, j, lID(i, j), next);
exit(1);
}
#if 0
if (wgt_dim>0)
obj_wgts[next] = uz->stencil; /* weight */
#endif
++next;
}
*ierr = ZOLTAN_OK;
}
/* let's keep this in the code for now; may be we'll use it later */
#if 0
/*
**************************************************************
* Prototype: ZOLTAN_NUM_GEOM_FN
* Return the dimension of a vertex, for geometric methods
**************************************************************
*/
static int get_num_geometry(void *data, int *ierr)
{
*ierr = ZOLTAN_OK;
return 2;
}
/*
**************************************************************
* Prototype: ZOLTAN_GEOM_MULTI_FN
* Return the coordinates of my objects (vertices), for
* geometric methods.
**************************************************************
*/
static void get_geometry_list(void *data, int sizeGID, int sizeLID,
int num_obj,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int num_dim, double *geom_vec, int *ierr)
{
UZData *uz = (UZData *) data;
int i, j, next=0;
if ( (sizeGID != 1) || (sizeLID != 1) || (num_dim != 2)){
*ierr = ZOLTAN_FATAL;
return;
}
for (i=uz->_sr; i<uz->_er; ++i)
for (j=uz->_sc; j<uz->_ec; ++j) {
geom_vec[next++] = (double) i;
geom_vec[next++] = (double) j;
}
*ierr = ZOLTAN_OK;
}
#endif
/*
**************************************************************
* Prototype: ZOLTAN_NUM_EDGES_MULTI_FN
* Return the number of edges for each vertex in the ID lists.
* For graph methods.
**************************************************************
*/
static void get_num_edges_list(void *data, int sizeGID, int sizeLID,
int num_obj,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int *numEdges, int *ierr)
{
UZData *uz = (UZData *) data;
int i, id, r, c, r2, c2, edgecnt, e;
if ( (sizeGID != 1) || (sizeLID != 1)){
*ierr = ZOLTAN_FATAL;
return;
}
for (i=0; i < num_obj ; ++i){
id = globalID[i];
r = getR(id);
c = getC(id);
if (r==0 || c==0 || r==(uz->meshR-1) || c==(uz->meshC-1)) {
/* we can probably do much smarter thing bu since
we're not going to time graph generation time,
simply run through over edges and see how many edges
it will have. */
edgecnt = 0;
for (e=0; e<uz->stencil; ++e) {
r2 = r+neig[e].r;
c2 = c+neig[e].c;
if (r2>=0 && r2<uz->meshR &&
c2>=0 && c2<uz->meshC)
++edgecnt;
}
numEdges[i] = edgecnt;
} else /* internal vertices always have all the edges */
numEdges[i] = uz->stencil;
if (uz->redgeto && (uz->redgeto[i]>=0))
++numEdges[i];
}
*ierr = ZOLTAN_OK;
}
/*
**************************************************************
* Prototype: ZOLTAN_EDGE_LIST_MULTI_FN
* For every vertex in the ID list, return a list of all its
* adjacent vertices, and the processes on which they reside.
* Also include the edge weights if any.
* For graph methods.
**************************************************************
*/
static void get_edge_list(void *data, int sizeGID, int sizeLID,
int num_obj, ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int *num_edges,
ZOLTAN_ID_PTR nborGID, int *nborProc,
int wgt_dim, float *ewgts, int *ierr)
{
UZData *uz = (UZData *) data;
int i, id, r, c, r2, c2, e;
ZOLTAN_ID_PTR nextID;
int *nextProc;
if ( (sizeGID != 1) || (sizeLID != 1) ||
(wgt_dim != 0)){ /* we are not using edge weights */
*ierr = ZOLTAN_FATAL;
return;
}
nextID = nborGID;
nextProc = nborProc;
/* printf("querying %d vertices\n", num_obj); */
for (i=0; i < num_obj ; ++i) {
id = globalID[i];
r = getR(id);
c = getC(id);
/* printf(" %d (%d,%d) : ", id, r, c); */
for (e=0; e<uz->stencil; ++e) {
r2 = r+neig[e].r;
c2 = c+neig[e].c;
if (r2>=0 && r2<uz->meshR &&
c2>=0 && c2<uz->meshC) {
*nextID++ = gID(r2, c2);
*nextProc++ = pID(r2/(uz->meshR/uz->procR), c2/(uz->meshC/uz->procC));
/* printf(" %d (%d, %d) [%d] ", *(nextID-1), r2, c2, *(nextProc-1)); */
}
}
if (uz->redgeto && (uz->redgeto[i]>=0)) {
r2 = getR(uz->redgeto[i]);
c2 = getC(uz->redgeto[i]);
*nextID++ = gID(r2, c2);
*nextProc++ = pID(r2/(uz->meshR/uz->procR), c2/(uz->meshC/uz->procC));
/* printf(" %d (%d, %d) [%d] ", *(nextID-1), r2, c2, *(nextProc-1)); */
}
/* printf("\n"); */
*ierr = ZOLTAN_OK;
}
}
void computeProcMesh(UZData *uz)
{
int i = (int) sqrt((double)uz->numProcs+0.1);
while (uz->numProcs % i)
--i;
uz->procR = i;
uz->procC = uz->numProcs / i;
}
#ifdef _DEBUG
void saveColor(char *exename, UZData *uz, int *gid_list, int *color, int ngids)
{
char fname[2048];
FILE *fp;
int i;
sprintf(fname, "%s.%dx%d.%d-point.%d.Of.%dx%d.txt", exename,
uz->meshR, uz->meshC, uz->stencil+1, uz->myRank, uz->procR, uz->procC);
if (!uz->myRank)
printf("Saving the colors in file '%s'\n", fname);
fp = fopen(fname, "w");
for (i=0; i<ngids; ++i)
fprintf(fp, "%d %d\n", gid_list[i], color[i]);
fclose(fp);
}
#endif
int main(int argc, char *argv[])
{
int rc, i, ngids, maxcol, ncolors;
float ver;
struct Zoltan_Struct *zz=NULL;
#ifdef ZOLTANV31
int numGidEntries, numLidEntries;
#else
ZOLTAN_GRAPH_EVAL graph;
int next;
#endif
int *color;
ZOLTAN_ID_PTR gid_list;
UZData uz;
double times[9]={0.,0.,0.,0.,0.,0.,0.,0.}; /* Used for timing measurements */
double gtimes[9]={0.,0.,0.,0.,0.,0.,0.,0.}; /* Used for timing measurements */
/******************************************************************
** Initialize MPI and Zoltan
******************************************************************/
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &uz.myRank);
MPI_Comm_size(MPI_COMM_WORLD, &uz.numProcs);
MPI_Barrier(MPI_COMM_WORLD);
times[0] = u_wseconds();
rc = Zoltan_Initialize(argc, argv, &ver);
if (rc != ZOLTAN_OK){
fprintf(stderr, "Sorry Zoltan initialize failed...\n");
goto End;
}
zz = Zoltan_Create(MPI_COMM_WORLD);
if (argc<3 && !uz.myRank) {
fprintf(stderr, "usage: %s [meshR] [meshC] [X-point stencil] [procR] [procC] [ws-beta] [<ZoltanParam>=<Val>] ...\n\n", argv[0]);
fprintf(stderr, "ws-beta: is the probablity of adding an edge to a vertex to generate Watts-Strogatz graphs\n");
fprintf(stderr, "Valid values for Stencil are 5, 7 and 9\n");
fprintf(stderr, "Zoltan Coloring Parameters and values are\n");
fprintf(stderr, "\tDISTANCE : 1 or 2\n");
fprintf(stderr, "\tSUPERSTEP_SIZE : suggested >= 100\n");
fprintf(stderr, "\tCOMM_PATTERN : S or A\n");
fprintf(stderr, "\tCOLOR_ORDER : I, B, U\n");
fprintf(stderr, "\tCOLORING_METHOD : F (for now)\n");
fprintf(stderr, "\n");
}
uz.procR = uz.procC = 0;
uz.meshR = uz.meshC = 1024;
uz.stencil = 9;
if (argc>1)
uz.meshR = atoi(argv[1]);
if (argc>2)
uz.meshC = atoi(argv[2]);
if (argc>3)
uz.stencil = atoi(argv[3]);
if (uz.stencil!=5 && uz.stencil!=7 && uz.stencil!=9) {
fprintf(stderr, "\t invalid stencil value. Valid values are 5, 7 and 9. Assumed 9.\n");
uz.stencil = 9;
}
--uz.stencil;
if (argc>4)
uz.procR = atoi(argv[4]);
if (argc>5)
uz.procC = atoi(argv[5]);
if (uz.procR <= 0 || uz.procC <= 0)
computeProcMesh(&uz);
if (uz.procR*uz.procC!=uz.numProcs) {
fprintf(stderr, "#Procs=%d but requested %dx%d Proc Mesh Partitioning...\n", uz.numProcs, uz.procR, uz.procC);
goto End;
}
if (argc>6)
uz.beta = atof(argv[6]);
else
uz.beta = 0.0;
/* compute which part of mesh I will compute */
uz.myR = uz.myRank / uz.procC;
uz.myC = uz.myRank % uz.procC;
uz._sr = uz.myR * (uz.meshR / uz.procR);
uz._er = (uz.myR+1) * (uz.meshR / uz.procR);
if (uz._er>uz.meshR)
uz._er = uz.meshR;
uz._sc = uz.myC * (uz.meshC / uz.procC);
uz._ec = (uz.myC+1) * (uz.meshC / uz.procC);
if (uz._ec>uz.meshC)
uz._ec = uz.meshC;
if (uz.myRank==0)
printf("Running %s on %d x %d processor mesh, generating %d-point %d x %d mesh with beta=%.3lf\n", argv[0], uz.procR, uz.procC, uz.stencil+1, uz.meshR, uz.meshC, uz.beta);
times[1] = u_wseconds();
uz.numredge = 0;
uz.redgeto = NULL;
if (uz.beta>0) { /* create random edges for WS graph */
int nlvtx= (uz._er-uz._sr) * (uz._ec-uz._sc), ngvtx=uz.meshC*uz.meshR, trsh=(int) (uz.beta*100.0);
uz.redgeto = (int *) malloc(nlvtx*sizeof(int));
for (i=0; i<nlvtx; ++i) {
int rv = Zoltan_Rand_InRange(NULL, 100);
if ( rv < trsh) {
uz.redgeto[i] = Zoltan_Rand_InRange(NULL, ngvtx);
++uz.numredge;
} else
uz.redgeto[i] = -1;
}
}
times[2] = u_wseconds();
/* printf("My rank %d/%d at proc-mesh loc (%d, %d) generating [%d, %d) x [%d, %d) + %d random edges\n", uz.myRank, uz.numProcs, uz.myR, uz.myC, uz._sr, uz._er, uz._sc, uz._ec, uz.numredge); */
/* General parameters */
#ifndef ZOLTANV31
if (uz.numredge) {
#if 0
Zoltan_Set_Param(zz, "GRAPH_SYMMETRIZE", "TRANSPOSE");
Zoltan_Set_Param(zz, "GRAPH_SYM_WEIGHT", "MAX");
#endif
Zoltan_Set_Param(zz, "GRAPH_BUILD_TYPE", "FAST");
} else
Zoltan_Set_Param(zz, "GRAPH_BUILD_TYPE", "FAST_NO_DUP");
#endif
Zoltan_Set_Param(zz, "DEBUG_LEVEL", "3");
Zoltan_Set_Param(zz, "NUM_GID_ENTRIES", "1");
Zoltan_Set_Param(zz, "NUM_LID_ENTRIES", "1");
Zoltan_Set_Param(zz, "OBJ_WEIGHT_DIM", "0");
/* coloring parameters */
Zoltan_Set_Param(zz, "SUPERSTEP_SIZE", "500"); /* let's make S=500 default */
for (i=7; i<argc; ++i) {
char param[256], *eq;
if (!uz.myRank)
printf("processing argv[%d]='%s'\n", i, argv[i]);
strncpy(param, argv[i], sizeof(param));
eq = strchr(param, '=');
if (!eq) {
fprintf(stderr, "invalid argument '%s', Zoltan Paramters should be in the format <ZoltanParam>=<Val>\n", param);
goto End;
}
*eq = 0;
Zoltan_Set_Param(zz, param, eq+1);
}
#if 0
/* Graph parameters */
Zoltan_Set_Param(zz, "CHECK_GRAPH", "2");
#endif
/* set call backs */
Zoltan_Set_Num_Obj_Fn(zz, get_number_of_objects, &uz);
Zoltan_Set_Obj_List_Fn(zz, get_object_list, &uz);
Zoltan_Set_Num_Edges_Multi_Fn(zz, get_num_edges_list, &uz);
Zoltan_Set_Edge_List_Multi_Fn(zz, get_edge_list, &uz);
#if 0
#ifndef ZOLTANV31
Zoltan_LB_Eval_Graph(zz, 0, &graph);
if (!uz.myRank) {
printf("EdgeCut Min=%8.0f Max=%8.0f Sum=%8.0f\n", graph.cuts[EVAL_GLOBAL_MIN], graph.cuts[EVAL_GLOBAL_MAX], graph.cuts[EVAL_GLOBAL_SUM]);
printf("#Vertices Min=%8.0f Max=%8.0f Sum=%8.0f imbal=%.2f\n", graph.nobj[EVAL_GLOBAL_MIN], graph.nobj[EVAL_GLOBAL_MAX], graph.nobj[EVAL_GLOBAL_SUM], graph.obj_imbalance);
}
#endif
#endif
/* now color */
ngids = get_number_of_objects(&uz, &rc);
gid_list = (ZOLTAN_ID_PTR) malloc(sizeof(ZOLTAN_ID_TYPE) * ngids);
#ifndef ZOLTANV31
next = 0;
for (i=uz._sr; i<uz._er; ++i) {
int j;
for (j=uz._sc; j<uz._ec; ++j) {
gid_list[next++] = i*uz.meshC + j;
}
}
#endif
color = (int *) malloc(sizeof(int) * ngids);
MPI_Barrier(MPI_COMM_WORLD);
times[3] = u_wseconds();
#ifdef ZOLTANV31
rc = Zoltan_Color(zz, /* input (all remaining fields are output) */
&numGidEntries, /* Number of integers used for a global ID */
&numLidEntries, /* Number of integers used for a local ID */
ngids, /* #objects to color in this proc */
gid_list, /* global ids of colored vertices */
NULL, /* we ignore local ids */
color); /* result color */
#else
rc = Zoltan_Color(zz, /* input (all remaining fields are output) */
1, /* Number of integers used for a global ID */
ngids, /* #objects to color in this proc */
gid_list, /* global ids of colored vertices */
color); /* result color */
#endif
MPI_Barrier(MPI_COMM_WORLD);
times[4] = u_wseconds();
MPI_Reduce(times, gtimes, 5, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
if (rc != ZOLTAN_OK)
fprintf(stderr, "Zoltan_Color failed with return code %d...\n", rc);
for (maxcol=i=0; i<ngids; ++i)
if (color[i] > maxcol)
maxcol = color[i];
MPI_Reduce(&maxcol, &ncolors, 1, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD);
if (uz.myRank==0) {
struct rusage usage;
printf("%s setup Proc-0: %8.2lf Max: %8.2lf\n", argv[0], times[1]-times[0], gtimes[1]-gtimes[0]);
printf("%s gen rand edges Proc-0: %8.2lf Max: %8.2lf\n", argv[0], times[2]-times[1], gtimes[2]-gtimes[1]);
printf("%s set gids Proc-0: %8.2lf Max: %8.2lf\n", argv[0], times[3]-times[2], gtimes[3]-gtimes[2]);
printf("%s Zoltan_Color call Proc-0: %8.2lf Max: %8.2lf\n", argv[0], times[4]-times[3], gtimes[4]-gtimes[3]);
printf("%s Coloring Time : %.2lf # Colors used : %d\n", argv[0], gtimes[4]-gtimes[0], ncolors);
getrusage(RUSAGE_SELF, &usage);
printf("%s maxrss=%ld minflt=%ld majflt=%ld nswap=%ld\n", argv[0], usage.ru_maxrss, usage.ru_minflt, usage.ru_majflt, usage.ru_nswap);
}
#ifdef _DEBUG
saveColor(argv[0], &uz, (int *) gid_list, color, ngids);
#endif
/******************************************************************
** Clean up
******************************************************************/
if (gid_list)
free(gid_list);
if (color)
free(color);
if (uz.redgeto)
free(uz.redgeto);
End:
Zoltan_Destroy(&zz);
MPI_Finalize();
return 0;
}

54
thirdParty/Zoltan/example/C/graph.txt vendored Normal file
View File

@ -0,0 +1,54 @@
##
## This simple structure is used by many of the nightly Zoltan tests.
## It can be interpreted as a mesh, a graph, a hypergraph, or simply
## as 25 objects to be partitioned.
##
## 21----22----23----24---25
## | | | | |
## 16----17----18----19---20
## | | | | |
## 11----12----13----14---15
## | | | | |
## 6-----7-----8-----9----10
## | | | | |
## 1-----2-----3-----4----5
##
## Regarded as a graph, there are 25 vertices with connectivity
## described by the arcs in the diagram.
##
## Number of vertices:
25
## Number of vertex neighbors:
80
## Here we list for each vertex, its global ID, its number of neighbors, and
## the global ID of each of its neighbors.
##
1 2 2 6
2 3 1 3 7
3 3 2 8 4
4 3 3 9 5
5 2 4 10
6 3 1 7 11
7 4 6 2 8 12
8 4 7 3 9 13
9 4 8 4 10 14
10 3 9 5 15
11 3 6 12 16
12 4 11 7 13 17
13 4 12 8 14 18
14 4 13 9 15 19
15 3 14 10 20
16 3 11 17 21
17 4 16 12 18 22
18 4 17 13 19 23
19 4 18 14 20 24
20 3 19 15 25
21 2 16 22
22 3 21 17 23
23 3 22 18 24
24 3 23 19 25
25 2 24 20

View File

@ -0,0 +1,86 @@
##
## This simple structure is used by many of the nightly Zoltan tests.
## It can be interpreted as a mesh, a graph, a hypergraph, or simply
## as 25 objects to be partitioned.
##
## 21----22----23----24---25
## | | | | |
## 16----17----18----19---20
## | | | | |
## 11----12----13----14---15
## | | | | |
## 6-----7-----8-----9----10
## | | | | |
## 1-----2-----3-----4----5
##
## Regarded as a hypergraph, we associate each of the 25 objects with a
## hyperedge. The hyperedge is composed of the object and its neighbors
## in the above structure. For example, hyperedge 1 contains vertices
## 1, 2 and 6. Hyperedge 13 contains vertices 13, 8, 12, 14 and 18.
##
## Number of vertices:
25
## Here we list the global ID of each vertex.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
## Number of hyperedges:
25
## Sum of the number of vertices in each hyperedge
105
## Here we list for each hyperedge, its global ID, the number of vertices it links,
## and the global ID of each vertex in the hyperedge.
1 3 1 2 6
2 4 1 2 3 7
3 4 2 3 4 8
4 4 3 4 5 9
5 3 4 5 10
6 4 1 6 7 11
7 5 2 6 7 8 12
8 5 3 7 8 9 13
9 5 4 8 9 10 14
10 4 5 9 10 15
11 4 6 11 12 16
12 5 7 11 12 13 17
13 5 8 12 13 14 18
14 5 9 13 14 15 19
15 4 10 14 15 20
16 4 11 16 17 21
17 5 12 16 17 18 22
18 5 13 17 18 19 23
19 5 14 18 19 20 24
20 4 15 19 20 25
21 3 16 21 22
22 4 17 21 22 23
23 4 18 22 23 24
24 4 19 23 24 25
25 3 20 24 25

49
thirdParty/Zoltan/example/C/mesh.txt vendored Normal file
View File

@ -0,0 +1,49 @@
##
## This simple structure is used by many of the nightly Zoltan tests.
## It can be interpreted as a mesh, a graph, a hypergraph, or simply
## as 25 objects to be partitioned.
##
## 21----22----23----24---25
## | | | | |
## 16----17----18----19---20
## | | | | |
## 11----12----13----14---15
## | | | | |
## 6-----7-----8-----9----10
## | | | | |
## 1-----2-----3-----4----5
##
## Regarded as a mesh, vertex 1 is at location (0,0)
## and vertex 25 is at location (4,4);
##
## Number of vertices:
25
## Here we list for each vertex, its global ID and location.
1 0 0
2 1 0
3 2 0
4 3 0
5 4 0
6 0 1
7 1 1
8 2 1
9 3 1
10 4 1
11 0 2
12 1 2
13 2 2
14 3 2
15 4 2
16 0 3
17 1 3
18 2 3
19 3 3
20 4 3
21 0 4
22 1 4
23 2 4
24 3 4
25 4 4

1026
thirdParty/Zoltan/example/C/migrateGRAPH.c vendored Normal file

File diff suppressed because it is too large Load Diff

48
thirdParty/Zoltan/example/C/objects.txt vendored Normal file
View File

@ -0,0 +1,48 @@
##
## This simple structure is used by many of the nightly Zoltan tests.
## It can be interpreted as a mesh, a graph, a hypergraph, or simply
## as 25 objects to be partitioned.
##
## 21----22----23----24---25
## | | | | |
## 16----17----18----19---20
## | | | | |
## 11----12----13----14---15
## | | | | |
## 6-----7-----8-----9----10
## | | | | |
## 1-----2-----3-----4----5
##
## Regarded as a collection of objects, we have objects 1 through 25.
##
## Number of objects:
25
## Global ID for each object
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

View File

@ -0,0 +1,795 @@
/*
* @HEADER
*
* ***********************************************************************
*
* Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
* Copyright 2012 Sandia Corporation
*
* Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
* the U.S. Government retains certain rights in this software.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Corporation nor the names of the
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Questions? Contact Karen Devine kddevin@sandia.gov
* Erik Boman egboman@sandia.gov
*
* ***********************************************************************
*
* @HEADER
*/
/**************************************************************
* Basic example of using Zoltan to partition a graph.
***************************************************************/
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "zoltan.h"
/* Name of file containing graph to be partitioned */
static char *global_fname="graph.txt";
/* Structure to hold graph data */
typedef struct{
int numMyVertices; /* total vertices in in my partition */
int numAllNbors; /* total number of neighbors of my vertices */
ZOLTAN_ID_TYPE *vertexGID; /* global ID of each of my vertices */
int *nborIndex; /* nborIndex[i] is location of start of neighbors for vertex i */
ZOLTAN_ID_TYPE *nborGID; /* nborGIDs[nborIndex[i]] is first neighbor of vertex i */
int *nborProc; /* process owning each nbor in nborGID */
} GRAPH_DATA;
/* Application defined query functions */
static int get_number_of_vertices(void *data, int *ierr);
static void get_vertex_list(void *data, int sizeGID, int sizeLID,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int wgt_dim, float *obj_wgts, int *ierr);
static void get_num_edges_list(void *data, int sizeGID, int sizeLID,
int num_obj,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int *numEdges, int *ierr);
static void get_edge_list(void *data, int sizeGID, int sizeLID,
int num_obj, ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int *num_edges,
ZOLTAN_ID_PTR nborGID, int *nborProc,
int wgt_dim, float *ewgts, int *ierr);
/* Functions to read graph in from file, distribute it, view it, handle errors */
static int get_next_line(FILE *fp, char *buf, int bufsize);
static int get_line_ints(char *buf, int bufsize, int *vals);
static void input_file_error(int numProcs, int tag, int startProc);
static void showGraphPartitions(int myProc, int numIDs, ZOLTAN_ID_TYPE *GIDs, int *parts, int nparts);
static void read_input_file(int myRank, int numProcs, char *fname, GRAPH_DATA *myData);
static unsigned int simple_hash(unsigned int *key, unsigned int n);
int main(int argc, char *argv[])
{
int i, rc;
float ver;
struct Zoltan_Struct *zz;
int changes, numGidEntries, numLidEntries, numImport, numExport;
int myRank, numProcs;
ZOLTAN_ID_PTR importGlobalGids, importLocalGids, exportGlobalGids, exportLocalGids;
int *importProcs, *importToPart, *exportProcs, *exportToPart;
int *parts;
FILE *fp;
GRAPH_DATA myGraph;
/******************************************************************
** Initialize MPI and Zoltan
******************************************************************/
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myRank);
MPI_Comm_size(MPI_COMM_WORLD, &numProcs);
rc = Zoltan_Initialize(argc, argv, &ver);
if (rc != ZOLTAN_OK){
printf("sorry...\n");
MPI_Finalize();
exit(0);
}
/******************************************************************
** Read graph from input file and distribute it
******************************************************************/
fp = fopen(global_fname, "r");
if (!fp){
if (myRank == 0) fprintf(stderr,"ERROR: Can not open %s\n",global_fname);
MPI_Finalize();
exit(1);
}
fclose(fp);
read_input_file(myRank, numProcs, global_fname, &myGraph);
/******************************************************************
** Create a Zoltan library structure for this instance of load
** balancing. Set the parameters and query functions that will
** govern the library's calculation. See the Zoltan User's
** Guide for the definition of these and many other parameters.
******************************************************************/
zz = Zoltan_Create(MPI_COMM_WORLD);
/* General parameters */
/*
Zoltan_Set_Param(zz, "DEBUG_LEVEL", "0");
Zoltan_Set_Param(zz, "LB_METHOD", "GRAPH");
Zoltan_Set_Param(zz, "NUM_GID_ENTRIES", "1");
Zoltan_Set_Param(zz, "NUM_LID_ENTRIES", "1");
Zoltan_Set_Param(zz, "OBJ_WEIGHT_DIM", "0");
Zoltan_Set_Param(zz, "RETURN_LISTS", "ALL");
*/
Zoltan_Set_Param(zz, "NUM_GID_ENTRIES", "1");
Zoltan_Set_Param(zz, "NUM_LID_ENTRIES", "1");
Zoltan_Set_Param(zz,"LB_METHOD","GRAPH");
#ifdef HAVE_PARMETIS
Zoltan_Set_Param(zz,"GRAPH_PACKAGE","PARMETIS");
Zoltan_Set_Param(zz,"PARMETIS_METHOD","PARTKWAY");
#else
#ifdef HAVE_SCOTCH
Zoltan_Set_Param(zz,"GRAPH_PACKAGE","SCOTCH");
#endif
#endif
Zoltan_Set_Param(zz,"EDGE_WEIGHT_DIM","1");
Zoltan_Set_Param(zz, "OBJ_WEIGHT_DIM", "0");
Zoltan_Set_Param(zz, "LB_APPROACH","PARTITION");
/* Graph parameters */
Zoltan_Set_Param(zz, "CHECK_GRAPH", "2");
Zoltan_Set_Param(zz, "PHG_EDGE_SIZE_THRESHOLD", ".35"); /* 0-remove all, 1-remove none */
/* Query functions - defined in simpleQueries.h */
Zoltan_Set_Num_Obj_Fn(zz, get_number_of_vertices, &myGraph);
Zoltan_Set_Obj_List_Fn(zz, get_vertex_list, &myGraph);
Zoltan_Set_Num_Edges_Multi_Fn(zz, get_num_edges_list, &myGraph);
Zoltan_Set_Edge_List_Multi_Fn(zz, get_edge_list, &myGraph);
/******************************************************************
** Zoltan can now partition the simple graph.
** In this simple example, we assume the number of partitions is
** equal to the number of processes. Process rank 0 will own
** partition 0, process rank 1 will own partition 1, and so on.
******************************************************************/
rc = Zoltan_LB_Partition(zz, /* input (all remaining fields are output) */
&changes, /* 1 if partitioning was changed, 0 otherwise */
&numGidEntries, /* Number of integers used for a global ID */
&numLidEntries, /* Number of integers used for a local ID */
&numImport, /* Number of vertices to be sent to me */
&importGlobalGids, /* Global IDs of vertices to be sent to me */
&importLocalGids, /* Local IDs of vertices to be sent to me */
&importProcs, /* Process rank for source of each incoming vertex */
&importToPart, /* New partition for each incoming vertex */
&numExport, /* Number of vertices I must send to other processes*/
&exportGlobalGids, /* Global IDs of the vertices I must send */
&exportLocalGids, /* Local IDs of the vertices I must send */
&exportProcs, /* Process to which I send each of the vertices */
&exportToPart); /* Partition to which each vertex will belong */
if (rc != ZOLTAN_OK){
printf("sorry...\n");
MPI_Finalize();
Zoltan_Destroy(&zz);
exit(0);
}
/******************************************************************
** Visualize the graph partitioning before and after calling Zoltan.
******************************************************************/
parts = (int *)malloc(sizeof(int) * myGraph.numMyVertices);
for (i=0; i < myGraph.numMyVertices; i++){
parts[i] = myRank;
}
if (myRank== 0){
printf("\nGraph partition before calling Zoltan\n");
}
showGraphPartitions(myRank, myGraph.numMyVertices, myGraph.vertexGID, parts, numProcs);
for (i=0; i < numExport; i++){
parts[exportLocalGids[i]] = exportToPart[i];
}
if (myRank == 0){
printf("Graph partition after calling Zoltan\n");
}
showGraphPartitions(myRank, myGraph.numMyVertices, myGraph.vertexGID, parts, numProcs);
free(parts);
/******************************************************************
** Free the arrays allocated by Zoltan_LB_Partition, and free
** the storage allocated for the Zoltan structure.
******************************************************************/
Zoltan_LB_Free_Part(&importGlobalGids, &importLocalGids,
&importProcs, &importToPart);
Zoltan_LB_Free_Part(&exportGlobalGids, &exportLocalGids,
&exportProcs, &exportToPart);
Zoltan_Destroy(&zz);
/**********************
** all done ***********
**********************/
MPI_Finalize();
if (myGraph.numMyVertices > 0){
free(myGraph.vertexGID);
free(myGraph.nborIndex);
if (myGraph.numAllNbors > 0){
free(myGraph.nborGID);
free(myGraph.nborProc);
}
}
return 0;
}
/* Application defined query functions */
static int get_number_of_vertices(void *data, int *ierr)
{
GRAPH_DATA *graph = (GRAPH_DATA *)data;
*ierr = ZOLTAN_OK;
return graph->numMyVertices;
}
static void get_vertex_list(void *data, int sizeGID, int sizeLID,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int wgt_dim, float *obj_wgts, int *ierr)
{
int i;
GRAPH_DATA *graph = (GRAPH_DATA *)data;
*ierr = ZOLTAN_OK;
/* In this example, return the IDs of our vertices, but no weights.
* Zoltan will assume equally weighted vertices.
*/
for (i=0; i<graph->numMyVertices; i++){
globalID[i] = graph->vertexGID[i];
localID[i] = i;
}
}
static void get_num_edges_list(void *data, int sizeGID, int sizeLID,
int num_obj,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int *numEdges, int *ierr)
{
int i, idx;
GRAPH_DATA *graph = (GRAPH_DATA *)data;
if ( (sizeGID != 1) || (sizeLID != 1) || (num_obj != graph->numMyVertices)){
*ierr = ZOLTAN_FATAL;
return;
}
for (i=0; i < num_obj ; i++){
idx = localID[i];
numEdges[i] = graph->nborIndex[idx+1] - graph->nborIndex[idx];
}
*ierr = ZOLTAN_OK;
return;
}
static void get_edge_list(void *data, int sizeGID, int sizeLID,
int num_obj, ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int *num_edges,
ZOLTAN_ID_PTR nborGID, int *nborProc,
int wgt_dim, float *ewgts, int *ierr)
{
int i, j, from, to;
int *nextProc;
ZOLTAN_ID_TYPE *nextNbor;
float *nextWgt;
GRAPH_DATA *graph = (GRAPH_DATA *)data;
*ierr = ZOLTAN_OK;
if ( (sizeGID != 1) || (sizeLID != 1) ||
(num_obj != graph->numMyVertices)) {
*ierr = ZOLTAN_FATAL;
return;
}
nextNbor = nborGID;
nextProc = nborProc;
nextWgt = ewgts;
for (i=0; i < num_obj; i++){
to = graph->nborIndex[localID[i]+1];
from = graph->nborIndex[localID[i]];
if ((to - from) != num_edges[i]){
*ierr = ZOLTAN_FATAL;
return;
}
for (j=from; j < to; j++){
*nextNbor++ = graph->nborGID[j];
*nextProc++ = graph->nborProc[j];
if (wgt_dim)
*nextWgt++ = (float)((graph->nborGID[j]<globalID[i]) ? graph->nborGID[j]
: globalID[i]);
}
}
return;
}
/* Function to find next line of information in input file */
static int get_next_line(FILE *fp, char *buf, int bufsize)
{
int i, cval, len;
char *c;
while (1){
c = fgets(buf, bufsize, fp);
if (c == NULL)
return 0; /* end of file */
len = strlen(c);
for (i=0, c=buf; i < len; i++, c++){
cval = (int)*c;
if (isspace(cval) == 0) break;
}
if (i == len) continue; /* blank line */
if (*c == '#') continue; /* comment */
if (c != buf){
strcpy(buf, c);
}
break;
}
return strlen(buf); /* number of characters */
}
/* Function to return the list of non-negative integers in a line */
static int get_line_ints(char *buf, int bufsize, int *vals)
{
char *c = buf;
int count=0;
while (1){
while (!(isdigit(*c))){
if ((c - buf) >= bufsize) break;
c++;
}
if ( (c-buf) >= bufsize) break;
vals[count++] = atoi(c);
while (isdigit(*c)){
if ((c - buf) >= bufsize) break;
c++;
}
if ( (c-buf) >= bufsize) break;
}
return count;
}
/* Proc 0 notifies others of error and exits */
static void input_file_error(int numProcs, int tag, int startProc)
{
int i, val[2];
val[0] = -1; /* error flag */
fprintf(stderr,"ERROR in input file.\n");
for (i=startProc; i < numProcs; i++){
/* these procs have posted a receive for "tag" expecting counts */
MPI_Send(val, 2, MPI_INT, i, tag, MPI_COMM_WORLD);
}
for (i=1; i < startProc; i++){
/* these procs are done and waiting for ok-to-go */
MPI_Send(val, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
}
MPI_Finalize();
exit(1);
}
/* Draw the partition assignments of the objects */
static void showGraphPartitions(int myProc, int numIDs, ZOLTAN_ID_TYPE *GIDs, int *parts, int nparts)
{
int partAssign[25], allPartAssign[25];
int i, j, part, cuts, prevPart=-1;
float imbal, localImbal, sum;
int *partCount=NULL;
partCount = (int *)calloc(sizeof(int), nparts);
memset(partAssign, 0, sizeof(int) * 25);
for (i=0; i < numIDs; i++){
partAssign[GIDs[i]-1] = parts[i];
}
MPI_Reduce(partAssign, allPartAssign, 25, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD);
if (myProc == 0){
cuts = 0;
for (i=20; i >= 0; i-=5){
for (j=0; j < 5; j++){
part = allPartAssign[i + j];
partCount[part]++;
if (j > 0){
if (part == prevPart){
printf("-----%d",part);
}
else{
printf("--x--%d",part);
cuts++;
prevPart = part;
}
}
else{
printf("%d",part);
prevPart = part;
}
}
printf("\n");
if (i > 0){
for (j=0; j < 5; j++){
if (allPartAssign[i+j] != allPartAssign[i+j-5]){
printf("x ");
cuts++;
}
else{
printf("| ");
}
}
printf("\n");
}
}
printf("\n");
for (sum=0, i=0; i < nparts; i++){
sum += partCount[i];
}
imbal = 0;
for (i=0; i < nparts; i++){
/* An imbalance measure. 1.0 is perfect balance, larger is worse */
localImbal = (nparts * partCount[i]) / sum;
if (localImbal > imbal) imbal = localImbal;
}
printf("Object imbalance (1.0 perfect, larger numbers are worse): %f\n",imbal);
printf("Total number of edge cuts: %d\n\n",cuts);
}
if (partCount) free(partCount);
}
/*
* Read the graph in the input file and distribute the vertices.
*/
void read_input_file(int myRank, int numProcs, char *fname, GRAPH_DATA *graph)
{
char buf[512];
int bufsize;
int numGlobalVertices, numGlobalNeighbors;
int num, nnbors, ack=0;
int vGID;
int i, j, procID;
int vals[128], send_count[2];
int *idx;
unsigned int id;
FILE *fp;
MPI_Status status;
int ack_tag = 5, count_tag = 10, id_tag = 15;
GRAPH_DATA *send_graph;
if (myRank == 0){
bufsize = 512;
fp = fopen(fname, "r");
/* Get the number of vertices */
num = get_next_line(fp, buf, bufsize);
if (num == 0) input_file_error(numProcs, count_tag, 1);
num = sscanf(buf, "%d", &numGlobalVertices);
if (num != 1) input_file_error(numProcs, count_tag, 1);
/* Get the number of vertex neighbors */
num = get_next_line(fp, buf, bufsize);
if (num == 0) input_file_error(numProcs, count_tag, 1);
num = sscanf(buf, "%d", &numGlobalNeighbors);
if (num != 1) input_file_error(numProcs, count_tag, 1);
/* Allocate arrays to read in entire graph */
graph->vertexGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * numGlobalVertices);
graph->nborIndex = (int *)malloc(sizeof(int) * (numGlobalVertices + 1));
graph->nborGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * numGlobalNeighbors);
graph->nborProc = (int *)malloc(sizeof(int) * numGlobalNeighbors);
graph->nborIndex[0] = 0;
for (i=0; i < numGlobalVertices; i++){
num = get_next_line(fp, buf, bufsize);
if (num == 0) input_file_error(numProcs, count_tag, 1);
num = get_line_ints(buf, bufsize, vals);
if (num < 2) input_file_error(numProcs, count_tag, 1);
vGID = vals[0];
nnbors = vals[1];
if (num < (nnbors + 2)) input_file_error(numProcs, count_tag, 1);
graph->vertexGID[i] = (ZOLTAN_ID_TYPE)vGID;
for (j=0; j < nnbors; j++){
graph->nborGID[graph->nborIndex[i] + j] = (ZOLTAN_ID_TYPE)vals[2 + j];
}
graph->nborIndex[i+1] = graph->nborIndex[i] + nnbors;
}
fclose(fp);
/* Assign each vertex to a process using a hash function */
for (i=0; i <numGlobalNeighbors; i++){
id = graph->nborGID[i];
graph->nborProc[i] = simple_hash(&id, numProcs);
}
/* Create a sub graph for each process */
send_graph = (GRAPH_DATA *)calloc(sizeof(GRAPH_DATA) , numProcs);
for (i=0; i < numGlobalVertices; i++){
id = graph->vertexGID[i];
procID = simple_hash(&id, numProcs);
send_graph[procID].numMyVertices++;
}
for (i=0; i < numProcs; i++){
num = send_graph[i].numMyVertices;
send_graph[i].vertexGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * num);
send_graph[i].nborIndex = (int *)calloc(sizeof(int) , (num + 1));
}
idx = (int *)calloc(sizeof(int), numProcs);
for (i=0; i < numGlobalVertices; i++){
id = graph->vertexGID[i];
nnbors = graph->nborIndex[i+1] - graph->nborIndex[i];
procID = simple_hash(&id, numProcs);
j = idx[procID];
send_graph[procID].vertexGID[j] = id;
send_graph[procID].nborIndex[j+1] = send_graph[procID].nborIndex[j] + nnbors;
idx[procID] = j+1;
}
for (i=0; i < numProcs; i++){
num = send_graph[i].nborIndex[send_graph[i].numMyVertices];
send_graph[i].nborGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * num);
send_graph[i].nborProc= (int *)malloc(sizeof(int) * num);
send_graph[i].numAllNbors = num;
}
memset(idx, 0, sizeof(int) * numProcs);
for (i=0; i < numGlobalVertices; i++){
id = graph->vertexGID[i];
nnbors = graph->nborIndex[i+1] - graph->nborIndex[i];
procID = simple_hash(&id, numProcs);
j = idx[procID];
if (nnbors > 0){
memcpy(send_graph[procID].nborGID + j, graph->nborGID + graph->nborIndex[i],
nnbors * sizeof(ZOLTAN_ID_TYPE));
memcpy(send_graph[procID].nborProc + j, graph->nborProc + graph->nborIndex[i],
nnbors * sizeof(int));
idx[procID] = j + nnbors;
}
}
free(idx);
/* Process zero sub-graph */
free(graph->vertexGID);
free(graph->nborIndex);
free(graph->nborGID);
free(graph->nborProc);
*graph = send_graph[0];
/* Send other processes their subgraph */
for (i=1; i < numProcs; i++){
send_count[0] = send_graph[i].numMyVertices;
send_count[1] = send_graph[i].numAllNbors;
MPI_Send(send_count, 2, MPI_INT, i, count_tag, MPI_COMM_WORLD);
MPI_Recv(&ack, 1, MPI_INT, i, ack_tag, MPI_COMM_WORLD, &status);
if (send_count[0] > 0){
MPI_Send(send_graph[i].vertexGID, send_count[0], ZOLTAN_ID_MPI_TYPE, i, id_tag, MPI_COMM_WORLD);
free(send_graph[i].vertexGID);
MPI_Send(send_graph[i].nborIndex, send_count[0] + 1, MPI_INT, i, id_tag + 1, MPI_COMM_WORLD);
free(send_graph[i].nborIndex);
if (send_count[1] > 0){
MPI_Send(send_graph[i].nborGID, send_count[1], ZOLTAN_ID_MPI_TYPE, i, id_tag + 2, MPI_COMM_WORLD);
free(send_graph[i].nborGID);
MPI_Send(send_graph[i].nborProc, send_count[1], MPI_INT, i, id_tag + 3, MPI_COMM_WORLD);
free(send_graph[i].nborProc);
}
}
}
free(send_graph);
/* signal all procs it is OK to go on */
ack = 0;
for (i=1; i < numProcs; i++){
MPI_Send(&ack, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
}
}
else{
MPI_Recv(send_count, 2, MPI_INT, 0, count_tag, MPI_COMM_WORLD, &status);
if (send_count[0] < 0){
MPI_Finalize();
exit(1);
}
ack = 0;
graph->numMyVertices = send_count[0];
graph->numAllNbors = send_count[1];
if (send_count[0] > 0){
graph->vertexGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * send_count[0]);
graph->nborIndex = (int *)malloc(sizeof(int) * (send_count[0] + 1));
if (send_count[1] > 0){
graph->nborGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * send_count[1]);
graph->nborProc = (int *)malloc(sizeof(int) * send_count[1]);
}
}
MPI_Send(&ack, 1, MPI_INT, 0, ack_tag, MPI_COMM_WORLD);
if (send_count[0] > 0){
MPI_Recv(graph->vertexGID,send_count[0], ZOLTAN_ID_MPI_TYPE, 0, id_tag, MPI_COMM_WORLD, &status);
MPI_Recv(graph->nborIndex,send_count[0] + 1, MPI_INT, 0, id_tag + 1, MPI_COMM_WORLD, &status);
if (send_count[1] > 0){
MPI_Recv(graph->nborGID,send_count[1], ZOLTAN_ID_MPI_TYPE, 0, id_tag + 2, MPI_COMM_WORLD, &status);
MPI_Recv(graph->nborProc,send_count[1], MPI_INT, 0, id_tag + 3, MPI_COMM_WORLD, &status);
}
}
/* ok to go on? */
MPI_Recv(&ack, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
if (ack < 0){
MPI_Finalize();
exit(1);
}
}
}
unsigned int simple_hash(unsigned int *key, unsigned int n)
{
unsigned int h, rest, *p, bytes, num_bytes;
char *byteptr;
num_bytes = (unsigned int) sizeof(int);
/* First hash the int-sized portions of the key */
h = 0;
for (p = (unsigned int *)key, bytes=num_bytes;
bytes >= (unsigned int) sizeof(int);
bytes-=sizeof(int), p++){
h = (h*2654435761U) ^ (*p);
}
/* Then take care of the remaining bytes, if any */
rest = 0;
for (byteptr = (char *)p; bytes > 0; bytes--, byteptr++){
rest = (rest<<8) | (*byteptr);
}
/* Merge the two parts */
if (rest)
h = (h*2654435761U) ^ rest;
/* Return h mod n */
return (h%n);
}

View File

@ -0,0 +1,448 @@
/*
* @HEADER
*
* ***********************************************************************
*
* Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
* Copyright 2012 Sandia Corporation
*
* Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
* the U.S. Government retains certain rights in this software.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Corporation nor the names of the
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Questions? Contact Karen Devine kddevin@sandia.gov
* Erik Boman egboman@sandia.gov
*
* ***********************************************************************
*
* @HEADER
*/
/* Basic example of using Zoltan to compute a quick partitioning
** of a set of objects.
***************************************************************/
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "zoltan.h"
/* Name of file containing objects to be partitioned */
static char *global_fname="objects.txt";
/* Structure to hold object data */
typedef struct{
int numGlobalObjects;
int numMyObjects;
ZOLTAN_ID_TYPE *myGlobalIDs;
} OBJECT_DATA;
static int get_number_of_objects(void *data, int *ierr);
static void get_object_list(void *data, int sizeGID, int sizeLID,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int wgt_dim, float *obj_wgts, int *ierr);
static int get_next_line(FILE *fp, char *buf, int bufsize);
static void input_file_error(int numProcs, int tag, int startProc);
static void showSimpleMeshPartitions(int myProc, int numIDs, ZOLTAN_ID_TYPE *GIDs, int *parts);
static void read_input_objects(int myRank, int numProcs, char *fname, OBJECT_DATA *myData);
int main(int argc, char *argv[])
{
int rc, i;
int myRank, numProcs;
float ver;
struct Zoltan_Struct *zz;
int changes, numGidEntries, numLidEntries, numImport, numExport;
ZOLTAN_ID_PTR importGlobalGids, importLocalGids;
ZOLTAN_ID_PTR exportGlobalGids, exportLocalGids;
int *importProcs, *importToPart, *exportProcs, *exportToPart;
int *parts = NULL;
FILE *fp;
OBJECT_DATA myData;
/******************************************************************
** Initialize MPI and Zoltan
******************************************************************/
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myRank);
MPI_Comm_size(MPI_COMM_WORLD, &numProcs);
rc = Zoltan_Initialize(argc, argv, &ver);
if (rc != ZOLTAN_OK){
printf("Error initializing Zoltan\n");
MPI_Finalize();
exit(0);
}
/******************************************************************
** Read objects from input file and distribute them unevenly
******************************************************************/
fp = fopen(global_fname, "r");
if (!fp){
if (myRank == 0) fprintf(stderr,"ERROR: Can not open %s\n",global_fname);
MPI_Finalize();
exit(1);
}
fclose(fp);
read_input_objects(myRank, numProcs, global_fname, &myData);
/******************************************************************
** Create a Zoltan library structure for this instance of load
** balancing. Set the parameters and query functions.
******************************************************************/
zz = Zoltan_Create(MPI_COMM_WORLD);
/* General parameters */
Zoltan_Set_Param(zz, "LB_METHOD", "BLOCK"); /* Zoltan method: "BLOCK" */
Zoltan_Set_Param(zz, "NUM_GID_ENTRIES", "1"); /* global ID is 1 integer */
Zoltan_Set_Param(zz, "NUM_LID_ENTRIES", "1"); /* local ID is 1 integer */
Zoltan_Set_Param(zz, "OBJ_WEIGHT_DIM", "0"); /* we omit object weights */
/* Query functions */
Zoltan_Set_Num_Obj_Fn(zz, get_number_of_objects, &myData);
Zoltan_Set_Obj_List_Fn(zz, get_object_list, &myData);
/******************************************************************
** Call Zoltan to partition the objects.
******************************************************************/
rc = Zoltan_LB_Partition(zz, /* input (all remaining fields are output) */
&changes, /* 1 if partitioning was changed, 0 otherwise */
&numGidEntries, /* Number of integers used for a global ID */
&numLidEntries, /* Number of integers used for a local ID */
&numImport, /* Number of objects to be sent to me */
&importGlobalGids, /* Global IDs of objects to be sent to me */
&importLocalGids, /* Local IDs of objects to be sent to me */
&importProcs, /* Process rank for source of each incoming object */
&importToPart, /* New partition for each incoming object */
&numExport, /* Number of objects I must send to other processes*/
&exportGlobalGids, /* Global IDs of the objects I must send */
&exportLocalGids, /* Local IDs of the objects I must send */
&exportProcs, /* Process to which I send each of the objects */
&exportToPart); /* Partition to which each object will belong */
if (rc != ZOLTAN_OK){
printf("Error in Zoltan library\n");
MPI_Finalize();
Zoltan_Destroy(&zz);
exit(0);
}
/******************************************************************
** Visualize the object partitioning before and after calling Zoltan.
**
** In this example, partition number equals process rank.
******************************************************************/
parts = (int *)malloc(sizeof(int) * myData.numMyObjects);
for (i=0; i < myData.numMyObjects; i++){
parts[i] = myRank;
}
if (myRank== 0){
printf("\nObject partition assignments before calling Zoltan\n");
}
showSimpleMeshPartitions(myRank, myData.numMyObjects, myData.myGlobalIDs, parts);
for (i=0; i < numExport; i++){
parts[exportLocalGids[i]] = exportToPart[i];
}
if (myRank == 0){
printf("Object partition assignments after calling Zoltan\n");
}
showSimpleMeshPartitions(myRank, myData.numMyObjects, myData.myGlobalIDs, parts);
/******************************************************************
** Free the arrays allocated by Zoltan_LB_Partition, and free
** the storage allocated for the Zoltan structure.
******************************************************************/
Zoltan_LB_Free_Part(&importGlobalGids, &importLocalGids,
&importProcs, &importToPart);
Zoltan_LB_Free_Part(&exportGlobalGids, &exportLocalGids,
&exportProcs, &exportToPart);
Zoltan_Destroy(&zz);
if (myData.numMyObjects) {
free(parts);
free(myData.myGlobalIDs);
}
MPI_Finalize();
return 0;
}
/* Application defined query functions */
static int get_number_of_objects(void *data, int *ierr)
{
OBJECT_DATA *objects = (OBJECT_DATA *)data;
*ierr = ZOLTAN_OK;
return objects->numMyObjects;
}
static void get_object_list(void *data, int sizeGID, int sizeLID,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int wgt_dim, float *obj_wgts, int *ierr)
{
int i;
OBJECT_DATA *objects = (OBJECT_DATA *)data;
*ierr = ZOLTAN_OK;
/* In this example, return the IDs of our objects, but no weights.
* Zoltan will assume equally weighted objects.
*/
for (i=0; i<objects->numMyObjects; i++){
globalID[i] = objects->myGlobalIDs[i];
localID[i] = i;
}
}
/* Function to find next line of information in input file */
static int get_next_line(FILE *fp, char *buf, int bufsize)
{
int i, cval, len;
char *c;
while (1){
c = fgets(buf, bufsize, fp);
if (c == NULL)
return 0; /* end of file */
len = strlen(c);
for (i=0, c=buf; i < len; i++, c++){
cval = (int)*c;
if (isspace(cval) == 0) break;
}
if (i == len) continue; /* blank line */
if (*c == '#') continue; /* comment */
if (c != buf){
strcpy(buf, c);
}
break;
}
return strlen(buf); /* number of characters */
}
/* Proc 0 notifies others of error and exits */
static void input_file_error(int numProcs, int tag, int startProc)
{
int i, val;
val = -1;
fprintf(stderr,"ERROR in input file.\n");
for (i=startProc; i < numProcs; i++){
/* these procs have posted receive for "tag" */
MPI_Send(&val, 1, MPI_INT, i, tag, MPI_COMM_WORLD);
}
for (i=1; i < startProc; i++){
/* these procs are done */
MPI_Send(&val, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
}
MPI_Finalize();
exit(1);
}
/* Draw the partition assignments of the objects */
void showSimpleMeshPartitions(int myProc, int numIDs, ZOLTAN_ID_TYPE *GIDs, int *parts)
{
int partAssign[25], allPartAssign[25];
int i, j, part;
memset(partAssign, 0, sizeof(int) * 25);
for (i=0; i < numIDs; i++){
partAssign[GIDs[i]-1] = parts[i];
}
MPI_Reduce(partAssign, allPartAssign, 25, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD);
if (myProc == 0){
for (i=20; i >= 0; i-=5){
for (j=0; j < 5; j++){
part = allPartAssign[i + j];
if (j < 4)
printf("%d-----",part);
else
printf("%d\n",part);
}
if (i > 0)
printf("| | | | |\n");
}
printf("\n");
}
}
/* Proc 0 reads the objects in the input file and divides them across processes */
void read_input_objects(int myRank, int numProcs, char *fname, OBJECT_DATA *myData)
{
char *buf;
int bufsize = 512;
int num, nobj, remainingObj, ack=0;
int i, j;
ZOLTAN_ID_TYPE *gids;
FILE *fp;
MPI_Status status;
int obj_ack_tag = 5, obj_count_tag = 10, obj_id_tag = 15;
if (myRank == 0){
buf = (char *)malloc(sizeof(char) * bufsize);
fp = fopen(fname, "r");
num = get_next_line(fp, buf, bufsize);
if (num == 0) input_file_error(numProcs, obj_count_tag, 1);
num = sscanf(buf, "%d", &myData->numGlobalObjects);
if (num != 1) input_file_error(numProcs, obj_count_tag, 1);
if (numProcs > 1){
nobj = myData->numGlobalObjects / 2;
remainingObj = myData->numGlobalObjects - nobj;
}
else{
nobj = myData->numGlobalObjects;
remainingObj = 0;
}
myData->myGlobalIDs = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * nobj);
myData->numMyObjects = nobj;
for (i=0; i < nobj; i++){
num = get_next_line(fp, buf, bufsize);
if (num == 0) input_file_error(numProcs, obj_count_tag, 1);
num = sscanf(buf, ZOLTAN_ID_SPEC , myData->myGlobalIDs + i);
if (num != 1) input_file_error(numProcs, obj_count_tag, 1);
}
gids = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * (nobj + 1));
for (i=1; i < numProcs; i++){
if (remainingObj > 1){
nobj = remainingObj / 2;
remainingObj -= nobj;
}
else if (remainingObj == 1){
nobj = 1;
remainingObj = 0;
}
else{
nobj = 0;
}
if ((i == numProcs - 1) && (remainingObj > 0))
nobj += remainingObj;
if (nobj > 0){
for (j=0; j < nobj; j++){
num = get_next_line(fp, buf, bufsize);
if (num == 0) input_file_error(numProcs, obj_count_tag, i);
num = sscanf(buf, ZOLTAN_ID_SPEC, gids + j);
if (num != 1) input_file_error(numProcs, obj_count_tag, i);
}
}
MPI_Send(&nobj, 1, MPI_INT, i, obj_count_tag, MPI_COMM_WORLD);
MPI_Recv(&ack, 1, MPI_INT, i, obj_ack_tag, MPI_COMM_WORLD, &status);
if (nobj > 0)
MPI_Send(gids, nobj, ZOLTAN_ID_MPI_TYPE, i, obj_id_tag, MPI_COMM_WORLD);
}
free(gids);
fclose(fp);
free(buf);
/* signal all procs it is OK to go on */
ack = 0;
for (i=1; i < numProcs; i++){
MPI_Send(&ack, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
}
}
else{
MPI_Recv(&myData->numMyObjects, 1, MPI_INT, 0, obj_count_tag, MPI_COMM_WORLD, &status);
ack = 0;
if (myData->numMyObjects > 0){
myData->myGlobalIDs = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * myData->numMyObjects);
MPI_Send(&ack, 1, MPI_INT, 0, obj_ack_tag, MPI_COMM_WORLD);
MPI_Recv(myData->myGlobalIDs, myData->numMyObjects, ZOLTAN_ID_MPI_TYPE, 0,
obj_id_tag, MPI_COMM_WORLD, &status);
}
else if (myData->numMyObjects == 0){
MPI_Send(&ack, 1, MPI_INT, 0, obj_ack_tag, MPI_COMM_WORLD);
}
else{
MPI_Finalize();
exit(1);
}
MPI_Recv(&ack, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
if (ack < 0){
MPI_Finalize();
exit(1);
}
}
}

View File

@ -0,0 +1,782 @@
/*
* @HEADER
*
* ***********************************************************************
*
* Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
* Copyright 2012 Sandia Corporation
*
* Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
* the U.S. Government retains certain rights in this software.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Corporation nor the names of the
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Questions? Contact Karen Devine kddevin@sandia.gov
* Erik Boman egboman@sandia.gov
*
* ***********************************************************************
*
* @HEADER
*/
/**************************************************************
* Basic example of using Zoltan to partition a graph.
***************************************************************/
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "zoltan.h"
/* Name of file containing graph to be partitioned */
static char *global_fname="graph.txt";
/* Structure to hold graph data
ZOLTAN_ID_TYPE is defined when Zoltan is compiled. It's size can
be obtained at runtime by a library call. (See zoltan_types.h).
*/
typedef struct{
int numMyVertices; /* total vertices in in my partition */
int numAllNbors; /* total number of neighbors of my vertices */
ZOLTAN_ID_TYPE *vertexGID; /* global ID of each of my vertices */
int *nborIndex; /* nborIndex[i] is location of start of neighbors for vertex i */
ZOLTAN_ID_TYPE *nborGID; /* nborGIDs[nborIndex[i]] is first neighbor of vertex i */
int *nborProc; /* process owning each nbor in nborGID */
} GRAPH_DATA;
/* Application defined query functions */
static int get_number_of_vertices(void *data, int *ierr);
static void get_vertex_list(void *data, int sizeGID, int sizeLID,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int wgt_dim, float *obj_wgts, int *ierr);
static void get_num_edges_list(void *data, int sizeGID, int sizeLID,
int num_obj,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int *numEdges, int *ierr);
static void get_edge_list(void *data, int sizeGID, int sizeLID,
int num_obj, ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int *num_edges,
ZOLTAN_ID_PTR nborGID, int *nborProc,
int wgt_dim, float *ewgts, int *ierr);
/* Functions to read graph in from file, distribute it, view it, handle errors */
static int get_next_line(FILE *fp, char *buf, int bufsize);
static int get_line_ints(char *buf, int bufsize, int *vals);
static void input_file_error(int numProcs, int tag, int startProc);
static void showGraphPartitions(int myProc, int numIDs, ZOLTAN_ID_TYPE *GIDs, int *parts, int nparts);
static void read_input_file(int myRank, int numProcs, char *fname, GRAPH_DATA *myData);
static unsigned int simple_hash(unsigned int *key, unsigned int n);
int main(int argc, char *argv[])
{
int i, rc;
float ver;
struct Zoltan_Struct *zz;
int changes, numGidEntries, numLidEntries, numImport, numExport;
int myRank, numProcs;
ZOLTAN_ID_PTR importGlobalGids, importLocalGids, exportGlobalGids, exportLocalGids;
int *importProcs, *importToPart, *exportProcs, *exportToPart;
int *parts = NULL;
FILE *fp;
GRAPH_DATA myGraph;
/******************************************************************
** Initialize MPI and Zoltan
******************************************************************/
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myRank);
MPI_Comm_size(MPI_COMM_WORLD, &numProcs);
rc = Zoltan_Initialize(argc, argv, &ver);
if (rc != ZOLTAN_OK){
printf("sorry...\n");
MPI_Finalize();
exit(0);
}
/******************************************************************
** Read graph from input file and distribute it
******************************************************************/
fp = fopen(global_fname, "r");
if (!fp){
if (myRank == 0) fprintf(stderr,"ERROR: Can not open %s\n",global_fname);
MPI_Finalize();
exit(1);
}
fclose(fp);
read_input_file(myRank, numProcs, global_fname, &myGraph);
/******************************************************************
** Create a Zoltan library structure for this instance of load
** balancing. Set the parameters and query functions that will
** govern the library's calculation. See the Zoltan User's
** Guide for the definition of these and many other parameters.
******************************************************************/
zz = Zoltan_Create(MPI_COMM_WORLD);
/* General parameters */
Zoltan_Set_Param(zz, "DEBUG_LEVEL", "0");
Zoltan_Set_Param(zz, "LB_METHOD", "GRAPH");
Zoltan_Set_Param(zz, "LB_APPROACH", "PARTITION");
Zoltan_Set_Param(zz, "NUM_GID_ENTRIES", "1");
Zoltan_Set_Param(zz, "NUM_LID_ENTRIES", "1");
Zoltan_Set_Param(zz, "RETURN_LISTS", "ALL");
/* Graph parameters */
Zoltan_Set_Param(zz, "CHECK_GRAPH", "2");
Zoltan_Set_Param(zz, "PHG_EDGE_SIZE_THRESHOLD", ".35"); /* 0-remove all, 1-remove none */
/* Query functions - defined in simpleQueries.h */
Zoltan_Set_Num_Obj_Fn(zz, get_number_of_vertices, &myGraph);
Zoltan_Set_Obj_List_Fn(zz, get_vertex_list, &myGraph);
Zoltan_Set_Num_Edges_Multi_Fn(zz, get_num_edges_list, &myGraph);
Zoltan_Set_Edge_List_Multi_Fn(zz, get_edge_list, &myGraph);
/******************************************************************
** Zoltan can now partition the simple graph.
** In this simple example, we assume the number of partitions is
** equal to the number of processes. Process rank 0 will own
** partition 0, process rank 1 will own partition 1, and so on.
******************************************************************/
rc = Zoltan_LB_Partition(zz, /* input (all remaining fields are output) */
&changes, /* 1 if partitioning was changed, 0 otherwise */
&numGidEntries, /* Number of integers used for a global ID */
&numLidEntries, /* Number of integers used for a local ID */
&numImport, /* Number of vertices to be sent to me */
&importGlobalGids, /* Global IDs of vertices to be sent to me */
&importLocalGids, /* Local IDs of vertices to be sent to me */
&importProcs, /* Process rank for source of each incoming vertex */
&importToPart, /* New partition for each incoming vertex */
&numExport, /* Number of vertices I must send to other processes*/
&exportGlobalGids, /* Global IDs of the vertices I must send */
&exportLocalGids, /* Local IDs of the vertices I must send */
&exportProcs, /* Process to which I send each of the vertices */
&exportToPart); /* Partition to which each vertex will belong */
if (rc != ZOLTAN_OK){
printf("sorry...\n");
MPI_Finalize();
Zoltan_Destroy(&zz);
exit(0);
}
/******************************************************************
** Visualize the graph partitioning before and after calling Zoltan.
******************************************************************/
parts = (int *)malloc(sizeof(int) * myGraph.numMyVertices);
for (i=0; i < myGraph.numMyVertices; i++){
parts[i] = myRank;
}
if (myRank== 0){
printf("\nGraph partition before calling Zoltan\n");
}
showGraphPartitions(myRank, myGraph.numMyVertices, myGraph.vertexGID, parts, numProcs);
for (i=0; i < numExport; i++){
parts[exportLocalGids[i]] = exportToPart[i];
}
if (myRank == 0){
printf("Graph partition after calling Zoltan\n");
}
showGraphPartitions(myRank, myGraph.numMyVertices, myGraph.vertexGID, parts, numProcs);
if (parts) free(parts);
/******************************************************************
** Free the arrays allocated by Zoltan_LB_Partition, and free
** the storage allocated for the Zoltan structure.
******************************************************************/
Zoltan_LB_Free_Part(&importGlobalGids, &importLocalGids,
&importProcs, &importToPart);
Zoltan_LB_Free_Part(&exportGlobalGids, &exportLocalGids,
&exportProcs, &exportToPart);
Zoltan_Destroy(&zz);
/**********************
** all done ***********
**********************/
MPI_Finalize();
if (myGraph.numMyVertices > 0){
free(myGraph.vertexGID);
free(myGraph.nborIndex);
if (myGraph.numAllNbors > 0){
free(myGraph.nborGID);
free(myGraph.nborProc);
}
}
return 0;
}
/* Application defined query functions */
static int get_number_of_vertices(void *data, int *ierr)
{
GRAPH_DATA *graph = (GRAPH_DATA *)data;
*ierr = ZOLTAN_OK;
return graph->numMyVertices;
}
static void get_vertex_list(void *data, int sizeGID, int sizeLID,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int wgt_dim, float *obj_wgts, int *ierr)
{
int i;
GRAPH_DATA *graph = (GRAPH_DATA *)data;
*ierr = ZOLTAN_OK;
/* In this example, return the IDs of our vertices, but no weights.
* Zoltan will assume equally weighted vertices.
*/
for (i=0; i<graph->numMyVertices; i++){
globalID[i] = graph->vertexGID[i];
localID[i] = i;
}
}
static void get_num_edges_list(void *data, int sizeGID, int sizeLID,
int num_obj,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int *numEdges, int *ierr)
{
int i, idx;
GRAPH_DATA *graph = (GRAPH_DATA *)data;
if ( (sizeGID != 1) || (sizeLID != 1) || (num_obj != graph->numMyVertices)){
*ierr = ZOLTAN_FATAL;
return;
}
for (i=0; i < num_obj ; i++){
idx = localID[i];
numEdges[i] = graph->nborIndex[idx+1] - graph->nborIndex[idx];
}
*ierr = ZOLTAN_OK;
return;
}
static void get_edge_list(void *data, int sizeGID, int sizeLID,
int num_obj, ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int *num_edges,
ZOLTAN_ID_PTR nborGID, int *nborProc,
int wgt_dim, float *ewgts, int *ierr)
{
int i, j, from, to;
int *nextProc;
ZOLTAN_ID_TYPE *nextNbor;
GRAPH_DATA *graph = (GRAPH_DATA *)data;
*ierr = ZOLTAN_OK;
if ( (sizeGID != 1) || (sizeLID != 1) ||
(num_obj != graph->numMyVertices)||
(wgt_dim != 0)){
*ierr = ZOLTAN_FATAL;
return;
}
nextNbor = nborGID;
nextProc = nborProc;
for (i=0; i < num_obj; i++){
/*
* In this example, we are not setting edge weights. Zoltan will
* set each edge to weight 1.0.
*/
to = graph->nborIndex[localID[i]+1];
from = graph->nborIndex[localID[i]];
if ((to - from) != num_edges[i]){
*ierr = ZOLTAN_FATAL;
return;
}
for (j=from; j < to; j++){
*nextNbor++ = graph->nborGID[j];
*nextProc++ = graph->nborProc[j];
}
}
return;
}
/* Function to find next line of information in input file */
static int get_next_line(FILE *fp, char *buf, int bufsize)
{
int i, cval, len;
char *c;
while (1){
c = fgets(buf, bufsize, fp);
if (c == NULL)
return 0; /* end of file */
len = strlen(c);
for (i=0, c=buf; i < len; i++, c++){
cval = (int)*c;
if (isspace(cval) == 0) break;
}
if (i == len) continue; /* blank line */
if (*c == '#') continue; /* comment */
if (c != buf){
strcpy(buf, c);
}
break;
}
return strlen(buf); /* number of characters */
}
/* Function to return the list of non-negative integers in a line */
static int get_line_ints(char *buf, int bufsize, int *vals)
{
char *c = buf;
int count=0;
while (1){
if ( (c-buf) >= bufsize) break;
while (!(isdigit(*c))){
if ((c - buf) >= bufsize) break;
c++;
}
if ( (c-buf) >= bufsize) break;
vals[count++] = atoi(c);
while (isdigit(*c)){
if ((c - buf) >= bufsize) break;
c++;
}
if ( (c-buf) >= bufsize) break;
}
return count;
}
/* Proc 0 notifies others of error and exits */
static void input_file_error(int numProcs, int tag, int startProc)
{
int i, val[2];
val[0] = -1; /* error flag */
fprintf(stderr,"ERROR in input file.\n");
for (i=startProc; i < numProcs; i++){
/* these procs have posted a receive for "tag" expecting counts */
MPI_Send(val, 2, MPI_INT, i, tag, MPI_COMM_WORLD);
}
for (i=1; i < startProc; i++){
/* these procs are done and waiting for ok-to-go */
MPI_Send(val, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
}
MPI_Finalize();
exit(1);
}
/* Draw the partition assignments of the objects */
static void showGraphPartitions(int myProc, int numIDs, ZOLTAN_ID_TYPE *GIDs, int *parts, int nparts)
{
int partAssign[25], allPartAssign[25];
int i, j, part, cuts, prevPart=-1;
float imbal, localImbal, sum;
int *partCount;
memset(partAssign, 0, sizeof(int) * 25);
for (i=0; i < numIDs; i++){
partAssign[GIDs[i]-1] = parts[i];
}
MPI_Reduce(partAssign, allPartAssign, 25, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD);
if (myProc == 0){
partCount = (int *)calloc(sizeof(int), nparts);
cuts = 0;
for (i=20; i >= 0; i-=5){
for (j=0; j < 5; j++){
part = allPartAssign[i + j];
partCount[part]++;
if (j > 0){
if (part == prevPart){
printf("-----%d",part);
}
else{
printf("--x--%d",part);
cuts++;
prevPart = part;
}
}
else{
printf("%d",part);
prevPart = part;
}
}
printf("\n");
if (i > 0){
for (j=0; j < 5; j++){
if (allPartAssign[i+j] != allPartAssign[i+j-5]){
printf("x ");
cuts++;
}
else{
printf("| ");
}
}
printf("\n");
}
}
printf("\n");
for (sum=0, i=0; i < nparts; i++){
sum += partCount[i];
}
imbal = 0;
for (i=0; i < nparts; i++){
/* An imbalance measure. 1.0 is perfect balance, larger is worse */
localImbal = (nparts * partCount[i]) / sum;
if (localImbal > imbal) imbal = localImbal;
}
printf("Object imbalance (1.0 perfect, larger numbers are worse): %f\n",imbal);
printf("Total number of edge cuts: %d\n\n",cuts);
if (nparts) free(partCount);
}
}
/*
* Read the graph in the input file and distribute the vertices.
*/
void read_input_file(int myRank, int numProcs, char *fname, GRAPH_DATA *graph)
{
char buf[512];
int bufsize;
int numGlobalVertices, numGlobalNeighbors;
int num, nnbors, ack=0;
int vGID;
int i, j, procID;
int vals[128], send_count[2];
int *idx;
unsigned int id;
FILE *fp;
MPI_Status status;
int ack_tag = 5, count_tag = 10, id_tag = 15;
GRAPH_DATA *send_graph;
if (myRank == 0){
bufsize = 512;
fp = fopen(fname, "r");
/* Get the number of vertices */
num = get_next_line(fp, buf, bufsize);
if (num == 0) input_file_error(numProcs, count_tag, 1);
num = sscanf(buf, "%d", &numGlobalVertices);
if (num != 1) input_file_error(numProcs, count_tag, 1);
/* Get the number of vertex neighbors */
num = get_next_line(fp, buf, bufsize);
if (num == 0) input_file_error(numProcs, count_tag, 1);
num = sscanf(buf, "%d", &numGlobalNeighbors);
if (num != 1) input_file_error(numProcs, count_tag, 1);
/* Allocate arrays to read in entire graph */
graph->vertexGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * numGlobalVertices);
graph->nborIndex = (int *)malloc(sizeof(int) * (numGlobalVertices + 1));
graph->nborGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * numGlobalNeighbors);
graph->nborProc = (int *)malloc(sizeof(int) * numGlobalNeighbors);
graph->nborIndex[0] = 0;
for (i=0; i < numGlobalVertices; i++){
num = get_next_line(fp, buf, bufsize);
if (num == 0) input_file_error(numProcs, count_tag, 1);
num = get_line_ints(buf, strlen(buf), vals);
if (num < 2) input_file_error(numProcs, count_tag, 1);
vGID = vals[0];
nnbors = vals[1];
if (num < (nnbors + 2)) input_file_error(numProcs, count_tag, 1);
graph->vertexGID[i] = (ZOLTAN_ID_TYPE)vGID;
for (j=0; j < nnbors; j++){
graph->nborGID[graph->nborIndex[i] + j] = (ZOLTAN_ID_TYPE)vals[2 + j];
}
graph->nborIndex[i+1] = graph->nborIndex[i] + nnbors;
}
fclose(fp);
/* Assign each vertex to a process using a hash function */
for (i=0; i <numGlobalNeighbors; i++){
id = (unsigned int)graph->nborGID[i];
graph->nborProc[i] = simple_hash(&id, numProcs);
}
/* Create a sub graph for each process */
send_graph = (GRAPH_DATA *)calloc(sizeof(GRAPH_DATA) , numProcs);
for (i=0; i < numGlobalVertices; i++){
id = (unsigned int)graph->vertexGID[i];
procID = simple_hash(&id, numProcs);
send_graph[procID].numMyVertices++;
}
for (i=0; i < numProcs; i++){
num = send_graph[i].numMyVertices;
send_graph[i].vertexGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * num);
send_graph[i].nborIndex = (int *)calloc(sizeof(int) , (num + 1));
}
idx = (int *)calloc(sizeof(int), numProcs);
for (i=0; i < numGlobalVertices; i++){
id = (unsigned int)graph->vertexGID[i];
nnbors = graph->nborIndex[i+1] - graph->nborIndex[i];
procID = simple_hash(&id, numProcs);
j = idx[procID];
send_graph[procID].vertexGID[j] = (ZOLTAN_ID_TYPE)id;
send_graph[procID].nborIndex[j+1] = send_graph[procID].nborIndex[j] + nnbors;
idx[procID] = j+1;
}
for (i=0; i < numProcs; i++){
num = send_graph[i].nborIndex[send_graph[i].numMyVertices];
send_graph[i].nborGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * num);
send_graph[i].nborProc= (int *)malloc(sizeof(int) * num);
send_graph[i].numAllNbors = num;
}
memset(idx, 0, sizeof(int) * numProcs);
for (i=0; i < numGlobalVertices; i++){
id = (unsigned int)graph->vertexGID[i];
nnbors = graph->nborIndex[i+1] - graph->nborIndex[i];
procID = simple_hash(&id, numProcs);
j = idx[procID];
if (nnbors > 0){
memcpy(send_graph[procID].nborGID + j, graph->nborGID + graph->nborIndex[i],
nnbors * sizeof(ZOLTAN_ID_TYPE));
memcpy(send_graph[procID].nborProc + j, graph->nborProc + graph->nborIndex[i],
nnbors * sizeof(int));
idx[procID] = j + nnbors;
}
}
free(idx);
/* Process zero sub-graph */
free(graph->vertexGID);
free(graph->nborIndex);
free(graph->nborGID);
free(graph->nborProc);
*graph = send_graph[0];
/* Send other processes their subgraph */
for (i=1; i < numProcs; i++){
send_count[0] = send_graph[i].numMyVertices;
send_count[1] = send_graph[i].numAllNbors;
MPI_Send(send_count, 2, MPI_INT, i, count_tag, MPI_COMM_WORLD);
MPI_Recv(&ack, 1, MPI_INT, i, ack_tag, MPI_COMM_WORLD, &status);
if (send_count[0] > 0){
MPI_Send(send_graph[i].vertexGID, send_count[0], ZOLTAN_ID_MPI_TYPE, i, id_tag, MPI_COMM_WORLD);
free(send_graph[i].vertexGID);
MPI_Send(send_graph[i].nborIndex, send_count[0] + 1, MPI_INT, i, id_tag + 1, MPI_COMM_WORLD);
free(send_graph[i].nborIndex);
if (send_count[1] > 0){
MPI_Send(send_graph[i].nborGID, send_count[1], ZOLTAN_ID_MPI_TYPE, i, id_tag + 2, MPI_COMM_WORLD);
free(send_graph[i].nborGID);
MPI_Send(send_graph[i].nborProc, send_count[1], MPI_INT, i, id_tag + 3, MPI_COMM_WORLD);
free(send_graph[i].nborProc);
}
}
}
free(send_graph);
/* signal all procs it is OK to go on */
ack = 0;
for (i=1; i < numProcs; i++){
MPI_Send(&ack, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
}
}
else{
MPI_Recv(send_count, 2, MPI_INT, 0, count_tag, MPI_COMM_WORLD, &status);
if (send_count[0] < 0){
MPI_Finalize();
exit(1);
}
ack = 0;
graph->numMyVertices = send_count[0];
graph->numAllNbors = send_count[1];
if (send_count[0] > 0){
graph->vertexGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * send_count[0]);
graph->nborIndex = (int *)malloc(sizeof(int) * (send_count[0] + 1));
if (send_count[1] > 0){
graph->nborGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * send_count[1]);
graph->nborProc = (int *)malloc(sizeof(int) * send_count[1]);
}
}
MPI_Send(&ack, 1, MPI_INT, 0, ack_tag, MPI_COMM_WORLD);
if (send_count[0] > 0){
MPI_Recv(graph->vertexGID,send_count[0],ZOLTAN_ID_MPI_TYPE, 0, id_tag, MPI_COMM_WORLD, &status);
MPI_Recv(graph->nborIndex,send_count[0] + 1, MPI_INT, 0, id_tag + 1, MPI_COMM_WORLD, &status);
if (send_count[1] > 0){
MPI_Recv(graph->nborGID,send_count[1], ZOLTAN_ID_MPI_TYPE, 0, id_tag + 2, MPI_COMM_WORLD, &status);
MPI_Recv(graph->nborProc,send_count[1], MPI_INT, 0, id_tag + 3, MPI_COMM_WORLD, &status);
}
}
/* ok to go on? */
MPI_Recv(&ack, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
if (ack < 0){
MPI_Finalize();
exit(1);
}
}
}
unsigned int simple_hash(unsigned int *key, unsigned int n)
{
unsigned int h, rest, *p, bytes, num_bytes;
char *byteptr;
num_bytes = (unsigned int) sizeof(int);
/* First hash the int-sized portions of the key */
h = 0;
for (p = (unsigned int *)key, bytes=num_bytes;
bytes >= (unsigned int) sizeof(int);
bytes-=sizeof(int), p++){
h = (h*2654435761U) ^ (*p);
}
/* Then take care of the remaining bytes, if any */
rest = 0;
for (byteptr = (char *)p; bytes > 0; bytes--, byteptr++){
rest = (rest<<8) | (*byteptr);
}
/* Merge the two parts */
if (rest)
h = (h*2654435761U) ^ rest;
/* Return h mod n */
return (h%n);
}

788
thirdParty/Zoltan/example/C/simpleHIER.c vendored Normal file
View File

@ -0,0 +1,788 @@
/*
* @HEADER
*
* ***********************************************************************
*
* Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
* Copyright 2012 Sandia Corporation
*
* Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
* the U.S. Government retains certain rights in this software.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Corporation nor the names of the
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Questions? Contact Karen Devine kddevin@sandia.gov
* Erik Boman egboman@sandia.gov
*
* ***********************************************************************
*
* @HEADER
*/
/**************************************************************
* Basic example of using Zoltan to partition a graph.
***************************************************************/
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "zoltan.h"
/* Name of file containing graph to be partitioned */
static char *global_fname="graph.txt";
/* Structure to hold graph data */
typedef struct{
int numMyVertices; /* total vertices in in my partition */
int numAllNbors; /* total number of neighbors of my vertices */
int *vertexGID; /* global ID of each of my vertices */
int *nborIndex; /* nborIndex[i] is location of start of neighbors for vertex i */
int *nborGID; /* nborGIDs[nborIndex[i]] is first neighbor of vertex i */
int *nborProc; /* process owning each nbor in nborGID */
} GRAPH_DATA;
/* Application defined query functions */
static int get_number_of_vertices(void *data, int *ierr);
static void get_vertex_list(void *data, int sizeGID, int sizeLID,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int wgt_dim, float *obj_wgts, int *ierr);
static void get_num_edges_list(void *data, int sizeGID, int sizeLID,
int num_obj,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int *numEdges, int *ierr);
static void get_edge_list(void *data, int sizeGID, int sizeLID,
int num_obj, ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int *num_edges,
ZOLTAN_ID_PTR nborGID, int *nborProc,
int wgt_dim, float *ewgts, int *ierr);
/* Functions to read graph in from file, distribute it, view it, handle errors */
static int get_next_line(FILE *fp, char *buf, int bufsize);
static int get_line_ints(char *buf, int bufsize, int *vals);
static void input_file_error(int numProcs, int tag, int startProc);
static void showGraphPartitions(int myProc, int numIDs, int *GIDs, int *parts, int nparts);
static void read_input_file(int myRank, int numProcs, char *fname, GRAPH_DATA *myData);
static unsigned int simple_hash(unsigned int *key, unsigned int n);
int main(int argc, char *argv[])
{
int i, rc;
float ver;
struct Zoltan_Struct *zz;
int changes, numGidEntries, numLidEntries, numImport, numExport;
int myRank, numProcs;
ZOLTAN_ID_PTR importGlobalGids, importLocalGids, exportGlobalGids, exportLocalGids;
int *importProcs, *importToPart, *exportProcs, *exportToPart;
int *parts;
FILE *fp;
GRAPH_DATA myGraph;
/******************************************************************
** Initialize MPI and Zoltan
******************************************************************/
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myRank);
MPI_Comm_size(MPI_COMM_WORLD, &numProcs);
if (numProcs < 4){
if (myRank == 0) fprintf(stderr,
"ERROR: This test requires at least 4 processes\n");
MPI_Finalize();
exit(1);
}
rc = Zoltan_Initialize(argc, argv, &ver);
if (rc != ZOLTAN_OK){
printf("sorry...\n");
MPI_Finalize();
exit(0);
}
/******************************************************************
** Read graph from input file and distribute it
******************************************************************/
fp = fopen(global_fname, "r");
if (!fp){
if (myRank == 0) fprintf(stderr,"ERROR: Can not open %s\n",global_fname);
MPI_Finalize();
exit(1);
}
fclose(fp);
read_input_file(myRank, numProcs, global_fname, &myGraph);
/******************************************************************
** Create a Zoltan library structure for this instance of load
** balancing. Set the parameters and query functions that will
** govern the library's calculation. See the Zoltan User's
** Guide for the definition of these and many other parameters.
******************************************************************/
zz = Zoltan_Create(MPI_COMM_WORLD);
/* General parameters */
Zoltan_Set_Param(zz, "DEBUG_LEVEL", "0");
Zoltan_Set_Param(zz, "HIER_DEBUG_LEVEL", "1");
Zoltan_Set_Param(zz, "LB_METHOD", "HIER");
Zoltan_Set_Param(zz, "HIER_ASSIST", "1");
Zoltan_Set_Param(zz, "TOPOLOGY", "2,2");
Zoltan_Set_Param(zz, "PHG_EDGE_SIZE_THRESHOLD", ".8");
Zoltan_Set_Param(zz, "NUM_GID_ENTRIES", "1");
Zoltan_Set_Param(zz, "NUM_LID_ENTRIES", "1");
Zoltan_Set_Param(zz, "RETURN_LISTS", "ALL");
/* Query functions - defined in simpleQueries.h */
Zoltan_Set_Num_Obj_Fn(zz, get_number_of_vertices, &myGraph);
Zoltan_Set_Obj_List_Fn(zz, get_vertex_list, &myGraph);
Zoltan_Set_Num_Edges_Multi_Fn(zz, get_num_edges_list, &myGraph);
Zoltan_Set_Edge_List_Multi_Fn(zz, get_edge_list, &myGraph);
/******************************************************************
** Zoltan can now partition the simple graph.
** In this simple example, we assume the number of partitions is
** equal to the number of processes. Process rank 0 will own
** partition 0, process rank 1 will own partition 1, and so on.
******************************************************************/
MPI_Barrier(MPI_COMM_WORLD);
if (myRank==0) fprintf(stderr,"GO Zoltan_LB_Partition\n");
MPI_Barrier(MPI_COMM_WORLD);
rc = Zoltan_LB_Partition(zz, /* input (all remaining fields are output) */
&changes, /* 1 if partitioning was changed, 0 otherwise */
&numGidEntries, /* Number of integers used for a global ID */
&numLidEntries, /* Number of integers used for a local ID */
&numImport, /* Number of vertices to be sent to me */
&importGlobalGids, /* Global IDs of vertices to be sent to me */
&importLocalGids, /* Local IDs of vertices to be sent to me */
&importProcs, /* Process rank for source of each incoming vertex */
&importToPart, /* New partition for each incoming vertex */
&numExport, /* Number of vertices I must send to other processes*/
&exportGlobalGids, /* Global IDs of the vertices I must send */
&exportLocalGids, /* Local IDs of the vertices I must send */
&exportProcs, /* Process to which I send each of the vertices */
&exportToPart); /* Partition to which each vertex will belong */
if (rc != ZOLTAN_OK){
printf("sorry...\n");
MPI_Finalize();
Zoltan_Destroy(&zz);
exit(0);
}
MPI_Barrier(MPI_COMM_WORLD);
if (myRank==0) fprintf(stderr,"DONE Zoltan_LB_Partition\n");
MPI_Barrier(MPI_COMM_WORLD);
/******************************************************************
** Visualize the graph partitioning before and after calling Zoltan.
******************************************************************/
parts = (int *)malloc(sizeof(int) * myGraph.numMyVertices);
for (i=0; i < myGraph.numMyVertices; i++){
parts[i] = myRank;
}
if (myRank== 0){
printf("\nGraph partition before calling Zoltan\n");
}
showGraphPartitions(myRank, myGraph.numMyVertices, myGraph.vertexGID, parts, numProcs);
for (i=0; i < numExport; i++){
parts[exportLocalGids[i]] = exportToPart[i];
}
if (myRank == 0){
printf("Graph partition after calling Zoltan\n");
}
showGraphPartitions(myRank, myGraph.numMyVertices, myGraph.vertexGID, parts, numProcs);
/******************************************************************
** Free the arrays allocated by Zoltan_LB_Partition, and free
** the storage allocated for the Zoltan structure.
******************************************************************/
Zoltan_LB_Free_Part(&importGlobalGids, &importLocalGids,
&importProcs, &importToPart);
Zoltan_LB_Free_Part(&exportGlobalGids, &exportLocalGids,
&exportProcs, &exportToPart);
Zoltan_Destroy(&zz);
/**********************
** all done ***********
**********************/
MPI_Finalize();
if (myGraph.numMyVertices > 0){
free(myGraph.vertexGID);
free(myGraph.nborIndex);
if (myGraph.numAllNbors > 0){
free(myGraph.nborGID);
free(myGraph.nborProc);
}
}
if (myGraph.numMyVertices) free(parts);
return 0;
}
/* Application defined query functions */
static int get_number_of_vertices(void *data, int *ierr)
{
GRAPH_DATA *graph = (GRAPH_DATA *)data;
*ierr = ZOLTAN_OK;
return graph->numMyVertices;
}
static void get_vertex_list(void *data, int sizeGID, int sizeLID,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int wgt_dim, float *obj_wgts, int *ierr)
{
int i;
GRAPH_DATA *graph = (GRAPH_DATA *)data;
*ierr = ZOLTAN_OK;
/* In this example, return the IDs of our vertices, but no weights.
* Zoltan will assume equally weighted vertices.
*/
for (i=0; i<graph->numMyVertices; i++){
globalID[i] = graph->vertexGID[i];
localID[i] = i;
}
}
static void get_num_edges_list(void *data, int sizeGID, int sizeLID,
int num_obj,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int *numEdges, int *ierr)
{
int i, idx;
GRAPH_DATA *graph = (GRAPH_DATA *)data;
if ( (sizeGID != 1) || (sizeLID != 1) || (num_obj != graph->numMyVertices)){
*ierr = ZOLTAN_FATAL;
return;
}
for (i=0; i < num_obj ; i++){
idx = localID[i];
numEdges[i] = graph->nborIndex[idx+1] - graph->nborIndex[idx];
}
*ierr = ZOLTAN_OK;
return;
}
static void get_edge_list(void *data, int sizeGID, int sizeLID,
int num_obj, ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int *num_edges,
ZOLTAN_ID_PTR nborGID, int *nborProc,
int wgt_dim, float *ewgts, int *ierr)
{
int i, j, from, to;
ZOLTAN_ID_PTR nextNbor;
int *nextProc;
GRAPH_DATA *graph = (GRAPH_DATA *)data;
*ierr = ZOLTAN_OK;
if ( (sizeGID != 1) || (sizeLID != 1) ||
(num_obj != graph->numMyVertices)||
(wgt_dim != 0)){
*ierr = ZOLTAN_FATAL;
return;
}
nextNbor = nborGID;
nextProc = nborProc;
for (i=0; i < num_obj; i++){
/*
* In this example, we are not setting edge weights. Zoltan will
* set each edge to weight 1.0.
*/
to = graph->nborIndex[localID[i]+1];
from = graph->nborIndex[localID[i]];
if ((to - from) != num_edges[i]){
*ierr = ZOLTAN_FATAL;
return;
}
for (j=from; j < to; j++){
*nextNbor++ = graph->nborGID[j];
*nextProc++ = graph->nborProc[j];
}
}
return;
}
/* Function to find next line of information in input file */
static int get_next_line(FILE *fp, char *buf, int bufsize)
{
int i, cval, len;
char *c;
while (1){
c = fgets(buf, bufsize, fp);
if (c == NULL)
return 0; /* end of file */
len = strlen(c);
for (i=0, c=buf; i < len; i++, c++){
cval = (int)*c;
if (isspace(cval) == 0) break;
}
if (i == len) continue; /* blank line */
if (*c == '#') continue; /* comment */
if (c != buf){
strcpy(buf, c);
}
break;
}
return strlen(buf); /* number of characters */
}
/* Function to return the list of non-negative integers in a line */
static int get_line_ints(char *buf, int bufsize, int *vals)
{
char *c = buf;
int count=0;
while (1){
while (!(isdigit(*c))){
if ((c - buf) >= bufsize) break;
c++;
}
if ( (c-buf) >= bufsize) break;
vals[count++] = atoi(c);
while (isdigit(*c)){
if ((c - buf) >= bufsize) break;
c++;
}
if ( (c-buf) >= bufsize) break;
}
return count;
}
/* Proc 0 notifies others of error and exits */
static void input_file_error(int numProcs, int tag, int startProc)
{
int i, val[2];
val[0] = -1; /* error flag */
fprintf(stderr,"ERROR in input file.\n");
for (i=startProc; i < numProcs; i++){
/* these procs have posted a receive for "tag" expecting counts */
MPI_Send(val, 2, MPI_INT, i, tag, MPI_COMM_WORLD);
}
for (i=1; i < startProc; i++){
/* these procs are done and waiting for ok-to-go */
MPI_Send(val, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
}
MPI_Finalize();
exit(1);
}
/* Draw the partition assignments of the objects */
static void showGraphPartitions(int myProc, int numIDs, int *GIDs, int *parts, int nparts)
{
int partAssign[25], allPartAssign[25];
int i, j, part, cuts, prevPart=-1;
float imbal, localImbal, sum;
memset(partAssign, 0, sizeof(int) * 25);
for (i=0; i < numIDs; i++){
partAssign[GIDs[i]-1] = parts[i];
}
MPI_Reduce(partAssign, allPartAssign, 25, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD);
if (myProc == 0){
int *partCount;
partCount = (int *)calloc(sizeof(int), nparts);
cuts = 0;
for (i=20; i >= 0; i-=5){
for (j=0; j < 5; j++){
part = allPartAssign[i + j];
partCount[part]++;
if (j > 0){
if (part == prevPart){
printf("-----%d",part);
}
else{
printf("--x--%d",part);
cuts++;
prevPart = part;
}
}
else{
printf("%d",part);
prevPart = part;
}
}
printf("\n");
if (i > 0){
for (j=0; j < 5; j++){
if (allPartAssign[i+j] != allPartAssign[i+j-5]){
printf("x ");
cuts++;
}
else{
printf("| ");
}
}
printf("\n");
}
}
printf("\n");
for (sum=0, i=0; i < nparts; i++){
sum += partCount[i];
}
imbal = 0;
for (i=0; i < nparts; i++){
/* An imbalance measure. 1.0 is perfect balance, larger is worse */
localImbal = (nparts * partCount[i]) / sum;
if (localImbal > imbal) imbal = localImbal;
}
printf("Object imbalance (1.0 perfect, larger numbers are worse): %f\n",imbal);
printf("Total number of edge cuts: %d\n\n",cuts);
if (nparts) free(partCount);
}
}
/*
* Read the graph in the input file and distribute the vertices.
*/
void read_input_file(int myRank, int numProcs, char *fname, GRAPH_DATA *graph)
{
char buf[512];
int bufsize;
int numGlobalVertices, numGlobalNeighbors;
int num, nnbors, ack=0;
int vGID;
int i, j, procID;
int vals[128], send_count[2];
int *idx;
unsigned int id;
FILE *fp;
MPI_Status status;
int ack_tag = 5, count_tag = 10, id_tag = 15;
GRAPH_DATA *send_graph;
if (myRank == 0){
bufsize = 512;
fp = fopen(fname, "r");
/* Get the number of vertices */
num = get_next_line(fp, buf, bufsize);
if (num == 0) input_file_error(numProcs, count_tag, 1);
num = sscanf(buf, "%d", &numGlobalVertices);
if (num != 1) input_file_error(numProcs, count_tag, 1);
/* Get the number of vertex neighbors */
num = get_next_line(fp, buf, bufsize);
if (num == 0) input_file_error(numProcs, count_tag, 1);
num = sscanf(buf, "%d", &numGlobalNeighbors);
if (num != 1) input_file_error(numProcs, count_tag, 1);
/* Allocate arrays to read in entire graph */
graph->vertexGID = (int *)malloc(sizeof(int) * numGlobalVertices);
graph->nborIndex = (int *)malloc(sizeof(int) * (numGlobalVertices + 1));
graph->nborGID = (int *)malloc(sizeof(int) * numGlobalNeighbors);
graph->nborProc = (int *)malloc(sizeof(int) * numGlobalNeighbors);
graph->nborIndex[0] = 0;
for (i=0; i < numGlobalVertices; i++){
num = get_next_line(fp, buf, bufsize);
if (num == 0) input_file_error(numProcs, count_tag, 1);
num = get_line_ints(buf, num, vals);
if (num < 2) input_file_error(numProcs, count_tag, 1);
vGID = vals[0];
nnbors = vals[1];
if (num < (nnbors + 2)) input_file_error(numProcs, count_tag, 1);
graph->vertexGID[i] = vGID;
for (j=0; j < nnbors; j++){
graph->nborGID[graph->nborIndex[i] + j] = vals[2 + j];
}
graph->nborIndex[i+1] = graph->nborIndex[i] + nnbors;
}
fclose(fp);
/* Assign each vertex to a process using a hash function */
for (i=0; i <numGlobalNeighbors; i++){
id = (unsigned int)graph->nborGID[i];
graph->nborProc[i] = simple_hash(&id, numProcs);
}
/* Create a sub graph for each process */
send_graph = (GRAPH_DATA *)calloc(sizeof(GRAPH_DATA) , numProcs);
for (i=0; i < numGlobalVertices; i++){
id = (unsigned int)graph->vertexGID[i];
procID = simple_hash(&id, numProcs);
send_graph[procID].numMyVertices++;
}
for (i=0; i < numProcs; i++){
num = send_graph[i].numMyVertices;
send_graph[i].vertexGID = (int *)malloc(sizeof(int) * num);
send_graph[i].nborIndex = (int *)calloc(sizeof(int) , (num + 1));
}
idx = (int *)calloc(sizeof(int), numProcs);
for (i=0; i < numGlobalVertices; i++){
id = (unsigned int)graph->vertexGID[i];
nnbors = graph->nborIndex[i+1] - graph->nborIndex[i];
procID = simple_hash(&id, numProcs);
j = idx[procID];
send_graph[procID].vertexGID[j] = id;
send_graph[procID].nborIndex[j+1] = send_graph[procID].nborIndex[j] + nnbors;
idx[procID] = j+1;
}
for (i=0; i < numProcs; i++){
num = send_graph[i].nborIndex[send_graph[i].numMyVertices];
send_graph[i].nborGID = (int *)malloc(sizeof(int) * num);
send_graph[i].nborProc= (int *)malloc(sizeof(int) * num);
send_graph[i].numAllNbors = num;
}
memset(idx, 0, sizeof(int) * numProcs);
for (i=0; i < numGlobalVertices; i++){
id = (unsigned int)graph->vertexGID[i];
nnbors = graph->nborIndex[i+1] - graph->nborIndex[i];
procID = simple_hash(&id, numProcs);
j = idx[procID];
if (nnbors > 0){
memcpy(send_graph[procID].nborGID + j, graph->nborGID + graph->nborIndex[i],
nnbors * sizeof(int));
memcpy(send_graph[procID].nborProc + j, graph->nborProc + graph->nborIndex[i],
nnbors * sizeof(int));
idx[procID] = j + nnbors;
}
}
free(idx);
/* Process zero sub-graph */
free(graph->vertexGID);
free(graph->nborIndex);
free(graph->nborGID);
free(graph->nborProc);
*graph = send_graph[0];
/* Send other processes their subgraph */
for (i=1; i < numProcs; i++){
send_count[0] = send_graph[i].numMyVertices;
send_count[1] = send_graph[i].numAllNbors;
MPI_Send(send_count, 2, MPI_INT, i, count_tag, MPI_COMM_WORLD);
MPI_Recv(&ack, 1, MPI_INT, i, ack_tag, MPI_COMM_WORLD, &status);
if (send_count[0] > 0){
MPI_Send(send_graph[i].vertexGID, send_count[0], MPI_INT, i, id_tag, MPI_COMM_WORLD);
free(send_graph[i].vertexGID);
MPI_Send(send_graph[i].nborIndex, send_count[0] + 1, MPI_INT, i, id_tag + 1, MPI_COMM_WORLD);
free(send_graph[i].nborIndex);
if (send_count[1] > 0){
MPI_Send(send_graph[i].nborGID, send_count[1], MPI_INT, i, id_tag + 2, MPI_COMM_WORLD);
free(send_graph[i].nborGID);
MPI_Send(send_graph[i].nborProc, send_count[1], MPI_INT, i, id_tag + 3, MPI_COMM_WORLD);
free(send_graph[i].nborProc);
}
}
}
free(send_graph);
/* signal all procs it is OK to go on */
ack = 0;
for (i=1; i < numProcs; i++){
MPI_Send(&ack, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
}
}
else{
MPI_Recv(send_count, 2, MPI_INT, 0, count_tag, MPI_COMM_WORLD, &status);
if (send_count[0] < 0){
MPI_Finalize();
exit(1);
}
ack = 0;
graph->numMyVertices = send_count[0];
graph->numAllNbors = send_count[1];
if (send_count[0] > 0){
graph->vertexGID = (int *)malloc(sizeof(int) * send_count[0]);
graph->nborIndex = (int *)malloc(sizeof(int) * (send_count[0] + 1));
if (send_count[1] > 0){
graph->nborGID = (int *)malloc(sizeof(int) * send_count[1]);
graph->nborProc = (int *)malloc(sizeof(int) * send_count[1]);
}
}
MPI_Send(&ack, 1, MPI_INT, 0, ack_tag, MPI_COMM_WORLD);
if (send_count[0] > 0){
MPI_Recv(graph->vertexGID,send_count[0], MPI_INT, 0, id_tag, MPI_COMM_WORLD, &status);
MPI_Recv(graph->nborIndex,send_count[0] + 1, MPI_INT, 0, id_tag + 1, MPI_COMM_WORLD, &status);
if (send_count[1] > 0){
MPI_Recv(graph->nborGID,send_count[1], MPI_INT, 0, id_tag + 2, MPI_COMM_WORLD, &status);
MPI_Recv(graph->nborProc,send_count[1], MPI_INT, 0, id_tag + 3, MPI_COMM_WORLD, &status);
}
}
/* ok to go on? */
MPI_Recv(&ack, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
if (ack < 0){
MPI_Finalize();
exit(1);
}
}
}
unsigned int simple_hash(unsigned int *key, unsigned int n)
{
unsigned int h, rest, *p, bytes, num_bytes;
char *byteptr;
num_bytes = (unsigned int) sizeof(int);
/* First hash the int-sized portions of the key */
h = 0;
for (p = (unsigned int *)key, bytes=num_bytes;
bytes >= (unsigned int) sizeof(int);
bytes-=sizeof(int), p++){
h = (h*2654435761U) ^ (*p);
}
/* Then take care of the remaining bytes, if any */
rest = 0;
for (byteptr = (char *)p; bytes > 0; bytes--, byteptr++){
rest = (rest<<8) | (*byteptr);
}
/* Merge the two parts */
if (rest)
h = (h*2654435761U) ^ rest;
/* Return h mod n */
return (h%n);
}

870
thirdParty/Zoltan/example/C/simplePHG.c vendored Normal file
View File

@ -0,0 +1,870 @@
/*
* @HEADER
*
* ***********************************************************************
*
* Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
* Copyright 2012 Sandia Corporation
*
* Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
* the U.S. Government retains certain rights in this software.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Corporation nor the names of the
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Questions? Contact Karen Devine kddevin@sandia.gov
* Erik Boman egboman@sandia.gov
*
* ***********************************************************************
*
* @HEADER
*/
/**************************************************************
* Basic example of using Zoltan to partition a hypergraph.
*
* We think a hypergraph as a matrix, where the hyperedges are
* the rows, and the vertices are the columns. If (i,j) is
* non-zero, this indicates that vertex j is in hyperedge i.
*
* In some Zoltan documentation, the non-zeroes in hypergraph
* matrices are called "pins".
*
***************************************************************/
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "zoltan.h"
/* Name of file containing hypergraph to be partitioned */
static char *global_fname="hypergraph.txt";
/* Structure to hold distributed hypergraph */
typedef struct{
/* Zoltan will partition vertices, while minimizing edge cuts */
int numGlobalVertices; /* number of vertices in global hypergraph */
int numMyVertices; /* number of vertices that I own initially */
ZOLTAN_ID_TYPE *vtxGID; /* global ID of these vertices */
int numGlobalEdges; /* number of edges in global hypergraph */
int numMyHEdges; /* number of my hyperedges */
int numAllNbors; /* number of vertices in my hyperedges */
ZOLTAN_ID_TYPE *edgeGID; /* global ID of each of my hyperedges */
int *nborIndex; /* index into nborGID array of edge's vertices */
ZOLTAN_ID_TYPE *nborGID; /* Vertices of edge edgeGID[i] begin at nborGID[nborIndex[i]] */
} HGRAPH_DATA;
/* 4 application defined query functions. If we were going to define
* a weight for each hyperedge, we would need to define 2 more query functions.
*/
static int get_number_of_vertices(void *data, int *ierr);
static void get_vertex_list(void *data, int sizeGID, int sizeLID,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int wgt_dim, float *obj_wgts, int *ierr);
static void get_hypergraph_size(void *data, int *num_lists, int *num_nonzeroes,
int *format, int *ierr);
static void get_hypergraph(void *data, int sizeGID, int num_edges, int num_nonzeroes,
int format, ZOLTAN_ID_PTR edgeGID, int *vtxPtr,
ZOLTAN_ID_PTR vtxGID, int *ierr);
/* Functions to read hypergraph in from file, distribute it, view it, handle errors */
static int get_next_line(FILE *fp, char *buf, int bufsize);
static int get_line_ints(char *buf, int bufsize, int *vals);
static void input_file_error(int numProcs, int tag, int startProc);
static void showHypergraph(int myProc, int numProc, int numIDs, ZOLTAN_ID_TYPE *GIDs, int *parts);
static void read_input_file(int myRank, int numProcs, char *fname, HGRAPH_DATA *data);
static HGRAPH_DATA global_hg;
int main(int argc, char *argv[])
{
int i, rc;
float ver;
struct Zoltan_Struct *zz;
int changes, numGidEntries, numLidEntries, numImport, numExport;
int myRank, numProcs;
ZOLTAN_ID_PTR importGlobalGids, importLocalGids, exportGlobalGids, exportLocalGids;
int *importProcs, *importToPart, *exportProcs, *exportToPart;
int *parts;
FILE *fp;
HGRAPH_DATA hg;
/******************************************************************
** Initialize MPI and Zoltan
******************************************************************/
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myRank);
MPI_Comm_size(MPI_COMM_WORLD, &numProcs);
rc = Zoltan_Initialize(argc, argv, &ver);
if (rc != ZOLTAN_OK){
printf("sorry...\n");
MPI_Finalize();
exit(0);
}
/******************************************************************
** Read hypergraph from input file and distribute it
******************************************************************/
fp = fopen(global_fname, "r");
if (!fp){
if (myRank == 0) fprintf(stderr,"ERROR: Can not open %s\n",global_fname);
MPI_Finalize();
exit(1);
}
fclose(fp);
read_input_file(myRank, numProcs, global_fname, &hg);
/******************************************************************
** Create a Zoltan library structure for this instance of load
** balancing. Set the parameters and query functions that will
** govern the library's calculation. See the Zoltan User's
** Guide for the definition of these and many other parameters.
******************************************************************/
zz = Zoltan_Create(MPI_COMM_WORLD);
/* General parameters */
Zoltan_Set_Param(zz, "DEBUG_LEVEL", "0");
Zoltan_Set_Param(zz, "LB_METHOD", "HYPERGRAPH"); /* partitioning method */
Zoltan_Set_Param(zz, "HYPERGRAPH_PACKAGE", "PHG"); /* version of method */
Zoltan_Set_Param(zz, "NUM_GID_ENTRIES", "1");/* global IDs are integers */
Zoltan_Set_Param(zz, "NUM_LID_ENTRIES", "1");/* local IDs are integers */
Zoltan_Set_Param(zz, "RETURN_LISTS", "ALL"); /* export AND import lists */
Zoltan_Set_Param(zz, "OBJ_WEIGHT_DIM", "0"); /* use Zoltan default vertex weights */
Zoltan_Set_Param(zz, "EDGE_WEIGHT_DIM", "0");/* use Zoltan default hyperedge weights */
/* PHG parameters - see the Zoltan User's Guide for many more
* (The "REPARTITION" approach asks Zoltan to create a partitioning that is
* better but is not too far from the current partitioning, rather than partitioning
* from scratch. It may be faster but of lower quality that LB_APPROACH=PARTITION.)
*/
Zoltan_Set_Param(zz, "LB_APPROACH", "REPARTITION");
/* Application defined query functions */
Zoltan_Set_Num_Obj_Fn(zz, get_number_of_vertices, &hg);
Zoltan_Set_Obj_List_Fn(zz, get_vertex_list, &hg);
Zoltan_Set_HG_Size_CS_Fn(zz, get_hypergraph_size, &hg);
Zoltan_Set_HG_CS_Fn(zz, get_hypergraph, &hg);
/******************************************************************
** Zoltan can now partition the vertices of hypergraph.
** In this simple example, we assume the number of partitions is
** equal to the number of processes. Process rank 0 will own
** partition 0, process rank 1 will own partition 1, and so on.
******************************************************************/
rc = Zoltan_LB_Partition(zz, /* input (all remaining fields are output) */
&changes, /* 1 if partitioning was changed, 0 otherwise */
&numGidEntries, /* Number of integers used for a global ID */
&numLidEntries, /* Number of integers used for a local ID */
&numImport, /* Number of vertices to be sent to me */
&importGlobalGids, /* Global IDs of vertices to be sent to me */
&importLocalGids, /* Local IDs of vertices to be sent to me */
&importProcs, /* Process rank for source of each incoming vertex */
&importToPart, /* New partition for each incoming vertex */
&numExport, /* Number of vertices I must send to other processes*/
&exportGlobalGids, /* Global IDs of the vertices I must send */
&exportLocalGids, /* Local IDs of the vertices I must send */
&exportProcs, /* Process to which I send each of the vertices */
&exportToPart); /* Partition to which each vertex will belong */
if (rc != ZOLTAN_OK){
printf("sorry...\n");
MPI_Finalize();
Zoltan_Destroy(&zz);
exit(0);
}
/******************************************************************
** Visualize the hypergraph partitioning before and after calling Zoltan.
******************************************************************/
parts = (int *)malloc(sizeof(int) * hg.numMyVertices);
for (i=0; i < hg.numMyVertices; i++){
parts[i] = myRank;
}
if (myRank== 0){
printf("\nHypergraph partition before calling Zoltan\n");
}
showHypergraph(myRank, numProcs, hg.numMyVertices, hg.vtxGID, parts);
for (i=0; i < numExport; i++){
parts[exportLocalGids[i]] = exportToPart[i];
}
if (myRank == 0){
printf("Graph partition after calling Zoltan\n");
}
showHypergraph(myRank, numProcs, hg.numMyVertices, hg.vtxGID, parts);
/******************************************************************
** Free the arrays allocated by Zoltan_LB_Partition, and free
** the storage allocated for the Zoltan structure.
******************************************************************/
Zoltan_LB_Free_Part(&importGlobalGids, &importLocalGids,
&importProcs, &importToPart);
Zoltan_LB_Free_Part(&exportGlobalGids, &exportLocalGids,
&exportProcs, &exportToPart);
Zoltan_Destroy(&zz);
/**********************
** all done ***********
**********************/
MPI_Finalize();
if (hg.numMyVertices > 0){
free(parts);
free(hg.vtxGID);
}
if (hg.numMyHEdges > 0){
free(hg.edgeGID);
free(hg.nborIndex);
if (hg.numAllNbors > 0){
free(hg.nborGID);
}
}
return 0;
}
/* Application defined query functions */
static int get_number_of_vertices(void *data, int *ierr)
{
HGRAPH_DATA *hg = (HGRAPH_DATA *)data;
*ierr = ZOLTAN_OK;
return hg->numMyVertices;
}
static void get_vertex_list(void *data, int sizeGID, int sizeLID,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int wgt_dim, float *obj_wgts, int *ierr)
{
int i;
HGRAPH_DATA *hg= (HGRAPH_DATA *)data;
*ierr = ZOLTAN_OK;
/* In this example, return the IDs of our vertices, but no weights.
* Zoltan will assume equally weighted vertices.
*/
for (i=0; i<hg->numMyVertices; i++){
globalID[i] = hg->vtxGID[i];
localID[i] = i;
}
}
static void get_hypergraph_size(void *data, int *num_lists, int *num_nonzeroes,
int *format, int *ierr)
{
HGRAPH_DATA *hg = (HGRAPH_DATA *)data;
*ierr = ZOLTAN_OK;
*num_lists = hg->numMyHEdges;
*num_nonzeroes = hg->numAllNbors;
/* We will provide compressed hyperedge (row) format. The alternative is
* is compressed vertex (column) format: ZOLTAN_COMPRESSED_VERTEX.
*/
*format = ZOLTAN_COMPRESSED_EDGE;
return;
}
static void get_hypergraph(void *data, int sizeGID, int num_edges, int num_nonzeroes,
int format, ZOLTAN_ID_PTR edgeGID, int *vtxPtr,
ZOLTAN_ID_PTR vtxGID, int *ierr)
{
int i;
HGRAPH_DATA *hg = (HGRAPH_DATA *)data;
*ierr = ZOLTAN_OK;
if ( (num_edges != hg->numMyHEdges) || (num_nonzeroes != hg->numAllNbors) ||
(format != ZOLTAN_COMPRESSED_EDGE)) {
*ierr = ZOLTAN_FATAL;
return;
}
for (i=0; i < num_edges; i++){
edgeGID[i] = hg->edgeGID[i];
vtxPtr[i] = hg->nborIndex[i];
}
for (i=0; i < num_nonzeroes; i++){
vtxGID[i] = hg->nborGID[i];
}
return;
}
/* Function to find next line of information in input file */
static int get_next_line(FILE *fp, char *buf, int bufsize)
{
int i, cval, len;
char *c;
while (1){
c = fgets(buf, bufsize, fp);
if (c == NULL)
return 0; /* end of file */
len = strlen(c);
for (i=0, c=buf; i < len; i++, c++){
cval = (int)*c;
if (isspace(cval) == 0) break;
}
if (i == len) continue; /* blank line */
if (*c == '#') continue; /* comment */
if (c != buf){
strcpy(buf, c);
}
break;
}
return strlen(buf); /* number of characters */
}
/* Function to return the list of non-negative integers in a line */
static int get_line_ints(char *buf, int bufsize, int *vals)
{
char *c = buf;
int count=0;
while (1){
while (!(isdigit(*c))){
if ((c - buf) >= bufsize) break;
c++;
}
if ( (c-buf) >= bufsize) break;
vals[count++] = atoi(c);
while (isdigit(*c)){
if ((c - buf) >= bufsize) break;
c++;
}
if ( (c-buf) >= bufsize) break;
}
return count;
}
/* Proc 0 notifies others of error and exits */
static void input_file_error(int numProcs, int tag, int startProc)
{
int i, val[3];
val[0] = -1; /* error flag */
fprintf(stderr,"ERROR in input file.\n");
for (i=startProc; i < numProcs; i++){
/* these procs have posted a receive for "tag" expecting counts */
MPI_Send(val, 3, MPI_INT, i, tag, MPI_COMM_WORLD);
}
for (i=1; i < startProc; i++){
/* these procs are done and waiting for ok-to-go */
MPI_Send(val, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
}
MPI_Finalize();
exit(1);
}
/* Draw the partition assignments of the objects */
static void showHypergraph(int myProc, int numProcs, int numIDs, ZOLTAN_ID_TYPE *GIDs, int *parts)
{
int *partAssign, *allPartAssign;
int i, j, part, count, numVtx, numEdges;
int edgeIdx, vtxIdx;
int maxPart, nPart, partIdx;
int **M;
int *partNums, *partCount;
ZOLTAN_ID_TYPE *nextID;
ZOLTAN_ID_TYPE edgeID, vtxID;
int cutn, cutl;
float imbal, localImbal;
numVtx = global_hg.numGlobalVertices;
numEdges = global_hg.numGlobalEdges;
partAssign = (int *)calloc(sizeof(int), numVtx);
allPartAssign = (int *)calloc(sizeof(int), numVtx);
for (i=0; i < numIDs; i++){
partAssign[GIDs[i]-1] = parts[i];
}
MPI_Reduce(partAssign, allPartAssign, numVtx, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD);
free(partAssign);
if (myProc > 0){
free(allPartAssign);
return;
}
/* Creating a dense matrix containing hyperedges, because this is small
* example problem, and it is simpler.
*/
M = (int **)calloc(sizeof(int *) , numEdges);
for (i=0; i < numEdges; i++){
M[i] = (int *)calloc(sizeof(int) , numVtx);
}
nextID = global_hg.nborGID;
maxPart = 0;
for (i=0; i < numEdges; i++){
edgeID = global_hg.edgeGID[i];
edgeIdx = (int)edgeID - 1;
count = global_hg.nborIndex[i+1] - global_hg.nborIndex[i];
for (j=0; j < count; j++){
vtxID = *nextID++;
vtxIdx = (int)vtxID - 1;
part = allPartAssign[vtxIdx];
if (part > maxPart) maxPart = part;
M[edgeIdx][vtxIdx] = part+1;
}
}
/* Calculate vertex balance measure 1.0 is perfect, higher is worse */
imbal = 0;
partCount = (int *)calloc(sizeof(int), maxPart+1);
for (i=0; i < numVtx; i++){
partCount[allPartAssign[i]]++;
}
imbal = 0.0;
for (part=0; part <= maxPart; part++){
localImbal = (float)(numProcs * partCount[part]) / (float)numVtx;
if (localImbal > imbal) imbal = localImbal;
}
free(partCount);
free(allPartAssign);
/* Print the hypergraph as a matrix */
printf("\n VERTICES\n ");
for (j=0; j < numVtx; j++){
if (j < 9)
printf("%d ",j+1);
else
printf("%d ",j+1);
}
printf(" NPARTS-1");
printf("\n ");
for (j=0; j < numVtx; j++){
printf("---");
}
printf("\n");
partNums = (int *)calloc(sizeof(int), maxPart + 1);
cutn = 0;
cutl = 0;
for (i=0; i < numEdges; i++){
nPart = 0;
if (i < 9)
printf("%d ",i+1);
else
printf("%d ",i+1);
for (j=0; j < numVtx; j++){
part = M[i][j];
partIdx = part - 1;
if (part > 0){
printf("%d ",partIdx);
if (partNums[partIdx] < i+1){
nPart++;
partNums[partIdx] = i+1;
}
}
else{
printf(" ");
}
}
if (nPart >= 2){
printf(" %d\n",nPart - 1);
cutn++;
cutl += (nPart - 1);
}
else{
printf("\n");
}
}
printf("Total number of cut edges: %d\n",cutn);
printf("Sum of NPARTS-1: %d\n",cutl);
printf("Balance of vertices across partitions: %f\n",imbal);
printf("\n");
for (i=0; i < numEdges; i++){
free(M[i]);
}
free(M);
free(partNums);
}
/*
* Read the hypergraph in the input file and distribute the non-zeroes. (See the
* matrix analogy at the top of the source file.)
*
* We will distribute the hyperedges (rows) to the processes. However, we could
* distribute the vertices (columns), or we could distribute the non-zeroes
* instead.
*
* Zoltan partitions the vertices, so we also create an initial partitioning of the vertices.
*/
void read_input_file(int myRank, int numProcs, char *fname, HGRAPH_DATA *hg)
{
char buf[512];
int bufsize;
int numGlobalVertices, numGlobalEdges, numGlobalNZ;
int num, count, nnbors, ack=0;
int to=-1, from, remaining;
int vGID;
int i, j;
int vals[128], send_count[3];
ZOLTAN_ID_TYPE *idx;
unsigned int id;
FILE *fp;
MPI_Status status;
int ack_tag = 5, count_tag = 10, id_tag = 15;
HGRAPH_DATA *send_hg;
if (myRank == 0){
bufsize = 512;
fp = fopen(fname, "r");
/* Get the number of vertices */
num = get_next_line(fp, buf, bufsize);
if (num == 0) input_file_error(numProcs, count_tag, 1);
num = sscanf(buf, "%d", &numGlobalVertices);
if (num != 1) input_file_error(numProcs, count_tag, 1);
global_hg.numGlobalVertices = numGlobalVertices;
global_hg.numMyVertices = numGlobalVertices;
global_hg.vtxGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * numGlobalVertices);
/* Get the vertex global IDs */
for (i=0; i < numGlobalVertices; i++){
num = get_next_line(fp, buf, bufsize);
if (num == 0) input_file_error(numProcs, count_tag, 1);
num = sscanf(buf, "%d", &vGID);
if (num != 1) input_file_error(numProcs, count_tag, 1);
global_hg.vtxGID[i] = (ZOLTAN_ID_TYPE)vGID;
}
/* Get the number hyperedges which contain those vertices */
num = get_next_line(fp, buf, bufsize);
if (num == 0) input_file_error(numProcs, count_tag, 1);
num = sscanf(buf, "%d", &numGlobalEdges);
if (num != 1) input_file_error(numProcs, count_tag, 1);
global_hg.numGlobalEdges = numGlobalEdges;
global_hg.numMyHEdges = numGlobalEdges;
global_hg.edgeGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * numGlobalEdges);
global_hg.nborIndex = (int *)malloc(sizeof(int) * (numGlobalEdges + 1));
/* Get the total number of vertices or neighbors in all the hyperedges of
* the hypergraph. Or get the number of non-zeroes in the matrix representing
* the hypergraph.
*/
num = get_next_line(fp, buf, bufsize);
if (num == 0) input_file_error(numProcs, count_tag, 1);
num = sscanf(buf, "%d", &numGlobalNZ);
if (num != 1) input_file_error(numProcs, count_tag, 1);
global_hg.nborGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * numGlobalNZ);
/* Get the list of vertices in each hyperedge */
global_hg.nborIndex[0] = 0;
for (i=0; i < numGlobalEdges; i++){
num = get_next_line(fp, buf, bufsize);
if (num == 0) input_file_error(numProcs, count_tag, 1);
num = get_line_ints(buf, bufsize, vals);
if (num < 2) input_file_error(numProcs, count_tag, 1);
id = vals[0];
nnbors = vals[1];
if (num < (nnbors + 2)) input_file_error(numProcs, count_tag, 1);
global_hg.edgeGID[i] = (ZOLTAN_ID_TYPE)id;
for (j=0; j < nnbors; j++){
global_hg.nborGID[global_hg.nborIndex[i] + j] = (ZOLTAN_ID_TYPE)vals[2 + j];
}
global_hg.nborIndex[i+1] = global_hg.nborIndex[i] + nnbors;
}
fclose(fp);
/* Create a sub graph for each process */
send_hg = (HGRAPH_DATA *)calloc(sizeof(HGRAPH_DATA) , numProcs);
/*
* Divide the vertices across the processes
*/
remaining = numGlobalVertices;
count = (numGlobalVertices / numProcs) + 1;
idx = global_hg.vtxGID;
for (i=0; i < numProcs; i++){
if (remaining == 0) count = 0;
if (count > remaining) count = remaining;
send_hg[i].numMyVertices = count;
if (count){
send_hg[i].vtxGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * count);
for (j=0; j < count; j++){
send_hg[i].vtxGID[j] = *idx++;
}
}
remaining -= count;
}
/*
* Assign hyperedges to processes, and create a sub-hypergraph for each process.
*/
remaining = numGlobalEdges;
count = (numGlobalEdges / numProcs) + 1;
from = 0;
for (i=0; i < numProcs; i++){
if (remaining == 0) count = 0;
if (count > remaining) count = remaining;
send_hg[i].numMyHEdges = count;
send_hg[i].numAllNbors = 0;
if (count > 0){
to = from + count;
nnbors = global_hg.nborIndex[to] - global_hg.nborIndex[from];
send_hg[i].numAllNbors = nnbors;
send_hg[i].edgeGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * count);
memcpy(send_hg[i].edgeGID, global_hg.edgeGID + from, sizeof(ZOLTAN_ID_TYPE) * count);
send_hg[i].nborIndex = (int *)malloc(sizeof(int) * (count + 1));
send_hg[i].nborIndex[0] = 0;
if (nnbors > 0){
num = global_hg.nborIndex[from];
for (j=1; j <= count; j++){
send_hg[i].nborIndex[j] = global_hg.nborIndex[from+j] - num;
}
send_hg[i].nborGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * nnbors);
memcpy(send_hg[i].nborGID,
global_hg.nborGID + global_hg.nborIndex[from],
sizeof(ZOLTAN_ID_TYPE) * nnbors);
}
}
remaining -= count;
from = to;
}
/* Send each process its hyperedges and the vertices in its partition */
*hg = send_hg[0];
for (i=1; i < numProcs; i++){
send_count[0] = send_hg[i].numMyVertices;
send_count[1] = send_hg[i].numMyHEdges;
send_count[2] = send_hg[i].numAllNbors;
MPI_Send(send_count, 3, MPI_INT, i, count_tag, MPI_COMM_WORLD);
MPI_Recv(&ack, 1, MPI_INT, i, ack_tag, MPI_COMM_WORLD, &status);
if (send_count[0] > 0){
MPI_Send(send_hg[i].vtxGID, send_count[0], ZOLTAN_ID_MPI_TYPE, i, id_tag, MPI_COMM_WORLD);
free(send_hg[i].vtxGID);
}
if (send_count[1] > 0){
MPI_Send(send_hg[i].edgeGID, send_count[1], ZOLTAN_ID_MPI_TYPE, i, id_tag + 1, MPI_COMM_WORLD);
free(send_hg[i].edgeGID);
MPI_Send(send_hg[i].nborIndex, send_count[1] + 1, MPI_INT, i, id_tag + 2, MPI_COMM_WORLD);
free(send_hg[i].nborIndex);
if (send_count[2] > 0){
MPI_Send(send_hg[i].nborGID, send_count[2], ZOLTAN_ID_MPI_TYPE, i, id_tag + 3, MPI_COMM_WORLD);
free(send_hg[i].nborGID);
}
}
}
free(send_hg);
/* signal all procs it is OK to go on */
ack = 0;
for (i=1; i < numProcs; i++){
MPI_Send(&ack, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
}
}
else{
MPI_Recv(send_count, 3, MPI_INT, 0, count_tag, MPI_COMM_WORLD, &status);
if (send_count[0] < 0){
MPI_Finalize();
exit(1);
}
ack = 0;
memset(hg, 0, sizeof(HGRAPH_DATA));
hg->numMyVertices = send_count[0];
hg->numMyHEdges = send_count[1];
hg->numAllNbors = send_count[2];
if (send_count[0] > 0){
hg->vtxGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * send_count[0]);
}
if (send_count[1] > 0){
hg->edgeGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * send_count[1]);
hg->nborIndex = (int *)malloc(sizeof(int) * (send_count[1] + 1));
if (send_count[2] > 0){
hg->nborGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * send_count[2]);
}
}
MPI_Send(&ack, 1, MPI_INT, 0, ack_tag, MPI_COMM_WORLD);
if (send_count[0] > 0){
MPI_Recv(hg->vtxGID,send_count[0], ZOLTAN_ID_MPI_TYPE, 0, id_tag, MPI_COMM_WORLD, &status);
if (send_count[1] > 0){
MPI_Recv(hg->edgeGID,send_count[1], ZOLTAN_ID_MPI_TYPE, 0, id_tag + 1, MPI_COMM_WORLD, &status);
MPI_Recv(hg->nborIndex,send_count[1] + 1, MPI_INT, 0, id_tag + 2, MPI_COMM_WORLD, &status);
if (send_count[2] > 0){
MPI_Recv(hg->nborGID,send_count[2], ZOLTAN_ID_MPI_TYPE, 0, id_tag + 3, MPI_COMM_WORLD, &status);
}
}
}
/* ok to go on? */
MPI_Recv(&ack, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
if (ack < 0){
MPI_Finalize();
exit(1);
}
}
MPI_Bcast(&(global_hg.numGlobalVertices), 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(&(global_hg.numGlobalEdges), 1, MPI_INT, 0, MPI_COMM_WORLD);
}

521
thirdParty/Zoltan/example/C/simpleRCB.c vendored Normal file
View File

@ -0,0 +1,521 @@
/*
* @HEADER
*
* ***********************************************************************
*
* Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
* Copyright 2012 Sandia Corporation
*
* Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
* the U.S. Government retains certain rights in this software.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Corporation nor the names of the
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Questions? Contact Karen Devine kddevin@sandia.gov
* Erik Boman egboman@sandia.gov
*
* ***********************************************************************
*
* @HEADER
*/
/***************************************************************
** Basic example of using Zoltan to compute an RCB partitioning
** of a very simple mesh or graph.
***************************************************************/
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "zoltan.h"
/* Name of file containing the mesh to be partitioned */
static char *global_fname="mesh.txt";
/* Structure to hold mesh data */
typedef struct{
int numGlobalPoints;
int numMyPoints;
ZOLTAN_ID_PTR myGlobalIDs;
float *x;
float *y;
} MESH_DATA;
/* Application defined query functions */
static int get_number_of_objects(void *data, int *ierr);
static void get_object_list(void *data, int sizeGID, int sizeLID,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int wgt_dim, float *obj_wgts, int *ierr);
static int get_num_geometry(void *data, int *ierr);
static void get_geometry_list(void *data, int sizeGID, int sizeLID,
int num_obj, ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int num_dim, double *geom_vec, int *ierr);
/* read in and display input mesh, handle errors */
static int get_next_line(FILE *fp, char *buf, int bufsize);
static void input_file_error(int numProcs, int tag, int startProc);
void read_input_objects(int myRank, int numProcs, char *fname, MESH_DATA *myData);
void showSimpleMeshPartitions(int myProc, int numIDs, ZOLTAN_ID_PTR IDs, int *parts);
int main(int argc, char *argv[])
{
int rc, i, myRank, numProcs;
float ver;
struct Zoltan_Struct *zz;
int changes, numGidEntries, numLidEntries, numImport, numExport;
ZOLTAN_ID_PTR importGlobalGids, importLocalGids, exportGlobalGids, exportLocalGids;
int *importProcs, *importToPart, *exportProcs, *exportToPart;
int *parts;
FILE *fp;
MESH_DATA myMesh;
/******************************************************************
** Initialize MPI and Zoltan
******************************************************************/
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myRank);
MPI_Comm_size(MPI_COMM_WORLD, &numProcs);
rc = Zoltan_Initialize(argc, argv, &ver);
if (rc != ZOLTAN_OK){
printf("sorry...\n");
MPI_Finalize();
exit(0);
}
/******************************************************************
** Read geometry from input file and distribute it unevenly
******************************************************************/
fp = fopen(global_fname, "r");
if (!fp){
if (myRank == 0) fprintf(stderr,"ERROR: Can not open %s\n",global_fname);
MPI_Finalize();
exit(1);
}
fclose(fp);
read_input_objects(myRank, numProcs, global_fname, &myMesh);
/******************************************************************
** Create a Zoltan library structure for this instance of load
** balancing. Set the parameters and query functions that will
** govern the library's calculation. See the Zoltan User's
** Guide for the definition of these and many other parameters.
******************************************************************/
zz = Zoltan_Create(MPI_COMM_WORLD);
/* General parameters */
Zoltan_Set_Param(zz, "DEBUG_LEVEL", "1");
Zoltan_Set_Param(zz, "LB_METHOD", "RCB");
Zoltan_Set_Param(zz, "NUM_GID_ENTRIES", "1");
Zoltan_Set_Param(zz, "NUM_LID_ENTRIES", "1");
Zoltan_Set_Param(zz, "OBJ_WEIGHT_DIM", "0");
Zoltan_Set_Param(zz, "RETURN_LISTS", "ALL");
/* RCB parameters */
Zoltan_Set_Param(zz, "RCB_OUTPUT_LEVEL", "0");
Zoltan_Set_Param(zz, "RCB_RECTILINEAR_BLOCKS", "1");
/*Zoltan_Set_Param(zz, "RCB_RECTILINEAR_BLOCKS", "0"); */
/* Query functions, to provide geometry to Zoltan */
Zoltan_Set_Num_Obj_Fn(zz, get_number_of_objects, &myMesh);
Zoltan_Set_Obj_List_Fn(zz, get_object_list, &myMesh);
Zoltan_Set_Num_Geom_Fn(zz, get_num_geometry, &myMesh);
Zoltan_Set_Geom_Multi_Fn(zz, get_geometry_list, &myMesh);
/******************************************************************
** Zoltan can now partition the vertices in the simple mesh.
** In this simple example, we assume the number of partitions is
** equal to the number of processes. Process rank 0 will own
** partition 0, process rank 1 will own partition 1, and so on.
******************************************************************/
rc = Zoltan_LB_Partition(zz, /* input (all remaining fields are output) */
&changes, /* 1 if partitioning was changed, 0 otherwise */
&numGidEntries, /* Number of integers used for a global ID */
&numLidEntries, /* Number of integers used for a local ID */
&numImport, /* Number of vertices to be sent to me */
&importGlobalGids, /* Global IDs of vertices to be sent to me */
&importLocalGids, /* Local IDs of vertices to be sent to me */
&importProcs, /* Process rank for source of each incoming vertex */
&importToPart, /* New partition for each incoming vertex */
&numExport, /* Number of vertices I must send to other processes*/
&exportGlobalGids, /* Global IDs of the vertices I must send */
&exportLocalGids, /* Local IDs of the vertices I must send */
&exportProcs, /* Process to which I send each of the vertices */
&exportToPart); /* Partition to which each vertex will belong */
if (rc != ZOLTAN_OK){
printf("sorry...\n");
MPI_Finalize();
Zoltan_Destroy(&zz);
exit(0);
}
/******************************************************************
** Visualize the mesh partitioning before and after calling Zoltan.
******************************************************************/
parts = (int *)malloc(sizeof(int) * myMesh.numMyPoints);
for (i=0; i < myMesh.numMyPoints; i++){
parts[i] = myRank;
}
if (myRank== 0){
printf("\nMesh partition assignments before calling Zoltan\n");
}
showSimpleMeshPartitions(myRank, myMesh.numMyPoints, myMesh.myGlobalIDs, parts);
for (i=0; i < numExport; i++){
parts[exportLocalGids[i]] = exportToPart[i];
}
if (myRank == 0){
printf("Mesh partition assignments after calling Zoltan\n");
}
showSimpleMeshPartitions(myRank, myMesh.numMyPoints, myMesh.myGlobalIDs, parts);
free(parts);
/******************************************************************
** Free the arrays allocated by Zoltan_LB_Partition, and free
** the storage allocated for the Zoltan structure.
******************************************************************/
Zoltan_LB_Free_Part(&importGlobalGids, &importLocalGids,
&importProcs, &importToPart);
Zoltan_LB_Free_Part(&exportGlobalGids, &exportLocalGids,
&exportProcs, &exportToPart);
Zoltan_Destroy(&zz);
/**********************
** all done ***********
**********************/
MPI_Finalize();
if (myMesh.numMyPoints > 0){
free(myMesh.myGlobalIDs);
free(myMesh.x);
free(myMesh.y);
}
return 0;
}
/* Application defined query functions */
static int get_number_of_objects(void *data, int *ierr)
{
MESH_DATA *mesh= (MESH_DATA *)data;
*ierr = ZOLTAN_OK;
return mesh->numMyPoints;
}
static void get_object_list(void *data, int sizeGID, int sizeLID,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int wgt_dim, float *obj_wgts, int *ierr)
{
int i;
MESH_DATA *mesh= (MESH_DATA *)data;
*ierr = ZOLTAN_OK;
/* In this example, return the IDs of our objects, but no weights.
* Zoltan will assume equally weighted objects.
*/
for (i=0; i<mesh->numMyPoints; i++){
globalID[i] = mesh->myGlobalIDs[i];
localID[i] = i;
}
}
static int get_num_geometry(void *data, int *ierr)
{
*ierr = ZOLTAN_OK;
return 2;
}
static void get_geometry_list(void *data, int sizeGID, int sizeLID,
int num_obj,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int num_dim, double *geom_vec, int *ierr)
{
int i;
MESH_DATA *mesh= (MESH_DATA *)data;
if ( (sizeGID != 1) || (sizeLID != 1) || (num_dim != 2)){
*ierr = ZOLTAN_FATAL;
return;
}
*ierr = ZOLTAN_OK;
for (i=0; i < num_obj ; i++){
geom_vec[2*i] = (double)mesh->x[i];
geom_vec[2*i + 1] = (double)mesh->y[i];
}
return;
}
static int get_next_line(FILE *fp, char *buf, int bufsize)
{
int i, cval, len;
char *c;
while (1){
c = fgets(buf, bufsize, fp);
if (c == NULL)
return 0; /* end of file */
len = strlen(c);
for (i=0, c=buf; i < len; i++, c++){
cval = (int)*c;
if (isspace(cval) == 0) break;
}
if (i == len) continue; /* blank line */
if (*c == '#') continue; /* comment */
if (c != buf){
strcpy(buf, c);
}
break;
}
return strlen(buf); /* number of characters */
}
/* Proc 0 notifies others of error and exits */
static void input_file_error(int numProcs, int tag, int startProc)
{
int i, val;
val = -1;
fprintf(stderr,"ERROR in input file.\n");
for (i=startProc; i < numProcs; i++){
/* these procs have posted receive for "tag" */
MPI_Send(&val, 1, MPI_INT, i, tag, MPI_COMM_WORLD);
}
for (i=1; i < startProc; i++){
/* these procs are done */
MPI_Send(&val, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
}
MPI_Finalize();
exit(1);
}
/* Proc 0 reads the points in the input file and divides them across processes */
void read_input_objects(int myRank, int numProcs, char *fname, MESH_DATA *myMesh)
{
char *buf;
int bufsize = 512;
int num, nobj, remaining, ack=0;
int i, j;
ZOLTAN_ID_PTR gids;
float *xcoord, *ycoord;
FILE *fp;
MPI_Status status;
int ack_tag = 5, count_tag = 10, id_tag = 15;
int x_tag = 20, y_tag = 25;
if (myRank == 0){
buf = (char *)malloc(sizeof(char) * bufsize);
fp = fopen(fname, "r");
num = get_next_line(fp, buf, bufsize);
if (num == 0) input_file_error(numProcs, count_tag, 1);
num = sscanf(buf, "%d", &myMesh->numGlobalPoints);
if (num != 1) input_file_error(numProcs, count_tag, 1);
if (numProcs > 1){
nobj = myMesh->numGlobalPoints / 2;
remaining = myMesh->numGlobalPoints - nobj;
}
else{
nobj = myMesh->numGlobalPoints;
remaining = 0;
}
myMesh->myGlobalIDs = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * nobj);
myMesh->x = (float *)malloc(sizeof(float) * nobj);
myMesh->y = (float *)malloc(sizeof(float) * nobj);
myMesh->numMyPoints= nobj;
for (i=0; i < nobj; i++){
num = get_next_line(fp, buf, bufsize);
if (num == 0) input_file_error(numProcs, count_tag, 1);
num = sscanf(buf, ZOLTAN_ID_SPEC "%f %f", myMesh->myGlobalIDs + i,
myMesh->x + i, myMesh->y + i);
if (num != 3) input_file_error(numProcs, count_tag, 1);
}
gids = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * (nobj + 1));
xcoord = (float *)malloc(sizeof(float) * (nobj + 1));
ycoord = (float *)malloc(sizeof(float) * (nobj + 1));
for (i=1; i < numProcs; i++){
if (remaining > 1){
nobj = remaining / 2;
remaining -= nobj;
}
else if (remaining == 1){
nobj = 1;
remaining = 0;
}
else{
nobj = 0;
}
if ((i == numProcs - 1) && (remaining > 0))
nobj += remaining;
if (nobj > 0){
for (j=0; j < nobj; j++){
num = get_next_line(fp, buf, bufsize);
if (num == 0) input_file_error(numProcs, count_tag, i);
num = sscanf(buf, ZOLTAN_ID_SPEC "%f %f", gids+j, xcoord+j, ycoord+j);
if (num != 3) input_file_error(numProcs, count_tag, i);
}
}
MPI_Send(&nobj, 1, MPI_INT, i, count_tag, MPI_COMM_WORLD);
MPI_Recv(&ack, 1, MPI_INT, i, ack_tag, MPI_COMM_WORLD, &status);
if (nobj > 0){
MPI_Send(gids, nobj, ZOLTAN_ID_MPI_TYPE, i, id_tag, MPI_COMM_WORLD);
MPI_Send(xcoord, nobj, MPI_FLOAT, i, x_tag, MPI_COMM_WORLD);
MPI_Send(ycoord, nobj, MPI_FLOAT, i, y_tag, MPI_COMM_WORLD);
}
}
free(gids);
free(xcoord);
free(ycoord);
fclose(fp);
free(buf);
/* signal all procs it is OK to go on */
ack = 0;
for (i=1; i < numProcs; i++){
MPI_Send(&ack, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
}
}
else{
MPI_Recv(&myMesh->numMyPoints, 1, MPI_INT, 0, count_tag, MPI_COMM_WORLD, &status);
ack = 0;
if (myMesh->numMyPoints > 0){
myMesh->myGlobalIDs = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * myMesh->numMyPoints);
myMesh->x = (float *)malloc(sizeof(float) * myMesh->numMyPoints);
myMesh->y = (float *)malloc(sizeof(float) * myMesh->numMyPoints);
MPI_Send(&ack, 1, MPI_INT, 0, ack_tag, MPI_COMM_WORLD);
MPI_Recv(myMesh->myGlobalIDs, myMesh->numMyPoints, ZOLTAN_ID_MPI_TYPE, 0,
id_tag, MPI_COMM_WORLD, &status);
MPI_Recv(myMesh->x, myMesh->numMyPoints, MPI_FLOAT, 0,
x_tag, MPI_COMM_WORLD, &status);
MPI_Recv(myMesh->y, myMesh->numMyPoints, MPI_FLOAT, 0,
y_tag, MPI_COMM_WORLD, &status);
}
else if (myMesh->numMyPoints == 0){
MPI_Send(&ack, 1, MPI_INT, 0, ack_tag, MPI_COMM_WORLD);
}
else{
MPI_Finalize();
exit(1);
}
MPI_Recv(&ack, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
if (ack < 0){
MPI_Finalize();
exit(1);
}
}
}
void showSimpleMeshPartitions(int myProc, int numIDs, ZOLTAN_ID_PTR GIDs, int *parts)
{
int partAssign[25], allPartAssign[25];
int i, j, part;
memset(partAssign, 0, sizeof(int) * 25);
for (i=0; i < numIDs; i++){
partAssign[GIDs[i]-1] = parts[i];
}
MPI_Reduce(partAssign, allPartAssign, 25, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD);
if (myProc == 0){
for (i=20; i >= 0; i-=5){
for (j=0; j < 5; j++){
part = allPartAssign[i + j];
if (j < 4)
printf("%d-----",part);
else
printf("%d\n",part);
}
if (i > 0)
printf("| | | | |\n");
}
printf("\n");
}
}

View File

@ -0,0 +1,14 @@
# Required modules
# Example definitions
ADD_SUBDIRECTORY(C)
IF (${PROJECT_NAME}_ENABLE_CXX)
ADD_SUBDIRECTORY(CPP)
ENDIF()
IF (ZOLTAN_BUILD_ZFDRIVE)
ADD_SUBDIRECTORY(Fortran)
ENDIF()

View File

@ -0,0 +1,12 @@
TRIBITS_ADD_EXECUTABLE_AND_TEST(
exampleBLOCK
SOURCES exampleBLOCK.cpp
ARGS
COMM serial mpi
NUM_MPI_PROCS 1-4
)
TRIBITS_COPY_FILES_TO_BINARY_DIR(CPPExamplesCopyFile
SOURCE_FILES objects.txt
)

View File

@ -0,0 +1,60 @@
# @HEADER
#
########################################################################
#
# Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
# Copyright 2012 Sandia Corporation
#
# Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
# the U.S. Government retains certain rights in this software.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the Corporation nor the names of the
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Questions? Contact Karen Devine kddevin@sandia.gov
# Erik Boman egboman@sandia.gov
#
########################################################################
#
# @HEADER
# The following line helps the test harness recover from build errors.
all-local:
include $(top_builddir)/Makefile.export.zoltan
EXEEXT = .exe
noinst_PROGRAMS = exampleBLOCK
exampleBLOCK_SOURCES = exampleBLOCK.cpp
exampleBLOCK_DEPENDENCIES = $(ZOLTAN_DEPS)
exampleBLOCK_CXXFLAGS = $(ZOLTAN_INCLUDES)
exampleBLOCK_LDADD = $(ZOLTAN_LIBS)
EXTRA_DIST = classicMakefile objects.txt

View File

@ -0,0 +1,544 @@
# Makefile.in generated by automake 1.11.3 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
# Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
# @HEADER
#
########################################################################
#
# Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
# Copyright 2012 Sandia Corporation
#
# Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
# the U.S. Government retains certain rights in this software.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the Corporation nor the names of the
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Questions? Contact Karen Devine kddevin@sandia.gov
# Erik Boman egboman@sandia.gov
#
########################################################################
#
# @HEADER
# The following line helps the test harness recover from build errors.
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
noinst_PROGRAMS = exampleBLOCK$(EXEEXT)
subdir = example/CPP
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/config/ax_f90_module_case.m4 \
$(top_srcdir)/config/ax_f90_module_flag.m4 \
$(top_srcdir)/config/tac_arg_check_mpi.m4 \
$(top_srcdir)/config/tac_arg_enable_export-makefiles.m4 \
$(top_srcdir)/config/tac_arg_enable_feature.m4 \
$(top_srcdir)/config/tac_arg_enable_feature_sub.m4 \
$(top_srcdir)/config/tac_arg_enable_feature_sub_check.m4 \
$(top_srcdir)/config/tac_arg_enable_option.m4 \
$(top_srcdir)/config/tac_arg_with_3pl_sub.m4 \
$(top_srcdir)/config/tac_arg_with_ar.m4 \
$(top_srcdir)/config/tac_arg_with_flags.m4 \
$(top_srcdir)/config/tac_arg_with_incdirs.m4 \
$(top_srcdir)/config/tac_arg_with_libdirs.m4 \
$(top_srcdir)/config/tac_arg_with_libs.m4 \
$(top_srcdir)/config/tac_arg_with_package.m4 \
$(top_srcdir)/config/tac_arg_with_perl.m4 \
$(top_srcdir)/config/wk_fc_get_vendor.m4 \
$(top_srcdir)/config/zac_arg_config_mpi.m4 \
$(top_srcdir)/config/zac_arg_with_id.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/src/include/Zoltan_config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
PROGRAMS = $(noinst_PROGRAMS)
am_exampleBLOCK_OBJECTS = exampleBLOCK-exampleBLOCK.$(OBJEXT)
exampleBLOCK_OBJECTS = $(am_exampleBLOCK_OBJECTS)
exampleBLOCK_LINK = $(CXXLD) $(exampleBLOCK_CXXFLAGS) $(CXXFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src/include
depcomp = $(SHELL) $(top_srcdir)/config/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
-o $@
SOURCES = $(exampleBLOCK_SOURCES)
DIST_SOURCES = $(exampleBLOCK_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALTERNATE_AR = @ALTERNATE_AR@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EXEEXT = .exe
FC = @FC@
FCFLAGS = @FCFLAGS@
FCFLAGS_f = @FCFLAGS_f@
FCFLAGS_f90 = @FCFLAGS_f90@
FCLIBS = @FCLIBS@
FC_MAJOR_VERSION = @FC_MAJOR_VERSION@
FC_MODNAME = @FC_MODNAME@
FC_MODNAME_Q = @FC_MODNAME_Q@
FC_VENDOR = @FC_VENDOR@
FC_VERSION = @FC_VERSION@
FC_VERSION_STRING = @FC_VERSION_STRING@
HAVE_PERL = @HAVE_PERL@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
MPI_CC = @MPI_CC@
MPI_CXX = @MPI_CXX@
MPI_FC = @MPI_FC@
MPI_RECV_LIMIT_FLAG = @MPI_RECV_LIMIT_FLAG@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL_EXE = @PERL_EXE@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_aux_dir = @ac_aux_dir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_FC = @ac_ct_FC@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
exampleBLOCK_SOURCES = exampleBLOCK.cpp
exampleBLOCK_DEPENDENCIES = $(ZOLTAN_DEPS)
exampleBLOCK_CXXFLAGS = $(ZOLTAN_INCLUDES)
exampleBLOCK_LDADD = $(ZOLTAN_LIBS)
EXTRA_DIST = classicMakefile objects.txt
all: all-am
.SUFFIXES:
.SUFFIXES: .cpp .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu example/CPP/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu example/CPP/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
clean-noinstPROGRAMS:
-test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
exampleBLOCK$(EXEEXT): $(exampleBLOCK_OBJECTS) $(exampleBLOCK_DEPENDENCIES) $(EXTRA_exampleBLOCK_DEPENDENCIES)
@rm -f exampleBLOCK$(EXEEXT)
$(exampleBLOCK_LINK) $(exampleBLOCK_OBJECTS) $(exampleBLOCK_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exampleBLOCK-exampleBLOCK.Po@am__quote@
.cpp.o:
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
exampleBLOCK-exampleBLOCK.o: exampleBLOCK.cpp
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(exampleBLOCK_CXXFLAGS) $(CXXFLAGS) -MT exampleBLOCK-exampleBLOCK.o -MD -MP -MF $(DEPDIR)/exampleBLOCK-exampleBLOCK.Tpo -c -o exampleBLOCK-exampleBLOCK.o `test -f 'exampleBLOCK.cpp' || echo '$(srcdir)/'`exampleBLOCK.cpp
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/exampleBLOCK-exampleBLOCK.Tpo $(DEPDIR)/exampleBLOCK-exampleBLOCK.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='exampleBLOCK.cpp' object='exampleBLOCK-exampleBLOCK.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(exampleBLOCK_CXXFLAGS) $(CXXFLAGS) -c -o exampleBLOCK-exampleBLOCK.o `test -f 'exampleBLOCK.cpp' || echo '$(srcdir)/'`exampleBLOCK.cpp
exampleBLOCK-exampleBLOCK.obj: exampleBLOCK.cpp
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(exampleBLOCK_CXXFLAGS) $(CXXFLAGS) -MT exampleBLOCK-exampleBLOCK.obj -MD -MP -MF $(DEPDIR)/exampleBLOCK-exampleBLOCK.Tpo -c -o exampleBLOCK-exampleBLOCK.obj `if test -f 'exampleBLOCK.cpp'; then $(CYGPATH_W) 'exampleBLOCK.cpp'; else $(CYGPATH_W) '$(srcdir)/exampleBLOCK.cpp'; fi`
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/exampleBLOCK-exampleBLOCK.Tpo $(DEPDIR)/exampleBLOCK-exampleBLOCK.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='exampleBLOCK.cpp' object='exampleBLOCK-exampleBLOCK.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(exampleBLOCK_CXXFLAGS) $(CXXFLAGS) -c -o exampleBLOCK-exampleBLOCK.obj `if test -f 'exampleBLOCK.cpp'; then $(CYGPATH_W) 'exampleBLOCK.cpp'; else $(CYGPATH_W) '$(srcdir)/exampleBLOCK.cpp'; fi`
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(PROGRAMS) all-local
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-noinstPROGRAMS mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am:
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am all-local check check-am clean \
clean-generic clean-noinstPROGRAMS ctags distclean \
distclean-compile distclean-generic distclean-tags distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
uninstall-am
all-local:
include $(top_builddir)/Makefile.export.zoltan
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -0,0 +1,77 @@
##
## a basic makefile to build examples
##
##
## The default type for a Zoltan global ID is "int". This can be changed
## with compile-time flags like:
##
## -DZOLTAN_ID_TYPE_LONG_LONG
##
## See src/include/zoltan_types.h for the valid id type macros. If Zoltan was compiled
## with one of these flags, then these examples need to be compiled with the same flag.
##
ID_TYPE_FLAG=-DZOLTAN_ID_TYPE_LONG_LONG
##
## Location of zoltan library, also location of Zoltan_config.h if
## using the autoconf build
BLD=../../build_both/src
##
## Location of zoltan "src" directory (for header files)
##
SRC=../../src
# Location of zoltan header files
ZOLTAN_INCLUDE=-I$(SRC)/include
##
## For an autoconf build, the location of Zoltan_config.h
##
ZOLTAN_CONFIG_INCLUDE=-I$(BLD)/include
##
## Headers for zoltan utilities, not often used by applications
## Needed for use of Zoltan_Hash in simpleGRAPH.c
##
ZOLTAN_UTIL_INCLUDE=-I$(SRC)/zz \
-I$(SRC)/par \
-I$(SRC)/order \
-I$(SRC)/tpls \
-I$(SRC)/lb \
-I$(SRC)/params \
-I$(SRC)/Utilities/shared
##
## If Zoltan was built with a third party library, provide the information required
## to link with that library.
##
SCOTCH=/home/lriesen/system/scotch_5.1.10a-32
PARMETIS=/home/lafisk/system/parmetis/ParMetis-3.1
TPL_LIB_DIR=-L$(PARMETIS) -L$(SCOTCH)/lib
TPL_INCLUDE=-I$(PARMETIS) -I$(SCOTCH)/include
TPL_LIBS=-lparmetis -lmetis -lptscotch -lscotch -lptscotcherr -lscotcherr
CXX=mpicxx
CXXFLAGS =$(ID_TYPE_FLAG)
EXAMPLE_NAMES = exampleBLOCK graphHier.cpp
all: $(EXAMPLE_NAMES)
%: %.cpp
$(CXX) $(CXXFLAGS) $(TPL_LIB_DIR) \
-I$(BLD)/include $(TPL_INCLUDE) $(ZOLTAN_INCLUDE) $(ZOLTAN_UTIL_INCLUDE) \
-o $@ $< $(BLD)/libzoltan.a $(TPL_LIBS) -lm
clean:
@rm -rf $(EXAMPLE_NAMES)

View File

@ -0,0 +1,542 @@
/*
* @HEADER
*
* ***********************************************************************
*
* Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
* Copyright 2012 Sandia Corporation
*
* Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
* the U.S. Government retains certain rights in this software.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Corporation nor the names of the
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Questions? Contact Karen Devine kddevin@sandia.gov
* Erik Boman egboman@sandia.gov
*
* ***********************************************************************
*
* @HEADER
*/
//
// Basic C++ example of using Zoltan to compute a quick partitioning
// of a set of objects.
//
#ifdef MPICPP
#undef MPICPP
#endif /* MPICPP */
//#define MPICPP // Uncomment to use C++ interface for MPI.
#include <mpi.h>
#include <stdio.h>
#include <zoltan_cpp.h>
// Class representing collection of objects to be partitioned.
class objectCollection {
private:
int numGlobalObjects;
int numMyObjects;
int *myGlobalIDs;
public:
// constructor
objectCollection():numGlobalObjects(0), numMyObjects(0), myGlobalIDs(NULL){}
// destructor
~objectCollection(){ if (myGlobalIDs) delete [] myGlobalIDs;}
void set_num_global_objects(int n) {numGlobalObjects = n;}
int get_num_global_objects() {return numGlobalObjects;}
void set_num_my_objects(int n) {numMyObjects = n;}
int get_num_my_objects() {return numMyObjects;}
void set_my_global_ids(int *p) {myGlobalIDs = p;}
int *get_my_global_ids() {return myGlobalIDs;}
// query functions that respond to requests from Zoltan
static int get_number_of_objects(void *data, int *ierr){
objectCollection *objs = (objectCollection *)data;
*ierr = ZOLTAN_OK;
return objs->numMyObjects;
}
static void get_object_list(void *data, int sizeGID, int sizeLID,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int wgt_dim, float *obj_wgts, int *ierr){
objectCollection *objs = (objectCollection *)data;
*ierr = ZOLTAN_OK;
// In this example, return the IDs of our objects, but no weights.
// Zoltan will assume equally weighted objects.
for (int i=0; i<objs->get_num_my_objects(); i++){
globalID[i] = objs->get_my_global_ids()[i];
localID[i] = i;
}
return;
}
};
static const char *global_fname="objects.txt"; // File containing objects to be partitioned.
static int get_next_line(FILE *fp, char *buf, int bufsize);
static void input_file_error(int numProcs, int tag, int startProc);
static void showSimpleMeshPartitions(int myProc, int numIDs, int *GIDs, int *parts);
static void read_input_objects(int myRank, int numProcs, const char *fname, objectCollection &myData);
static void MPIExit()
{
#ifdef MPICPP
MPI::Finalize();
#else
MPI_Finalize();
#endif
}
int main(int argc, char *argv[])
{
/////////////////////////////////
// Initialize MPI and Zoltan
/////////////////////////////////
int rank, size;
float version;
#ifdef MPICPP
MPI::Init(argc, argv);
rank = MPI::COMM_WORLD.Get_rank();
size = MPI::COMM_WORLD.Get_size();
#else
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
#endif
Zoltan_Initialize(argc, argv, &version);
/////////////////////////////////
// Create a Zoltan object
/////////////////////////////////
#ifdef MPICPP
Zoltan *zz = new Zoltan(MPI::COMM_WORLD);
#else
Zoltan *zz = new Zoltan(MPI_COMM_WORLD);
#endif
if (zz == NULL){
MPIExit();
exit(0);
}
//////////////////////////////////////////////////////////////////
// Read objects from input file and distribute them unevenly
//////////////////////////////////////////////////////////////////
FILE *fp = fopen(global_fname, "r");
if (!fp){
if (rank == 0) fprintf(stderr,"ERROR: Can not open %s\n",global_fname);
MPIExit();
exit(1);
}
fclose(fp);
objectCollection objects;
read_input_objects(rank, size, global_fname, objects);
///////////////////////////////////////////////////////////////////
// Set the Zoltan parameters, and the names of the query functions
///////////////////////////////////////////////////////////////////
// General parameters
zz->Set_Param( "LB_METHOD", "BLOCK"); /* Zoltan method: "BLOCK" */
zz->Set_Param( "NUM_GID_ENTRIES", "1"); /* global ID is 1 integer */
zz->Set_Param( "NUM_LID_ENTRIES", "1"); /* local ID is 1 integer */
zz->Set_Param( "OBJ_WEIGHT_DIM", "0"); /* we omit object weights */
// Query functions
zz->Set_Num_Obj_Fn(objectCollection::get_number_of_objects, &objects);
zz->Set_Obj_List_Fn(objectCollection::get_object_list, &objects);
////////////////////////////////////////////////////////////////
// Zoltan can now partition the objects in this collection.
// In this simple example, we assume the number of partitions is
// equal to the number of processes. Process rank 0 will own
// partition 0, process rank 1 will own partition 1, and so on.
////////////////////////////////////////////////////////////////
int changes;
int numGidEntries;
int numLidEntries;
int numImport;
ZOLTAN_ID_PTR importGlobalIds;
ZOLTAN_ID_PTR importLocalIds;
int *importProcs;
int *importToPart;
int numExport;
ZOLTAN_ID_PTR exportGlobalIds;
ZOLTAN_ID_PTR exportLocalIds;
int *exportProcs;
int *exportToPart;
int rc = zz->LB_Partition(changes, numGidEntries, numLidEntries,
numImport, importGlobalIds, importLocalIds, importProcs, importToPart,
numExport, exportGlobalIds, exportLocalIds, exportProcs, exportToPart);
if (rc != ZOLTAN_OK){
printf("Partitioning failed on process %d\n",rank);
MPIExit();
delete zz;
exit(0);
}
/////////////////////////////////////////////////////////////////
// Visualize the partitioning before and after calling Zoltan.
//
// In this example, partition number equals process rank.
/////////////////////////////////////////////////////////////////
int *parts = new int [objects.get_num_my_objects()];
for (int i=0; i < objects.get_num_my_objects(); i++){
parts[i] = rank;
}
if (rank == 0){
printf("\nObject partition assignments before calling Zoltan\n");
}
showSimpleMeshPartitions(rank, objects.get_num_my_objects(),
objects.get_my_global_ids(), parts);
for (int i=0; i < numExport; i++){
parts[exportLocalIds[i]] = exportToPart[i];
}
if (rank == 0){
printf("Object partition assignments after calling Zoltan\n");
}
showSimpleMeshPartitions(rank, objects.get_num_my_objects(),
objects.get_my_global_ids(), parts);
delete [] parts;
////////////////////////////////////////////////////////////////
// Free the arrays allocated by LB_Partition, and free
// the storage allocated for the Zoltan structure and the mesh.
////////////////////////////////////////////////////////////////
Zoltan::LB_Free_Part(&importGlobalIds, &importLocalIds, &importProcs,
&importToPart);
Zoltan::LB_Free_Part(&exportGlobalIds, &exportLocalIds, &exportProcs,
&exportToPart);
delete zz;
////////////////////////////////////////////////////////////////
// all done ////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
MPIExit();
return 0;
}
/* Function to find next line of information in input file */
static int get_next_line(FILE *fp, char *buf, int bufsize)
{
int i, cval, len;
char *c;
while (1){
c = fgets(buf, bufsize, fp);
if (c == NULL)
return 0; /* end of file */
len = strlen(c);
for (i=0, c=buf; i < len; i++, c++){
cval = (int)*c;
if (isspace(cval) == 0) break;
}
if (i == len) continue; /* blank line */
if (*c == '#') continue; /* comment */
if (c != buf){
strcpy(buf, c);
}
break;
}
return strlen(buf); /* number of characters */
}
// Proc 0 notifies others of error and exits
static void input_file_error(int numProcs, int tag, int startProc)
{
int i, val;
val = -1;
fprintf(stderr,"ERROR in input file.\n");
for (i=startProc; i < numProcs; i++){
// these procs have posted receive for "tag"
#ifdef MPICPP
MPI::COMM_WORLD.Send(&val, 1, MPI::INT, i, tag);
#else
MPI_Send(&val, 1, MPI_INT, i, tag, MPI_COMM_WORLD);
#endif
}
for (i=1; i < startProc; i++){
// these procs are done
#ifdef MPICPP
MPI::COMM_WORLD.Send(&val, 1, MPI::INT, i, 0);
#else
MPI_Send(&val, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
#endif
}
MPIExit();
exit(0);
}
/* Draw the partition assignments of the objects */
void showSimpleMeshPartitions(int myProc, int numIDs, int *GIDs, int *parts)
{
int partAssign[25], allPartAssign[25];
int i, j, part;
memset(partAssign, 0, sizeof(int) * 25);
for (i=0; i < numIDs; i++){
partAssign[GIDs[i]-1] = parts[i];
}
#ifdef MPICPP
MPI::COMM_WORLD.Reduce(partAssign, allPartAssign, 25, MPI::INT, MPI::MAX, 0);
#else
MPI_Reduce(partAssign, allPartAssign, 25, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD);
#endif
if (myProc == 0){
for (i=20; i >= 0; i-=5){
for (j=0; j < 5; j++){
part = allPartAssign[i + j];
if (j < 4)
printf("%d-----",part);
else
printf("%d\n",part);
}
if (i > 0)
printf("| | | | |\n");
}
printf("\n");
}
}
//
// Proc 0 reads the objects in the input file and divides them across processes
//
void read_input_objects(int myRank, int numProcs, const char *fname, objectCollection &myData)
{
int val, nobj, remainingObj;
int obj_ack_tag = 5, obj_count_tag = 10, obj_id_tag = 15;
#ifdef MPICPP
MPI::Status status;
#else
MPI_Status status;
#endif
if (myRank == 0){
char *buf = new char [512];
FILE *fp = fopen(fname, "r");
int num = get_next_line(fp, buf, 512);
if (num == 0) input_file_error(numProcs, obj_count_tag, 1);
num = sscanf(buf, "%d", &val);
myData.set_num_global_objects(val);
if (num != 1) input_file_error(numProcs, obj_count_tag, 1);
if (numProcs > 1){
nobj = myData.get_num_global_objects() / 2;
remainingObj = myData.get_num_global_objects() - nobj;
}
else{
nobj = myData.get_num_global_objects();
remainingObj = 0;
}
int *mygids = new int [nobj];
myData.set_num_my_objects(nobj);
myData.set_my_global_ids(mygids);
for (int i=0; i < nobj; i++){
num = get_next_line(fp, buf, 512);
if (num == 0) input_file_error(numProcs, obj_count_tag, 1);
num = sscanf(buf, "%d", &val);
if (num != 1) input_file_error(numProcs, obj_count_tag, 1);
mygids[i] = val;
}
int *gids = new int [nobj + 1];
int ack = 0;
for (int i=1; i < numProcs; i++){
if (remainingObj > 1){
nobj = remainingObj / 2;
remainingObj -= nobj;
}
else if (remainingObj == 1){
nobj = 1;
remainingObj = 0;
}
else{
nobj = 0;
}
if ((i == numProcs - 1) && (remainingObj > 0))
nobj += remainingObj;
if (nobj > 0){
for (int j=0; j < nobj; j++){
num = get_next_line(fp, buf, 512);
if (num == 0) input_file_error(numProcs, obj_count_tag, i);
num = sscanf(buf, "%d", &val);
if (num != 1) input_file_error(numProcs, obj_count_tag, i);
gids[j] = val;;
}
}
#ifdef MPICPP
MPI::COMM_WORLD.Send(&nobj, 1, MPI::INT, i, obj_count_tag);
MPI::COMM_WORLD.Recv(&ack, 1, MPI::INT, i, obj_ack_tag, status);
#else
MPI_Send(&nobj, 1, MPI_INT, i, obj_count_tag, MPI_COMM_WORLD);
MPI_Recv(&ack, 1, MPI_INT, i, obj_ack_tag, MPI_COMM_WORLD, &status);
#endif
if (nobj > 0)
MPI_Send(gids, nobj, MPI_INT, i, obj_id_tag, MPI_COMM_WORLD);
}
delete [] gids;
delete [] buf;
fclose(fp);
/* signal all procs it is OK to go on */
ack = 0;
for (int i=1; i < numProcs; i++){
#ifdef MPICPP
MPI::COMM_WORLD.Send(&ack, 1, MPI::INT, i, 0);
#else
MPI_Send(&ack, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
#endif
}
}
else{
#ifdef MPICPP
MPI::COMM_WORLD.Recv(&val, 1, MPI::INT, 0, obj_count_tag, status);
#else
MPI_Recv(&val, 1, MPI_INT, 0, obj_count_tag, MPI_COMM_WORLD, &status);
#endif
myData.set_num_my_objects(val);
int ack = 0;
if (myData.get_num_my_objects() > 0){
int *mygids = new int [myData.get_num_my_objects()];
#ifdef MPICPP
MPI::COMM_WORLD.Send(&ack, 1, MPI::INT, 0, obj_ack_tag);
MPI::COMM_WORLD.Recv(mygids, myData.get_num_my_objects(), MPI::INT, 0,
obj_id_tag, status);
#else
MPI_Send(&ack, 1, MPI_INT, 0, obj_ack_tag, MPI_COMM_WORLD);
MPI_Recv(mygids, myData.get_num_my_objects(), MPI_INT, 0,
obj_id_tag, MPI_COMM_WORLD, &status);
#endif
myData.set_my_global_ids(mygids);
}
else if (myData.get_num_my_objects() == 0){
#ifdef MPICPP
MPI::COMM_WORLD.Send(&ack, 1, MPI::INT, 0, obj_ack_tag);
#else
MPI_Send(&ack, 1, MPI_INT, 0, obj_ack_tag, MPI_COMM_WORLD);
#endif
}
else{
MPIExit();
exit(1);
}
#ifdef MPICPP
MPI::COMM_WORLD.Recv(&ack, 1, MPI::INT, 0, 0, status);
#else
MPI_Recv(&ack, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
#endif
if (ack < 0){
MPIExit();
exit(1);
}
}
}

View File

@ -0,0 +1,48 @@
##
## This simple structure is used by many of the nightly Zoltan tests.
## It can be interpreted as a mesh, a graph, a hypergraph, or simply
## as 25 objects to be partitioned.
##
## 21----22----23----24---25
## | | | | |
## 16----17----18----19---20
## | | | | |
## 11----12----13----14---15
## | | | | |
## 6-----7-----8-----9----10
## | | | | |
## 1-----2-----3-----4----5
##
## Regarded as a collection of objects, we have objects 1 through 25.
##
## Number of objects:
25
## Global ID for each object
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

View File

@ -0,0 +1,13 @@
TRIBITS_ADD_EXECUTABLE_AND_TEST(
simpleRCB_f90
SOURCES simpleRCB.f90 zoltanRCBmod.f90 mpi_h.f
ARGS
COMM mpi
NUM_MPI_PROCS 1-4
)
TRIBITS_COPY_FILES_TO_BINARY_DIR(FortranExamplesCopyFiles
SOURCE_FILES mesh.txt
)

View File

@ -0,0 +1,31 @@
##
## a basic makefile to build examples
##
BLD=../../Obj_autotools/
ZOLTAN_INCLUDE=-I. -I$(BLD)/src
FC=mpif90
FCFLAGS =$(ID_TYPE_FLAG)
EXAMPLE_NAMES= simpleRCB
all: $(EXAMPLE_NAMES)
mpi_h.mod:
$(FC) $(FCFLAGS) -c mpi_h.f
zoltanRCBex.mod: mpi_h.mod
$(FC) $(FCFLAGS) \
$(TPL_INCLUDE) $(ZOLTAN_INCLUDE) \
-c zoltanRCBmod.f90
simpleRCB: mpi_h.mod zoltanRCBex.mod
$(FC) $(FCFLAGS) $(TPL_LIB_DIR) \
$(TPL_INCLUDE) $(ZOLTAN_INCLUDE) \
-o $@ simpleRCB.f90 zoltanRCBmod.o mpi_h.o $(BLD)/src/libzoltan.a $(TPL_LIBS) -lm
clean:
@rm -rf $(EXAMPLE_NAMES) *.mod

View File

@ -0,0 +1,37 @@
36
1 0 0
2 0 1
3 0 2
4 0 3
5 0 4
6 0 5
7 1 0
8 1 1
9 1 2
10 1 3
11 1 4
12 1 5
13 2 0
14 2 1
15 2 2
16 2 3
17 2 4
18 2 5
19 3 0
20 3 1
21 3 2
22 3 3
23 3 4
24 3 5
25 4 0
26 4 1
27 4 2
28 4 3
29 4 4
30 4 5
31 5 0
32 5 1
33 5 2
34 5 3
35 5 4
36 5 5

View File

@ -0,0 +1,59 @@
!!
!! @HEADER
!!
!!!!**********************************************************************
!!
!! Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
!! Copyright 2012 Sandia Corporation
!!
!! Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
!! the U.S. Government retains certain rights in this software.
!!
!! Redistribution and use in source and binary forms, with or without
!! modification, are permitted provided that the following conditions are
!! met:
!!
!! 1. Redistributions of source code must retain the above copyright
!! notice, this list of conditions and the following disclaimer.
!!
!! 2. Redistributions in binary form must reproduce the above copyright
!! notice, this list of conditions and the following disclaimer in the
!! documentation and/or other materials provided with the distribution.
!!
!! 3. Neither the name of the Corporation nor the names of the
!! contributors may be used to endorse or promote products derived from
!! this software without specific prior written permission.
!!
!! THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
!! EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
!! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
!! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
!! CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
!! EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
!! PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
!! PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
!! LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
!! NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
!! SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
!!
!! Questions? Contact Karen Devine kddevin@sandia.gov
!! Erik Boman egboman@sandia.gov
!!
!!!!**********************************************************************
!!
!! @HEADER
!!
!--------------------------------------------------------------------------
! Purpose: Provide the MPI include file as a module.
!--------------------------------------------------------------------------
! Author(s): William F. Mitchell
!--------------------------------------------------------------------------
!--------------------------------------------------------------------------
! Revision History:
! 2 September 1999: Date of creation.
!--------------------------------------------------------------------------
module mpi_h
include "mpif.h"
end module mpi_h

View File

@ -0,0 +1,271 @@
!!
!! @HEADER
!!
!!!!**********************************************************************
!!
!! Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
!! Copyright 2012 Sandia Corporation
!!
!! Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
!! the U.S. Government retains certain rights in this software.
!!
!! Redistribution and use in source and binary forms, with or without
!! modification, are permitted provided that the following conditions are
!! met:
!!
!! 1. Redistributions of source code must retain the above copyright
!! notice, this list of conditions and the following disclaimer.
!!
!! 2. Redistributions in binary form must reproduce the above copyright
!! notice, this list of conditions and the following disclaimer in the
!! documentation and/or other materials provided with the distribution.
!!
!! 3. Neither the name of the Corporation nor the names of the
!! contributors may be used to endorse or promote products derived from
!! this software without specific prior written permission.
!!
!! THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
!! EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
!! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
!! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
!! CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
!! EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
!! PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
!! PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
!! LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
!! NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
!! SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
!!
!! Questions? Contact Karen Devine kddevin@sandia.gov
!! Erik Boman egboman@sandia.gov
!!
!!!!**********************************************************************
!!
!! @HEADER
!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! //
!! File: driver.cc //
!! Project: Local HSFC Ordering //
!! Author: Michael Wolf //
!! Date Started: 11/02/2009 //
!! //
!! Description: //
!! File tests local HSFC ordering for simple test problem //
!! //
!! $Id: driver.cc 11 2009-11-10 00:15:18Z mmwolf $ //
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
program exampleRCB
use mpi_h
use zoltan
use zoltanRCBex
implicit none
integer(Zoltan_INT) :: error
real(Zoltan_FLOAT) :: version
!!! numGlobObjs, numLocObjs, GIDs, xcoords, ycoords defined in zoltanRCBex module
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
interface
subroutine readInputObjects(fname,numGlobObjs,numLocObjs,GIDs,xs,ys)
character (len=*) :: fname
integer :: numGlobObjs, numLocObjs
integer, allocatable :: GIDs(:)
real, allocatable :: xs(:), ys(:)
end subroutine readInputObjects
end interface
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! Body of program
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
call MPI_Init(error)
error = Zoltan_Initialize(version)
call readInputObjects("mesh.txt",numGlobObjs,numLocObjs,GIDs,xcoords,ycoords)
call partitionMeshWithRCB()
call visualizePartition()
deallocate(GIDs)
deallocate(xcoords,ycoords)
!! function in zoltanRCBex module that cleans up Zoltan data structures
call zoltanCleanUp()
call MPI_Finalize(error)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end program exampleRCB
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine readInputObjects(fname, numGlobObjs, numLocObjs,GIDs,xcoords,ycoords)
use mpi_h
implicit none
character (len=*) :: fname
integer :: numGlobObjs, numLocObjs
integer, allocatable :: GIDs(:)
real, allocatable :: xcoords(:), ycoords(:)
! Local declarations
integer :: fnum = 2, i, currIndx
integer :: myRank, numProcs, mpi_ierr
integer :: tmpGID
real :: tmpX, tmpY
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
call MPI_Comm_rank(MPI_COMM_WORLD, myrank, mpi_ierr)
call MPI_Comm_size(MPI_COMM_WORLD, numProcs, mpi_ierr)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! Scan data to determine # local objects
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
open(unit = fnum, file = fname)
read(fnum,*) numGlobObjs
numLocObjs=0
do i = 1, numGlobObjs, 1
read(fnum,*) tmpGID, tmpX, tmpY
!! assumes gids start at 1, gives round robin initial distribution
if ( MOD(tmpGID-1,numProcs) == myRank) then
numLocObjs = numLocObjs + 1
end if
end do
close(fnum)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! Allocate data for my part of mesh
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
allocate(GIDs(numLocObjs))
allocate(xcoords(numLocObjs))
allocate(ycoords(numLocObjs))
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! Fill data for my part of mesh
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
open(unit = fnum, file = fname)
read(fnum,*) numGlobObjs
currIndx = 1
do i = 1, numGlobObjs, 1
read(fnum,*) tmpGID, tmpX, tmpY
!! assumes gids start at 1, gives round robin initial distribution
if ( MOD(tmpGID-1,numProcs) == myRank) then
GIDs(currIndx) = tmpGID
xcoords(currIndx) = tmpX
ycoords(currIndx) = tmpY
currIndx = currIndx + 1
end if
end do
close(fnum)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end subroutine readInputObjects
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! Works for this specific 6x6 mesh
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine showSimpleMeshPartitions(myProc, numIDs, GIDs, parts)
use mpi_h
implicit none
integer :: myProc, numIDs
integer :: GIDs(*), parts(*)
!! Local variables
integer :: partAssign(36)
integer :: allPartAssign(36)
integer :: i, j, part, mpi_ierr
integer :: partRow(6)
data partAssign/ 36 * 0/
do i = 1, numIDs, 1
partAssign(GIDs(i)) = parts(i);
end do
call MPI_Reduce(partAssign, allPartAssign, 36, MPI_INTEGER, MPI_MAX, 0, MPI_COMM_WORLD, mpi_ierr);
if (myProc == 0) then
do i=30, 0, -6
do j = 1, 6, 1
partRow(j) = allPartAssign(i+j);
end do
write(*,'(I1,A,I1,A,I1,A,I1,A,I1,A,I1)') partRow(1), '-----', partRow(2), '-----', partRow(3), '-----', &
partRow(4), '-----', partRow(5), '-----', partRow(6)
if (i > 0) then
write(*,'(A)') '| | | | | |'
end if
end do
write(*,*)
end if
end subroutine showSimpleMeshPartitions
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine visualizePartition()
use mpi_h
use zoltanRCBex
implicit none
!! Variables defined in zoltanRCBex module:
!! numLocObjs, GIDs, numExport, exportLocalGids, exportToPart
!! local variables
integer :: parts(numLocObjs)
integer :: myrank, i, error
call MPI_Comm_rank(MPI_COMM_WORLD, myrank, error)
do i=1, numLocObjs, 1
parts(i) = myRank;
end do
if (myRank== 0) then
write (*,*) 'Mesh part assignments before calling Zoltan'
end if
call showSimpleMeshPartitions(myRank, numLocObjs, GIDs, parts);
do i=1, numExport, 1
parts(exportLocalGids(i)) = exportToPart(i)
end do
if (myRank == 0) then
write (*,*) 'Mesh part assignments after calling Zoltan'
end if
call showSimpleMeshPartitions(myRank, numLocObjs, GIDs, parts)
end subroutine visualizePartition
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

View File

@ -0,0 +1,262 @@
!!
!! @HEADER
!!
!!!!**********************************************************************
!!
!! Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
!! Copyright 2012 Sandia Corporation
!!
!! Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
!! the U.S. Government retains certain rights in this software.
!!
!! Redistribution and use in source and binary forms, with or without
!! modification, are permitted provided that the following conditions are
!! met:
!!
!! 1. Redistributions of source code must retain the above copyright
!! notice, this list of conditions and the following disclaimer.
!!
!! 2. Redistributions in binary form must reproduce the above copyright
!! notice, this list of conditions and the following disclaimer in the
!! documentation and/or other materials provided with the distribution.
!!
!! 3. Neither the name of the Corporation nor the names of the
!! contributors may be used to endorse or promote products derived from
!! this software without specific prior written permission.
!!
!! THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
!! EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
!! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
!! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
!! CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
!! EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
!! PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
!! PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
!! LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
!! NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
!! SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
!!
!! Questions? Contact Karen Devine kddevin@sandia.gov
!! Erik Boman egboman@sandia.gov
!!
!!!!**********************************************************************
!!
!! @HEADER
!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! //
!! File: driver.cc //
!! Project: Local HSFC Ordering //
!! Author: Michael Wolf //
!! Date Started: 11/02/2009 //
!! //
!! Description: //
!! File tests local HSFC ordering for simple test problem //
!! //
!! $Id: driver.cc 11 2009-11-10 00:15:18Z mmwolf $ //
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
module zoltanRCBex
use mpi_h
use zoltan
implicit none
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! Mesh data for RCB
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer :: numGlobObjs, numLocObjs
integer(ZOLTAN_INT), dimension(:), allocatable :: GIDs
real, dimension(:), allocatable :: xcoords, ycoords
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! Zoltan data to store in module
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
LOGICAL :: changes
INTEGER(Zoltan_INT) :: numGidEntries, numLidEntries
INTEGER(Zoltan_INT) :: numImport, numExport
INTEGER(Zoltan_INT), POINTER, DIMENSION(:) :: importGlobalGids, exportGlobalGids
INTEGER(Zoltan_INT), POINTER, DIMENSION(:) :: importLocalGids, exportLocalGids
INTEGER(Zoltan_INT), POINTER, DIMENSION(:) :: importProcs, exportProcs
INTEGER(Zoltan_INT), POINTER, DIMENSION(:) :: importToPart, exportToPart
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
contains
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine partitionMeshWithRCB()
use zoltan
use mpi_h
implicit none
!!!!!!!!!!!!!!!!!!!!!!!
!! local variables
!!!!!!!!!!!!!!!!!!!!!!!
type(Zoltan_Struct), pointer :: zz_obj
integer(ZOLTAN_INT) :: ierr
!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! Body of subroutine
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
nullify(zz_obj)
zz_obj => Zoltan_Create(MPI_COMM_WORLD)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! General Zoltan Parameters
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ierr = Zoltan_Set_Param(zz_obj, "LB_METHOD", "RCB")
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! register query functions
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ierr = Zoltan_Set_Fn(zz_obj, ZOLTAN_NUM_OBJ_FN_TYPE,zoltNumObjs)
ierr = Zoltan_Set_Fn(zz_obj, ZOLTAN_OBJ_LIST_FN_TYPE,zoltGetObjs)
ierr = Zoltan_Set_Fn(zz_obj, ZOLTAN_NUM_GEOM_FN_TYPE,zoltNumGeom)
ierr = Zoltan_Set_Fn(zz_obj, ZOLTAN_GEOM_FN_TYPE, zoltGeom)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! Use Zoltan to partition the vertices in the simple mesh.
!!
!! Params:
!! zz_obj -- input (all remaining fields are output)
!! changes -- 1 if partition was changed, 0 otherwise
!! numGidEntries -- Number of integers used for a global ID
!! numLidEntries -- Number of integers used for a local ID
!! numImport -- Number of vertices to be sent to me
!! importGlobalGids -- Global IDs of vertices to be sent to me
!! importLocalGids -- Local IDs of vertices to be sent to me
!! importProcs -- Process rank for source of each incoming vertex
!! importToPart -- New part for each incoming vertex
!! numExport -- Number of vertices I must send to other processes
!! exportGlobalGids -- Global IDs of the vertices I must send
!! exportLocalGids -- Local IDs of the vertices I must send
!! exportProcs -- Process to which I send each of the vertices
!! exportToPart -- Part to which each vertex will belong
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ierr = Zoltan_LB_Partition(zz_obj, changes, numGidEntries, numLidEntries, &
numImport, importGlobalGids, importLocalGids, importProcs, importToPart, &
numExport, exportGlobalGids, exportLocalGids, exportProcs, exportToPart)
call Zoltan_Destroy(zz_obj)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end subroutine partitionMeshWithRCB
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! Frees arrays allocated by Zoltan_LB_Partition
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine zoltanCleanup()
use zoltan
implicit none
integer :: error
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
error = Zoltan_LB_Free_Part(importGlobalGids, importLocalGids, importProcs, importToPart)
error = Zoltan_LB_Free_Part(exportGlobalGids, exportLocalGids, exportProcs, exportToPart)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end subroutine zoltanCleanup
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! User defined query function to register with Zoltan
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer function zoltNumObjs(data, ierr)
use zoltan
implicit none
! Local declarations
INTEGER(Zoltan_INT), intent(in) :: data(*)
integer(ZOLTAN_INT), intent(out) :: ierr
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
zoltNumObjs = numLocObjs
ierr = ZOLTAN_OK
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end function zoltNumObjs
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! User defined query function to register with Zoltan
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine zoltGetObjs (data, num_gid_entries, num_lid_entries, global_ids, &
local_ids, wgt_dim, obj_wgts, ierr)
use zoltan
implicit none
integer(ZOLTAN_INT), intent(in) :: data(*)
integer(ZOLTAN_INT), intent(in) :: num_gid_entries
integer(ZOLTAN_INT), intent(in) :: num_lid_entries
integer(ZOLTAN_INT), intent(out) :: global_ids(*)
integer(ZOLTAN_INT), intent(out) :: local_ids(*)
integer(ZOLTAN_INT), intent(in) :: wgt_dim
real(ZOLTAN_FLOAT), intent(out) :: obj_wgts(*)
integer(ZOLTAN_INT), intent(out) :: ierr
! local declarations
integer :: i
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
do i= 1, numLocObjs
global_ids(i) = GIDs(i)
local_ids(i) = i
end do
ierr = ZOLTAN_OK
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end subroutine
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! User defined query function to register with Zoltan
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer function zoltNumGeom(data, ierr)
use zoltan
implicit none
integer(ZOLTAN_INT), intent(in) :: data(*)
integer(ZOLTAN_INT) :: ierr
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
zoltNumGeom = 2
ierr = ZOLTAN_OK
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end function zoltNumGeom
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! User defined query function to register with Zoltan
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine zoltGeom(data, num_gid_entries, num_lid_entries, global_id, &
local_id, geom_vec, ierr)
use zoltan
implicit none
integer(ZOLTAN_INT), intent(in) :: data(*)
integer(ZOLTAN_INT), intent(in) :: num_gid_entries
integer(ZOLTAN_INT), intent(in) :: num_lid_entries
integer(ZOLTAN_INT), intent(in) :: global_id
integer(ZOLTAN_INT), intent(in) :: local_id
real(ZOLTAN_DOUBLE), intent(out) :: geom_vec(*)
integer(ZOLTAN_INT), intent(out) :: ierr
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
geom_vec(1) = xcoords(local_id)
geom_vec(2) = ycoords(local_id)
ierr = ZOLTAN_OK
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end subroutine zoltGeom
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end module zoltanRCBex

53
thirdParty/Zoltan/example/Makefile.am vendored Normal file
View File

@ -0,0 +1,53 @@
# @HEADER
#
########################################################################
#
# Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
# Copyright 2012 Sandia Corporation
#
# Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
# the U.S. Government retains certain rights in this software.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the Corporation nor the names of the
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Questions? Contact Karen Devine kddevin@sandia.gov
# Erik Boman egboman@sandia.gov
#
########################################################################
#
# @HEADER
# The following line helps the test harness recover from build errors.
all-local:
if HAVE_ZOLTAN_CPPDRIVER
SUBDIRS = C CPP
else
SUBDIRS = C
endif

628
thirdParty/Zoltan/example/Makefile.in vendored Normal file
View File

@ -0,0 +1,628 @@
# Makefile.in generated by automake 1.11.3 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
# Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
# @HEADER
#
########################################################################
#
# Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
# Copyright 2012 Sandia Corporation
#
# Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
# the U.S. Government retains certain rights in this software.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the Corporation nor the names of the
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Questions? Contact Karen Devine kddevin@sandia.gov
# Erik Boman egboman@sandia.gov
#
########################################################################
#
# @HEADER
# The following line helps the test harness recover from build errors.
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = example
DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/config/ax_f90_module_case.m4 \
$(top_srcdir)/config/ax_f90_module_flag.m4 \
$(top_srcdir)/config/tac_arg_check_mpi.m4 \
$(top_srcdir)/config/tac_arg_enable_export-makefiles.m4 \
$(top_srcdir)/config/tac_arg_enable_feature.m4 \
$(top_srcdir)/config/tac_arg_enable_feature_sub.m4 \
$(top_srcdir)/config/tac_arg_enable_feature_sub_check.m4 \
$(top_srcdir)/config/tac_arg_enable_option.m4 \
$(top_srcdir)/config/tac_arg_with_3pl_sub.m4 \
$(top_srcdir)/config/tac_arg_with_ar.m4 \
$(top_srcdir)/config/tac_arg_with_flags.m4 \
$(top_srcdir)/config/tac_arg_with_incdirs.m4 \
$(top_srcdir)/config/tac_arg_with_libdirs.m4 \
$(top_srcdir)/config/tac_arg_with_libs.m4 \
$(top_srcdir)/config/tac_arg_with_package.m4 \
$(top_srcdir)/config/tac_arg_with_perl.m4 \
$(top_srcdir)/config/wk_fc_get_vendor.m4 \
$(top_srcdir)/config/zac_arg_config_mpi.m4 \
$(top_srcdir)/config/zac_arg_with_id.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/src/include/Zoltan_config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-dvi-recursive install-exec-recursive \
install-html-recursive install-info-recursive \
install-pdf-recursive install-ps-recursive install-recursive \
installcheck-recursive installdirs-recursive pdf-recursive \
ps-recursive uninstall-recursive
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
distdir
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = C CPP
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
sed_rest='s,^[^/]*/*,,'; \
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
sed_butlast='s,/*[^/]*$$,,'; \
while test -n "$$dir1"; do \
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
if test "$$first" != "."; then \
if test "$$first" = ".."; then \
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
else \
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
if test "$$first2" = "$$first"; then \
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
else \
dir2="../$$dir2"; \
fi; \
dir0="$$dir0"/"$$first"; \
fi; \
fi; \
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
done; \
reldir="$$dir2"
ACLOCAL = @ACLOCAL@
ALTERNATE_AR = @ALTERNATE_AR@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EXEEXT = @EXEEXT@
FC = @FC@
FCFLAGS = @FCFLAGS@
FCFLAGS_f = @FCFLAGS_f@
FCFLAGS_f90 = @FCFLAGS_f90@
FCLIBS = @FCLIBS@
FC_MAJOR_VERSION = @FC_MAJOR_VERSION@
FC_MODNAME = @FC_MODNAME@
FC_MODNAME_Q = @FC_MODNAME_Q@
FC_VENDOR = @FC_VENDOR@
FC_VERSION = @FC_VERSION@
FC_VERSION_STRING = @FC_VERSION_STRING@
HAVE_PERL = @HAVE_PERL@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
MPI_CC = @MPI_CC@
MPI_CXX = @MPI_CXX@
MPI_FC = @MPI_FC@
MPI_RECV_LIMIT_FLAG = @MPI_RECV_LIMIT_FLAG@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL_EXE = @PERL_EXE@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_aux_dir = @ac_aux_dir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_FC = @ac_ct_FC@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
@HAVE_ZOLTAN_CPPDRIVER_FALSE@SUBDIRS = C
@HAVE_ZOLTAN_CPPDRIVER_TRUE@SUBDIRS = C CPP
all: all-recursive
.SUFFIXES:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu example/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu example/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
$(RECURSIVE_CLEAN_TARGETS):
@fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d "$(distdir)/$$subdir" \
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|| exit 1; \
fi; \
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
$(am__relativize); \
new_distdir=$$reldir; \
dir1=$$subdir; dir2="$(top_distdir)"; \
$(am__relativize); \
new_top_distdir=$$reldir; \
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
($(am__cd) $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$new_top_distdir" \
distdir="$$new_distdir" \
am__remove_distdir=: \
am__skip_length_check=: \
am__skip_mode_fix=: \
distdir) \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-recursive
all-am: Makefile all-local
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-generic mostlyclean-am
distclean: distclean-recursive
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
html-am:
info: info-recursive
info-am:
install-data-am:
install-dvi: install-dvi-recursive
install-dvi-am:
install-exec-am:
install-html: install-html-recursive
install-html-am:
install-info: install-info-recursive
install-info-am:
install-man:
install-pdf: install-pdf-recursive
install-pdf-am:
install-ps: install-ps-recursive
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am:
.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
install-am install-strip tags-recursive
.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
all all-am all-local check check-am clean clean-generic ctags \
ctags-recursive distclean distclean-generic distclean-tags \
distdir dvi dvi-am html html-am info info-am install \
install-am install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
installdirs-am maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags \
tags-recursive uninstall uninstall-am
all-local:
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

57
thirdParty/Zoltan/example/README vendored Normal file
View File

@ -0,0 +1,57 @@
# @HEADER
#
########################################################################
#
# Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
# Copyright 2012 Sandia Corporation
#
# Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
# the U.S. Government retains certain rights in this software.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the Corporation nor the names of the
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Questions? Contact Karen Devine kddevin@sandia.gov
# Erik Boman egboman@sandia.gov
#
########################################################################
#
# @HEADER
$Id$
Some simple C examples may be found in the "C" directory, and
C++ examples in the "CPP" directory. Edit the classicMakefile found
in those directories to build the examples.
Note that C++ implementations vary widely. If you have trouble
building the CPP examples, try defining or not defining
the MPI_CPP or NAMESPACES_OK values in the tests' source files.
To run an example, launch it on any number of processes as you would
any MPI application:
mpirun -np 4 simpleRCB