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

685
thirdParty/Zoltan/src/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,685 @@
#
# A) Package-specific configuration options
#
ASSERT_DEFINED(${PACKAGE_NAME}_ENABLE_METIS)
SET(HAVE_METIS ${${PACKAGE_NAME}_ENABLE_METIS})
ASSERT_DEFINED(${PACKAGE_NAME}_ENABLE_ParMETIS)
SET(HAVE_PARMETIS ${${PACKAGE_NAME}_ENABLE_ParMETIS})
ASSERT_DEFINED(${PACKAGE_NAME}_ENABLE_PaToH)
SET(HAVE_PATOH ${${PACKAGE_NAME}_ENABLE_PaToH})
ASSERT_DEFINED(${PACKAGE_NAME}_ENABLE_Scotch)
SET(HAVE_SCOTCH ${${PACKAGE_NAME}_ENABLE_Scotch})
ASSERT_DEFINED(${PACKAGE_NAME}_ENABLE_OVIS)
SET(HAVE_OVIS ${${PACKAGE_NAME}_ENABLE_OVIS})
ASSERT_DEFINED(${PACKAGE_NAME}_ENABLE_Zlib)
SET(ZHAVE_GZIP ${${PACKAGE_NAME}_ENABLE_Zlib})
ASSERT_DEFINED(${PACKAGE_NAME}_ENABLE_PURIFY)
SET(HAVE_PURIFY ${${PACKAGE_NAME}_ENABLE_PURIFY})
TRIBITS_CONFIGURE_FILE(${PACKAGE_NAME}_config.h)
#
# B) Define the header and source files (and directories)
#
#
# src
#
SET(HEADERS "")
SET(NOINSTALLHEADERS "")
SET(SOURCES "")
SET(MODULES "")
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
SET(HEADERS ${HEADERS}
${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE_NAME}_config.h
)
#
# src/include
#
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
APPEND_SET(HEADERS
include/lbi_const.h
include/zoltan_align.h
include/zoltan_cpp.h
include/zoltan.h
include/zoltan_types.h
include/zoltan_comm.h
include/zoltan_comm_cpp.h
include/zoltan_timer_cpp.h
include/zoltan_timer.h
include/zoltan_dd.h
Utilities/DDirectory/zoltan_dd_const.h
include/zoltan_dd_cpp.h
include/zoltan_partition_tree.h
include/zoltan_mem.h
include/zoltan_eval.h
)
#
# src/all
#
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/all)
APPEND_SET(NOINSTALLHEADERS
all/all_allo_const.h
)
APPEND_SET(SOURCES
all/all_allo.c
)
#
# src/coloring
#
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/coloring)
APPEND_SET(NOINSTALLHEADERS
coloring/coloring_const.h
coloring/coloring.h
coloring/g2l_hash.h
coloring/bucket.h
)
APPEND_SET(SOURCES
coloring/coloring.c
coloring/color_test.c
coloring/g2l_hash.c
coloring/bucket.c
)
#
# src/graph
#
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/graph)
APPEND_SET(NOINSTALLHEADERS
graph/graph.h
graph/graph_const.h
)
APPEND_SET(SOURCES
graph/graph.c
)
#
# src/ha
#
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/ha)
APPEND_SET(NOINSTALLHEADERS
ha/ha_const.h
ha/ha_ovis.h
)
APPEND_SET(SOURCES
ha/divide_machine.c
ha/get_processor_name.c
ha/ha_ovis.c
)
#
# src/hier
#
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/hier)
APPEND_SET(NOINSTALLHEADERS
hier/hier.h
)
APPEND_SET(SOURCES
hier/hier.c
hier/hier_free_struct.c
)
#
# src/hsfc
#
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/hsfc)
APPEND_SET(NOINSTALLHEADERS
hsfc/hsfc.h
hsfc/hsfc_const.h
hsfc/hsfc_hilbert_const.h
)
APPEND_SET(SOURCES
hsfc/hsfc_box_assign.c
hsfc/hsfc.c
hsfc/hsfc_hilbert.c
hsfc/hsfc_point_assign.c
)
#
# src/lb
#
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/lb)
APPEND_SET(NOINSTALLHEADERS
lb/lb_const.h
lb/lb_init_const.h
)
APPEND_SET(SOURCES
lb/lb_balance.c
lb/lb_box_assign.c
lb/lb_copy.c
lb/lb_eval.c
lb/lb_free.c
lb/lb_init.c
lb/lb_invert.c
lb/lb_migrate.c
lb/lb_part2proc.c
lb/lb_point_assign.c
lb/lb_remap.c
lb/lb_set_fn.c
lb/lb_set_method.c
lb/lb_set_part_sizes.c
)
#
# src/matrix
#
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/matrix)
APPEND_SET(NOINSTALLHEADERS
matrix/zoltan_matrix.h
)
APPEND_SET(SOURCES
matrix/matrix_build.c
matrix/matrix_distribute.c
matrix/matrix_operations.c
matrix/matrix_sym.c
matrix/matrix_utils.c
)
#
# src/order
#
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/order)
APPEND_SET(NOINSTALLHEADERS
order/order_const.h
)
APPEND_SET(SOURCES
order/hsfcOrder.c
order/order.c
order/order_struct.c
order/order_tools.c
order/perm.c
)
IF (${PACKAGE_NAME}_ENABLE_HUND)
APPEND_SET(SOURCES
order/hund.c
)
ENDIF()
#
# src/par
#
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/par)
APPEND_SET(NOINSTALLHEADERS
par/par_average_const.h
par/par_bisect_const.h
par/par_const.h
par/par_median_const.h
par/par_tflops_special_const.h
)
APPEND_SET(SOURCES
par/par_average.c
par/par_bisect.c
par/par_median.c
par/par_median_randomized.c
par/par_stats.c
par/par_sync.c
par/par_tflops_special.c
)
#
# src/params
#
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/params)
APPEND_SET(NOINSTALLHEADERS
params/key_params.h
params/params_const.h
)
APPEND_SET(SOURCES
params/assign_param_vals.c
params/bind_param.c
params/check_param.c
params/free_params.c
params/key_params.c
params/print_params.c
params/set_param.c
)
#
# src/tpls
#
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/tpls)
APPEND_SET(NOINSTALLHEADERS
tpls/third_library_const.h
tpls/third_library.h
tpls/third_library_tools.h
tpls/graph_util.h
)
APPEND_SET(SOURCES
tpls/build_graph.c
tpls/postprocessing.c
tpls/preprocessing.c
tpls/scatter_graph.c
tpls/third_library.c
tpls/verify_graph.c
)
IF (${PACKAGE_NAME}_ENABLE_ParMETIS OR ${PACKAGE_NAME}_ENABLE_METIS)
APPEND_SET(NOINSTALLHEADERS
tpls/parmetis_interface.h
)
APPEND_SET(SOURCES
tpls/parmetis_interface.c
)
ENDIF()
IF (${PACKAGE_NAME}_ENABLE_Scotch)
APPEND_SET(NOINSTALLHEADERS
tpls/scotch_interface.h
)
APPEND_SET(SOURCES
tpls/scotch_interface.c
)
ENDIF()
#
# src/phg
#
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/phg)
APPEND_SET(NOINSTALLHEADERS
phg/phg_comm.h
phg/phg_const.h
phg/phg_distrib.h
phg/phg.h
phg/phg_lookup.h
phg/phg_verbose.h
phg/phg_hypergraph.h
phg/phg_tree.h
phg/phg_util.h
)
APPEND_SET(SOURCES
phg/phg_build.c
phg/phg_build_calls.c
phg/phg.c
phg/phg_lookup.c
phg/phg_verbose.c
phg/phg_coarse.c
phg/phg_comm.c
phg/phg_distrib.c
phg/phg_gather.c
phg/phg_hypergraph.c
phg/phg_match.c
phg/phg_order.c
phg/phg_parkway.c
phg/phg_patoh.c
phg/phg_plot.c
phg/phg_rdivide.c
phg/phg_refinement.c
phg/phg_scale.c
phg/phg_serialpartition.c
phg/phg_tree.c
phg/phg_partition_tree.c
phg/phg_two_ways.c
phg/phg_util.c
phg/phg_Vcycle.c
)
#
# src/rcb
#
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/rcb)
APPEND_SET(NOINSTALLHEADERS
rcb/create_proc_list_const.h
rcb/rcb_const.h
rcb/rcb.h
rcb/rib_const.h
rcb/rib.h
rcb/shared.h
)
APPEND_SET(SOURCES
rcb/box_assign.c
rcb/create_proc_list.c
rcb/inertial1d.c
rcb/inertial2d.c
rcb/inertial3d.c
rcb/point_assign.c
rcb/rcb_box.c
rcb/rcb_partition_tree.c
rcb/rcb.c
rcb/rcb_util.c
rcb/rib.c
rcb/rib_util.c
rcb/shared.c
)
#
# src/reftree
#
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/reftree)
APPEND_SET(NOINSTALLHEADERS
reftree/reftree_const.h
reftree/reftree.h
)
APPEND_SET(SOURCES
reftree/reftree_build.c
reftree/reftree_coarse_path.c
reftree/reftree_hash.c
reftree/reftree_part.c
)
#
# src/simple
#
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/simple)
APPEND_SET(SOURCES
simple/block.c
simple/cyclic.c
simple/random.c
)
APPEND_SET(NOINSTALLHEADERS
simple/simple_const.h
)
#
# src/timer
#
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/timer)
APPEND_SET(NOINSTALLHEADERS
timer/timer_const.h
)
APPEND_SET(SOURCES
timer/timer_params.c
)
#
# src/Utilities
#
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/Utilities/Communication)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/Utilities/DDirectory)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/Utilities/Timer)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/Utilities/shared)
APPEND_SET(NOINSTALLHEADERS
Utilities/Communication/comm.h
Utilities/DDirectory/DD_Memory.h
Utilities/Timer/timer.h
Utilities/shared/zoltan_util.h
Utilities/shared/zoltan_id.h
)
APPEND_SET(SOURCES
Utilities/Communication/comm_exchange_sizes.c
Utilities/Communication/comm_invert_map.c
Utilities/Communication/comm_do.c
Utilities/Communication/comm_do_reverse.c
Utilities/Communication/comm_info.c
Utilities/Communication/comm_create.c
Utilities/Communication/comm_resize.c
Utilities/Communication/comm_sort_ints.c
Utilities/Communication/comm_destroy.c
Utilities/Communication/comm_invert_plan.c
Utilities/Timer/zoltan_timer.c
Utilities/Timer/timer.c
Utilities/DDirectory/DD_Find.c
Utilities/DDirectory/DD_Destroy.c
Utilities/DDirectory/DD_Set_Neighbor_Hash_Fn3.c
Utilities/DDirectory/DD_Remove.c
Utilities/DDirectory/DD_Create.c
Utilities/DDirectory/DD_Update.c
Utilities/DDirectory/DD_Stats.c
Utilities/DDirectory/DD_Hash2.c
Utilities/DDirectory/DD_Memory.c
Utilities/DDirectory/DD_Print.c
Utilities/DDirectory/DD_Set_Neighbor_Hash_Fn2.c
Utilities/DDirectory/DD_Set_Hash_Fn.c
Utilities/DDirectory/DD_Set_Neighbor_Hash_Fn1.c
Utilities/Memory/mem.c
Utilities/shared/zoltan_align.c
Utilities/shared/zoltan_id.c
)
#
# src/zz
#
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/zz)
APPEND_SET(NOINSTALLHEADERS
zz/zz_const.h
zz/zz_hash.h
zz/zz_heap.h
zz/zz_id_const.h
zz/zz_rand.h
zz/zz_sort.h
zz/zz_util_const.h
)
APPEND_SET(SOURCES
zz/zz_coord.c
zz/zz_gen_files.c
zz/zz_hash.c
zz/zz_map.c
zz/zz_heap.c
zz/zz_init.c
zz/zz_obj_list.c
zz/zz_rand.c
zz/zz_set_fn.c
zz/zz_sort.c
zz/zz_struct.c
zz/zz_back_trace.c
zz/zz_util.c
)
#
# src/fort
#
IF(${PROJECT_NAME}_ENABLE_Fortran AND BUILD_ZOLTAN_F90_INTERFACE)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/fort)
APPEND_SET(NOINSTALLHEADERS
fort/cwrap_fmangle.h
fort/set_borderobjlist.fn
fort/set_borderobjlist.if
fort/set_childlist.fn
fort/set_childlist.if
fort/set_childweight.fn
fort/set_childweight.if
fort/set_coarseobjlist.fn
fort/set_coarseobjlist.if
fort/set_edgelist.fn
fort/set_edgelist.if
fort/set_edgelistmulti.fn
fort/set_edgelistmulti.if
fort/set_firstborderobj.fn
fort/set_firstborderobj.if
fort/set_firstcoarseobj.fn
fort/set_firstcoarseobj.if
fort/set_firstobj.fn
fort/set_firstobj.if
fort/set_fixedobjlist.fn
fort/set_fixedobjlist.if
fort/set_geom.fn
fort/set_geom.if
fort/set_geommulti.fn
fort/set_geommulti.if
fort/set_hgcs.fn
fort/set_hgcs.if
fort/set_hgedgeweights.fn
fort/set_hgedgeweights.if
fort/set_hgsizecs.fn
fort/set_hgsizecs.if
fort/set_hgsizeedgeweights.fn
fort/set_hgsizeedgeweights.if
fort/set_hiermethod.fn
fort/set_hiermethod.if
fort/set_hiernumlevels.fn
fort/set_hiernumlevels.if
fort/set_hierpartition.fn
fort/set_hierpartition.if
fort/set_midmigrate.fn
fort/set_midmigrate.if
fort/set_midmigratepp.fn
fort/set_midmigratepp.if
fort/set_nextborderobj.fn
fort/set_nextborderobj.if
fort/set_nextcoarseobj.fn
fort/set_nextcoarseobj.if
fort/set_nextobj.fn
fort/set_nextobj.if
fort/set_numborderobj.fn
fort/set_numborderobj.if
fort/set_numchild.fn
fort/set_numchild.if
fort/set_numcoarseobj.fn
fort/set_numcoarseobj.if
fort/set_numedges.fn
fort/set_numedges.if
fort/set_numedgesmulti.fn
fort/set_numedgesmulti.if
fort/set_numfixedobj.fn
fort/set_numfixedobj.if
fort/set_numgeom.fn
fort/set_numgeom.if
fort/set_numobj.fn
fort/set_numobj.if
fort/set_objlist.fn
fort/set_objlist.if
fort/set_objsize.fn
fort/set_objsize.if
fort/set_objsizemulti.fn
fort/set_objsizemulti.if
fort/set_packobj.fn
fort/set_packobj.if
fort/set_packobjmulti.fn
fort/set_packobjmulti.if
fort/set_partition.fn
fort/set_partition.if
fort/set_partitionmulti.fn
fort/set_partitionmulti.if
fort/set_postmigrate.fn
fort/set_postmigrate.if
fort/set_postmigratepp.fn
fort/set_postmigratepp.if
fort/set_premigrate.fn
fort/set_premigrate.if
fort/set_premigratepp.fn
fort/set_premigratepp.if
fort/set_unpackobj.fn
fort/set_unpackobj.if
fort/set_unpackobjmulti.fn
fort/set_unpackobjmulti.if
)
APPEND_SET(SOURCES
fort/ztypes.f90
fort/zoltan_user_data.f90
fort/fwrap.f90
fort/cwrap.c
)
# FILE(GLOB MODULES ${CMAKE_CURRENT_BINARY_DIR}/*.mod)
# MESSAGE("KDDKDD MODULES " ${MODULES})
APPEND_SET(MODULES
${CMAKE_CURRENT_BINARY_DIR}/zoltan.mod
${CMAKE_CURRENT_BINARY_DIR}/zoltan_types.mod
${CMAKE_CURRENT_BINARY_DIR}/zoltan_user_data.mod
)
ENDIF()
#
# C) Define the targets for package's library(s)
#
IF (NOT TPL_ENABLE_MPI)
SET(DEPLIBS simpi)
ENDIF()
IF(NOT MSVC)
# Add libm linking for ceil, floor and such.
LIST(APPEND IMPORTEDLIBS m)
ENDIF()
TRIBITS_ADD_LIBRARY(
zoltan
HEADERS ${HEADERS}
NOINSTALLHEADERS ${NOINSTALLHEADERS}
SOURCES ${SOURCES}
DEPLIBS ${DEPLIBS}
IMPORTEDLIBS ${IMPORTEDLIBS}
)
INSTALL(FILES ${MODULES} DESTINATION ${CMAKE_INSTALL_PREFIX}/include)

800
thirdParty/Zoltan/src/Makefile.am vendored Normal file
View File

@ -0,0 +1,800 @@
# @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:
@echo ""
@echo "Trilinos package Zoltan subdirectory src built successfully."
@echo ""
ALL_H = \
$(srcdir)/all/all_allo_const.h
ALL = \
$(srcdir)/all/all_allo.c
COLORING_H = \
$(srcdir)/coloring/coloring_const.h \
$(srcdir)/coloring/coloring.h \
$(srcdir)/coloring/bucket.h \
$(srcdir)/coloring/g2l_hash.h
COLORING = \
$(srcdir)/coloring/coloring.c \
$(srcdir)/coloring/color_test.c \
$(srcdir)/coloring/bucket.c \
$(srcdir)/coloring/g2l_hash.c
GRAPH_H = \
$(srcdir)/graph/graph_const.h \
$(srcdir)/graph/graph.h
GRAPH = \
$(srcdir)/graph/graph.c
HA_H = \
$(srcdir)/ha/ha_const.h \
$(srcdir)/ha/ha_ovis.h
HA = \
$(srcdir)/ha/divide_machine.c \
$(srcdir)/ha/get_processor_name.c \
$(srcdir)/ha/ha_ovis.c
HIER_H = \
$(srcdir)/hier/hier.h
HIER = \
$(srcdir)/hier/hier.c \
$(srcdir)/hier/hier_free_struct.c
HSFC_H = \
$(srcdir)/hsfc/hsfc.h \
$(srcdir)/hsfc/hsfc_const.h \
$(srcdir)/hsfc/hsfc_hilbert_const.h
HSFC = \
$(srcdir)/hsfc/hsfc_box_assign.c \
$(srcdir)/hsfc/hsfc.c \
$(srcdir)/hsfc/hsfc_hilbert.c \
$(srcdir)/hsfc/hsfc_point_assign.c
INCLUDE_H = \
$(srcdir)/include/lbi_const.h \
$(srcdir)/include/zoltan_align.h \
$(srcdir)/include/zoltan_cpp.h \
$(srcdir)/include/zoltan.h \
$(srcdir)/include/zoltan_eval.h \
$(srcdir)/include/zoltan_types.h \
$(srcdir)/include/zoltan_comm.h \
$(srcdir)/include/zoltan_comm_cpp.h \
$(srcdir)/include/zoltan_timer_cpp.h \
$(srcdir)/include/zoltan_timer.h \
$(srcdir)/include/zoltan_dd.h \
$(srcdir)/include/zoltan_dd_cpp.h \
$(srcdir)/include/zoltan_partition_tree.h \
$(srcdir)/include/zoltan_mem.h
# $(srcdir)/Zoltan_ConfigDefs.h
LB_H = \
$(srcdir)/lb/lb_const.h \
$(srcdir)/lb/lb_init_const.h
LB = \
$(srcdir)/lb/lb_balance.c \
$(srcdir)/lb/lb_box_assign.c \
$(srcdir)/lb/lb_copy.c \
$(srcdir)/lb/lb_eval.c \
$(srcdir)/lb/lb_free.c \
$(srcdir)/lb/lb_init.c \
$(srcdir)/lb/lb_invert.c \
$(srcdir)/lb/lb_migrate.c \
$(srcdir)/lb/lb_part2proc.c \
$(srcdir)/lb/lb_point_assign.c \
$(srcdir)/lb/lb_remap.c \
$(srcdir)/lb/lb_set_fn.c \
$(srcdir)/lb/lb_set_method.c \
$(srcdir)/lb/lb_set_part_sizes.c
MATRIX_H = \
$(srcdir)/matrix/matrix.h
MATRIX = \
$(srcdir)/matrix/matrix_build.c \
$(srcdir)/matrix/matrix_distribute.c \
$(srcdir)/matrix/matrix_operations.c \
$(srcdir)/matrix/matrix_sym.c \
$(srcdir)/matrix/matrix_utils.c
ORDER_H = \
$(srcdir)/order/order_const.h \
$(srcdir)/order/hsfcOrder.h
ORDER = \
$(srcdir)/order/order.c \
$(srcdir)/order/order_struct.c \
$(srcdir)/order/order_tools.c \
$(srcdir)/order/hsfcOrder.c \
$(srcdir)/order/perm.c
PAR_H = \
$(srcdir)/par/par_average_const.h \
$(srcdir)/par/par_bisect_const.h \
$(srcdir)/par/par_const.h \
$(srcdir)/par/par_median_const.h \
$(srcdir)/par/par_tflops_special_const.h
PAR = \
$(srcdir)/par/par_average.c \
$(srcdir)/par/par_bisect.c \
$(srcdir)/par/par_median.c \
$(srcdir)/par/par_median_randomized.c \
$(srcdir)/par/par_stats.c \
$(srcdir)/par/par_sync.c \
$(srcdir)/par/par_tflops_special.c
PARAMS_H = \
$(srcdir)/params/key_params.h \
$(srcdir)/params/params_const.h
PARAMS = \
$(srcdir)/params/assign_param_vals.c \
$(srcdir)/params/bind_param.c \
$(srcdir)/params/check_param.c \
$(srcdir)/params/free_params.c \
$(srcdir)/params/key_params.c \
$(srcdir)/params/print_params.c \
$(srcdir)/params/set_param.c
TPLS_H = \
$(srcdir)/tpls/third_library_const.h \
$(srcdir)/tpls/third_library.h \
$(srcdir)/tpls/third_library_tools.h \
$(srcdir)/tpls/graph_util.h
TPLS = \
$(srcdir)/tpls/build_graph.c \
$(srcdir)/tpls/postprocessing.c \
$(srcdir)/tpls/preprocessing.c \
$(srcdir)/tpls/scatter_graph.c \
$(srcdir)/tpls/third_library.c \
$(srcdir)/tpls/verify_graph.c
EXTRA_PARMETIS_INTERFACE_H = \
$(srcdir)/tpls/parmetis_interface.h
EXTRA_PARMETIS_INTERFACE = \
$(srcdir)/tpls/parmetis_interface.c
if BUILD_PARMETIS
PARMETIS_INTERFACE_H = $(EXTRA_PARMETIS_INTERFACE_H)
PARMETIS_INTERFACE = $(EXTRA_PARMETIS_INTERFACE)
else
PARMETIS_INTERFACE_H =
PARMETIS_INTERFACE =
endif
EXTRA_SCOTCH_INTERFACE_H = \
$(srcdir)/tpls/scotch_interface.h
EXTRA_SCOTCH_INTERFACE = \
$(srcdir)/tpls/scotch_interface.c
if BUILD_SCOTCH
SCOTCH_INTERFACE_H = $(EXTRA_SCOTCH_INTERFACE_H)
SCOTCH_INTERFACE = $(EXTRA_SCOTCH_INTERFACE)
else
SCOTCH_INTERFACE_H =
SCOTCH_INTERFACE =
endif
PHG_H = \
$(srcdir)/phg/phg_comm.h \
$(srcdir)/phg/phg_const.h \
$(srcdir)/phg/phg_distrib.h \
$(srcdir)/phg/phg.h \
$(srcdir)/phg/phg_lookup.h \
$(srcdir)/phg/phg_verbose.h \
$(srcdir)/phg/phg_hypergraph.h \
$(srcdir)/phg/phg_tree.h \
$(srcdir)/phg/phg_util.h
PHG = \
$(srcdir)/phg/phg_build.c \
$(srcdir)/phg/phg_build_calls.c \
$(srcdir)/phg/phg.c \
$(srcdir)/phg/phg_lookup.c \
$(srcdir)/phg/phg_verbose.c \
$(srcdir)/phg/phg_coarse.c \
$(srcdir)/phg/phg_comm.c \
$(srcdir)/phg/phg_distrib.c \
$(srcdir)/phg/phg_gather.c \
$(srcdir)/phg/phg_hypergraph.c \
$(srcdir)/phg/phg_match.c \
$(srcdir)/phg/phg_order.c \
$(srcdir)/phg/phg_parkway.c \
$(srcdir)/phg/phg_patoh.c \
$(srcdir)/phg/phg_plot.c \
$(srcdir)/phg/phg_rdivide.c \
$(srcdir)/phg/phg_refinement.c \
$(srcdir)/phg/phg_scale.c \
$(srcdir)/phg/phg_serialpartition.c \
$(srcdir)/phg/phg_util.c \
$(srcdir)/phg/phg_tree.c \
$(srcdir)/phg/phg_partition_tree.c \
$(srcdir)/phg/phg_Vcycle.c
RCB_H = \
$(srcdir)/rcb/create_proc_list_const.h \
$(srcdir)/rcb/rcb_const.h \
$(srcdir)/rcb/rcb.h \
$(srcdir)/rcb/rib_const.h \
$(srcdir)/rcb/rib.h \
$(srcdir)/rcb/shared.h
RCB = \
$(srcdir)/rcb/box_assign.c \
$(srcdir)/rcb/create_proc_list.c \
$(srcdir)/rcb/inertial1d.c \
$(srcdir)/rcb/inertial2d.c \
$(srcdir)/rcb/inertial3d.c \
$(srcdir)/rcb/point_assign.c \
$(srcdir)/rcb/rcb_box.c \
$(srcdir)/rcb/rcb_partition_tree.c \
$(srcdir)/rcb/rcb.c \
$(srcdir)/rcb/rcb_util.c \
$(srcdir)/rcb/rib.c \
$(srcdir)/rcb/rib_util.c \
$(srcdir)/rcb/shared.c
REFTREE_H = \
$(srcdir)/reftree/reftree_const.h \
$(srcdir)/reftree/reftree.h
REFTREE = \
$(srcdir)/reftree/reftree_build.c \
$(srcdir)/reftree/reftree_coarse_path.c \
$(srcdir)/reftree/reftree_hash.c \
$(srcdir)/reftree/reftree_part.c
SIMPLE = \
$(srcdir)/simple/block.c \
$(srcdir)/simple/cyclic.c \
$(srcdir)/simple/random.c
SIMPLE_H = \
$(srcdir)/simple/simple_const.h
TIMER_H = \
$(srcdir)/timer/timer_const.h
TIMER = \
$(srcdir)/timer/timer_params.c
UTILITIES_H = \
$(srcdir)/Utilities/Communication/comm.h \
$(srcdir)/Utilities/DDirectory/DD.h \
$(srcdir)/Utilities/Timer/timer.h \
$(srcdir)/Utilities/shared/zoltan_util.h \
$(srcdir)/Utilities/shared/zoltan_id.h
UTILITIES = \
$(srcdir)/Utilities/Communication/comm_exchange_sizes.c \
$(srcdir)/Utilities/Communication/comm_invert_map.c \
$(srcdir)/Utilities/Communication/comm_do.c \
$(srcdir)/Utilities/Communication/comm_do_reverse.c \
$(srcdir)/Utilities/Communication/comm_info.c \
$(srcdir)/Utilities/Communication/comm_create.c \
$(srcdir)/Utilities/Communication/comm_resize.c \
$(srcdir)/Utilities/Communication/comm_sort_ints.c \
$(srcdir)/Utilities/Communication/comm_destroy.c \
$(srcdir)/Utilities/Communication/comm_invert_plan.c \
$(srcdir)/Utilities/Timer/zoltan_timer.c \
$(srcdir)/Utilities/Timer/timer.c \
$(srcdir)/Utilities/DDirectory/DD_Memory.c \
$(srcdir)/Utilities/DDirectory/DD_Find.c \
$(srcdir)/Utilities/DDirectory/DD_Destroy.c \
$(srcdir)/Utilities/DDirectory/DD_Set_Neighbor_Hash_Fn3.c \
$(srcdir)/Utilities/DDirectory/DD_Remove.c \
$(srcdir)/Utilities/DDirectory/DD_Create.c \
$(srcdir)/Utilities/DDirectory/DD_Update.c \
$(srcdir)/Utilities/DDirectory/DD_Stats.c \
$(srcdir)/Utilities/DDirectory/DD_Hash2.c \
$(srcdir)/Utilities/DDirectory/DD_Print.c \
$(srcdir)/Utilities/DDirectory/DD_Set_Neighbor_Hash_Fn2.c \
$(srcdir)/Utilities/DDirectory/DD_Set_Hash_Fn.c \
$(srcdir)/Utilities/DDirectory/DD_Set_Neighbor_Hash_Fn1.c \
$(srcdir)/Utilities/Memory/mem.c \
$(srcdir)/Utilities/shared/zoltan_align.c \
$(srcdir)/Utilities/shared/zoltan_id.c
# ??
# $(srcdir)/Utilities/Communication/Epetra_ZoltanMpiDistributor.cpp \
# $(srcdir)/Utilities/DDirectory/DD_Main_2.cpp \
# $(srcdir)/Utilities/Communication/comm_main_2.cpp
ZZ_H = \
$(srcdir)/zz/zz_const.h \
$(srcdir)/zz/zz_heap.h \
$(srcdir)/zz/zz_id_const.h \
$(srcdir)/zz/zz_rand.h \
$(srcdir)/zz/zz_sort.h \
$(srcdir)/zz/murmur3.h \
$(srcdir)/zz/zz_util_const.h
ZZ = \
$(srcdir)/zz/zz_coord.c \
$(srcdir)/zz/zz_gen_files.c \
$(srcdir)/zz/zz_hash.c \
$(srcdir)/zz/murmur3.c \
$(srcdir)/zz/zz_map.c \
$(srcdir)/zz/zz_heap.c \
$(srcdir)/zz/zz_init.c \
$(srcdir)/zz/zz_obj_list.c \
$(srcdir)/zz/zz_rand.c \
$(srcdir)/zz/zz_set_fn.c \
$(srcdir)/zz/zz_sort.c \
$(srcdir)/zz/zz_struct.c \
$(srcdir)/zz/zz_back_trace.c \
$(srcdir)/zz/zz_util.c
EXTRA_FORTRAN_H = \
$(srcdir)/fort/cwrap_fmangle.h \
$(srcdir)/fort/set_borderobjlist.fn \
$(srcdir)/fort/set_borderobjlist.if \
$(srcdir)/fort/set_childlist.fn \
$(srcdir)/fort/set_childlist.if \
$(srcdir)/fort/set_childweight.fn \
$(srcdir)/fort/set_childweight.if \
$(srcdir)/fort/set_coarseobjlist.fn \
$(srcdir)/fort/set_coarseobjlist.if \
$(srcdir)/fort/set_edgelist.fn \
$(srcdir)/fort/set_edgelist.if \
$(srcdir)/fort/set_edgelistmulti.fn \
$(srcdir)/fort/set_edgelistmulti.if \
$(srcdir)/fort/set_firstborderobj.fn \
$(srcdir)/fort/set_firstborderobj.if \
$(srcdir)/fort/set_firstcoarseobj.fn \
$(srcdir)/fort/set_firstcoarseobj.if \
$(srcdir)/fort/set_firstobj.fn \
$(srcdir)/fort/set_firstobj.if \
$(srcdir)/fort/set_fixedobjlist.fn \
$(srcdir)/fort/set_fixedobjlist.if \
$(srcdir)/fort/set_geom.fn \
$(srcdir)/fort/set_geom.if \
$(srcdir)/fort/set_geommulti.fn \
$(srcdir)/fort/set_geommulti.if \
$(srcdir)/fort/set_hgcs.fn \
$(srcdir)/fort/set_hgcs.if \
$(srcdir)/fort/set_hgedgeweights.fn \
$(srcdir)/fort/set_hgedgeweights.if \
$(srcdir)/fort/set_hgsizecs.fn \
$(srcdir)/fort/set_hgsizecs.if \
$(srcdir)/fort/set_hgsizeedgeweights.fn \
$(srcdir)/fort/set_hgsizeedgeweights.if \
$(srcdir)/fort/set_hiermethod.fn \
$(srcdir)/fort/set_hiermethod.if \
$(srcdir)/fort/set_hiernumlevels.fn \
$(srcdir)/fort/set_hiernumlevels.if \
$(srcdir)/fort/set_hierpartition.fn \
$(srcdir)/fort/set_hierpartition.if \
$(srcdir)/fort/set_midmigrate.fn \
$(srcdir)/fort/set_midmigrate.if \
$(srcdir)/fort/set_midmigratepp.fn \
$(srcdir)/fort/set_midmigratepp.if \
$(srcdir)/fort/set_nextborderobj.fn \
$(srcdir)/fort/set_nextborderobj.if \
$(srcdir)/fort/set_nextcoarseobj.fn \
$(srcdir)/fort/set_nextcoarseobj.if \
$(srcdir)/fort/set_nextobj.fn \
$(srcdir)/fort/set_nextobj.if \
$(srcdir)/fort/set_numborderobj.fn \
$(srcdir)/fort/set_numborderobj.if \
$(srcdir)/fort/set_numchild.fn \
$(srcdir)/fort/set_numchild.if \
$(srcdir)/fort/set_numcoarseobj.fn \
$(srcdir)/fort/set_numcoarseobj.if \
$(srcdir)/fort/set_numedges.fn \
$(srcdir)/fort/set_numedges.if \
$(srcdir)/fort/set_numedgesmulti.fn \
$(srcdir)/fort/set_numedgesmulti.if \
$(srcdir)/fort/set_numfixedobj.fn \
$(srcdir)/fort/set_numfixedobj.if \
$(srcdir)/fort/set_numgeom.fn \
$(srcdir)/fort/set_numgeom.if \
$(srcdir)/fort/set_numobj.fn \
$(srcdir)/fort/set_numobj.if \
$(srcdir)/fort/set_objlist.fn \
$(srcdir)/fort/set_objlist.if \
$(srcdir)/fort/set_objsize.fn \
$(srcdir)/fort/set_objsize.if \
$(srcdir)/fort/set_objsizemulti.fn \
$(srcdir)/fort/set_objsizemulti.if \
$(srcdir)/fort/set_packobj.fn \
$(srcdir)/fort/set_packobj.if \
$(srcdir)/fort/set_packobjmulti.fn \
$(srcdir)/fort/set_packobjmulti.if \
$(srcdir)/fort/set_partition.fn \
$(srcdir)/fort/set_partition.if \
$(srcdir)/fort/set_partitionmulti.fn \
$(srcdir)/fort/set_partitionmulti.if \
$(srcdir)/fort/set_postmigrate.fn \
$(srcdir)/fort/set_postmigrate.if \
$(srcdir)/fort/set_postmigratepp.fn \
$(srcdir)/fort/set_postmigratepp.if \
$(srcdir)/fort/set_premigrate.fn \
$(srcdir)/fort/set_premigrate.if \
$(srcdir)/fort/set_premigratepp.fn \
$(srcdir)/fort/set_premigratepp.if \
$(srcdir)/fort/set_unpackobj.fn \
$(srcdir)/fort/set_unpackobj.if \
$(srcdir)/fort/set_unpackobjmulti.fn \
$(srcdir)/fort/set_unpackobjmulti.if
EXTRA_FORTRAN = \
$(srcdir)/fort/ztypes.f90 \
$(srcdir)/fort/cwrap.c \
$(srcdir)/fort/zoltan_user_data.f90 \
$(srcdir)/fort/fwrap.f90
if BUILD_ZOLTAN_F90_INTERFACE
FORTRAN_H =$(EXTRA_FORTRAN_H)
FORTRAN = $(EXTRA_FORTRAN)
else
FORTRAN_H =
FORTRAN =
endif
# ------------------------------------------------------------------------
# Zoltan library specifications
# ------------------------------------------------------------------------
ZOLTAN_LIB = libzoltan.a
ZOLTAN_H = \
$(ALL_H) \
$(COLORING_H) \
$(GRAPH_H) \
$(HA_H) \
$(HIER_H) \
$(HSFC_H) \
$(INCLUDE_H) \
$(LB_H) \
$(MATRIX_H) \
$(ORDER_H) \
$(PAR_H) \
$(PARAMS_H) \
$(TPLS_H) \
$(PARMETIS_INTERFACE_H) \
$(PHG_H) \
$(RCB_H) \
$(REFTREE_H) \
$(SCOTCH_INTERFACE_H) \
$(TIMER_H) \
$(SIMPLE_H) \
$(UTILITIES_H) \
$(ZZ_H) \
$(FORTRAN_H)
libzoltan_a_SOURCES = \
$(ALL) \
$(COLORING) \
$(GRAPH) \
$(HA) \
$(HIER) \
$(HSFC) \
$(LB) \
$(MATRIX) \
$(ORDER) \
$(PAR) \
$(PARAMS) \
$(TPLS) \
$(PARMETIS_INTERFACE) \
$(PHG) \
$(RCB) \
$(REFTREE) \
$(SCOTCH_INTERFACE) \
$(SIMPLE) \
$(TIMER) \
$(UTILITIES) \
$(ZZ) \
$(FORTRAN)
EXTRA_libzoltan_a_SOURCES = \
$(EXTRA_PARMETIS_INTERFACE_H) \
$(EXTRA_PARMETIS_INTERFACE) \
$(EXTRA_SCOTCH_INTERFACE_H) \
$(EXTRA_SCOTCH_INTERFACE) \
$(EXTRA_FORTRAN_H) \
$(EXTRA_FORTRAN)
if F90_MODULE_LOWERCASE
FORTRAN_MODULES = \
zoltan_types.mod \
zoltan.mod \
zoltan_user_data.mod
else
FORTRAN_MODULES = \
ZOLTAN_TYPES.mod \
ZOLTAN.mod \
ZOLTAN_USER_DATA.mod
endif
include $(top_builddir)/Makefile.export.zoltan
EXPORT_INCLUDES = $(ZOLTAN_LIBRARY_INCLUDES)
AM_CPPFLAGS = $(EXPORT_INCLUDES) @MPI_RECV_LIMIT_FLAG@
# ------------------------------------------------------------------------
# For using a special archiver
# ------------------------------------------------------------------------
# SPECIAL NOTE: Why is the "else" there? For some reason, automake
# fails to define <lib>_AR of USE_ALTERNATE_AR is false, so we have to
# define it manually.
if USE_ALTERNATE_AR
libzoltan_a_AR = $(ALTERNATE_AR)
else
libzoltan_a_AR = $(AR) cru
endif
# ------------------------------------------------------------------------
# Some C++ compilers create extra .o-files for templates. We need to
# be sure to include these, and this is the hack to do it.
# ------------------------------------------------------------------------
libzoltan_a_LIBADD = $(XTRALDADD)
# ------------------------------------------------------------------------
# List of all libraries to install in $(libexecdir)
# ------------------------------------------------------------------------
#np# replace new_package with the name of the package being autotool'ed here
lib_LIBRARIES = $(ZOLTAN_LIB)
# ------------------------------------------------------------------------
# List of all headers to install in $(includedir)
# ------------------------------------------------------------------------
# Eventually we will try to install fewer headers
include_HEADERS = $(INCLUDE_H)
# ------------------------------------------------------------------------
# List of all Fortran Module files to install in $(includedir)
# ------------------------------------------------------------------------
if BUILD_ZOLTAN_F90_INTERFACE
include_HEADERS += $(FORTRAN_MODULES)
endif
# ------------------------------------------------------------------------
# Other files we want in the tarball
# ------------------------------------------------------------------------
EXTRA_FORTRAN_INTERFACE = \
$(srcdir)/fort/README \
$(srcdir)/fort/makefile
ZOLTAN_MATLAB = \
$(srcdir)/matlab/README \
$(srcdir)/matlab/mmread.m \
$(srcdir)/matlab/mmwrite.m \
$(srcdir)/matlab/plotcolors.m \
$(srcdir)/matlab/zdrive.matlab \
$(srcdir)/matlab/zoltPartSpy.m \
$(srcdir)/matlab/zoltan.m
ZOLTAN_POSTPROCESS = \
$(srcdir)/postprocessing/bin/toscotchperm.py \
$(srcdir)/postprocessing/ordering/README \
$(srcdir)/postprocessing/ordering/mm_input.c \
$(srcdir)/postprocessing/ordering/mm_input.h \
$(srcdir)/postprocessing/ordering/order_eval.c \
$(srcdir)/postprocessing/ordering/order_eval.h \
$(srcdir)/postprocessing/ordering/ordering.py \
$(srcdir)/postprocessing/ordering/toscotchperm.py \
$(srcdir)/postprocessing/ordering/zdrive.inp \
$(srcdir)/postprocessing/ordering/zdrive.inp.parmetis \
$(srcdir)/postprocessing/ordering/zdrive.inp.scotch
NATIVE_ZOLTAN_BUILD = \
$(srcdir)/makefile \
$(srcdir)/makefile_sub \
$(srcdir)/makefile.zscript \
$(srcdir)/Utilities/makefile \
$(srcdir)/Utilities/makefile_sub \
$(srcdir)/Utilities/Config/Config.RedStorm \
$(srcdir)/Utilities/Config/Config.aix \
$(srcdir)/Utilities/Config/Config.octopiLamPureTest \
$(srcdir)/Utilities/Config/Config.octopiLamTest \
$(srcdir)/Utilities/Config/Config.octopiPureTest \
$(srcdir)/Utilities/Config/Config.bgl \
$(srcdir)/Utilities/Config/Config.octopiTest \
$(srcdir)/Utilities/Config/Config.odin \
$(srcdir)/Utilities/Config/Config.osf1 \
$(srcdir)/Utilities/Config/Config.pure \
$(srcdir)/Utilities/Config/Config.pure_siMPI \
$(srcdir)/Utilities/Config/Config.g++ \
$(srcdir)/Utilities/Config/Config.purecov \
$(srcdir)/Utilities/Config/Config.gcc \
$(srcdir)/Utilities/Config/Config.purecov2 \
$(srcdir)/Utilities/Config/Config.gcc64 \
$(srcdir)/Utilities/Config/Config.qed \
$(srcdir)/Utilities/Config/Config.gcc_siMPI \
$(srcdir)/Utilities/Config/Config.quantify \
$(srcdir)/Utilities/Config/Config.sadl14088 \
$(srcdir)/Utilities/Config/Config.generic \
$(srcdir)/Utilities/Config/Config.sgi32 \
$(srcdir)/Utilities/Config/Config.ibm \
$(srcdir)/Utilities/Config/Config.sgi64 \
$(srcdir)/Utilities/Config/Config.solaris \
$(srcdir)/Utilities/Config/Config.sun \
$(srcdir)/Utilities/Config/Config.linux \
$(srcdir)/Utilities/Config/Config.linux32 \
$(srcdir)/Utilities/Config/Config.linux64 \
$(srcdir)/Utilities/Config/Config.sunos_forte7 \
$(srcdir)/Utilities/Config/Config.linux64lam \
$(srcdir)/Utilities/Config/Config.tbird \
$(srcdir)/Utilities/Config/Config.linux64lamcov \
$(srcdir)/Utilities/Config/Config.linux64lampure \
$(srcdir)/Utilities/Config/Config.linux64pure \
$(srcdir)/Utilities/Config/Config.linux64scotch \
$(srcdir)/Utilities/Config/Config.linux_cca \
$(srcdir)/Utilities/Config/Config.ubgl \
$(srcdir)/Utilities/Config/Config.vampir \
$(srcdir)/Utilities/Config/Config.mac32 \
$(srcdir)/Utilities/Config/Config.x1 \
$(srcdir)/Utilities/Config/Config.mac64 \
$(srcdir)/Utilities/Config/Config.mac64_siMPI \
$(srcdir)/Utilities/Config/Config.xt4scotch \
$(srcdir)/Utilities/Config/Config.zscript
EXTRA_DIST = $(ZOLTAN_H) \
$(srcdir)/Utilities/Communication/README \
$(srcdir)/Utilities/Memory/README \
$(srcdir)/Utilities/Timer/README \
$(srcdir)/Utilities/DDirectory/README \
$(srcdir)/Utilities/README \
$(NATIVE_ZOLTAN_BUILD) \
$(ZOLTAN_MATLAB) $(ZOLTAN_POSTPROCESS)
#EXTRA_DIST = $(ZOLTAN_H) \
# $(srcdir)/Utilities/Communication/README \
# $(srcdir)/Utilities/Memory/README \
# $(srcdir)/Utilities/Timer/README \
# $(srcdir)/Utilities/DDirectory/README \
# $(srcdir)/Utilities/README \
# $(NATIVE_ZOLTAN_BUILD) \
# $(EXTRA_FORTRAN_INTERFACE) \
# $(srcdir)/fdriver_old/README \
# $(srcdir)/fdriver_old/makefile \
# $(ZOLTAN_MATLAB) $(ZOLTAN_POSTPROCESS)
# ------------------------------------------------------------------------
# Special stuff to install in our special $(execincludedir)
# ------------------------------------------------------------------------
#np# replace new_package with the name of the package being autotool'ed here
# SPECIAL NOTE: New_Package_config.h is a machine-dependent file, so we need
# to install it in the machine-dependent directory. However, that is
# not a default installation directory, so we had to create it
# special.
# All Trilinos headers are now installed in the same directory
execincludedir = $(includedir)
#np# replace new_package with the name of the package being autotool'ed here
nodist_execinclude_HEADERS = include/Zoltan_config.h
# Add the absolute path to src/fort to F90 build line, so F90 can find
# the files included in fwrap.f90.
AM_FCFLAGS = -I@abs_top_srcdir@/src/fort
AM_FFLAGS = -I@abs_top_srcdir@/src/fort
# Build zfdrive only if HAVE_MPI; I haven't figured out a proper build of
# siMPI's Fortran interface yet (and serial zfdrive is not an important
# use case).
FDRIVER_SUBDIR =
if BUILD_TESTS
if BUILD_ZOLTAN_F90_INTERFACE
if HAVE_MPI
FDRIVER_SUBDIR += fdriver
endif
endif
endif
#SUBDIRS = .
if BUILD_TESTS
SUBDIRS = . driver $(FDRIVER_SUBDIR)
else
SUBDIRS = .
endif
# ------------------------------------------------------------------------
# Files to be deleted by 'make maintainer-clean'
# ------------------------------------------------------------------------
MAINTAINERCLEANFILES = Makefile.in
MOSTLYCLEANFILES = *.mod
# ------------------------------------------------------------------------
# Explicit FORTRAN dependencies to allow parallel builds (make -j)
# KDD: 4/28/15 Specifying the dependencies does not seem to help
# KDD: the parallel F90 builds (although articles online
# KDD: indicate it should). I'll comment them out
# KDD: and use .NOTPARALLEL: instead.
# ------------------------------------------------------------------------
#if BUILD_ZOLTAN_F90_INTERFACE
#if F90_MODULE_LOWERCASE
#zoltan.mod: zoltan_types.mod zoltan_user_data.mod $(srcdir)/fort/fwrap.f90 \
# $(EXTRA_FORTRAN_H)
#zoltan_user_data.mod: $(srcdir)/fort/zoltan_user_data.f90 zoltan_types.mod
#zoltan_types.mod: $(srcdir)/fort/ztypes.f90
#else
#ZOLTAN.mod: ZOLTAN_TYPES.mod ZOLTAN_USER_DATA.mod $(srcdir)/fort/fwrap.f90 \
# $(EXTRA_FORTRAN_H)
#ZOLTAN_USER_DATA.mod: $(srcdir)/fort/zoltan_user_data.f90 ZOLTAN_TYPES.mod
#ZOLTAN_TYPES.mod: $(srcdir)/fort/ztypes.f90
#endif
#endif
if BUILD_ZOLTAN_F90_INTERFACE
.NOTPARALLEL:
endif

3887
thirdParty/Zoltan/src/Makefile.in vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,75 @@
# @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
COMM DIRECTORY -- Package to efficiently perform unstructured communication
operations. The same pattern can be created once and
used repeatedly.
--------------------------------------------------------------------------------
comm_const.h -- Comm_Obj data structure definition and prototypes for
communication package functions.
comm_main.c -- Main routine to test the communication library.
comm_create.c -- Routine to create communication object.
comm_destroy.c -- Free the space allocated for a communication object.
comm_resize.c -- This routine allows the user to describe variable sizes
for the objects to be communicated.
comm_exchange_sizes.c -- When objects are being resized, this updates the
receiving processors' knowledge of message sizes.
comm_do.c -- Routine that uses communication object to actually perform
unstructured communication.
comm_do_reverse.c -- This routine performs the inverse communication of the
operation described in a communication object.
comm_invert_map.c -- Given a set of messages to send, determine the
corresponding set of recieves for each processor
(or vice versa).
comm_sort_ints.c -- Version of quicksort which is used in comm routines.

View File

@ -0,0 +1,161 @@
/*
* @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
*/
#ifndef __COMM_H
#define __COMM_H
#include <mpi.h>
#include "zoltan_types.h"
#include "zoltan_util.h"
#include "zoltan_comm.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/* Data structures and macros for the Zoltan Communication Package. */
/* This file should be included only by communication package files. */
/* Communication package users should include zoltan_comm.h. */
#ifndef TRUE
#define FALSE (0)
#define TRUE (1)
#endif /* !TRUE */
#define ZOLTAN_COMM_ERROR(a,b,c) \
ZOLTAN_PRINT_ERROR((c),(b),(a));
#define ZOLTAN_COMM_WARNING(a,b,c) \
ZOLTAN_PRINT_WARNING((c),(b),(a));
/* Data structures for communication object. */
struct Zoltan_Comm_Obj { /* data for mapping between decompositions */
int *procs_to; /* processors I'll send to */
int *procs_from; /* processors I'll receive from*/
int *lengths_to; /* # items I send in my messages */
int *lengths_from; /* # items I recv in my messages */
/* Following arrays used if send/recv data is packed contiguously */
int *starts_to; /* where in item lists each send starts */
int *starts_from; /* where in item lists each recv starts */
/* Following arrays used is send/recv data not packed contiguously */
int *indices_to; /* indices of items I send in my msgs */
/* ordered consistent with lengths_to */
int *indices_from; /* indices for where to put arriving data */
/* ordered consistent with lengths_from */
/* Above information is sufficient if items are all of the same size */
/* If item sizes are variable, then need following additional arrays */
int *sizes; /* size of each item to send (if items vary) */
/* Note only on sending processor: */
/* assuming recv proc can figure it out */
int *sizes_to; /* size of each msg to send (if items vary) */
int *sizes_from; /* size of each msg to recv (if items vary) */
/* Following used if send/recv data is packed contiguously & items vary */
int *starts_to_ptr; /* where in dense array sends starts */
int *starts_from_ptr; /* where in dense each recv starts */
/* Following used is send/recv data not packed contiguously & items vary */
int *indices_to_ptr; /* where to find items I send in my msgs */
/* ordered consistent with lengths_to */
int *indices_from_ptr; /* where to find items I recv */
/* ordered consistent with lengths_from */
/* Note: ALL above arrays include data for self-msg */
int nvals; /* number of values I own to start */
int nvals_recv; /* number of values I own after remapping */
int nrecvs; /* number of msgs I'll recv (w/o self_msg) */
int nsends; /* number of msgs I'll send (w/o self_msg) */
int nindices_to;
int nindices_from;
int self_msg; /* do I have data for myself? */
int max_send_size; /* size of longest message I send (w/o self) */
int total_recv_size; /* total amount of data I'll recv (w/ self) */
int maxed_recvs; /* do I have to many receives to post all
* at once? if so use MPI_Alltoallv */
MPI_Comm comm; /* communicator for operation */
MPI_Request *request; /* MPI requests for posted recvs */
MPI_Status *status; /* MPI status for those recvs */
ZOLTAN_COMM_OBJ* plan_reverse; /* to support POST & WAIT */
char* recv_buff; /* To support POST & WAIT */
};
/* Red Storm MPI permits a maximum of 2048 receives. We set our
* limit of posted receives to 2000, leaving some for the application.
*/
#ifndef MPI_RECV_LIMIT
/* Decided for Trilinos v10/Zoltan v3.2 would almost always use */
/* MPI_Alltoall communication instead of point-to-point. */
/* August 2009 */
/* #define MPI_RECV_LIMIT 4 */
/* Decided for zoltan_gid_64 branch to always used posted receives because
* Alltoall requires that offsets be 32-bit integers. October 2010
*/
#define MPI_RECV_LIMIT 0
/* #define MPI_RECV_LIMIT 2000 */
#endif
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif
#endif

View File

@ -0,0 +1,424 @@
/*
* @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
*/
#include <stdio.h>
#include "comm.h"
#include "zoltan_mem.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/* From the mapping of where to send things, construct the communication */
/* data structures. */
/* Note: This routine sets up data structure assuming all objects are the */
/* same size. If this isn't the case, a subsequent call to Comm_Resize */
/* is needed. */
int Zoltan_Comm_Create(
ZOLTAN_COMM_OBJ **cobj, /* returned communicator object */
int nvals, /* number of values I currently own */
int *assign, /* processor assignment for all my values */
MPI_Comm comm, /* communicator for xfer operation */
int tag, /* message tag I can use */
int *pnvals_recv) /* returned # vals I own after communication */
{
ZOLTAN_COMM_OBJ *plan; /* returned communication data structure */
int *starts=NULL; /* pointers into list of vals for procs */
int *lengths_to=NULL; /* lengths of messages I'll send */
int *procs_to=NULL; /* processors I'll send to */
int *indices_to=NULL; /* local_id values I'll be sending */
int *starts_to=NULL; /* where in list my sends begin */
int *lengths_from=NULL; /* lengths of messages I'll receive */
int *procs_from=NULL; /* processors I'll receive from */
int *starts_from=NULL; /* pointers for where to put recv data */
int my_proc; /* my processor tag in communicator */
int nprocs; /* number of processors in communicator */
int max_send_size =0; /* size of longest message I send */
int total_recv_size; /* total size of messages I recv */
int no_send_buff; /* is data nicely grouped by processor? */
int nactive = 0; /* number of values to remap */
int self_msg = 0; /* do I have data for myself? */
int nsends=0; /* # procs I'll send to (including self) */
int nrecvs=0; /* # procs I'll recv from (including self) */
int proc; /* processor I communicate with */
int prev_proc; /* processor on previous loop pass */
int index; /* index into list of objects */
int out_of_mem; /* am I out of memory? */
int comm_flag; /* status flag */
int i, j; /* loop counters */
static char *yo = "Zoltan_Comm_Create";
if (comm == MPI_COMM_NULL){
ZOLTAN_COMM_ERROR("Invalid communicator: MPI_COMM_NULL.", yo, -1);
return ZOLTAN_FATAL;
}
comm_flag = ZOLTAN_OK;
MPI_Comm_rank(comm, &my_proc);
MPI_Comm_size(comm, &nprocs);
/* First check to see if items are grouped by processor with no gaps. */
/* If so, indices_to should be NULL (= identity) */
/* Make data structures that will allow me to traverse arrays quickly. */
/* Begin by determining number of objects I'm sending to each processor. */
starts = (int *) ZOLTAN_MALLOC((nprocs + 1) * sizeof(int));
out_of_mem = FALSE;
if (starts == NULL) {
out_of_mem = TRUE;
goto Mem_Err;
}
/* First, use starts to count values going to each proc. */
for (i = 0; i < nprocs; i++) {
starts[i] = 0;
}
/* Note: Negative assign value means ignore item. */
/* Non-trailing negatives mean data not packed so need send_buf. */
/* Could (but don't) allow negatives between processor blocks w/o buf. */
nactive = 0;
no_send_buff = TRUE;
prev_proc = nprocs;
for (i = 0; i < nvals; i++) {
proc = assign[i];
if (no_send_buff && proc != prev_proc) { /* Checks if blocked by proc */
if (proc >= 0 && (starts[proc] || prev_proc < 0)) {
no_send_buff = FALSE;
}
else {
prev_proc = proc;
}
}
if (proc >= 0) {
++starts[proc];
++nactive;
}
}
self_msg = (starts[my_proc] != 0);
if (no_send_buff) {
/* Grouped by processor. Array indices_to can be NULL (= identity) */
nsends = 0;
for (i = 0; i < nprocs; i++) {
if (starts[i] != 0) ++nsends;
}
indices_to = NULL;
lengths_to = (int *) ZOLTAN_MALLOC(nsends * sizeof(int));
starts_to = (int *) ZOLTAN_MALLOC(nsends * sizeof(int));
procs_to = (int *) ZOLTAN_MALLOC(nsends * sizeof(int));
if (nsends != 0 && (lengths_to == NULL || starts_to == NULL ||
procs_to == NULL)) {
out_of_mem = TRUE;
goto Mem_Err;
}
index = 0;
/* Note that procs_to is in the order the data was passed in. */
for (i = 0; i < nsends; i++) {
starts_to[i] = index;
proc = assign[index];
procs_to[i] = proc;
index += starts[proc];
}
/* Now sort the outgoing procs. */
/* This keeps recvs deterministic if I ever invert communication */
/* It also allows for better balance of traffic in comm_do */
Zoltan_Comm_Sort_Ints(procs_to, starts_to, nsends);
max_send_size = 0;
for (i = 0; i < nsends; i++) {
proc = procs_to[i];
lengths_to[i] = starts[proc];
if (proc != my_proc && lengths_to[i] > max_send_size) {
max_send_size = lengths_to[i];
}
}
}
else { /* Not grouped by processor. More complex data structures. */
/* Sum starts values to be offsets into indices_to array. */
nsends = (starts[0] != 0);
for (i = 1; i < nprocs; i++) {
if (starts[i] != 0)
++nsends;
starts[i] += starts[i - 1];
}
for (i = nprocs - 1; i; i--)
starts[i] = starts[i - 1];
starts[0] = 0;
indices_to = (int *) ZOLTAN_MALLOC(nactive * sizeof(int));
if (nactive != 0 && indices_to == NULL) {
out_of_mem = TRUE;
goto Mem_Err;
}
for (i = 0; i < nvals; i++) {
proc = assign[i];
if (proc >= 0) {
indices_to[starts[proc]] = i;
++starts[proc];
}
}
/* Indices_to array now has the data in clumps for each processor. */
/* Now reconstruct starts array to index into indices_to. */
for (i = nprocs - 1; i; i--) {
starts[i] = starts[i - 1];
}
starts[0] = 0;
starts[nprocs] = nactive;
/* Construct lengths_to, starts_to and procs_to arrays. */
/* Note: If indices_to is needed, procs are in increasing order */
lengths_to = (int *) ZOLTAN_MALLOC(nsends * sizeof(int));
starts_to = (int *) ZOLTAN_MALLOC(nsends * sizeof(int));
procs_to = (int *) ZOLTAN_MALLOC(nsends * sizeof(int));
if (nsends != 0 && (lengths_to == NULL || starts_to == NULL ||
procs_to == NULL)) {
out_of_mem = TRUE;
goto Mem_Err;
}
j = 0;
max_send_size = 0;
for (i = 0; i < nprocs; i++) {
if (starts[i + 1] != starts[i]) {
starts_to[j] = starts[i];
lengths_to[j] = starts[i + 1] - starts[i];
if (i != my_proc && lengths_to[j] > max_send_size) {
max_send_size = lengths_to[j];
}
procs_to[j] = i;
j++;
}
}
}
/* Now change nsends to count only non-self messages */
nsends -= self_msg;
Mem_Err:
ZOLTAN_FREE(&starts);
/* Determine how many messages & what length I'll receive. */
comm_flag = Zoltan_Comm_Invert_Map(lengths_to, procs_to, nsends, self_msg,
&lengths_from, &procs_from, &nrecvs, my_proc, nprocs,
out_of_mem,tag, comm);
starts_from = (int *) ZOLTAN_MALLOC((nrecvs + self_msg) * sizeof(int));
if (starts_from == NULL && nrecvs + self_msg != 0) {
comm_flag = ZOLTAN_MEMERR;
}
else {
j = 0;
for (i = 0; i < nrecvs + self_msg; i++) {
starts_from[i] = j;
j += lengths_from[i];
}
}
if (comm_flag != ZOLTAN_OK) {
if (comm_flag == ZOLTAN_MEMERR) {
ZOLTAN_COMM_ERROR("Out of memory", yo, my_proc);
}
ZOLTAN_FREE(&starts_from);
ZOLTAN_FREE(&indices_to);
ZOLTAN_FREE(&procs_to);
ZOLTAN_FREE(&starts_to);
ZOLTAN_FREE(&lengths_to);
ZOLTAN_FREE(&lengths_from);
ZOLTAN_FREE(&procs_from);
return(comm_flag);
}
total_recv_size = 0;
for (i = 0; i < nrecvs + self_msg; i++)
total_recv_size += lengths_from[i];
plan = (ZOLTAN_COMM_OBJ *) ZOLTAN_MALLOC(sizeof(ZOLTAN_COMM_OBJ));
plan->lengths_to = lengths_to;
plan->starts_to = starts_to;
plan->procs_to = procs_to;
plan->indices_to = indices_to;
plan->lengths_from = lengths_from;
plan->starts_from = starts_from;
plan->procs_from = procs_from;
plan->indices_from = NULL;
plan->sizes = NULL;
plan->sizes_to = NULL;
plan->sizes_from = NULL;
plan->starts_to_ptr = NULL;
plan->starts_from_ptr = NULL;
plan->indices_to_ptr = NULL;
plan->indices_from_ptr = NULL;
plan->nvals = nvals;
plan->nvals_recv = total_recv_size;
plan->nrecvs = nrecvs;
plan->nsends = nsends;
plan->nindices_to = nactive;
plan->nindices_from = 0;
plan->self_msg = self_msg;
plan->max_send_size = max_send_size;
plan->total_recv_size = total_recv_size;
plan->maxed_recvs = 0;
plan->comm = comm;
plan->plan_reverse = NULL;
if (MPI_RECV_LIMIT > 0){
/* If we have a limit to the number of posted receives we are allowed,
** and our plan has exceeded that, then switch to an MPI_Alltoallv so
** that we will have fewer receives posted when we do the communication.
*/
MPI_Allreduce(&nrecvs, &i, 1, MPI_INT, MPI_MAX, comm);
if (i > MPI_RECV_LIMIT){
plan->maxed_recvs = 1;
}
}
if (plan->maxed_recvs){
plan->request = NULL;
plan->status = NULL;
}
else{
plan->request = (MPI_Request *) ZOLTAN_MALLOC(plan->nrecvs * sizeof(MPI_Request));
plan->status = (MPI_Status *) ZOLTAN_MALLOC(plan->nrecvs * sizeof(MPI_Status));
if (plan->nrecvs && ((plan->request == NULL) || (plan->status == NULL)))
comm_flag = ZOLTAN_MEMERR;
}
*pnvals_recv = total_recv_size;
*cobj = plan;
return (comm_flag);
}
#define COPY_BUFFER(buf, type, num) \
if (((num)>0) && from->buf) { \
to->buf = (type *)ZOLTAN_MALLOC((num) * sizeof(type)); \
if (!to->buf) { \
ZOLTAN_PRINT_ERROR(proc, yo, "Insufficient memory."); \
Zoltan_Comm_Destroy(toptr); \
return ZOLTAN_MEMERR; \
} \
memcpy(to->buf, from->buf, (num) * sizeof(type)); \
} \
else { \
to->buf = NULL; \
}
ZOLTAN_COMM_OBJ *Zoltan_Comm_Copy(ZOLTAN_COMM_OBJ *from)
{
ZOLTAN_COMM_OBJ *to = NULL;
Zoltan_Comm_Copy_To(&to, from);
return to;
}
int Zoltan_Comm_Copy_To(ZOLTAN_COMM_OBJ **toptr, ZOLTAN_COMM_OBJ *from)
{
static char *yo = "Zoltan_Comm_Copy_To";
int proc = 0;
ZOLTAN_COMM_OBJ *to= NULL;
if (!toptr){
return ZOLTAN_FATAL;
}
if (*toptr){
Zoltan_Comm_Destroy(toptr);
}
if (from){
MPI_Comm_rank(from->comm, &proc);
to = *toptr = (ZOLTAN_COMM_OBJ *)ZOLTAN_MALLOC(sizeof(ZOLTAN_COMM_OBJ));
*to = *from;
MPI_Comm_dup(from->comm, &(to->comm));
COPY_BUFFER(procs_to, int, to->nsends);
COPY_BUFFER(procs_from, int, to->nrecvs);
COPY_BUFFER(lengths_to, int, to->nsends);
COPY_BUFFER(lengths_from, int, to->nrecvs);
COPY_BUFFER(starts_to, int, to->nsends);
COPY_BUFFER(starts_from, int, to->nrecvs + to->self_msg);
COPY_BUFFER(indices_to, int, to->nindices_to);
COPY_BUFFER(indices_from, int, to->nindices_from);
COPY_BUFFER(sizes, int, to->nvals + 1);
COPY_BUFFER(sizes_to, int, to->nsends + to->self_msg);
COPY_BUFFER(sizes_from, int, to->nrecvs + to->self_msg);
COPY_BUFFER(starts_to_ptr, int, to->nsends + to->self_msg);
COPY_BUFFER(starts_from_ptr, int, to->nrecvs + to->self_msg);
COPY_BUFFER(indices_to_ptr, int, to->nvals);
COPY_BUFFER(indices_from_ptr, int, to->nvals);
COPY_BUFFER(request, MPI_Request, to->nrecvs);
COPY_BUFFER(status, MPI_Status, to->nrecvs);
}
return ZOLTAN_OK;
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,91 @@
/*
* @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
*/
#include <stdio.h>
#include "comm.h"
#include "zoltan_mem.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
int Zoltan_Comm_Destroy(
ZOLTAN_COMM_OBJ **plan) /* communication data structure pointer */
{
if (*plan == NULL) return ZOLTAN_OK;
/* Free fields of the communication object. */
ZOLTAN_FREE(&((*plan)->status));
ZOLTAN_FREE(&((*plan)->request));
ZOLTAN_FREE(&((*plan)->sizes));
ZOLTAN_FREE(&((*plan)->sizes_to));
ZOLTAN_FREE(&((*plan)->sizes_from));
ZOLTAN_FREE(&((*plan)->starts_to_ptr));
ZOLTAN_FREE(&((*plan)->starts_from_ptr));
ZOLTAN_FREE(&((*plan)->indices_to_ptr));
ZOLTAN_FREE(&((*plan)->indices_from_ptr));
ZOLTAN_FREE(&((*plan)->indices_from));
ZOLTAN_FREE(&((*plan)->indices_to));
ZOLTAN_FREE(&((*plan)->lengths_from));
ZOLTAN_FREE(&((*plan)->starts_to));
ZOLTAN_FREE(&((*plan)->starts_from));
ZOLTAN_FREE(&((*plan)->lengths_to));
ZOLTAN_FREE(&((*plan)->procs_from));
ZOLTAN_FREE(&((*plan)->procs_to));
/* Free the communication object itself */
ZOLTAN_FREE(plan);
return(ZOLTAN_OK);
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,840 @@
/*
* @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
*/
#include <stdio.h>
#include <memory.h>
#include <mpi.h>
#include "comm.h"
#include "zoltan_mem.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#if 0
static void show_int_buffers(int me, int procs, char *buf, int *bcounts, int *boffsets)
{
int i,p;
int *ibuf = (int *)buf;
printf("%d count offset (values)\n",me);
for (p=0; p < procs; p++){
printf("%d %d (",bcounts[p]/4, boffsets[p]/4);
for (i=0; i < bcounts[p]/4; i++){
printf("%d ",*ibuf);
ibuf++;
}
printf(")\n\n");
fflush(stdout);
}
}
#endif
/* Given the communication object, perform a communication operation as
efficiently as possible. */
/* Several cases are supported:
I. All objects are of same size (sizes == NULL)
A. Data is already packed by destination proc (indices_to == NULL)
Can just send straight out of user space.
B. Data not packed by destination proc (indices_to != NULL)
Need to allocate send buff and copy it in before sending
II. Objects of variable sizes (sizes != NULL)
Same two cases above, but offsets are more complicated.
Need stars_to_ptr/_from_ptr to address memory for (A), and
indices_to_ptr/_from_ptr to address memory for (B).
III. On receive, we need to do opposite of the send.
Can receive directly into user space if indices_from == NULL
Otherwise need to receive in buffer and copy.
*/
/*****************************************************************************/
int Zoltan_Comm_Do(
ZOLTAN_COMM_OBJ * plan, /* communication data structure */
int tag, /* message tag for communicating */
char *send_data, /* array of data I currently own */
int nbytes, /* multiplier for sizes */
char *recv_data) /* array of data I'll own after comm */
{
int status = ZOLTAN_OK;
if (!plan->maxed_recvs){
status = Zoltan_Comm_Do_Post (plan, tag, send_data, nbytes, recv_data);
if (status == ZOLTAN_OK)
status = Zoltan_Comm_Do_Wait (plan, tag, send_data, nbytes, recv_data);
}
else{
status = Zoltan_Comm_Do_AlltoAll(plan, send_data, nbytes, recv_data);
}
return status;
}
/*****************************************************************************/
int Zoltan_Comm_Do_Post(
ZOLTAN_COMM_OBJ * plan, /* communication data structure */
int tag, /* message tag for communicating */
char *send_data, /* array of data I currently own */
int nbytes, /* multiplier for sizes */
char *recv_data) /* array of data I'll own after comm */
{
char *send_buff; /* space to buffer outgoing data */
int my_proc; /* processor ID */
size_t self_recv_address = 0;/* where in recv_data self info starts */
int self_num=0; /* where in send list my_proc appears */
size_t offset; /* offset into array I'm copying into */
int self_index = 0; /* send offset for data I'm keeping */
int out_of_mem; /* am I out of memory? */
int nblocks; /* number of procs who need my data */
int proc_index; /* loop counter over procs to send to */
int i, j, k, jj; /* loop counters */
static char *yo = "Zoltan_Comm_Do_Post";
/* Check input parameters */
if (!plan) {
MPI_Comm_rank(MPI_COMM_WORLD, &my_proc);
ZOLTAN_COMM_ERROR("Communication plan = NULL", yo, my_proc);
return ZOLTAN_FATAL;
}
/* If not point to point, currently we do synchroneous communications */
if (plan->maxed_recvs){
int status;
status = Zoltan_Comm_Do_AlltoAll(plan, send_data, nbytes, recv_data);
return (status);
}
MPI_Comm_rank(plan->comm, &my_proc);
if ((plan->nsends + plan->self_msg) && !send_data) {
size_t sum = 0;
if (plan->sizes_to) /* Not an error if all sizes_to == 0 */
for (i = 0; i < (plan->nsends + plan->self_msg); i++)
sum += plan->sizes_to[i];
if (!plan->sizes_to || (plan->sizes_to && sum)) {
ZOLTAN_COMM_ERROR("nsends not zero, but send_data = NULL",
yo, my_proc);
return ZOLTAN_FATAL;
}
}
if ((plan->nrecvs + plan->self_msg) && !recv_data) {
size_t sum = 0;
if (plan->sizes_from) /* Not an error if all sizes_from == 0 */
for (i = 0; i < (plan->nrecvs + plan->self_msg); i++)
sum += plan->sizes_from[i];
if (!plan->sizes_from || (plan->sizes_from && sum)) {
ZOLTAN_COMM_ERROR("nrecvs not zero, but recv_data = NULL",
yo, my_proc);
return ZOLTAN_FATAL;
}
}
if (nbytes < 0) {
ZOLTAN_COMM_ERROR("Scale factor nbytes is negative", yo, my_proc);
return ZOLTAN_FATAL;
}
/* Post irecvs */
out_of_mem = 0;
if (plan->indices_from == NULL) {
/* Data can go directly into user space. */
plan->recv_buff = recv_data;
}
else { /* Need to buffer receive to reorder */
size_t rsize = (size_t) (plan->total_recv_size) * (size_t) nbytes;
plan->recv_buff = (char *) ZOLTAN_MALLOC(rsize);
if (plan->recv_buff == NULL && rsize != 0)
out_of_mem = 1;
}
if (!out_of_mem) {
if (plan->sizes == NULL) { /* All data the same size */
k = 0;
for (i = 0; i < plan->nrecvs + plan->self_msg; i++) {
if (plan->procs_from[i] != my_proc) {
MPI_Irecv((void *)
&plan->recv_buff[(size_t)(plan->starts_from[i]) * (size_t)nbytes],
plan->lengths_from[i] * nbytes,
(MPI_Datatype) MPI_BYTE, plan->procs_from[i], tag,
plan->comm, &plan->request[k]);
k++;
}
else {
self_recv_address = (size_t)(plan->starts_from[i]) * (size_t)nbytes;
}
}
}
else { /* Data of varying sizes */
k = 0;
for (i = 0; i < plan->nrecvs + plan->self_msg; i++) {
if (plan->procs_from[i] != my_proc) {
if (plan->sizes_from[i]) {
MPI_Irecv((void *)
&plan->recv_buff[(size_t)(plan->starts_from_ptr[i])
* (size_t)nbytes],
plan->sizes_from[i] * nbytes,
(MPI_Datatype) MPI_BYTE, plan->procs_from[i],
tag, plan->comm, &plan->request[k]);
}
else
plan->request[k] = MPI_REQUEST_NULL;
k++;
}
else {
self_recv_address = (size_t)(plan->starts_from_ptr[i]) * (size_t)nbytes;
}
}
}
}
/* Do remaining allocation to check for any mem problems. */
if (plan->indices_to != NULL) { /* can't sent straight from input */
size_t ssize = (size_t)(plan->max_send_size) * (size_t)nbytes;
send_buff = (char *) ZOLTAN_MALLOC(ssize);
if (send_buff == 0 && ssize != 0)
out_of_mem = 1;
}
else
send_buff = NULL;
/* Barrier to ensure irecvs are posted before doing any sends. */
/* Simultaneously see if anyone out of memory */
MPI_Allreduce(&out_of_mem, &j, 1, MPI_INT, MPI_SUM, plan->comm);
if (j > 0) { /* Some proc is out of memory -> Punt */
ZOLTAN_FREE(&send_buff);
if (plan->indices_from != NULL)
ZOLTAN_FREE(&plan->recv_buff);
return (ZOLTAN_MEMERR);
}
/* Send out data */
/* Scan through procs_to list to start w/ higher numbered procs */
/* This should balance message traffic. */
nblocks = plan->nsends + plan->self_msg;
proc_index = 0;
while (proc_index < nblocks && plan->procs_to[proc_index] < my_proc)
proc_index++;
if (proc_index == nblocks)
proc_index = 0;
if (plan->sizes == NULL) { /* Data all of same size */
if (plan->indices_to == NULL) { /* data already blocked by processor. */
for (i = proc_index, j = 0; j < nblocks; j++) {
if (plan->procs_to[i] != my_proc) {
MPI_Rsend((void *) &send_data[(size_t)(plan->starts_to[i]) * (size_t)nbytes],
plan->lengths_to[i] * nbytes,
(MPI_Datatype) MPI_BYTE, plan->procs_to[i], tag,
plan->comm);
}
else
self_num = i;
if (++i == nblocks)
i = 0;
}
if (plan->self_msg) { /* Copy data to self. */
/* I use array+offset instead of &(array[offset]) because of
a bug with PGI v9 */
/* I use memmove because I'm not sure that the pointer are not
overlapped. */
memmove(
plan->recv_buff+self_recv_address,
send_data+(size_t)(plan->starts_to[self_num])*(size_t)nbytes,
(size_t) (plan->lengths_to[self_num]) * (size_t) nbytes);
}
}
else { /* Not blocked by processor. Need to buffer. */
for (i = proc_index, jj = 0; jj < nblocks; jj++) {
if (plan->procs_to[i] != my_proc) {
/* Need to pack message first. */
offset = 0;
j = plan->starts_to[i];
for (k = 0; k < plan->lengths_to[i]; k++) {
memcpy(&send_buff[offset],
&send_data[(size_t)(plan->indices_to[j++]) * (size_t)nbytes], nbytes);
offset += nbytes;
}
MPI_Rsend((void *) send_buff, plan->lengths_to[i] * nbytes,
(MPI_Datatype) MPI_BYTE, plan->procs_to[i], tag, plan->comm);
}
else {
self_num = i;
self_index = plan->starts_to[i];
}
if (++i == nblocks)
i = 0;
}
if (plan->self_msg) { /* Copy data to self. */
for (k = 0; k < plan->lengths_to[self_num]; k++) {
memcpy(&plan->recv_buff[self_recv_address],
&send_data[(size_t)(plan->indices_to[self_index++]) * (size_t)nbytes], nbytes);
self_recv_address += nbytes;
}
}
ZOLTAN_FREE(&send_buff);
}
}
else { /* Data of differing sizes */
if (plan->indices_to == NULL) { /* data already blocked by processor. */
for (i = proc_index, j = 0; j < nblocks; j++) {
if (plan->procs_to[i] != my_proc) {
if (plan->sizes_to[i]) {
MPI_Rsend((void *)
&send_data[(size_t)(plan->starts_to_ptr[i]) * (size_t)nbytes],
plan->sizes_to[i] * nbytes,
(MPI_Datatype) MPI_BYTE, plan->procs_to[i],
tag, plan->comm);
}
}
else
self_num = i;
if (++i == nblocks)
i = 0;
}
if (plan->self_msg) { /* Copy data to self. */
if (plan->sizes_to[self_num]) {
char* lrecv = &plan->recv_buff[self_recv_address];
char* lsend = &send_data[(size_t)(plan->starts_to_ptr[self_num]) * (size_t)nbytes];
int sindex = plan->sizes_to[self_num], idx;
for (idx=0; idx<nbytes; idx++) {
memcpy(lrecv, lsend, sindex);
lrecv += sindex;
lsend += sindex;
}
}
}
}
else { /* Not blocked by processor. Need to buffer. */
for (i = proc_index, jj = 0; jj < nblocks; jj++) {
if (plan->procs_to[i] != my_proc) {
/* Need to pack message first. */
offset = 0;
j = plan->starts_to[i];
for (k = 0; k < plan->lengths_to[i]; k++) {
if (plan->sizes[plan->indices_to[j]]) {
memcpy(&send_buff[offset],
&send_data[(size_t)(plan->indices_to_ptr[j]) * (size_t)nbytes],
(size_t)(plan->sizes[plan->indices_to[j]]) * (size_t)nbytes);
offset += (size_t)(plan->sizes[plan->indices_to[j]]) * (size_t)nbytes;
}
j++;
}
if (plan->sizes_to[i]) {
MPI_Rsend((void *) send_buff,
plan->sizes_to[i] * nbytes,
(MPI_Datatype) MPI_BYTE, plan->procs_to[i],
tag, plan->comm);
}
}
else
self_num = i;
if (++i == nblocks)
i = 0;
}
if (plan->self_msg) { /* Copy data to self. */
if (plan->sizes_to[self_num]) {
j = plan->starts_to[self_num];
for (k = 0; k < plan->lengths_to[self_num]; k++) {
int kk = plan->indices_to_ptr[j];
char* lrecv = &plan->recv_buff[self_recv_address];
size_t send_idx = (size_t)kk * (size_t)nbytes;
char* lsend = &send_data[send_idx];
int sindex = plan->sizes[plan->indices_to[j]], idx;
for (idx=0; idx<nbytes; idx++) {
memcpy(lrecv, lsend, sindex);
lrecv += sindex;
lsend += sindex;
}
self_recv_address += (size_t)(plan->sizes[plan->indices_to[j]])
* (size_t) nbytes;
j++;
}
}
}
ZOLTAN_FREE(&send_buff);
}
}
return (ZOLTAN_OK);
}
/*****************************************************************************/
int Zoltan_Comm_Do_Wait(
ZOLTAN_COMM_OBJ * plan, /* communication data structure */
int tag, /* message tag for communicating */
char *send_data, /* array of data I currently own */
int nbytes, /* multiplier for sizes */
char *recv_data) /* array of data I'll own after comm */
{
MPI_Status status; /* return from Waitany */
int my_proc; /* processor ID */
int self_num; /* where in send list my_proc appears */
int i, j, k, jj; /* loop counters */
/* If not point to point, currently we do synchroneous communications */
if (plan->maxed_recvs){
/* Do nothing */
return (ZOLTAN_OK);
}
MPI_Comm_rank(plan->comm, &my_proc);
/* Wait for messages to arrive & unpack them if necessary. */
/* Note: since request is in plan, could wait in later routine. */
if (plan->indices_from == NULL) { /* No copying required */
if (plan->nrecvs > 0) {
MPI_Waitall(plan->nrecvs, plan->request, plan->status);
}
}
else { /* Need to copy into recv_data. */
if (plan->self_msg) { /* Unpack own data before waiting */
for (self_num = 0; self_num < plan->nrecvs + plan->self_msg; self_num++)
if (plan->procs_from[self_num] == my_proc) break;
k = plan->starts_from[self_num];
if (!plan->sizes_from || plan->sizes_from[self_num]) {
for (j = plan->lengths_from[self_num]; j; j--) {
memcpy(&recv_data[(size_t)(plan->indices_from[k]) * (size_t)nbytes],
&plan->recv_buff[(size_t)k * (size_t)nbytes], nbytes);
k++;
}
}
}
else
self_num = plan->nrecvs;
for (jj = 0; jj < plan->nrecvs; jj++) {
MPI_Waitany(plan->nrecvs, plan->request, &i, &status);
if (i == MPI_UNDEFINED) break; /* No more receives */
if (i >= self_num) i++;
k = plan->starts_from[i];
for (j = plan->lengths_from[i]; j; j--) {
memcpy(&recv_data[(size_t)(plan->indices_from[k]) * (size_t)nbytes],
&plan->recv_buff[(size_t)k * (size_t)nbytes], nbytes);
k++;
}
}
ZOLTAN_FREE(&plan->recv_buff);
}
return (ZOLTAN_OK);
}
/*****************************************************************************/
/* Do_Post would require posting more receives than allowed on this platform.
* We use MPI_AlltoAllv instead, which is probably implemented such that each
* process does one receive at a time.
*/
int Zoltan_Comm_Do_AlltoAll(
ZOLTAN_COMM_OBJ * plan, /* communication data structure */
char *send_data, /* array of data I currently own */
int nbytes, /* multiplier for sizes */
char *recv_data) /* array of data I'll own after comm */
{
static char *yo = "Zoltan_Comm_Do_AlltoAll";
char *outbuf=NULL, *inbuf=NULL, *buf=NULL;
int *outbufCounts=NULL, *outbufOffsets=NULL;
int *inbufCounts=NULL, *inbufOffsets=NULL;
int nprocs, me, i, j, k, p, sorted;
int nSendMsgs, nSendItems, nRecvMsgs, nRecvItems;
int length, offset, itemSize, outbufLen;
int sm = (plan->self_msg > 0) ? 1 : 0;
nSendMsgs = plan->nsends + sm;
nRecvMsgs = plan->nrecvs + sm;
for (i=0, nSendItems=0; i <nSendMsgs; i++){
nSendItems += plan->lengths_to[i];
}
for (i=0, nRecvItems=0; i <nRecvMsgs; i++){
nRecvItems += plan->lengths_from[i];
}
MPI_Comm_size(plan->comm, &nprocs);
MPI_Comm_rank(plan->comm, &me);
outbufCounts = (int *) ZOLTAN_CALLOC(nprocs , sizeof(int));
outbufOffsets = (int *) ZOLTAN_CALLOC(nprocs , sizeof(int));
inbufCounts = (int *) ZOLTAN_CALLOC(nprocs , sizeof(int));
inbufOffsets = (int *) ZOLTAN_CALLOC(nprocs , sizeof(int));
if (!outbufCounts || !outbufOffsets || !inbufCounts || !inbufOffsets){
ZOLTAN_COMM_ERROR("memory error", yo, me);
}
/* The *_to fields of the plan refer to the items in the send_data buffer,
* and how to pull out the correct items for each receiver. The
* *_from fields of the plan refer to the recv_data buffer. Items
* arrive in process rank order, and these fields tell us where to
* put them in the recv_data buffer.
*/
/* CREATE SEND BUFFER */
sorted = 0;
if (plan->indices_to == NULL){
sorted = 1;
for (i=1; i< nSendMsgs; i++){
if (plan->starts_to[i] < plan->starts_to[i-1]){
sorted = 0;
break;
}
}
}
if (plan->sizes_to){
/*
* Each message contains items for a process, and each item may be
* a different size.
*/
for (i=0, outbufLen=0; i < nSendMsgs; i++){
outbufLen += plan->sizes_to[i];
}
if (plan->indices_to){
/*
* items are not grouped by message
*/
buf = outbuf = (char *)ZOLTAN_MALLOC((size_t)outbufLen * (size_t)nbytes);
if (outbufLen && nbytes && !outbuf){
ZOLTAN_COMM_ERROR("memory error", yo, me);
}
for (p=0, i=0, k=0; p < nprocs; p++){
length = 0;
if (i < nSendMsgs){
if (plan->procs_to[i] == p){ /* procs_to is sorted */
for (j=0; j < plan->lengths_to[i]; j++,k++){
itemSize = plan->sizes[plan->indices_to[k]] * nbytes;
offset = plan->indices_to_ptr[k] * nbytes;
memcpy(buf, send_data + offset, itemSize);
buf += itemSize;
length += itemSize;
}
i++;
}
}
outbufCounts[p] = length;
if (p){
outbufOffsets[p] = outbufOffsets[p-1] + outbufCounts[p-1];
}
}
}
else{
/*
* items are stored contiguously for each message
*/
if (!sorted || (plan->nvals > nSendItems) ){
buf = outbuf = (char *)ZOLTAN_MALLOC((size_t)outbufLen * (size_t)nbytes);
if (outbufLen && nbytes && !outbuf){
ZOLTAN_COMM_ERROR("memory error", yo, me);
}
}
else{
/* All items in send_data are being sent, and they are sorted
* in process rank order.
*/
outbuf = send_data;
}
for (p=0, i=0; p < nprocs; p++){
length = 0;
if (i < nSendMsgs){
if (plan->procs_to[i] == p){ /* procs_to is sorted */
length = plan->sizes_to[i] * nbytes;
offset = plan->starts_to_ptr[i] * nbytes;
if ((!sorted || (plan->nvals > nSendItems)) && length){
memcpy(buf, send_data + offset, length);
buf += length;
}
i++;
}
}
outbufCounts[p] = length;
if (p){
outbufOffsets[p] = outbufOffsets[p-1] + outbufCounts[p-1];
}
}
}
}
else if (plan->indices_to){
/*
* item sizes are constant, however the items belonging in a given
* message may not be contiguous in send_data
*/
buf = outbuf = (char *)ZOLTAN_MALLOC((size_t)nSendItems * (size_t)nbytes);
if (nSendMsgs && nbytes && !outbuf){
ZOLTAN_COMM_ERROR("memory error", yo, me);
}
for (p=0, i=0, k=0; p < nprocs; p++){
length = 0;
if (i < nSendMsgs){
if (plan->procs_to[i] == p){ /* procs_to is sorted */
for (j=0; j < plan->lengths_to[i]; j++,k++){
offset = plan->indices_to[k] * nbytes;
memcpy(buf, send_data + offset, nbytes);
buf += nbytes;
}
length = plan->lengths_to[i] * nbytes;
i++;
}
}
outbufCounts[p] = length;
if (p){
outbufOffsets[p] = outbufOffsets[p-1] + outbufCounts[p-1];
}
}
}
else{
/* item sizes are constant, and items belonging to a
* given message are always stored contiguously in send_data
*/
if (!sorted || (plan->nvals > nSendItems)){
buf = outbuf = (char *)ZOLTAN_MALLOC((size_t)nSendItems * (size_t)nbytes);
if (nSendItems && nbytes && !outbuf){
ZOLTAN_COMM_ERROR("memory error", yo, me);
}
}
else{
/* send_data is sorted by process, and we don't skip
* any of the data in the buffer, so we can use send_data
* in the alltoall call
*/
outbuf = send_data;
}
for (p=0,i=0; p < nprocs; p++){
length = 0;
if (i < nSendMsgs){
if (plan->procs_to[i] == p){ /* procs_to is sorted */
offset = plan->starts_to[i] * nbytes;
length = plan->lengths_to[i] * nbytes;
if ((!sorted || (plan->nvals > nSendItems)) && length){
memcpy(buf, send_data + offset, length);
buf += length;
}
i++;
}
}
outbufCounts[p] = length;
if (p){
outbufOffsets[p] = outbufOffsets[p-1] + outbufCounts[p-1];
}
}
}
/* CREATE RECEIVE BUFFER */
sorted = 0;
if (plan->indices_from == NULL){
sorted = 1;
for (i=1; i< nRecvMsgs; i++){
if (plan->starts_from[i] < plan->starts_from[i-1]){
sorted = 0;
break;
}
}
}
if (sorted){
/* Caller already expects received data to be ordered by
* the sending process rank.
*/
inbuf = recv_data;
}
else{
inbuf = (char *)ZOLTAN_MALLOC((size_t)(plan->total_recv_size) * (size_t)nbytes);
if (plan->total_recv_size && nbytes && !inbuf){
ZOLTAN_COMM_ERROR("memory error", yo, me);
}
}
for (p=0, i=0; p < nprocs; p++){
length = 0;
if (i < nRecvMsgs){
if (plan->procs_from[i] == p){
if (plan->sizes == NULL){
length = plan->lengths_from[i] * nbytes;
}
else{
length = plan->sizes_from[i] * nbytes;
}
i++;
}
}
inbufCounts[p] = length;
if (p){
inbufOffsets[p] = inbufOffsets[p-1] + inbufCounts[p-1];
}
}
/* EXCHANGE DATA */
MPI_Alltoallv(outbuf, outbufCounts, outbufOffsets, MPI_BYTE,
inbuf, inbufCounts, inbufOffsets, MPI_BYTE,
plan->comm);
if (outbuf != send_data){
ZOLTAN_FREE(&outbuf);
}
ZOLTAN_FREE(&outbufCounts);
ZOLTAN_FREE(&outbufOffsets);
/* WRITE RECEIVED DATA INTO USER'S BUFFER WHERE IT'S EXPECTED */
if (!sorted){
buf = inbuf;
if (plan->sizes == NULL){
/* each item in each message is nbytes long */
if (plan->indices_from == NULL){
for (i=0; i < nRecvMsgs; i++){
offset = plan->starts_from[i] * nbytes;
length = plan->lengths_from[i] * nbytes;
memcpy(recv_data + offset, buf, length);
buf += length;
}
}
else{
for (i=0,k=0; i < nRecvMsgs; i++){
for (j=0; j < plan->lengths_from[i]; j++,k++){
offset = plan->indices_from[k] * nbytes;
memcpy(recv_data + offset, buf, nbytes);
buf += nbytes;
}
}
}
}
else{ /* (sizes!=NULL) && (indices_from!=NULL) not allowed by Zoltan_Comm_Resize */
/* items can be different sizes */
for (i=0; i < nRecvMsgs; i++){
offset = plan->starts_from_ptr[i] * nbytes;
length = plan->sizes_from[i] * nbytes;
memcpy(recv_data + offset, buf, length);
buf += length;
}
}
ZOLTAN_FREE(&inbuf);
}
ZOLTAN_FREE(&inbufCounts);
ZOLTAN_FREE(&inbufOffsets);
return ZOLTAN_OK;
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,278 @@
/*
* @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
*/
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include "zoltan_mem.h"
#include "comm.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
static void free_reverse_plan(ZOLTAN_COMM_OBJ *plan)
{
if (plan && (plan->plan_reverse != NULL)) {
if (plan->plan_reverse->sizes != NULL) {
ZOLTAN_FREE(&plan->plan_reverse->sizes);
ZOLTAN_FREE(&plan->plan_reverse->sizes_to);
ZOLTAN_FREE(&plan->plan_reverse->sizes_from);
ZOLTAN_FREE(&plan->plan_reverse->starts_to_ptr);
ZOLTAN_FREE(&plan->plan_reverse->starts_from_ptr);
ZOLTAN_FREE(&plan->plan_reverse->indices_to_ptr);
ZOLTAN_FREE(&plan->plan_reverse->indices_from_ptr);
}
ZOLTAN_FREE(&(plan->plan_reverse->status));
ZOLTAN_FREE(&(plan->plan_reverse->request));
ZOLTAN_FREE(&plan->plan_reverse);
}
}
static int create_reverse_plan(
ZOLTAN_COMM_OBJ *plan, /* communication data structure */
int tag,
int *sizes) /* variable size of objects (if not NULL) */
{
int total_send_length;/* total message length I send in plan */
int max_recv_length; /* biggest message I recv in plan */
int sum_recv_sizes; /* sum of the item sizes I receive */
int comm_flag; /* status flag */
int i; /* loop counter */
static char *yo = "Zoltan_Comm_Reverse_Plan";
/* Check input parameters */
if (!plan){
ZOLTAN_COMM_ERROR("Communication plan = NULL.", yo, -1);
return ZOLTAN_FATAL;
}
/* Let Zoltan_Comm_Do check the remaining parameters. */
total_send_length = 0;
for (i = 0; i < plan->nsends + plan->self_msg; i++) {
total_send_length += plan->lengths_to[i];
}
max_recv_length = 0;
for (i = 0; i < plan->nrecvs; i++) {
if (plan->lengths_from[i] > max_recv_length)
max_recv_length = plan->lengths_from[i];
}
plan->plan_reverse =(ZOLTAN_COMM_OBJ*)ZOLTAN_MALLOC(sizeof(ZOLTAN_COMM_OBJ));
plan->plan_reverse->nvals = plan->nvals_recv;
plan->plan_reverse->nvals_recv = plan->nvals;
plan->plan_reverse->lengths_to = plan->lengths_from;
plan->plan_reverse->procs_to = plan->procs_from;
plan->plan_reverse->indices_to = plan->indices_from;
plan->plan_reverse->starts_to = plan->starts_from;
plan->plan_reverse->lengths_from = plan->lengths_to;
plan->plan_reverse->procs_from = plan->procs_to;
plan->plan_reverse->indices_from = plan->indices_to;
plan->plan_reverse->starts_from = plan->starts_to;
plan->plan_reverse->nrecvs = plan->nsends;
plan->plan_reverse->nsends = plan->nrecvs;
plan->plan_reverse->self_msg = plan->self_msg;
plan->plan_reverse->max_send_size = max_recv_length;
plan->plan_reverse->total_recv_size = total_send_length;
plan->plan_reverse->comm = plan->comm;
plan->plan_reverse->sizes = NULL;
plan->plan_reverse->sizes_to = NULL;
plan->plan_reverse->sizes_from = NULL;
plan->plan_reverse->starts_to_ptr = NULL;
plan->plan_reverse->starts_from_ptr = NULL;
plan->plan_reverse->indices_to_ptr = NULL;
plan->plan_reverse->indices_from_ptr = NULL;
plan->plan_reverse->maxed_recvs = 0;
plan->plan_reverse->plan_reverse = NULL;
plan->plan_reverse->recv_buff = NULL;
if (MPI_RECV_LIMIT > 0){
/* If we have a limit to the number of posted receives we are allowed,
** and our plan has exceeded that, then switch to an MPI_Alltoallv so
** that we will have fewer receives posted when we do the communication.
*/
MPI_Allreduce(&plan->nsends, &i, 1, MPI_INT, MPI_MAX, plan->comm);
if (i > MPI_RECV_LIMIT){
plan->plan_reverse->maxed_recvs = 1;
}
}
if (plan->plan_reverse->maxed_recvs){
plan->plan_reverse->request = NULL;
plan->plan_reverse->status = NULL;
}
else{
plan->plan_reverse->request = (MPI_Request *)
ZOLTAN_MALLOC(plan->plan_reverse->nrecvs * sizeof(MPI_Request));
if (plan->plan_reverse->request == NULL && plan->plan_reverse->nrecvs != 0) {
return(ZOLTAN_MEMERR);
}
plan->plan_reverse->status = (MPI_Status *)
ZOLTAN_MALLOC(plan->plan_reverse->nrecvs * sizeof(MPI_Status));
if (plan->plan_reverse->status == NULL && plan->plan_reverse->nrecvs != 0) {
return(ZOLTAN_MEMERR);
}
}
comm_flag =Zoltan_Comm_Resize(plan->plan_reverse,sizes,tag,&sum_recv_sizes);
if (comm_flag != ZOLTAN_OK) {
return(comm_flag);
}
if (sum_recv_sizes != plan->plan_reverse->total_recv_size){
/* Sanity check */
return(ZOLTAN_FATAL);
}
return ZOLTAN_OK;
}
/******************************************************************************/
int Zoltan_Comm_Do_Reverse(
ZOLTAN_COMM_OBJ *plan, /* communication data structure */
int tag, /* message tag for communicating */
char *send_data, /* array of data I currently own */
int nbytes, /* # bytes per data item */
int *sizes, /* variable size of objects (if not NULL) */
char *recv_data) /* array of data I'll own after reverse comm */
{
int status;
/* create plan->plan_reverse
*/
status = create_reverse_plan(plan, tag, sizes);
if (status == ZOLTAN_OK){
if (plan->plan_reverse->maxed_recvs){
/* use MPI_Alltoallv to implement plan->plan_reverse, because comm_do_post
* would post more receives that allowed on this machine
*/
status = Zoltan_Comm_Do_AlltoAll(plan->plan_reverse, send_data, nbytes, recv_data);
}
else{
/* use post/wait which is faster when each sends to few
*/
status = Zoltan_Comm_Do_Post(plan->plan_reverse, tag, send_data, nbytes, recv_data);
if (status == ZOLTAN_OK){
status = Zoltan_Comm_Do_Wait (plan->plan_reverse, tag, send_data, nbytes, recv_data);
}
}
}
free_reverse_plan(plan);
return status;
}
/******************************************************************************/
/* Perform a reverse communication operation. Communication object describes */
/* an action, and this routine does the opposite. Can be used to return */
/* updated data to originating processor. */
int Zoltan_Comm_Do_Reverse_Post(
ZOLTAN_COMM_OBJ *plan, /* communication data structure */
int tag, /* message tag for communicating */
char *send_data, /* array of data I currently own */
int nbytes, /* # bytes per data item */
int *sizes, /* variable size of objects (if not NULL) */
char *recv_data) /* array of data I'll own after reverse comm */
{
int comm_flag; /* status flag */
/* create plan->plan_reverse
*/
comm_flag = create_reverse_plan(plan, tag, sizes);
if (comm_flag == ZOLTAN_OK){
/* post the receives of plan->plan_reverse
*/
comm_flag = Zoltan_Comm_Do_Post(plan->plan_reverse, tag, send_data, nbytes,
recv_data);
}
if (comm_flag != ZOLTAN_OK){
free_reverse_plan(plan);
}
return (comm_flag);
}
/******************************************************************************/
int Zoltan_Comm_Do_Reverse_Wait(
ZOLTAN_COMM_OBJ *plan, /* communication data structure */
int tag, /* message tag for communicating */
char *send_data, /* array of data I currently own */
int nbytes, /* # bytes per data item */
int *sizes, /* variable size of objects (if not NULL) */
char *recv_data) /* array of data I'll own after reverse comm */
{
int comm_flag; /* status flag */
comm_flag = Zoltan_Comm_Do_Wait(plan->plan_reverse, tag, send_data, nbytes, recv_data);
free_reverse_plan(plan);
return(comm_flag);
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,104 @@
/*
* @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
*/
#include <stdio.h>
#include <mpi.h>
#include "comm.h"
#include "zoltan_mem.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
int Zoltan_Comm_Exchange_Sizes(
int *sizes_to, /* value I need to exchange (size of true msg) */
int *procs_to, /* procs I send to */
int nsends, /* number of messages I'll send */
int self_msg, /* do I copy data to myself? */
int *sizes_from, /* (returned) size of all my receives */
int *procs_from, /* procs I recv from */
int nrecvs, /* number of messages I receive */
int *total_recv_size, /* (returned) sum of all incoming sizes */
int my_proc, /* my processor number */
int tag, /* message tag I can use */
MPI_Comm comm) { /* communicator */
int self_index_to; /* location of self in procs_to */
MPI_Status status; /* status of commuication operation */
int i; /* loop counter */
/* If sizes vary, then I need to communicate message lengths */
self_index_to = -1;
for (i = 0; i < nsends + self_msg; i++) {
if (procs_to[i] != my_proc)
MPI_Send((void *) &sizes_to[i], 1, MPI_INT, procs_to[i], tag, comm);
else
self_index_to = i;
}
*total_recv_size = 0;
for (i = 0; i < nrecvs + self_msg; i++) {
if (procs_from[i] != my_proc)
MPI_Recv((void *) &sizes_from[i], 1, MPI_INT, procs_from[i],
tag, comm, &status);
else
sizes_from[i] = sizes_to[self_index_to];
*total_recv_size += sizes_from[i];
}
return (ZOLTAN_OK);
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,176 @@
/*
* @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
*/
#include <stdio.h>
#include <memory.h>
#include <mpi.h>
#include "comm.h"
#include "zoltan_mem.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/* Given the communication plan, return information about the plan. */
/* All array memory must be allocated by the calling routines, and */
/* is assumed to be of the correct size. */
/* Values are not returned when arguments are NULL. */
int Zoltan_Comm_Info(
ZOLTAN_COMM_OBJ *plan, /* communication data structure */
int *nsends, /* number of sends in plan */
int *send_procs, /* list of procs to which messages are sent */
int *send_lengths, /* number of values to be sent to each proc
in procs_to */
int *send_nvals, /* number of values to send */
int *send_max_size, /* max size of msg to be sent. */
int *send_list, /* proc assignment of each value to be sent
(same as "assign" in Zoltan_Comm_Create) */
int *nrecvs, /* number of receives in plan */
int *recv_procs, /* list of procs from which messages are
received. */
int *recv_lengths, /* number of values to be received from each
proc in procs_from */
int *recv_nvals, /* number of values to recv */
int *recv_total_size, /* total size of items to be received. */
int *recv_list, /* proc assignment of each value to be received
(inverse of sent_list) */
int *self_msg /* number of self-messages in plan */
)
{
static char *yo = "Zoltan_Comm_Info";
int i, j, k, my_proc;
/* Check input parameters */
if (!plan) {
MPI_Comm_rank(MPI_COMM_WORLD, &my_proc);
ZOLTAN_COMM_ERROR("Communication plan = NULL", yo, my_proc);
return ZOLTAN_FATAL;
}
if (nsends)
*nsends = plan->nsends;
if (send_procs)
for (i = 0; i < plan->nsends + plan->self_msg; i++)
send_procs[i] = plan->procs_to[i];
if (send_lengths)
for (i = 0; i < plan->nsends + plan->self_msg; i++)
send_lengths[i] = plan->lengths_to[i];
if (send_nvals)
*send_nvals = plan->nvals;
if (send_max_size)
*send_max_size = plan->max_send_size;
if (send_list) {
for (i = 0; i < plan->nvals; i++) send_list[i] = -1;
if (plan->indices_to == NULL) {
for (i = 0; i < plan->nsends + plan->self_msg; i++) {
k = plan->starts_to[i];
for (j = 0; j < plan->lengths_to[i]; j++)
send_list[k+j] = plan->procs_to[i];
}
}
else {
for (i = 0; i < plan->nsends + plan->self_msg; i++) {
k = plan->starts_to[i];
for (j = 0; j < plan->lengths_to[i]; j++)
send_list[plan->indices_to[k+j]] = plan->procs_to[i];
}
}
}
if (nrecvs)
*nrecvs = plan->nrecvs;
if (recv_procs)
for (i = 0; i < plan->nrecvs + plan->self_msg; i++)
recv_procs[i] = plan->procs_from[i];
if (recv_lengths)
for (i = 0; i < plan->nrecvs + plan->self_msg; i++)
recv_lengths[i] = plan->lengths_from[i];
if (recv_nvals)
*recv_nvals = plan->nvals_recv;
if (recv_total_size)
*recv_total_size = plan->total_recv_size;
if (recv_list) {
for (i = 0; i < plan->nvals_recv; i++) recv_list[i] = -1;
if (plan->indices_from == NULL) {
for (i = 0; i < plan->nrecvs + plan->self_msg; i++) {
k = plan->starts_from[i];
for (j = 0; j < plan->lengths_from[i]; j++)
recv_list[k+j] = plan->procs_from[i];
}
}
else {
for (i = 0; i < plan->nrecvs + plan->self_msg; i++) {
k = plan->starts_from[i];
for (j = 0; j < plan->lengths_from[i]; j++)
recv_list[plan->indices_from[k+j]] = plan->procs_from[i];
}
}
}
if (self_msg)
*self_msg = plan->self_msg;
return (ZOLTAN_OK);
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,225 @@
/*
* @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
*/
#include <stdio.h>
#include <mpi.h>
#include "comm.h"
#include "zoltan_mem.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/* Knowing who I send to, determine how many messages I'll receive, */
/* and their lengths. Upon entry, the arrays "lengths_to" and "procs_to" */
/* contain list of processors I send to and the lengths of the corresponding */
/* messages. Upon exit, "lengths_from" and "procs_from" contain receive info. */
/* Note: By reinterpreting "to" and "from", this routine can do the opposite: */
/* given "from" data it computes "to" data. */
/* Data is allowed to be mapped from me to me. */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
int Zoltan_Comm_Invert_Map(
int *lengths_to, /* number of items I'm sending */
int *procs_to, /* procs I send to */
int nsends, /* number of messages I'll send */
int self_msg, /* do I copy data to myself? */
int **plengths_from, /* number of items I'm receiving */
int **pprocs_from, /* procs I recv lengths from */
int *pnrecvs, /* number of messages I receive */
int my_proc, /* my processor number */
int nprocs, /* total number of processors */
int out_of_mem, /* tell everyone I'm out of memory? */
int tag, /* message tag I can use */
MPI_Comm comm) /* communicator */
{
int *lengths_from; /* lengths of my recvs */
int *procs_from; /* procs I recv lengths from */
int *msg_count; /* binary flag for procs I send to (nprocs) */
int *counts; /* argument to Reduce_scatter */
int nrecvs=0; /* number of messages I'll receive */
int i,j; /* loop counter */
MPI_Status status; /* return MPI argument */
MPI_Request *req = NULL;
int local_out_of_mem; /* Temporary variable to work-around a compiler
bug; see comments below. */
int max_nrecvs;
int *sendbuf=NULL, *recvbuf=NULL;
msg_count = (int *) ZOLTAN_MALLOC(nprocs * sizeof(int));
counts = (int *) ZOLTAN_MALLOC(nprocs * sizeof(int));
if (msg_count == NULL || counts == NULL) out_of_mem = 1;
/* Work-around for compiler bug suggested by Rich Schiek.
* With 64-bit linux, OpenMPI 1.2.5, and Intel 10.1 compilers with
* optimization, passing the address of out_of_mem to MPI_Allreduce
* causes a crash in MPI_Allreduce. Rich and Tom Russo theorize that in
* Zoltan_Comm_Create, out_of_mem is stored in a register, and taking
* the address of a register is undefined. Copying out_of_mem to a
* local variable avoids the problem.
* See Zoltan Bugzilla bug 3825 for more info.
*/
local_out_of_mem = out_of_mem;
MPI_Allreduce((void *) &local_out_of_mem, (void *) &i, 1, MPI_INT, MPI_MAX, comm);
if (i) {
ZOLTAN_FREE(&counts);
ZOLTAN_FREE(&msg_count);
return(ZOLTAN_MEMERR);
}
for (i = 0; i < nprocs; i++) {
msg_count[i] = 0;
counts[i] = 1;
}
for (i = 0; i < nsends + self_msg; i++)
msg_count[procs_to[i]] = 1;
/*
* KDDKDD: Replaced MPI_Reduce_scatter with MPI_Reduce and MPI_Scatter
* KDDKDD: to avoid reported problems with MPICH 1.5.2.1.
* KDDKDD: Some sort of MPI_TYPE_INDEXED error.
* KDDKDD: Bug fix suggested by Clark Dohrmann and Rob Hoekstra.
* KDDKDD: July 20, 2004
MPI_Reduce_scatter((void *) msg_count, (void *) &nrecvs, counts, MPI_INT,
MPI_SUM, comm);
*/
MPI_Reduce(msg_count, counts, nprocs, MPI_INT, MPI_SUM, 0, comm);
MPI_Scatter(counts, 1, MPI_INT, &nrecvs, 1, MPI_INT, 0, comm);
max_nrecvs = 0;
if (my_proc == 0){
for (i=0; i < nprocs; i++){
if (counts[i] > max_nrecvs)
max_nrecvs = counts[i];
}
}
MPI_Bcast(&max_nrecvs, 1, MPI_INT, 0, comm);
ZOLTAN_FREE(&counts);
ZOLTAN_FREE(&msg_count);
lengths_from = (int *) ZOLTAN_MALLOC(nrecvs*sizeof(int));
procs_from = (int *) ZOLTAN_MALLOC(nrecvs*sizeof(int));
/* Note: these mallocs should never fail as prior frees are larger. */
if (MPI_RECV_LIMIT == 0 || max_nrecvs <= MPI_RECV_LIMIT){
req = (MPI_Request *)ZOLTAN_MALLOC(sizeof(MPI_Request) * nrecvs);
if (!req && nrecvs){
ZOLTAN_FREE(&lengths_from);
ZOLTAN_FREE(&procs_from);
return(ZOLTAN_MEMERR);
}
/* Note: I'm counting on having a unique tag or some of my incoming */
/* messages might get confused with others. */
for (i=0; i < nrecvs; i++){
MPI_Irecv(lengths_from + i, 1, MPI_INT, MPI_ANY_SOURCE, tag, comm, req + i);
}
for (i=0; i < nsends+self_msg; i++){
MPI_Send(lengths_to + i, 1, MPI_INT, procs_to[i], tag, comm);
}
for (i=0; i < nrecvs; i++){
MPI_Wait(req + i, &status);
procs_from[i] = status.MPI_SOURCE;
}
ZOLTAN_FREE(&req);
}
else{ /* some large HPC machines have a limit on number of posted receives */
sendbuf = (int *)ZOLTAN_CALLOC(sizeof(int) , nprocs);
recvbuf = (int *)ZOLTAN_MALLOC(sizeof(int) * nprocs);
if (!sendbuf || !recvbuf){
ZOLTAN_FREE(&lengths_from);
ZOLTAN_FREE(&procs_from);
return(ZOLTAN_MEMERR);
}
for (i=0; i < nsends + self_msg; i++){
sendbuf[procs_to[i]] = lengths_to[i];
}
MPI_Alltoall(sendbuf, 1, MPI_INT, recvbuf, 1, MPI_INT, comm);
ZOLTAN_FREE(&sendbuf);
for (i=0, j=0; i < nprocs; i++){
if (recvbuf[i] > 0){
lengths_from[j] = recvbuf[i];
procs_from[j] = i;
if (++j == nrecvs) break;
}
}
ZOLTAN_FREE(&recvbuf);
}
/* Sort recv lists to keep execution deterministic (e.g. for debugging) */
Zoltan_Comm_Sort_Ints(procs_from, lengths_from, nrecvs);
*plengths_from = lengths_from;
*pprocs_from = procs_from;
*pnrecvs = nrecvs - self_msg; /* Only return number of true messages */
return(ZOLTAN_OK);
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,182 @@
/*
* @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
*/
#include <stdio.h>
#include "comm.h"
#include "zoltan_mem.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/*
* Given a communication plan, invert the plan for the reverse communication.
* The sizes in the inverted plan are assumed to be uniform.
* The input plan is overwritten with the inverted plan.
* If an error occurs, the old plan is returned unchanged.
* Note: receives in new plan are blocked, even if sends in old
* plan were not. This blocking allows variable sized sends to be
* done with the new plan (Zoltan_Comm_Resize). However, it also means
* the new plan can not do exactly what Zoltan_Comm_Do_Reverse can do.
* If the application cares about the order of received data, it should
* not use this routine.
*/
int Zoltan_Comm_Invert_Plan(
ZOLTAN_COMM_OBJ **plan /* communicator object to be inverted */
)
{
static char *yo = "Zoltan_Comm_Invert_Plan";
ZOLTAN_COMM_OBJ *old = *plan, *new = NULL;
int i, ierr = ZOLTAN_OK;
int total_send_length;
int max_recv_length;
if (old == NULL){
ZOLTAN_COMM_ERROR("NULL input plan.", yo, -1);
ierr = ZOLTAN_FATAL;
goto End;
}
total_send_length = 0;
for (i = 0; i < old->nsends + old->self_msg; i++) {
total_send_length += old->lengths_to[i];
}
max_recv_length = 0;
for (i = 0; i < old->nrecvs; i++) {
if (old->lengths_from[i] > max_recv_length)
max_recv_length = old->lengths_from[i];
}
new = (ZOLTAN_COMM_OBJ *) ZOLTAN_MALLOC(sizeof(ZOLTAN_COMM_OBJ));
if (!new) {
ierr = ZOLTAN_MEMERR;
goto End;
}
new->lengths_to = old->lengths_from;
new->starts_to = old->starts_from;
new->procs_to = old->procs_from;
new->indices_to = old->indices_from;
new->lengths_from = old->lengths_to;
new->starts_from = old->starts_to;
new->procs_from = old->procs_to;
new->indices_from = NULL; /* In new plan, receives are blocked. */
/* Assumption: uniform object sizes in output plans. */
/* Can be changed by later calls to Zoltan_Comm_Resize. */
new->sizes = NULL;
new->sizes_to = NULL;
new->sizes_from = NULL;
new->starts_to_ptr = NULL;
new->starts_from_ptr = NULL;
new->indices_to_ptr = NULL;
new->indices_from_ptr = NULL;
new->nvals = old->nvals_recv;
new->nvals_recv = old->nvals;
new->nrecvs = old->nsends;
new->nsends = old->nrecvs;
new->self_msg = old->self_msg;
new->max_send_size = max_recv_length;
new->total_recv_size = total_send_length;
new->comm = old->comm;
new->maxed_recvs = 0;
if (MPI_RECV_LIMIT > 0){
/* If we have a limit to the number of posted receives we are allowed,
** and our plan has exceeded that, then switch to an MPI_Alltoallv so
** that we will have fewer receives posted when we do the communication.
*/
MPI_Allreduce(&new->nrecvs, &i, 1, MPI_INT, MPI_MAX, new->comm);
if (i > MPI_RECV_LIMIT){
new->maxed_recvs = 1;
}
}
if (new->maxed_recvs){
new->request = NULL;
new->status = NULL;
}
else{
new->request = (MPI_Request *) ZOLTAN_MALLOC(new->nrecvs*sizeof(MPI_Request));
new->status = (MPI_Status *) ZOLTAN_MALLOC(new->nrecvs*sizeof(MPI_Status));
if (new->nrecvs && ((new->request == NULL) || (new->status == NULL))) {
ierr = ZOLTAN_MEMERR;
goto End;
}
}
End:
if (ierr == ZOLTAN_OK) {
if (old->indices_to) ZOLTAN_FREE(&(old->indices_to));
if (old->sizes) ZOLTAN_FREE(&(old->sizes));
if (old->sizes_to) ZOLTAN_FREE(&(old->sizes_to));
if (old->sizes_from) ZOLTAN_FREE(&(old->sizes_from));
if (old->starts_to_ptr) ZOLTAN_FREE(&(old->starts_to_ptr));
if (old->starts_from_ptr) ZOLTAN_FREE(&(old->starts_from_ptr));
if (old->indices_to_ptr) ZOLTAN_FREE(&(old->indices_to_ptr));
if (old->indices_from_ptr) ZOLTAN_FREE(&(old->indices_from_ptr));
if (old->request) ZOLTAN_FREE(&(old->request));
if (old->status) ZOLTAN_FREE(&(old->status));
ZOLTAN_FREE(&old);
*plan = new;
}
else {
if (new) {
ZOLTAN_FREE(&(new->request));
ZOLTAN_FREE(&(new->status));
ZOLTAN_FREE(&new);
}
}
return (ierr);
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,316 @@
/*
* @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
*/
#include <stdio.h>
#include <mpi.h>
#include "comm.h"
#include "zoltan_mem.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
int Zoltan_Comm_Resize(
ZOLTAN_COMM_OBJ *plan, /* communication plan object */
int *sizes, /* size of each item I'm sending */
int tag, /* message tag I can use */
int *sum_recv_sizes) /* sum of the sizes of the items I'll receive */
{
int return_flag; /* returned error code */
int my_proc; /* my processor ID */
int nsends, nrecvs; /* number of msgs I'll send & recv */
int self_msg; /* do I have data for myself? */
int sum; /* running total of item sizes */
int *offset = NULL; /* address of each item in send array */
int *index = NULL; /* indices into start_from_ptr */
int *sort_val = NULL; /* start_from to order properly */
int *sizes_to = NULL; /* size of each msg to send (if items vary) */
int *sizes_from = NULL;/* size of each msg to recv (if items vary) */
int *starts_to_ptr = NULL; /* where in dense vector sends start */
int *starts_from_ptr = NULL; /* where in dense vector recvs start */
int *indices_to_ptr = NULL; /* where to find items I send */
/* ordered like procs_to */
int *indices_from_ptr = NULL; /* where to find items I recv */
/* ordered like procs_from */
int var_sizes; /* items have variable sizes? */
int i, j, k; /* loop counters */
static char *yo = "Zoltan_Comm_Resize";
/* If sizes vary, then I need to compute and communicate message lengths */
/* First check if sizes array is NULL on all procs. */
MPI_Comm_rank(plan->comm, &my_proc);
i = (sizes != NULL);
MPI_Allreduce(&i, &var_sizes, 1, MPI_INT, MPI_LOR, plan->comm);
if (var_sizes && plan->indices_from != NULL) {
/* Can't do w/o individual item sizes */
ZOLTAN_COMM_ERROR("Non-blocked, variable-sized recvs not supported", yo, my_proc);
return(ZOLTAN_FATAL);
}
ZOLTAN_FREE(&plan->sizes);
ZOLTAN_FREE(&plan->sizes_to);
ZOLTAN_FREE(&plan->sizes_from);
ZOLTAN_FREE(&plan->starts_to_ptr);
ZOLTAN_FREE(&plan->starts_from_ptr);
ZOLTAN_FREE(&plan->indices_to_ptr);
ZOLTAN_FREE(&plan->indices_from_ptr);
nsends = plan->nsends;
nrecvs = plan->nrecvs;
self_msg = plan->self_msg;
if (!var_sizes) { /* Easy case. Size = length */
plan->total_recv_size = 0;
for (i = 0; i < nrecvs + self_msg; i++) {
plan->total_recv_size += plan->lengths_from[i];
}
plan->max_send_size = 0;
for (i = 0; i < nsends + self_msg; i++) {
if (plan->procs_to[i] != my_proc &&
plan->lengths_to[i] > plan->max_send_size) {
plan->max_send_size = plan->lengths_to[i];
}
}
return_flag = ZOLTAN_OK;
}
else { /* Need to actually compute message sizes */
plan->sizes = (int *) ZOLTAN_MALLOC((plan->nvals + 1) * sizeof(int));
if (plan->sizes == NULL) {
return_flag = ZOLTAN_MEMERR;
goto Mem_Err;
}
for (i = 0; i < plan->nvals; i++) plan->sizes[i] = sizes[i];
return_flag = ZOLTAN_OK;
sizes_to = (int *) ZOLTAN_MALLOC((nsends + self_msg) * sizeof(int));
if (sizes_to == NULL && (nsends + self_msg) != 0) {
return_flag = ZOLTAN_MEMERR;
goto Mem_Err;
}
sizes_from = (int *) ZOLTAN_MALLOC((nrecvs + self_msg) * sizeof(int));
if (sizes_from == NULL && (nrecvs + self_msg) != 0) {
return_flag = ZOLTAN_MEMERR;
goto Mem_Err;
}
for (i = 0; i < nsends + self_msg; i++)
sizes_to[i] = 0;
/* Several cases:
1. indices_to == NULL
=> starts_to != NULL, need to allocate, set starts_to_ptr
2. indices_to != NULL (=> starts_to == NULL)
need to allocate, set indices_to_ptr
3,4. mirror cases for _from
*/
starts_to_ptr = (int *) ZOLTAN_MALLOC((nsends + self_msg) * sizeof(int));
if (starts_to_ptr == NULL && (nsends + self_msg) != 0) {
return_flag = ZOLTAN_MEMERR;
goto Mem_Err;
}
if (plan->indices_to == NULL) {
/* Simpler case; sends already blocked by processor */
index = (int *) ZOLTAN_MALLOC((nsends + self_msg) * sizeof(int));
sort_val = (int *) ZOLTAN_MALLOC((nsends + self_msg) * sizeof(int));
if ((index == NULL || sort_val == NULL) && nsends + self_msg > 0) {
return_flag = ZOLTAN_MEMERR;
goto Mem_Err;
}
for (i = 0; i < nsends + self_msg; i++) {
j = plan->starts_to[i];
for (k = 0; k < plan->lengths_to[i]; k++) {
sizes_to[i] += sizes[j++];
}
if (sizes_to[i] > plan->max_send_size &&
plan->procs_to[i] != my_proc)
plan->max_send_size = sizes_to[i];
}
for (i = 0; i < nsends + self_msg; i++) {
sort_val[i] = plan->starts_to[i];
index[i] = i;
}
Zoltan_Comm_Sort_Ints(sort_val, index, nsends + self_msg);
sum = 0;
for (i = 0; i < nsends + self_msg; i++) {
starts_to_ptr[index[i]] = sum;
sum += sizes_to[index[i]];
}
ZOLTAN_FREE(&index);
ZOLTAN_FREE(&sort_val);
}
else { /* Harder case, sends not blocked */
offset = (int *) ZOLTAN_MALLOC(plan->nvals * sizeof(int));
indices_to_ptr = (int *) ZOLTAN_MALLOC(plan->nvals * sizeof(int));
if ((offset == NULL || indices_to_ptr == NULL) && plan->nvals != 0) {
return_flag = ZOLTAN_MEMERR;
goto Mem_Err;
}
/* Compute address for every item in send array */
sum = 0;
for (i = 0; i < plan->nvals; i++) {
offset[i] = sum;
sum += sizes[i];
}
sum = 0;
plan->max_send_size = 0;
for (i = 0; i < nsends + self_msg; i++) {
starts_to_ptr[i] = sum;
j = plan->starts_to[i];
for (k = 0; k < plan->lengths_to[i]; k++) {
indices_to_ptr[j] = offset[plan->indices_to[j]];
sizes_to[i] += sizes[plan->indices_to[j++]];
}
if (sizes_to[i] > plan->max_send_size &&
plan->procs_to[i] != my_proc)
plan->max_send_size = sizes_to[i];
sum += sizes_to[i];
}
ZOLTAN_FREE(&offset);
}
/* Note: This routine only gets message sizes, not object sizes. */
/* Anything requiring item sizes requires more code */
/* Should such functionality reside here? */
Zoltan_Comm_Exchange_Sizes(sizes_to, plan->procs_to, nsends, self_msg,
sizes_from, plan->procs_from, nrecvs,
&plan->total_recv_size, my_proc, tag, plan->comm);
starts_from_ptr = (int *) ZOLTAN_MALLOC((nrecvs + self_msg) * sizeof(int));
if (starts_from_ptr == NULL && (nrecvs + self_msg) != 0) {
return_flag = ZOLTAN_MEMERR;
goto Mem_Err;
}
if (plan->indices_from == NULL) {
/* Simpler case; recvs already blocked by processor */
/* Harder case currently excluded at top of file */
index = (int *) ZOLTAN_MALLOC((nrecvs + self_msg) * sizeof(int));
sort_val = (int *) ZOLTAN_MALLOC((nrecvs + self_msg) * sizeof(int));
if ((index == NULL || sort_val == NULL) && nrecvs + self_msg > 0) {
return_flag = ZOLTAN_MEMERR;
goto Mem_Err;
}
for (i = 0; i < nrecvs + self_msg; i++) {
sort_val[i] = plan->starts_from[i];
index[i] = i;
}
Zoltan_Comm_Sort_Ints(sort_val, index, nrecvs + self_msg);
sum = 0;
for (i = 0; i < nrecvs + self_msg; i++) {
starts_from_ptr[index[i]] = sum;
sum += sizes_from[index[i]];
}
ZOLTAN_FREE(&index);
ZOLTAN_FREE(&sort_val);
}
/*else {*/ /* Harder case, recvs not blocked */
/* Not currently supported */
/* Can't do w/o individual item sizes */
/* Currently checked for at top of file */
/*}*/
}
Mem_Err:
if (return_flag == ZOLTAN_MEMERR) {
ZOLTAN_FREE(&index);
ZOLTAN_FREE(&sort_val);
ZOLTAN_FREE(&offset);
ZOLTAN_FREE(&plan->sizes);
ZOLTAN_FREE(&plan->sizes_to);
ZOLTAN_FREE(&plan->sizes_from);
ZOLTAN_FREE(&plan->starts_to_ptr);
ZOLTAN_FREE(&plan->starts_from_ptr);
ZOLTAN_FREE(&plan->indices_to_ptr);
ZOLTAN_FREE(&plan->indices_from_ptr);
}
plan->sizes_to = sizes_to;
plan->sizes_from = sizes_from;
plan->starts_to_ptr = starts_to_ptr;
plan->starts_from_ptr = starts_from_ptr;
plan->indices_to_ptr = indices_to_ptr;
plan->indices_from_ptr = indices_from_ptr;
if (sum_recv_sizes)
*sum_recv_sizes = plan->total_recv_size;
return(return_flag);
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,124 @@
/*
* @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
*/
#include <string.h>
#include "comm.h"
#include "zoltan_mem.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/* Given a list of processors & message data, sort them by proc ID */
/* This routine will ensure that the ordering produced by the invert_map */
/* routines is deterministic. This should make bugs more reproducible. */
/* This is a distribution count sort (Knuth) */
/* An easily fixed assumption is that the smallest integer is zero! */
int Zoltan_Comm_Sort_Ints(
int *vals_sort, /* values to be sorted */
int *vals_other, /* other array to be reordered w/ sort */
int nvals) /* length of these two arrays */
{
int *store=NULL, *copy_sort=NULL, *copy_other=NULL, *p;
int i;
int top; /* largest integer to sort, smallest is 0 by assumption */
int err = ZOLTAN_OK;
int already_sorted = 1; /* flag indicating whether vals_sort is
already sorted; can exit early and skip
memory allocations if it is. */
if (nvals < 1 || vals_sort == NULL || vals_other == NULL)
return ZOLTAN_FATAL;
if (nvals == 1)
return ZOLTAN_OK; /* fastest way to sort 1 item is to return */
/* find largest value (sort sometimes used for non processor lists) */
top = vals_sort[0];
for (i = 1; i < nvals; i++) {
if (vals_sort[i-1] > vals_sort[i]) already_sorted = 0;
if (top < vals_sort[i]) top = vals_sort[i];
}
if (already_sorted)
return ZOLTAN_OK;
store = (int*) ZOLTAN_CALLOC (top+2, sizeof(int));
copy_sort = (int*) ZOLTAN_MALLOC (nvals * sizeof(int));
copy_other = (int*) ZOLTAN_MALLOC (nvals * sizeof(int));
if (store && copy_sort && copy_other) {
memcpy (copy_sort, vals_sort, nvals * sizeof(int));
memcpy (copy_other, vals_other, nvals * sizeof(int));
p = store+1;
for (i = 0; i < nvals; i++)
p[copy_sort[i]]++; /* count number of occurances */
for (i = 1; i < top+1; i++)
p[i] += p[i-1]; /* compute partial sums */
/* assert: p[top] = nvals */
p = store; /* effectively shifts down by one */
for (i = 0; i < nvals; i++) {
vals_sort [p[copy_sort [i]]] = copy_sort [i];
vals_other [p[copy_sort [i]]] = copy_other[i];
++p[copy_sort [i]];
}
}
else
err = ZOLTAN_MEMERR;
Zoltan_Multifree (__FILE__, __LINE__, 3, &copy_sort, &copy_other, &store);
return err;
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,257 @@
/*
* @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
*/
#include <stdio.h>
#include <stdlib.h>
#include "zoltan_dd_const.h"
#include "zoltan_align.h"
#include "zz_hash.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/* NOTE: See file, README, for associated documentation. (RTH) */
/* Zoltan_DD_Create assumes the global object being managed by the
* directory is a Zoltan global ID, which is a ZOLTAN_ID_TYPE-tuple.
* The "num_gid" parameter is where we specify how many ZOLTAN_ID_TYPEs
* are in the object (zz->Num_GID).
*
* However, some Zoltan code uses a data directory to manage other
* global integer values. When the ZOLTAN_ID_TYPE was always be an
* unsigned integer, that worked.
*
* But now that the ZOLTAN_ID_TYPE can be specified at compile time,
* we need to be more careful.
*
* If the global value is not a Zoltan global ID, then the "num_gid"
* parameter should be factor which, when multiplied by a ZOLTAN_ID_TYPE,
* give an object of the same length as the global value.
*
* So if ZOLTAN_ID_TYPE is a 32-bit int, and the global value being
* managed by the data directory is a 64-bit int, "num_gid" should
* be "2".
*
* The "num_lid" parameter specifies the number ZOLTAN_ID_TYPEs in
* the local ID.
*
* The "user_length" parameter specifies the number of chars in the
* user data.
*/
/******************* Zoltan_DD_Create() ***************************/
int Zoltan_DD_Create (
Zoltan_DD_Directory **dd, /* contains directory state and pointers */
MPI_Comm comm, /* Dup'ed and saved for future use */
int num_gid, /* Number of entries in a global ID. */
int num_lid, /* Number of entries in a local ID.
If zero, ignore LIDs */
int user_length, /* Optional user data length in chars, 0 ignore */
int table_length, /* sizeof hash table, use default if 0 */
int debug_level /* control actions to errors, normally 0 */
)
{
int size, i;
int my_proc;
int array[3], max_array[3], min_array[3];
char *yo = "Zoltan_DD_Create";
if (MPI_Comm_rank(comm, &my_proc) != MPI_SUCCESS) {
ZOLTAN_PRINT_ERROR (-1, yo, "MPI_Comm_rank failed");
return ZOLTAN_FATAL;
}
/* input sanity check */
if (dd == NULL || num_gid < 1 || table_length < 0 || num_lid < 0) {
ZOLTAN_PRINT_ERROR (my_proc, yo, "Invalid input argument");
return ZOLTAN_FATAL;
}
if (debug_level > 4)
ZOLTAN_TRACE_IN (my_proc, yo, NULL);
/* insure all processors are using the same GID, LID, USER lengths */
array[0] = num_gid;
array[1] = num_lid;
array[2] = user_length;
MPI_Allreduce (array, max_array, 3, MPI_INT, MPI_MAX, comm);
MPI_Allreduce (array, min_array, 3, MPI_INT, MPI_MIN, comm);
if (max_array[0] != min_array[0] || max_array[1] != min_array[1]
|| max_array[2] != min_array[2]) {
ZOLTAN_PRINT_ERROR(-1,yo,"LID, GID, USER data lengths differ globally");
return ZOLTAN_FATAL;
}
/* malloc memory for the directory structure + hash table */
size = (table_length) ? table_length: ZOLTAN_DD_HASH_TABLE_COUNT;
size = Zoltan_Recommended_Hash_Size(size);
*dd = (Zoltan_DD_Directory*) ZOLTAN_MALLOC (sizeof (Zoltan_DD_Directory)
+ size * sizeof(DD_NodeIdx));
if (*dd == NULL) {
ZOLTAN_PRINT_ERROR (my_proc, yo, "Can not malloc hash table");
if (debug_level > 4)
ZOLTAN_TRACE_OUT(my_proc, yo, NULL);
return ZOLTAN_MEMERR;
}
/* NULL heads of link list in hash table */
for (i = 0; i < size; i++) (*dd)->table[i] = -1; /* NULL values */
(*dd)->nodecnt = 0;
(*dd)->nodelist = NULL;
(*dd)->nodedata = NULL;
(*dd)->nodelistlen = 0;
(*dd)->nextfreenode = -1;
/* save useful constants into directory for convenience */
(*dd)->debug_level = debug_level; /* [0,3], default 0 */
(*dd)->gid_length = num_gid; /* saved input Num_GID */
(*dd)->lid_length = num_lid; /* saved input Num_LIB */
(*dd)->table_length = size; /* # of linked list heads */
(*dd)->user_data_length = user_length; /* optional user data length */
(*dd)->hash = Zoltan_DD_Hash2;/* default hash algorithm */
(*dd)->hashdata = NULL; /* no hash data */
(*dd)->hashfn = NULL; /* no hash function */
(*dd)->cleanup = NULL; /* user registered cleanup */
(*dd)->max_id_length = (num_gid > num_lid) ? num_gid : num_lid;
/* frequently used dynamic allocation computed sizes */
size = ((num_gid + num_lid) * sizeof(ZOLTAN_ID_TYPE)) + user_length;
(*dd)->nodedata_size = size;
(*dd)->update_msg_size = size + sizeof(DD_Update_Msg);
size = num_gid * sizeof(ZOLTAN_ID_TYPE);
(*dd)->remove_msg_size = size + sizeof(DD_Remove_Msg);
size = user_length + ((*dd)->max_id_length * sizeof(ZOLTAN_ID_TYPE));
(*dd)->find_msg_size = size + sizeof(DD_Find_Msg);
/* force alignment */
(*dd)->nodedata_size = Zoltan_Align_size_t((*dd)->nodedata_size);
(*dd)->update_msg_size = Zoltan_Align_size_t((*dd)->update_msg_size);
(*dd)->remove_msg_size = Zoltan_Align_size_t((*dd)->remove_msg_size);
(*dd)->find_msg_size = Zoltan_Align_size_t((*dd)->find_msg_size);
/* duplicate MPI comm to prevent future comm changes from disrupting */
/* directory communications & save the associated comm size & rank */
if (MPI_Comm_dup (comm, &((*dd)->comm)) != MPI_SUCCESS
|| MPI_Comm_size (comm, &((*dd)->nproc)) != MPI_SUCCESS
|| MPI_Comm_rank (comm, &((*dd)->my_proc)) != MPI_SUCCESS) {
ZOLTAN_PRINT_ERROR (my_proc, yo, "MPI Problem, unable to continue");
return ZOLTAN_FATAL;
}
if (debug_level > 4)
ZOLTAN_TRACE_OUT (my_proc, yo, NULL);
return ZOLTAN_OK;
}
/******************* Copy functions ***************************/
Zoltan_DD_Directory *Zoltan_DD_Copy(Zoltan_DD_Directory *from)
{
Zoltan_DD_Directory *to = NULL;
Zoltan_DD_Copy_To(&to, from);
return to;
}
int Zoltan_DD_Copy_To(Zoltan_DD_Directory **toptr, Zoltan_DD_Directory *from)
{
static char *yo = "Zoltan_DD_Copy_To";
Zoltan_DD_Directory *to= NULL;
if (!toptr) {
return ZOLTAN_FATAL;
}
if (*toptr) {
Zoltan_DD_Destroy(toptr);
}
if (from) {
DD_NodeIdx i;
to = *toptr =
(Zoltan_DD_Directory *)ZOLTAN_MALLOC(
sizeof (Zoltan_DD_Directory) +
(from->table_length * sizeof(DD_NodeIdx)));
if (!to) {
ZOLTAN_PRINT_ERROR(from->my_proc, yo, "Insufficient memory.");
return ZOLTAN_MEMERR;
}
*to = *from;
memcpy(to->table, from->table, to->table_length * sizeof(DD_NodeIdx));
MPI_Comm_dup(from->comm, &(to->comm));
if (to->nodelistlen) {
to->nodelist = (DD_Node *) ZOLTAN_MALLOC(to->nodelistlen * sizeof(DD_Node));
memcpy(to->nodelist, from->nodelist, to->nodelistlen * sizeof(DD_Node));
to->nodedata = (char *) ZOLTAN_MALLOC(to->nodelistlen * to->nodedata_size);
memcpy(to->nodedata, from->nodedata, to->nodelistlen * to->nodedata_size);
for (i = 0; i < to->nodelistlen; i++) {
to->nodelist[i].gid = (ZOLTAN_ID_PTR)(to->nodedata + i*to->nodedata_size);
}
}
}
return ZOLTAN_OK;
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,93 @@
/*
* @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
*/
#include <stdio.h>
#include <stdlib.h>
#include "zoltan_dd_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/********************** Zoltan_DD_Destroy() *********************/
void Zoltan_DD_Destroy (Zoltan_DD_Directory **dd)
{
char *yo = "ZOLTAN_DD_Destroy";
/* input sanity check */
if (dd == NULL || *dd == NULL) {
ZOLTAN_PRINT_ERROR (0, yo, "Input argument dd is NULL");
return;
}
if ((*dd)->debug_level > 4)
ZOLTAN_TRACE_IN ((*dd)->my_proc, yo, NULL);
ZOLTAN_FREE(&((*dd)->nodelist));
ZOLTAN_FREE(&((*dd)->nodedata));
/* execute user registered cleanup function, if needed */
if ((*dd)->cleanup != NULL)
(*dd)->cleanup((*dd)->hashdata);
MPI_Comm_free (&((*dd)->comm)); /* free MPI Comm, ignore errors */
if ((*dd)->debug_level > 4)
ZOLTAN_TRACE_OUT ((*dd)->my_proc, yo, NULL);
ZOLTAN_FREE (dd); /* free directory structure */
return;
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,337 @@
/*
* @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
*/
#include <stdio.h>
#include <stdlib.h>
#include "zoltan_dd_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
int Zoltan_DD_GetLocalKeys(Zoltan_DD_Directory *dd,
ZOLTAN_ID_PTR *gid,
int *size)
{
int ierr = ZOLTAN_OK;
int i, k;
DD_NodeIdx nodeidx;
DD_Node *ptr;
int gid_alloc_size;
gid_alloc_size = dd->table_length;
(*gid) = (ZOLTAN_ID_PTR)ZOLTAN_MALLOC(
gid_alloc_size*dd->gid_length*sizeof(ZOLTAN_ID_TYPE));
k= 0;
for (i = 0; i < dd->table_length; i++)
for (nodeidx = dd->table[i]; nodeidx != -1;
nodeidx = dd->nodelist[nodeidx].next) {
ptr = dd->nodelist + nodeidx;
if (k >= gid_alloc_size) {
gid_alloc_size *= 2;
(*gid) = (ZOLTAN_ID_PTR)
ZOLTAN_REALLOC((*gid),
gid_alloc_size*dd->gid_length*sizeof(ZOLTAN_ID_TYPE));
}
ZOLTAN_SET_ID (dd->gid_length, (*gid)+k*dd->gid_length, ptr->gid);
k++;
}
(*size) = k;
return (ierr);
}
/* NOTE: See file, README, for associated documentation. (RTH) */
static int DD_Find_Local (Zoltan_DD_Directory *dd, ZOLTAN_ID_PTR gid,
ZOLTAN_ID_PTR lid, char *user, int *partition, int *owner) ;
/******************** Zoltan_DD_Find() **************************/
int Zoltan_DD_Find (
Zoltan_DD_Directory *dd, /* contains directory state information */
ZOLTAN_ID_PTR gid, /* Incoming list of GIDs to get owners proc */
ZOLTAN_ID_PTR lid, /* Outgoing corresponding list of LIDs */
char *data, /* Outgoing optional corresponding user data */
int *partition, /* Outgoing optional partition information */
int count, /* Count of GIDs in above list (in) */
int *owner) /* Outgoing optional list of data owners */
{
ZOLTAN_COMM_OBJ *plan = NULL; /* efficient MPI communication */
char *rbuff = NULL; /* receive buffer */
char *rbufftmp = NULL; /* pointer into receive buffer */
char *sbuff = NULL; /* send buffer */
char *sbufftmp = NULL; /* pointer into send buffer */
int *procs = NULL; /* list of processors to contact */
DD_Find_Msg *ptr = NULL;
int i;
int nrec; /* number of messages to receive */
int err = ZOLTAN_OK; /* return error condition */
int errcount; /* count of GIDs not found */
char *yo = "Zoltan_DD_Find";
/* input sanity check */
if (dd == NULL || count < 0 || (gid == NULL && count > 0)) {
ZOLTAN_PRINT_ERROR (dd ? dd->my_proc : ZOLTAN_DD_NO_PROC, yo,
"Invalid input argument");
return ZOLTAN_FATAL;
}
if (dd->debug_level > 4)
ZOLTAN_TRACE_IN(dd->my_proc, yo, NULL);
/* allocate memory for processors to contact for directory info */
if (count) {
procs = (int*) ZOLTAN_MALLOC (sizeof(int) * count);
if (procs == NULL) {
ZOLTAN_PRINT_ERROR (dd->my_proc, yo, "Unable to malloc proc list");
if (dd->debug_level > 4)
ZOLTAN_TRACE_OUT(dd->my_proc, yo, NULL);
return ZOLTAN_MEMERR;
}
}
/* allocate memory for DD_Find_Msg send buffer */
if (count) {
sbuff = (char*) ZOLTAN_CALLOC (count, dd->find_msg_size);
if (sbuff == NULL) {
ZOLTAN_FREE (&procs);
ZOLTAN_PRINT_ERROR (dd->my_proc, yo, "Unable to malloc send buffer");
if (dd->debug_level > 4)
ZOLTAN_TRACE_OUT(dd->my_proc, yo, NULL);
return ZOLTAN_MEMERR;
}
}
if (dd->debug_level > 6)
ZOLTAN_PRINT_INFO(dd->my_proc, yo, "After mallocs");
/* for each GID, fill DD_Find_Msg buffer and contact list */
sbufftmp = sbuff;
for (i = 0; i < count; i++) {
procs[i] = dd->hash (gid + i*dd->gid_length, dd->gid_length, dd->nproc,
dd->hashdata, dd->hashfn);
ptr = (DD_Find_Msg*) sbufftmp;
sbufftmp += dd->find_msg_size;
ptr->index = i;
ptr->proc = procs[i];
ZOLTAN_SET_ID (dd->gid_length, ptr->id, gid + i*dd->gid_length);
}
if (dd->debug_level > 6)
ZOLTAN_PRINT_INFO(dd->my_proc, yo, "After fill");
/* create efficient communication plan */
err = Zoltan_Comm_Create (&plan, count, procs, dd->comm,
ZOLTAN_DD_FIND_MSG_TAG, &nrec);
if (dd->debug_level > 6)
ZOLTAN_PRINT_INFO(dd->my_proc, yo, "After Comm_Create");
if (err != ZOLTAN_OK)
goto fini;
/* allocate receive buffer */
if (nrec) {
rbuff = (char*) ZOLTAN_MALLOC ((size_t)nrec*(size_t)(dd->find_msg_size));
if (rbuff == NULL) {
err = ZOLTAN_MEMERR;
goto fini;
}
}
/* send out find messages across entire system */
err = Zoltan_Comm_Do (plan, ZOLTAN_DD_FIND_MSG_TAG+1, sbuff,
dd->find_msg_size, rbuff);
if (err != ZOLTAN_OK)
goto fini;
if (dd->debug_level > 6)
ZOLTAN_PRINT_INFO(dd->my_proc, yo, "After Comm_Do");
/* get find messages directed to me, fill in return information */
errcount = 0;
rbufftmp = rbuff;
for (i = 0; i < nrec; i++) {
ptr = (DD_Find_Msg*) rbufftmp;
rbufftmp += dd->find_msg_size;
err = DD_Find_Local (dd, ptr->id, ptr->id,
(char *)(ptr->id + dd->max_id_length),
&ptr->partition, &ptr->proc);
if (err == ZOLTAN_WARN)
++errcount;
}
if (dd->debug_level > 6)
ZOLTAN_PRINT_INFO(dd->my_proc, yo, "After fill in return info");
/* send return information back to requester */
err = Zoltan_Comm_Do_Reverse(plan, ZOLTAN_DD_FIND_MSG_TAG+2, rbuff,
dd->find_msg_size, NULL, sbuff);
if (err != ZOLTAN_OK)
goto fini;
if (dd->debug_level > 6)
ZOLTAN_PRINT_INFO(dd->my_proc, yo, "After Comm_Reverse");
/* fill in user supplied lists with returned information */
sbufftmp = sbuff;
for (i = 0; i < count; i++) {
ptr = (DD_Find_Msg*) sbufftmp;
sbufftmp += dd->find_msg_size;
if (owner)
owner[ptr->index] = ptr->proc;
if (partition)
partition[ptr->index] = ptr->partition ;
if (lid)
ZOLTAN_SET_ID(dd->lid_length,lid+ptr->index*dd->lid_length,ptr->id);
if (data)
memcpy(data + (size_t)(ptr->index) * (size_t)(dd->user_data_length),
ptr->id + dd->max_id_length, dd->user_data_length);
}
if (dd->debug_level > 6)
ZOLTAN_PRINT_INFO(dd->my_proc, yo, "After fill return lists");
/* err = ZOLTAN_OK; */
MPI_Allreduce(&errcount, &err, 1, MPI_INT, MPI_SUM, dd->comm);
err = (err) ? ZOLTAN_WARN : ZOLTAN_OK;
/* if at least one GID was not found, potentially notify caller of error */
if (dd->debug_level > 0) {
char str[100]; /* diagnostic message string */
sprintf (str, "Processed %d GIDs, GIDs not found: %d", count, errcount);
ZOLTAN_PRINT_INFO (dd->my_proc, yo, str);
}
fini:
ZOLTAN_FREE (&sbuff);
ZOLTAN_FREE (&rbuff);
ZOLTAN_FREE (&procs) ;
Zoltan_Comm_Destroy (&plan);
if (dd->debug_level > 4)
ZOLTAN_TRACE_OUT(dd->my_proc, yo, NULL);
return err;
}
/****************** DD_Find_Local() ***************************/
/* For a given gid, DD_Find_Local() provides its local ID, owner, optional
* user data, and partition from the local distributed directory. An error
* is returned if the gid is not found.
*/
static int DD_Find_Local (Zoltan_DD_Directory *dd,
ZOLTAN_ID_PTR gid, /* incoming GID to locate (in) */
ZOLTAN_ID_PTR lid, /* gid's LID (out) */
char *user, /* gid's user data (out) */
int *partition, /* gid's partition number (out) */
int *owner) /* gid's owner (processor number) (out) */
{
DD_Node *ptr;
DD_NodeIdx nodeidx;
int index;
char *yo = "DD_Find_Local";
/* input sanity check */
if (dd == NULL || owner == NULL || gid == NULL) {
ZOLTAN_PRINT_ERROR ((dd == NULL) ? 0 : dd->my_proc, yo, "Invalid input");
return ZOLTAN_FATAL;
}
if (dd->debug_level > 5)
ZOLTAN_TRACE_IN (dd->my_proc, yo, NULL);
/* compute offset into hash table to find head of linked list */
index = Zoltan_DD_Hash2 (gid, dd->gid_length, dd->table_length,
dd->hashdata, NULL);
/* walk link list until end looking for matching global ID */
for (nodeidx = dd->table[index]; nodeidx != -1;
nodeidx = dd->nodelist[nodeidx].next) {
ptr = dd->nodelist + nodeidx;
if (ZOLTAN_EQ_ID (dd->gid_length, gid, ptr->gid) == TRUE) {
/* matching global ID found! Return gid's information */
if (lid) ZOLTAN_SET_ID(dd->lid_length, lid, ptr->gid + dd->gid_length);
if (user) memcpy(user, ptr->gid + (dd->gid_length + dd->lid_length),
dd->user_data_length);
if (owner) *owner = ptr->owner;
if (partition) *partition = ptr->partition;
if (dd->debug_level > 5)
ZOLTAN_TRACE_OUT (dd->my_proc, yo, NULL);
return ZOLTAN_OK;
}
}
if (owner != NULL)
*owner = -1; /* JDT Added -1 owner not found */
if (dd->debug_level > 5)
ZOLTAN_TRACE_OUT (dd->my_proc, yo, NULL);
if (dd->debug_level > 0) {
ZOLTAN_PRINT_INFO(dd->my_proc, yo, "GID not found");
return ZOLTAN_WARN;
}
return ZOLTAN_WARN;
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,163 @@
/*
* @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
*/
#include <stdio.h>
#include <stdlib.h>
#include "zoltan_dd_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/* NOTE: See file, README, for associated documentation. (RTH) */
/*****************************************************************************/
/* DD_Hash2 is a hash function for Zoltan ids (local or global).
* It is derived from Zoltan_Hash.
*
* Input:
* key: a key to hash of type ZOLTAN_ID_PTR
* num_id_entries: the number of (ZOLTAN_ID_TYPE-sized) entries of
* the key to use
* n: the range of the hash function is 0..n-1
*
* Return value:
* the hash value, an unsigned integer between 0 and n-1
*/
#define ZZ_MURMUR_HASH
#ifdef ZZ_MURMUR_HASH
#include "murmur3.c"
unsigned int Zoltan_DD_Hash2(ZOLTAN_ID_PTR key, int num_id_entries,
unsigned int n,
void *hashdata, ZOLTAN_HASH_FN *fn)
{
/*
* Algorithm:
* Murmurhash3 as in Zoltan_Hash, with a different seed value.
* MurmurHash3 was written by Austin Appleby, and is placed in the
* public domain. The author hereby disclaims copyright to this source
* code.
*/
uint32_t k;
MurmurHash3_x86_32((void *)key, sizeof(ZOLTAN_ID_TYPE)*num_id_entries,
14, (void *)&k);
return(k % n);
}
#endif /* ZZ_MURMUR_HASH */
#ifdef ZZ_KNUTH_HASH
#define ZOLTAN_DD_HASH_CONSTANT 2654435761U /* consider 516595003U */
unsigned int Zoltan_DD_Hash2(ZOLTAN_ID_PTR key, int num_id_entries,
unsigned int n,
void *hashdata, ZOLTAN_HASH_FN *fn)
{
/*
* Algorithm:
* This hash function is based on Don Knuth's golden ratio
* multiplicative method. Bitwise xor is used for keys
* longer than an int. The method works well for keys
* of size one or two ints, which is typically the case.
*
* This hash function should be replaced with a stronger method
* if good hashing of a large number of keys is important.
*
* Author:
* Erik Boman, eboman@cs.sandia.gov (SNL 9226)
* Replaced explict constant with #define below. Consider changing
* to new constant. Changed name to DD_Hash2. RTH
*/
unsigned int h, rest, *p, bytes, num_bytes;
char *byteptr;
num_bytes = (unsigned int) num_id_entries * sizeof(ZOLTAN_ID_TYPE);
/* 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*ZOLTAN_DD_HASH_CONSTANT) ^ (*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*ZOLTAN_DD_HASH_CONSTANT) ^ rest;
/* Return h mod n */
return (h%n);
}
#endif /* ZOLTAN_KNUTH_HASH */
void Zoltan_DD_default_cleanup (void * hashdata)
{
ZOLTAN_FREE(&hashdata);
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,179 @@
/*
* @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
*/
#include <stdio.h>
#include <stdlib.h>
#include "zoltan_dd_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/*
* Idea: Store hash table as array of bucket heads, pointing into
* an array-based linked list of nodes (instead of to individually
* allocated nodes).
* The array-based memory would have a free-memory list running
* through it, allowing items to be added to or deleted from the
* directory.
*/
/******************************************************************************/
int DD_Memory_Alloc_Nodelist(
Zoltan_DD_Directory *dd, /* directory state information */
DD_NodeIdx count, /* Number of GIDs in update list */
float overalloc /* Percentage to extra nodes to
allocate (for future dynamic
additions). */
)
{
/* Allocate node memory and initialize it to be all free. */
/* Return error code if memory alloc fails. */
int ierr = ZOLTAN_OK;
DD_Node *ptr;
char *dataptr;
DD_NodeIdx nodeidx;
DD_NodeIdx len = count * (1. + overalloc);
dd->nodelistlen = len;
if (len > 0) {
dd->nodelist = (DD_Node *) ZOLTAN_MALLOC(sizeof(DD_Node) * len);
dd->nodedata = (char *) ZOLTAN_MALLOC(dd->nodedata_size * len);
/* TODO ADD ERROR CHECK */
/* Initialize the freenode list; all nodes are initially free. */
/* Also initialize gid pointers to nodedata. */
dd->nextfreenode = 0;
for (ptr = dd->nodelist, dataptr = dd->nodedata, nodeidx = 0;
nodeidx < len;
nodeidx++, ptr++, dataptr += dd->nodedata_size) {
ptr->next = nodeidx + 1;
ptr->gid = (ZOLTAN_ID_PTR) dataptr;
ptr->free = 1;
}
dd->nodelist[len-1].next = -1; /* NULL value at end of list */
}
dd->nodecnt = 0;
return ierr;
}
/******************************************************************************/
DD_NodeIdx DD_Memory_Alloc_Node(Zoltan_DD_Directory *dd)
{
/* "allocate" a node by removing it from the free list and returning
* its NodeIdx.
*/
DD_NodeIdx returnnode;
if (dd->nextfreenode == -1) {
/* No more room for new nodes in the node list.
* Realloc memory and set up a new freelist.
*/
DD_NodeIdx newlen = dd->nodelistlen * 2;
DD_NodeIdx nodeidx;
DD_Node *ptr;
char *dataptr;
dd->nodelist = (DD_Node *) ZOLTAN_REALLOC(dd->nodelist,
sizeof(DD_Node) * newlen);
dd->nodedata = (char *) ZOLTAN_REALLOC(dd->nodedata,
dd->nodedata_size * newlen);
/* TODO ADD ERROR CHECK */
/* Reinitialize the gid pointers in the realloc'ed nodelist. */
for (ptr = dd->nodelist, dataptr = dd->nodedata, nodeidx = 0;
nodeidx < newlen;
ptr++, dataptr += dd->nodedata_size, nodeidx++)
ptr->gid = (ZOLTAN_ID_PTR) dataptr;
/* Initialize free list in the newly extended memory */
dd->nextfreenode = dd->nodelistlen;
for (nodeidx = dd->nodelistlen; nodeidx < newlen-1; nodeidx++) {
dd->nodelist[nodeidx].next = nodeidx+1;
dd->nodelist[nodeidx].free = 1;
}
dd->nodelist[newlen-1].next = -1;
dd->nodelist[newlen-1].free = 1;
dd->nodelistlen = newlen;
}
returnnode = dd->nextfreenode;
dd->nextfreenode = dd->nodelist[returnnode].next;
dd->nodelist[returnnode].next = -1;
dd->nodelist[returnnode].free = 0;
dd->nodecnt++;
return returnnode;
}
/******************************************************************************/
void DD_Memory_Free_Node(
Zoltan_DD_Directory *dd,
DD_NodeIdx freenode
)
{
/* "free" a node by returning it to the free list. */
/* TODO Error check: freenode should be < nodelistlen */
dd->nodelist[freenode].next = dd->nextfreenode;
dd->nodelist[freenode].free = 1;
dd->nextfreenode = freenode;
dd->nodecnt--;
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,69 @@
/*
* @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
*/
#ifndef ZOLTAN_DD_MEMORY_H_
#define ZOLTAN_DD_MEMORY_H_
#include <stdio.h>
#include <stdlib.h>
#include "zoltan_dd_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
extern int *DD_Memory_Alloc_Nodelist(Zoltan_DD_Directory *, DD_NodeIdx , float);
extern DD_NodeIdx DD_Memory_Alloc_Node(Zoltan_DD_Directory *);
extern void DD_Memory_Free_Node(Zoltan_DD_Directory*, DD_NodeIdx);
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif
#endif

View File

@ -0,0 +1,115 @@
/*
* @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
*/
#include <stdio.h>
#include <stdlib.h>
#include "zoltan_dd_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/* NOTE: See file, README, for associated documentation. (RTH) */
/******************** Zoltan_DD_Print() ***********************/
int Zoltan_DD_Print (
Zoltan_DD_Directory *dd) /* contains directory state information */
{
int i,j;
DD_NodeIdx nodeidx;
DD_Node *ptr;
char *yo = "Zoltan_DD_Print";
/* input sanity checks */
if (dd == NULL) {
ZOLTAN_PRINT_ERROR (ZOLTAN_DD_NO_PROC, yo, "NULL dd input argument");
return ZOLTAN_FATAL;
}
if (dd->debug_level > 4)
ZOLTAN_TRACE_IN (dd->my_proc, yo, NULL);
/* walk linked list printing each node */
for (i = 0; i < dd->table_length; i++)
for (nodeidx = dd->table[i]; nodeidx != -1;
nodeidx = dd->nodelist[nodeidx].next) {
ptr = dd->nodelist + nodeidx;
printf ("ZOLTAN DD Print(%d): \tList %3d, \tGID ", dd->my_proc, i);
printf("(");
for (j = 0 ; j < dd->gid_length; j++)
printf(ZOLTAN_ID_SPEC " ", ptr->gid[j]);
printf(") ");
if (dd->lid_length > 0) {
printf("\tLID (");
for (j = 0; j < dd->lid_length; j++)
printf( ZOLTAN_ID_SPEC " ", ptr->gid[j+dd->gid_length]);
printf(") ");
}
printf ("\tPart %d\n", ptr->partition);
printf ("\tOwner %d\n", ptr->owner);
}
if (dd->debug_level > 4)
ZOLTAN_TRACE_OUT (dd->my_proc, yo, NULL) ;
return ZOLTAN_OK;
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,261 @@
/*
* @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
*/
#include <stdio.h>
#include <stdlib.h>
#include "zoltan_dd_const.h"
#include "DD_Memory.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/* NOTE: See file, README, for associated documentation. (RTH) */
static int DD_Remove_Local (Zoltan_DD_Directory *dd, ZOLTAN_ID_PTR gid) ;
/******************** Zoltan_DD_Remove() ***********************/
int Zoltan_DD_Remove (
Zoltan_DD_Directory *dd, /* directory state infomation */
ZOLTAN_ID_PTR gid, /* Incoming list of GIDs to remove */
int count) /* Number of GIDs in removal list */
{
int *procs = NULL; /* list of processors to contact */
DD_Remove_Msg *ptr = NULL;
ZOLTAN_COMM_OBJ *plan = NULL; /* efficient MPI communication */
char *sbuff = NULL; /* send buffer */
char *sbufftmp = NULL;/* pointer into send buffer */
char *rbuff = NULL; /* receive buffer */
char *rbufftmp = NULL;/* pointer into receive buffer */
int nrec; /* number of receives to expect */
int i;
int err; /* error condition to return */
int errcount; /* count of GIDs not found */
char str[100]; /* string to build error messages */
char *yo = "Zoltan_DD_Remove";
/* input sanity checks */
if (dd == NULL || count < 0 || (gid == NULL && count > 0)) {
ZOLTAN_PRINT_ERROR (dd ? dd->my_proc : ZOLTAN_DD_NO_PROC, yo,
"Invalid input argument");
return ZOLTAN_FATAL;
}
if (dd->debug_level > 4)
ZOLTAN_TRACE_IN (dd->my_proc, yo, NULL);
/* allocate memory for processor contact list */
if (count) {
procs = (int*) ZOLTAN_MALLOC (sizeof(int) * count);
if (procs == NULL) {
ZOLTAN_PRINT_ERROR (dd->my_proc, yo, "Unable to malloc proc list");
if (dd->debug_level > 4)
ZOLTAN_TRACE_OUT (dd->my_proc, yo, NULL);
return ZOLTAN_MEMERR;
}
}
/* allocate memory for DD_Remove_Msg send buffer */
if (count) {
sbuff = (char*)ZOLTAN_MALLOC((size_t)(dd->remove_msg_size)*(size_t)count);
if (sbuff == NULL) {
ZOLTAN_PRINT_ERROR (dd->my_proc, yo, "Unable to malloc send buffer");
err = ZOLTAN_MEMERR;
goto fini;
}
}
if (dd->debug_level > 6)
ZOLTAN_PRINT_INFO (dd->my_proc, yo, "After proc & sbuff mallocs");
/* for each GID, fill in contact list and then message structure */
sbufftmp = sbuff;
for (i = 0; i < count; i++) {
procs[i] = dd->hash(gid + i*dd->gid_length, dd->gid_length, dd->nproc,
dd->hashdata, dd->hashfn);
ptr = (DD_Remove_Msg*) sbufftmp;
sbufftmp += dd->remove_msg_size;
ptr->owner = dd->my_proc;
ZOLTAN_SET_ID (dd->gid_length, ptr->gid, gid + i * dd->gid_length);
}
/* now create efficient communication plan */
err = Zoltan_Comm_Create (&plan, count, procs, dd->comm,
ZOLTAN_DD_REMOVE_MSG_TAG, &nrec);
if (err != ZOLTAN_OK) {
ZOLTAN_PRINT_ERROR (dd->my_proc, yo, "Comm_Create error");
goto fini;
}
if (dd->debug_level > 6)
ZOLTAN_PRINT_INFO (dd->my_proc, yo, "After Zoltan_Comm_Create");
/* allocate receive buffer for nrec DD_Remove_Msg structures */
if (nrec) {
rbuff = (char*)ZOLTAN_MALLOC((size_t)nrec*(size_t)(dd->remove_msg_size));
if (rbuff == NULL) {
ZOLTAN_PRINT_ERROR (dd->my_proc, yo, "Receive buffer malloc failed");
err = ZOLTAN_MEMERR;
goto fini;
}
}
/* send my remove messages & receive removes directed to me */
err = Zoltan_Comm_Do (plan, ZOLTAN_DD_UPDATE_MSG_TAG+1, sbuff,
dd->remove_msg_size, rbuff);
if (err != ZOLTAN_OK) {
ZOLTAN_PRINT_ERROR (dd->my_proc, yo, "Comm_Do error");
goto fini;
}
if (dd->debug_level > 6)
ZOLTAN_PRINT_INFO (dd->my_proc, yo, "After Zoltan_Comm_Do");
/* for each message rec'd, remove local directory info */
errcount = 0;
rbufftmp = rbuff;
for (i = 0; i < nrec; i++) {
ptr = (DD_Remove_Msg*) rbufftmp;
rbufftmp += dd->remove_msg_size;
err = DD_Remove_Local (dd, ptr->gid);
if (err == ZOLTAN_WARN)
++errcount;
}
err = ZOLTAN_OK;
if (dd->debug_level) {
sprintf (str, "Processed %d GIDs (%d local), %d GIDs not found",
count, nrec, errcount);
ZOLTAN_PRINT_INFO (dd->my_proc, yo, str);
err = (errcount) ? ZOLTAN_WARN : ZOLTAN_OK;
}
/* done, now free up things and return */
fini:
ZOLTAN_FREE (&procs);
ZOLTAN_FREE (&sbuff);
ZOLTAN_FREE (&rbuff);
Zoltan_Comm_Destroy (&plan);
if (dd->debug_level > 4)
ZOLTAN_TRACE_OUT (dd->my_proc, yo, NULL);
return err;
}
/****************** DD_Remove_Local() **************************/
/* The given global ID, gid, is removed from the local distributed
* directory. An error is returned if the gid is not found.
*/
static int DD_Remove_Local (Zoltan_DD_Directory *dd,
ZOLTAN_ID_PTR gid) /* GID to be removed (in) */
{
DD_Node *ptr;
DD_NodeIdx nodeidx, prevnodeidx;
int index;
char *yo = "DD_Remove_Local";
/* input sanity checking */
if (dd == NULL || gid == NULL) {
ZOLTAN_PRINT_ERROR ((dd == NULL) ? ZOLTAN_DD_NO_PROC : dd->my_proc,
yo, "Invalid input argument");
return ZOLTAN_FATAL;
}
if (dd->debug_level > 5)
ZOLTAN_TRACE_IN (dd->my_proc, yo, NULL);
/* compute offset into hash table to find head of linked list */
index = Zoltan_DD_Hash2 (gid, dd->gid_length, dd->table_length,
dd->hashdata, NULL);
/* walk linked list until end looking for matching gid (key) */
prevnodeidx = -1;
for (nodeidx = dd->table[index]; nodeidx != -1;
nodeidx = dd->nodelist[nodeidx].next) {
ptr = dd->nodelist + nodeidx;
if (ZOLTAN_EQ_ID(dd->gid_length, gid, ptr->gid) == TRUE) {
/* found node to remove, need to preserve its next ptr */
if (prevnodeidx != -1)
dd->nodelist[prevnodeidx].next = ptr->next;
else
dd->table[index] = ptr->next;
DD_Memory_Free_Node(dd, nodeidx); /* now OK to delete node */
if (dd->debug_level > 5)
ZOLTAN_TRACE_OUT (dd->my_proc, yo, NULL);
return ZOLTAN_OK;
}
prevnodeidx = nodeidx;
}
/* We get here only if the global ID has not been found */
if (dd->debug_level > 5)
ZOLTAN_TRACE_OUT (dd->my_proc, yo, NULL);
return ZOLTAN_WARN;
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,101 @@
/*
* @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
*/
#include <stdio.h>
#include <stdlib.h>
#include "zoltan_dd_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/* NOTE: See file, README, for associated documentation. (RTH) */
static unsigned int dd_hash_user (
ZOLTAN_ID_PTR gid, int gid_length,
unsigned int nproc,
void *data,
ZOLTAN_HASH_FN *fn)
{
return (*fn)(gid, gid_length, nproc);
}
/************* Zoltan_DD_Set_Hash_Fn() ***********************/
int Zoltan_DD_Set_Hash_Fn (
Zoltan_DD_Directory *dd, /* directory state information */
ZOLTAN_HASH_FN *hash)
{
char *yo = "Zoltan_DD_Set_Hash_Fn";
/* input sanity checking */
if (dd == NULL || hash == NULL) {
ZOLTAN_PRINT_ERROR (0, yo, "Invalid input argument");
return ZOLTAN_FATAL ;
}
dd->hash = (DD_Hash_fn*)dd_hash_user;
dd->hashdata = NULL;
dd->hashfn = hash;
dd->cleanup = (DD_Cleanup_fn*) NULL;
if (dd->debug_level > 0)
ZOLTAN_PRINT_INFO (dd->my_proc, yo, "Successful");
return ZOLTAN_OK;
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,124 @@
/*
* @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
*/
#include <stdio.h>
#include <stdlib.h>
#include "zoltan_dd_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
struct dd_nh1_struct {
int max_gid ;
int groupsize ;
};
static unsigned int dd_nh1 (ZOLTAN_ID_PTR gid, int gid_length,
unsigned int nproc, struct dd_nh1_struct* hashdata, ZOLTAN_HASH_FN *fn) ;
/************* Zoltan_DD_Set_Hash_Fn1() ***********************/
/*
** These routines associate the first n=groupsize GIDs to proc 0, the
** next n to proc 1, etc. It assumes the GIDs are consecutive numbers.
** It assumes that GIDs primarily stay near their original owner. The
** GID length is assumed to be 1. GIDs outside of range are evenly
** distributed among the processors via modulo(nproc).
*/
int Zoltan_DD_Set_Neighbor_Hash_Fn1 (
Zoltan_DD_Directory *dd, /* directory state information */
int size) /* number of reserved GIDs per CPU */
{
char *yo = "Zoltan_DD_Set_Neighbor_Hash_Fn1";
struct dd_nh1_struct *hashdata;
if (dd == NULL) {
ZOLTAN_PRINT_ERROR (0, yo, "NULL DDirectory pointer");
return ZOLTAN_FATAL;
}
if (size < 1) {
ZOLTAN_PRINT_WARN (0, yo, "Invalid input argument; size < 1");
return ZOLTAN_WARN;
}
hashdata = (struct dd_nh1_struct*) ZOLTAN_MALLOC(sizeof(struct dd_nh1_struct));
if (hashdata == NULL) {
ZOLTAN_PRINT_ERROR (0, yo, "Memory error");
return ZOLTAN_FATAL;
}
hashdata->groupsize = size;
dd->hash = (DD_Hash_fn*) &dd_nh1;
dd->hashfn = NULL;
dd->hashdata = hashdata;
dd->cleanup = (DD_Cleanup_fn*) &Zoltan_DD_default_cleanup;
hashdata->max_gid = size * dd->nproc; /* larger GIDs out of range */
return ZOLTAN_OK;
}
static unsigned int dd_nh1 (ZOLTAN_ID_PTR gid, int gid_length,
unsigned int nproc, struct dd_nh1_struct* hashdata, ZOLTAN_HASH_FN *fn)
{
int id = (signed) *gid;
return (unsigned int) ((id < hashdata->max_gid) ? (id / hashdata->groupsize)
: (id % (int)nproc));
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,213 @@
/*
* @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
*/
#include <stdio.h>
#include <stdlib.h>
#include "zoltan_dd_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
typedef struct
{
int high;
int low;
int proc;
} Range_Info;
struct dd_nh2_struct {
Range_Info *ptr;
int nproc;
int low_limit;
int high_limit;
int debug_level;
int count;
};
static unsigned int dd_nh2 (ZOLTAN_ID_PTR gid, int gid_length,
unsigned int nproc, struct dd_nh2_struct* hashdata, ZOLTAN_HASH_FN *fn);
static int compare_sort (const void *a, const void *b);
static int compare_search (const void *a, const void *b);
static void dd_nh2_cleanup (struct dd_nh2_struct* hashdata);
/************* Zoltan_DD_Set_Hash_Fn2() ***********************/
/*
** These routines allow the user to specify a beginning and ending GID
** (number) per processor to associate an arbitrary GID to its orginal
** owner processor. It assumes the GIDs are consecutive numbers.
** It assumes that GIDs primarily stay near their original owner. It
** requires that the number of high, low, & proc entries is 'n'. It
** assumes the GID length is 1.
*/
int Zoltan_DD_Set_Neighbor_Hash_Fn2 (
Zoltan_DD_Directory *dd, /* directory state information */
int *proc, /* list of processors for following info */
int *low, /* lowest GID for corresponding processor */
int *high, /* highest GID for corresponding processor */
int n) /* number of processors in above lists */
{
int i;
char *yo = "Zoltan_DD_Set_Hash_Fn2";
struct dd_nh2_struct *hashdata;
if (dd == NULL || proc == NULL || low == NULL || high == NULL) {
ZOLTAN_PRINT_ERROR (0, yo, "Invalid input argument");
return ZOLTAN_FATAL;
}
hashdata = (struct dd_nh2_struct*) ZOLTAN_MALLOC(sizeof(struct dd_nh2_struct));
if (hashdata == NULL) {
ZOLTAN_PRINT_ERROR (0, yo, "Memory error");
return ZOLTAN_FATAL;
}
/* register functions for automatic invocation */
dd->hash = (DD_Hash_fn*) &dd_nh2;
dd->hashdata = hashdata;
dd->hashfn = NULL;
dd->cleanup = (DD_Cleanup_fn*)&dd_nh2_cleanup;
/* malloc and initialize storage for range information structures */
hashdata->ptr = (Range_Info*) ZOLTAN_MALLOC (n * sizeof (Range_Info));
if (hashdata->ptr == NULL) {
ZOLTAN_PRINT_ERROR (dd->my_proc, yo, "Unable to Malloc range info");
return ZOLTAN_MEMERR;
}
for (i = 0; i < n; i++) {
hashdata->ptr[i].high = high[i] ;
hashdata->ptr[i].low = low [i] ;
hashdata->ptr[i].proc = (proc[i] < n) ? proc[i] : 0;
}
/* do not assume user lists were ordered */
qsort (hashdata->ptr, n, sizeof (Range_Info), compare_sort);
hashdata->low_limit = hashdata->ptr[0].low;
hashdata->high_limit = hashdata->ptr[n-1].high;
hashdata->debug_level = dd->debug_level;
hashdata->count = n;
hashdata->nproc = dd->nproc;
return ZOLTAN_OK;
}
static unsigned int dd_nh2 (ZOLTAN_ID_PTR gid, int gid_length,
unsigned int junk, struct dd_nh2_struct* hashdata, ZOLTAN_HASH_FN *fn)
{
Range_Info *p;
char *yo = "dd_ny2";
int id = (signed) *gid;
/* check if gid is out of range */
if (id > hashdata->high_limit || id < hashdata->low_limit)
return id % hashdata->nproc;
p = (Range_Info*) bsearch (gid, hashdata->ptr, hashdata->count, sizeof (Range_Info),
compare_search);
if (p == NULL) { /* shouldn't happen */
if (hashdata->debug_level > 1)
ZOLTAN_PRINT_ERROR (0, yo, "C function bsearch returned NULL.") ;
return id % hashdata->nproc;
}
return p->proc;
}
static int compare_sort (const void *a, const void *b)
{
if (((Range_Info*) a)->low < ((Range_Info *) b)->low) return -1;
if (((Range_Info*) a)->low > ((Range_Info *) b)->low) return 1;
else return 0 ;
}
static int compare_search (const void *a, const void *b)
{
int temp = (signed) *((ZOLTAN_ID_TYPE *) a);
if (temp < ((Range_Info*) b)->low) return -1;
if (temp > ((Range_Info*) b)->high) return 1;
else return 0 ;
}
static void dd_nh2_cleanup (struct dd_nh2_struct *hashdata)
{
if (hashdata == NULL) return;
ZOLTAN_FREE (&hashdata->ptr);
ZOLTAN_FREE (&hashdata);
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,129 @@
/*
* @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
*/
#include <stdio.h>
#include <stdlib.h>
#include "zoltan_dd_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
struct dd_nh3_struct {
int remainder;
int average;
int breakpt;
int total_;};
static unsigned int dd_nh3 (ZOLTAN_ID_PTR gid, int gid_length,
unsigned int nproc, struct dd_nh3_struct* hashdata, ZOLTAN_HASH_FN *);
/************* Zoltan_DD_Set_Hash_Fn3() ***********************/
/*
** These routines associate the first n=groupsize GIDs to proc 0, the
** next n to proc 1, etc. It assumes the GIDs are consecutive numbers.
** It assumes that GIDs primarily stay near their original owner. The
** GID length is assumed to be 1. GIDs outside of range are evenly
** distributed among the processors via modulo(nproc). This method
** is designed for Trilinos/Epetra linear map.
*/
int Zoltan_DD_Set_Neighbor_Hash_Fn3 (
Zoltan_DD_Directory *dd, /* directory state information */
int total) /* total number of GIDS */
{
char *yo = "Zoltan_DD_Set_Hash_Fn3";
struct dd_nh3_struct *hashdata;
if (dd == NULL || total < 1) {
ZOLTAN_PRINT_ERROR (0, yo, "Invalid input argument");
return ZOLTAN_FATAL;
}
hashdata = (struct dd_nh3_struct*) ZOLTAN_MALLOC(sizeof(struct dd_nh3_struct));
if (hashdata == NULL) {
ZOLTAN_PRINT_ERROR (0, yo, "Memory error");
return ZOLTAN_FATAL;
}
hashdata->total_ = total;
hashdata->average = total / dd->nproc;
hashdata->remainder = total % dd->nproc;
hashdata->breakpt = (hashdata->average+1) * hashdata->remainder;
dd->hash = (DD_Hash_fn*) &dd_nh3;
dd->hashdata = hashdata;
dd->hashfn = NULL;
dd->cleanup = (DD_Cleanup_fn*)&Zoltan_DD_default_cleanup;
return ZOLTAN_OK;
}
static unsigned int dd_nh3 (ZOLTAN_ID_PTR gid, int gid_length,
unsigned int nproc, struct dd_nh3_struct * hashdata, ZOLTAN_HASH_FN *fn)
{
int id = (signed) *gid;
if (id < hashdata->breakpt)
return id/(hashdata->average+1);
if (id < hashdata->total_)
return hashdata->remainder + (id-hashdata->breakpt)/hashdata->average;
return 0; /* error, gid is out of range */
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,124 @@
/*
* @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
*/
#include <stdio.h>
#include <stdlib.h>
#include "zoltan_dd_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/* NOTE: See file, README, for associated documentation. (RTH) */
/******************* Zoltan_DD_Stats() ***************************/
void Zoltan_DD_Stats (
Zoltan_DD_Directory *dd) /* directory state information */
{
int node_count = 0; /* counts Nodes in local directory */
int maxlength = 0; /* length of longest linked list */
int list_count = 0; /* number of linked lints in hash table */
int length;
int i;
DD_NodeIdx nodeidx;
DD_Node *ptr;
char str[100]; /* used to build message string */
char *yo = "Zoltan_DD_Stats";
/* Input sanity check */
if (dd == NULL) {
ZOLTAN_PRINT_ERROR (0, yo, "Invalid input argument.");
return;
}
if (dd->debug_level > 4)
ZOLTAN_TRACE_IN (dd->my_proc, yo, NULL);
/* walk down each list in hash table to find every Node */
for (i = 0; i < dd->table_length; i++) {
length = 0; /* reset length for next count */
if (dd->table[i] != -1)
list_count++; /* count of distict linked lists */
for (nodeidx = dd->table[i]; nodeidx != -1;
nodeidx = dd->nodelist[nodeidx].next) {
ptr = dd->nodelist + nodeidx;
if (dd->debug_level > 6) {
sprintf(str, "GID " ZOLTAN_ID_SPEC ", Owner %d, Table Index %d.",
*ptr->gid, ptr->owner, i);
ZOLTAN_PRINT_INFO (dd->my_proc, yo, str);
}
length++; /* linked list length */
node_count++; /* count of Nodes */
}
if (length > maxlength)
maxlength = length; /* save length of longest linked list */
}
sprintf(str, "Hash table size %d, %d nodes on %d lists, max list length %d.",
dd->table_length, node_count, list_count, maxlength);
ZOLTAN_PRINT_INFO (dd->my_proc, yo, str);
if (dd->debug_level > 4)
ZOLTAN_TRACE_OUT (dd->my_proc, yo, NULL);
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,358 @@
/*
* @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
*/
#include <stdio.h>
#include <stdlib.h>
#include "zoltan_dd_const.h"
#include "DD_Memory.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
static int DD_Update_Local (Zoltan_DD_Directory *dd, ZOLTAN_ID_PTR gid,
ZOLTAN_ID_PTR lid, char *user, int partition, int owner);
/****************** Zoltan_DD_Update() *************************/
int Zoltan_DD_Update (
Zoltan_DD_Directory *dd, /* directory state information */
ZOLTAN_ID_PTR gid, /* Incoming list of GIDs to update */
ZOLTAN_ID_PTR lid, /* Incoming corresponding LIDs (optional) */
char *user, /* Incoming list of user data (optional) */
int *partition, /* Optional, grouping of GIDs to partitions */
int count) /* Number of GIDs in update list */
{
int *procs = NULL; /* list of processors to contact */
DD_Update_Msg *ptr = NULL;
ZOLTAN_COMM_OBJ *plan = NULL; /* for efficient MPI communication */
char *sbuff = NULL; /* send buffer */
char *sbufftmp = NULL;/* pointer into send buffer */
char *rbuff = NULL; /* receive buffer */
char *rbufftmp = NULL;/* pointer into receive buffer */
int nrec = 0; /* number of receives to expect */
int i;
int err;
int errcount = 0; /* count of GIDs not found, added */
char str[100]; /* build error message string */
char *yo = "Zoltan_DD_Update";
/* input sanity checking */
if (dd == NULL || count < 0 || (gid == NULL && count > 0)) {
ZOLTAN_PRINT_ERROR ((dd == NULL ? ZOLTAN_DD_NO_PROC : dd->my_proc), yo,
"Invalid input argument");
return ZOLTAN_FATAL;
}
if (dd->debug_level > 4)
ZOLTAN_TRACE_IN(dd->my_proc, yo, NULL);
/* part of initializing the error checking process */
/* for each linked list head, walk its list resetting errcheck */
if (dd->debug_level)
for (i = 0; i < dd->table_length; i++) {
DD_NodeIdx nodeidx;
for (nodeidx = dd->table[i]; nodeidx != -1;
nodeidx = dd->nodelist[nodeidx].next)
dd->nodelist[nodeidx].errcheck = ZOLTAN_DD_NO_PROC;
}
if (dd->debug_level > 6)
ZOLTAN_PRINT_INFO(dd->my_proc, yo, "After reset errcheck");
/* allocate memory for list of processors to contact */
if (count) {
procs = (int*) ZOLTAN_MALLOC (sizeof(int) * count);
if (procs == NULL) {
ZOLTAN_PRINT_ERROR (dd->my_proc, yo, "Unable to malloc proc list");
err = ZOLTAN_MEMERR;
goto fini;
}
}
/* allocate memory for DD_Update_Msg send buffer */
if (count) {
sbuff = (char*) ZOLTAN_CALLOC (count, dd->update_msg_size);
if (sbuff == NULL) {
ZOLTAN_PRINT_ERROR (dd->my_proc, yo, "Unable to malloc send buffer");
err = ZOLTAN_MEMERR;
goto fini;
}
}
if (dd->debug_level > 6)
ZOLTAN_PRINT_INFO(dd->my_proc, yo, "After mallocs");
/* for each GID given, fill in contact list and then message structure */
sbufftmp = sbuff;
for (i = 0; i < count; i++) {
procs[i] = dd->hash(gid + i*dd->gid_length, dd->gid_length, dd->nproc,
dd->hashdata, dd->hashfn);
ptr = (DD_Update_Msg*) sbufftmp;
sbufftmp += dd->update_msg_size;
ptr->lid_flag = (lid) ? 1 : 0;
ptr->user_flag = (user) ? 1 : 0;
ptr->partition_flag = (partition) ? 1 : 0;
ptr->partition = (partition) ? *(partition + i) : -1;
ptr->owner = dd->my_proc;
ZOLTAN_SET_ID (dd->gid_length, ptr->gid, gid + i * dd->gid_length);
if (lid) {
ZOLTAN_SET_ID(dd->lid_length, ptr->gid + dd->gid_length,
lid + i * dd->lid_length);
}
else {
memset(ptr->gid + dd->gid_length, 0, dd->lid_length);
}
if (user) {
memcpy(ptr->gid + (dd->gid_length + dd->lid_length),
user + (size_t)i * (size_t)(dd->user_data_length),
dd->user_data_length);
}
else {
memset(ptr->gid + (dd->gid_length + dd->lid_length), 0,
dd->user_data_length);
}
}
if (dd->debug_level > 6)
ZOLTAN_PRINT_INFO(dd->my_proc, yo, "After fill contact list");
/* now create efficient communication plan */
err = Zoltan_Comm_Create (&plan, count, procs, dd->comm,
ZOLTAN_DD_UPDATE_MSG_TAG, &nrec);
if (err != ZOLTAN_OK) {
ZOLTAN_PRINT_ERROR (dd->my_proc, yo, "Comm_Create error");
goto fini;
}
if (dd->debug_level > 6)
ZOLTAN_PRINT_INFO(dd->my_proc, yo, "After Comm_Create");
/* If dd has no nodes allocated (e.g., first call to DD_Update;
* create the nodelist and freelist
*/
if (nrec && dd->nodelistlen == 0) {
DD_Memory_Alloc_Nodelist(dd, (DD_NodeIdx) nrec, 0.);
/* TODO Add overalloc parameter */
}
/* allocate receive buffer for nrec DD_Update_Msg structures */
if (nrec) {
rbuff = (char*)ZOLTAN_MALLOC((size_t)nrec*(size_t)(dd->update_msg_size));
if (rbuff == NULL) {
ZOLTAN_PRINT_ERROR (dd->my_proc, yo, "Receive buffer malloc failed");
err = ZOLTAN_MEMERR;
goto fini;
}
}
/* send my update messages & receive updates directed to me */
err = Zoltan_Comm_Do (plan, ZOLTAN_DD_UPDATE_MSG_TAG+1, sbuff,
dd->update_msg_size, rbuff);
if (err != ZOLTAN_OK) {
ZOLTAN_PRINT_ERROR (dd->my_proc, yo, "Comm_Do error");
goto fini;
}
if (dd->debug_level > 6)
ZOLTAN_PRINT_INFO(dd->my_proc, yo, "After Comm_Do");
/* for each message rec'd, update local directory information */
errcount = 0;
rbufftmp = rbuff;
for (i = 0; i < nrec; i++) {
ptr = (DD_Update_Msg *) rbufftmp;
rbufftmp += dd->update_msg_size;
err = DD_Update_Local (dd, ptr->gid,
(ptr->lid_flag) ? (ptr->gid + dd->gid_length) : NULL,
(char*)((ptr->user_flag)?(ptr->gid+(dd->gid_length+dd->lid_length)):NULL),
(ptr->partition_flag) ? (ptr->partition) : -1, /* illegal partition */
ptr->owner);
if (err != ZOLTAN_OK)
++errcount;
}
if (dd->debug_level > 6)
ZOLTAN_PRINT_INFO(dd->my_proc, yo, "After Local update");
err = ZOLTAN_OK;
if (dd->debug_level) /* overwrite error return if extra checking is on */
err = (errcount) ? ZOLTAN_WARN : ZOLTAN_OK;
fini:
ZOLTAN_FREE (&procs);
ZOLTAN_FREE (&sbuff);
ZOLTAN_FREE (&rbuff);
Zoltan_Comm_Destroy (&plan);
if (dd->debug_level) {
sprintf (str, "Processed %d GIDs (%d local), %d GID errors", count,
nrec, errcount);
ZOLTAN_PRINT_INFO (dd->my_proc, yo, str);
}
if (dd->debug_level > 4)
ZOLTAN_TRACE_OUT(dd->my_proc, yo, NULL);
return err;
}
/***************** DD_Update_Local () **********************/
/* DD_Update_Local() unconditionally updates the information associated
* with a global ID. If the gid was not found, it is added to the directory.
*/
static int DD_Update_Local (Zoltan_DD_Directory *dd,
ZOLTAN_ID_PTR gid, /* GID to update (in) */
ZOLTAN_ID_PTR lid, /* gid's LID (in), NULL if not needed */
char *user, /* gid's user data (in), NULL if not needed */
int partition, /* gid's partition (in), -1 if not used */
int owner) /* gid's current owner (proc number) (in) */
{
int index;
char *yo = "DD_Update_Local";
DD_NodeIdx nodeidx;
DD_Node *ptr;
/* input sanity checking */
if (dd == NULL || owner < 0 || owner >= dd->nproc || gid == NULL) {
ZOLTAN_PRINT_ERROR (dd ? dd->my_proc : ZOLTAN_DD_NO_PROC, yo,
"Invalid input parameter");
return ZOLTAN_FATAL;
}
if (dd->debug_level > 5)
ZOLTAN_TRACE_IN (dd->my_proc, yo, NULL);
/* compute offset into hash table to find head of linked list */
index = Zoltan_DD_Hash2 (gid, dd->gid_length, dd->table_length,
dd->hashdata, NULL);
/* walk linked list until end looking for matching gid */
for (nodeidx = dd->table[index]; nodeidx != -1;
nodeidx = dd->nodelist[nodeidx].next) {
ptr = dd->nodelist + nodeidx;
if (ZOLTAN_EQ_ID (dd->gid_length, gid, ptr->gid) == TRUE) {
/* found match, update directory information */
if (lid)
ZOLTAN_SET_ID (dd->lid_length,ptr->gid + dd->gid_length, lid);
if (user)
memcpy(ptr->gid + (dd->gid_length + dd->lid_length), user,
dd->user_data_length);
ptr->owner = owner;
if (partition != -1)
ptr->partition = partition;
/* Response to multiple updates to a gid in 1 update cycle */
if (dd->debug_level > 0 && ptr->errcheck != owner) {
ZOLTAN_PRINT_INFO (dd->my_proc, yo, "Multiply defined GID");
if (dd->debug_level > 4)
ZOLTAN_TRACE_OUT (dd->my_proc, yo, NULL);
return ZOLTAN_WARN;
}
ptr->errcheck = owner;
if (dd->debug_level > 5)
ZOLTAN_TRACE_OUT (dd->my_proc, yo, NULL);
return ZOLTAN_OK; /* ignore all errors */
}
}
/* gid not found. Create new DD_Node and fill it in */
nodeidx = DD_Memory_Alloc_Node(dd);
ptr = dd->nodelist + nodeidx;
ZOLTAN_SET_ID (dd->gid_length, ptr->gid, gid);
if (lid) {
ZOLTAN_SET_ID(dd->lid_length,ptr->gid + dd->gid_length, lid);
}
else {
memset(ptr->gid + dd->gid_length, 0,
dd->lid_length*sizeof(ZOLTAN_ID_TYPE));
}
if (user) {
memcpy(ptr->gid + (dd->gid_length + dd->lid_length), user,
dd->user_data_length);
}
else {
memset(ptr->gid + (dd->gid_length+dd->lid_length), 0,
dd->user_data_length);
}
ptr->partition = partition;
ptr->owner = owner;
ptr->errcheck = owner;
/* Add node to the linked list */
ptr->next = dd->table[index];
dd->table[index] = nodeidx;
if (dd->debug_level > 6)
ZOLTAN_PRINT_INFO (dd->my_proc, yo, "Created new directory item");
if (dd->debug_level > 5)
ZOLTAN_TRACE_OUT (dd->my_proc, yo, NULL);
return ZOLTAN_OK;
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,458 @@
# @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
ZOLTAN Distributed Directory (DD) Software Documentation
The owner (i.e. the processor number) of any computational object is
subject to change during computation as a result of load balancing.
An application may use this directory module to find objects when it
needs them. A distributed directory balances the load (in terms of
memory and processing time) and avoids the bottle neck of a centralized
directory design.
This distributed directory module may be used alone or in conjunction
with Zoltan's load balancing capability and memory and communication
services. The user should note that external names (subroutines, etc.)
which prefaced by Zoltan_DD_ are reserved when using this module.
The user initially creates an empty distributed directory using
Zoltan_DD_Create. Then GID information is added to the directory using
Zoltan_DD_Update. Zoltan_DD_Update is also called after data migration
or refinements. The directory maintains the global ID's basic
information: local ID (optional), partition (optional), arbitrary user
data (optional), and current data owner. Zoltan_DD_Find returns this
information for a list of global IDs. When the user has finished using
the directory, its memory is returned to the system by Zoltan_DD_Destroy.
When necessary, a selected list of global IDs may be removed from the
directory by Zoltan_DD_Remove.
An object is known by its global ID. Hashing provides very fast
lookup for the information associated with a global ID in a two step
process. The first hash of the global ID yields the processor number
owning the directory entry for that global ID. The directory entry
owner remains constant even if the object (global ID) migrates in time.
Second, a different hash algorithm of the global ID looks up the
associated information in directory processor's hash table. The user
may optionally register their own (first) hash function to take
advantage of their knowledge of their global ID naming scheme and the
global ID's neighboring processors. See the documentation for
Zoltan_DD_Hash() for more information. If no user hash function is
registered, Zoltan's LB_Hash() will be used for the first hash. This
module's design was strongly influenced by the paper "Communication
Support for Adaptive Computation" by Pinar and Hendrickson.
The files DD_Set_Neighbor_Hash_Fn1 and DD_Set_Neighbor_Hash_Fn1 provide
examples of how a user can create their own hash functions taking advantage
of their knowledge of how the GID naming scheme might correlate to a
reasonable location for its directory information. These are also fully
tested and useful functions.
-----------------------------------
-----------------------------------
Source code location: Utilities/Directory
Function prototype file: Utilities/Directory/DD_Const.h
Library name: libzoltan_dd.a
Other libraries used by this library:
libmpi.a
libzoltan_mem.a
libzoltan_comm.a
Other header files used by this library
mem_const.h
comm_const.h
zoltan_util.h
Data Stuctures:
Zoltan_DD_Directory: state & storage used by all DD routines.
Routines:
Zoltan_DD_Create: Allocates memory and initializes the directory.
Zoltan_DD_Destroy: Terminate the directory and frees its memory.
Zoltan_DD_Update: Adds or updates global IDs' directory information.
Zoltan_DD_Find: Returns global IDs' information (owner, local ID, etc.)
Zoltan_DD_Remove: Eliminates selected global IDs from the directory.
Zoltan_DD_Stats: Provides statistics about hash table & linked lists.
Zoltan_DD_Print: Displays the contents (GIDs, etc) of each directory.
Zoltan_DD_Set_Hash_Fn: Registers a user's optional hash function.
Zoltan_DD_Set_Hash_Fn1: Model for user's to create their own hash function.
Zoltan_DD_Set_Hash_Fn2: Model for user's to create their own hash function.
Internal Data Structures: (not user accessable)
DD_Node: linked list element storing information about a global ID
DD_Update_Msg: Message with new data about global IDs
DD_Find_Msg: Messages to/from directory returning global IDs' info
DD_Remove_Msg: Message to eliminate all traces of selected global IDs.
Internal Routines: (not user callable)
DD_Update_Local:
DD_Find_local:
DD_Remove_Local:
DD_Hash2: // renamed copy of LB_Hash
Files in DDirectory:
DD_Const.h // return error codes, prototypes, structures
DD_Create.c
DD_Destroy.c
DD_Find.c
DD_Hash2.c
DD_Remove.c
DD_Set_Hash_Fn.c
DD_Set_Neighbor_Hash_Fn.c
DD_Stats.c
DD_Update.c
DD_Set_Hash_Fn1.c
DD_Set_Hash_Fn2.c
README // this file
---------------------------------------
---------------------------------------
int Zoltan_DD_Create (Zoltan_DD_Directory **dd, MPI_Comm comm,
int num_gid, int num_lid, int user_length, int table_length,
int debug_level)
----------------------------------------
Zoltan_DD_Create() allocates and initializes memory for the DD_Directory
structure. It must be called before any other distributed directory
routines. MPI must be initialized prior to calling Zoltan_DD_Create().
The DD_Directory struct must be passed to all other distributed directory
routines. The MPI Comm argument designates the processors used for the
distributed directory. The MPI Comm argument is duplicated and stored for
later use.
Note the need for double indirection in the DD_Directory calling argument
in order to allocate memory in behalf of the user program.
The user can set the debug level argument in the Zoltan_DD_Create()
to determine the module's response to multiple updates for any global ID
within one update cycle. If the argument is set to 0, all multiple updates
are ignored (but the last determines the directory information.) If the
argument is set to 1, an error is returned if the multiple updates
represent different owners for the same global ID. If the debug level is 2,
an error return and an error message are generated if multiple updates
represent different owners for the same global ID. If the level is 3, an
error return and an error message are generated for a multiple update even
if the updates represent the same owner for a global ID.
Arguments: (all are in)
dd Structure maintains directory state and hash table. (in/out)
comm MPI comm dup'ed & stored specifying directory processors.
num_gid Length of global ID.
num_lid Length of local ID or zero to ignore local IDs.
user_length Length of user defined data field (optional, may be zero).
table_length Length of hash table (zero forces default value).
debug_level Legal values range in [0,3]. Sets response to various error
conditions where 3 is the most verbose.
Return Value:
int Error code.
----------------------------------
----------------------------------
void Zoltan_DD_Destroy (Zoltan_DD_Directory **dd)
----------------------------------
This routine frees all memory allocated for the distributed directory.
No calls to any distributed directory functions are permitted after
calling this routine. Free() has no error return. Hence this routine
has no practical error return. MPI is necessary for this routine only
to free the previously saved MPI comm.
Arguments:
dd Directory structure to be deallocated
Returned Value:
NONE
-----------------------------------
-----------------------------------
int Zoltan_DD_Update (Zoltan_DD_Directory *dd, LB_ID_PTR gid,
LB_ID_PTR lid, LB_ID_PTR user, int *partition, int count)
-----------------------------------
Zoltan_DD_Update() takes a list of global IDs and corresponding lists of
optional local IDs, optional user data, and optional partitions. This
routine updates the information for existing directory entries or creates
a new entry (filled with given data) if a global ID is not found. NULL
lists should be passed for optional arguments not desired. If all
entries were found (and updated), the return is ZOLTAN_DD_NORMAL_RETURN.
If at least one global ID was not found, the return value is
ZOLTAN_DD_GID_ADDED. This function should be called initially and
whenever objects are migrated to keep the distributed directory current.
The user can set the debug level argument in the Zoltan_DD_Create()
to determine the module's response to multiple updates for any global ID
within one update cycle. If the argument is set to 0, all multiple updates
are ignored (but the last determines the directory information.) If the
argument is set to 1, an error is returned if the multiple updates
represent different owners for the same global ID. If the debug level is 2,
an error return and an error message are generated if multiple updates
represent different owners for the same global ID. If the level is 3, an
error return and an error message are generated for a multiple update even
if the updates represent the same owner for a global ID.
Arguments:
dd Distributed directory structure state information.
gid List of global IDs to update (in).
lid List of corresponding local IDs (optional) (in).
user List of corresponding user data (optional) (in).
partition List of corresponding partitions (optional) (in).
count Number of global IDs in update list.
Returned Value:
int Error code.
------------------------------------
------------------------------------
int Zoltan_DD_Find (Zoltan_DD_DDirectory *dd, LB_ID_PTR gid,
LB_ID_PTR lid, LB_ID_PTR data, int *partition, int count,
int *owner)
------------------------------------
Given a list of global IDs, Zoltan_DD_Find() returns corresponding
lists of the global IDs' owners, local IDs, partitions, and optional
user data. NULL lists must be provided for optional information not
being used.
Arguments:
dd Distributed directory structure state information.
gid List of global IDs whose information is requested.
lid Corresponding list of local IDs (optional) (out).
data Corresponding list of user data (optional) (out).
partition Corresponding list of partitions (optional) (out).
count Count of global IDs in above list
owner Corresponding list of data owners (out).
Returned Value:
int Error code.
------------------------------------
------------------------------------
int Zoltan_DD_Remove (Zoltan_DD_Directory *dd, LB_ID_PTR gid,
int count)
------------------------------------
Zoltan_DD_Remove() takes a list of global_IDs and removes all of
their information from the distributed directory.
Arguments:
dd Distributed directory structure state information.
gid List of global IDs to eliminate from the directory.
count Number of global IDs to be removed.
Returned Value:
int Error code.
-------------------------------------
-------------------------------------
void Zoltan_DD_Set_Hash_Fn (Zoltan_DD_Directory *dd,
unsigned int (*hash) (LB_ID_PTR, int, unsigned int))
-------------------------------------
Enables the user to register a new hash function for the distributed
directory. (If this routine is not called, the default hash function
LB_Hash() will be used automatically.) This hash function determines
which processor maintains the distributed directory entry for a given
global ID. Inexperienced users do not need this routine.
Experienced users may elect to create their own hash function based on
their knowledge of their global ID naming scheme. The user's hash
function must have calling arguments compatible with LB_Hash().
Consider that a user has defined a hash function, myhash, as
unsigned int myhash(LB_ID_PTR gid, int length, unsigned int naverage)
{
return *gid / naverage ; // length assumed to be 1
// naverage = total_gids/nproc
}
Then the call to register this hash function is:
Zoltan_DD_Set_Hash (myhash) ;
NOTE: This hash function might group the gid's directory information
near the gid's owning processor's neighborhood, for an
appropriate naming scheme.
Arguments:
dd Distributed directory structure state information.
hash Name of user's hash function.
Returned Value:
NONE
----------------------------------------
----------------------------------------
void Zoltan_DD_Stats (Zoltan_DD_Directory *dd)
----------------------------------------
This routine prints out summary information about the local distributed
directory. It includes the hash table length, number of GIDs stored in
the local directory, the number of linked lists, and the length of the
longest linked list. The dd->debug_level (set by an argument into the
Zoltan_DD_Create function controls this routines verbosity.
Arguments:
dd Distributed directory structure for state information
Returned Value:
NONE
----------------------------------------
----------------------------------------
int Zoltan_DD_Set_Neighbor_Hash_Fn1 (Zoltan_DD_Directory *dd, int size)
----------------------------------------
This routine associates the first size GIDs to proc 0, the next size to
proc 1, etc. It assumes the GIDs are consecutive numbers. It assumes
that GIDs primarily stay near their original owner. The GID length is
assumed to be 1. GIDs outside of the range are evenly distributed among
the processors via modulo(nproc). This is a model for the user to develop
their own similar routine.
Arguments: (all are in)
dd Structure maintains directory state and hash table.
size Number of consecutive GIDs associated with a processor.
Return Value:
int Error Code.
----------------------------------------
----------------------------------------
int Zoltan_DD_Set_Neighbor_Hash_Fn2 (Zoltan_DD_Directory *dd, int *proc,
int *low, int *high, int n)
----------------------------------------
This routine allows the user to specify a beginning and ending GID
"numbers" per directory processor. It assumes that GIDs primarily stay
near their original owner. It requires that the numbers of high, low, &
proc entries are all n. It assumes the GID length is 1. It is a model for
the user to develop their own similar routine. Users should note the
registration of a cleanup routine to free local static memory when the
distributed directory is destroyed. GIDs outside the range specified by
high and low lists are evenly distributed among the processors via modulo
(nproc).
Arguments: (all are in)
dd Structure maintains directory state and hash table.
proc List of processor ids labeling for corresponding high, low value.
low List of low GID limits corresponding to proc list.
high List of high GID limits corresponding to proc list.
n Number of elements in the above lists. Should be nproc!
Return Value:
int Error Code.
----------------------------------------
----------------------------------------
int Zoltan_DD_Print (Zoltan_DD_Directory *dd)
----------------------------------------
This utility displays (to stdout) the entire contents of the distributed
directory at one line per GID.
Arguments:
dd Structure maintains directory state and hash table.
Return Value:
int Error Code.
----------------------------------------
/***************** Developer's Notes *****************************/
Because Zoltan places no restrictions on the content or length of global
IDs, hashing does not guarantee a balanced distribution of objects in
the distributed directory. Note also, the worst case behavior of a hash
table lookup is very bad (essentially becoming a linear search).
Fortunately, the average behavior is very good! The user may specify
their own hash function in place of the default LB_Hash() to improve
performance.
This software module is built on top of the Zoltan Communications
functions for efficiency. Improvements to the communications library
will automatically benefit the distributed directory.
Global BUG: The distributed directory should be implemented via
client-server processes or threads. However, MPI is
not fully thread aware, yet.
FUTURE: The C99 capability for variable length arrays would
significantly simplify many of these following
routines. (It eliminates the malloc/free calls for
temporary storage. This helps prevent memory leaks.)
Other C99 features may also improve code readability.
The "inline" capability can potentially improve
performance.

View File

@ -0,0 +1,204 @@
/*
* @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
*/
#ifndef ZOLTAN_DD_H
#define ZOLTAN_DD_H
#include "zoltan_mem.h"
#include "zoltan_comm.h"
#include "zoltan_types.h"
#include "zoltan_id.h"
#include "zoltan_util.h"
#include "zoltan_dd.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#define ZOLTAN_DD_HASH_TABLE_COUNT 100000 /* default # of linked list heads */
#define ZOLTAN_DD_NO_PROC -1 /* not a possible processor # */
/* Tags for MPI communications. These need unique values. Arbitrary */
#define ZOLTAN_DD_FIND_MSG_TAG 29137 /* needs 3 consecutive values */
#define ZOLTAN_DD_UPDATE_MSG_TAG 29140 /* needs 2 consecutive values */
#define ZOLTAN_DD_REMOVE_MSG_TAG 29142 /* needs 2 consecutive values */
#ifndef TRUE
#define FALSE (0)
#define TRUE (1)
#endif /* !TRUE */
/*********** Distributed Directory Function Prototypes ************/
unsigned int Zoltan_DD_Hash2(ZOLTAN_ID_PTR key, int num_id_entries,
unsigned int n, void *hashdata, ZOLTAN_HASH_FN *fn);
void Zoltan_DD_default_cleanup(void *hashdata);
typedef unsigned int DD_Hash_fn(ZOLTAN_ID_PTR, int, unsigned int, void *,
ZOLTAN_HASH_FN *);
typedef void DD_Cleanup_fn(void*);
/************ Zoltan_DD_Directory, DD_Node **********************/
typedef int DD_NodeIdx; /* Index into dd->nodelist;
must be a signed type as -1 indicates NULL */
/* The following structure, DD_Node, is the basic unit of the hash table's
* linked list. DD_Node contains the global ID(used as the table lookup
* key) and other necessary information. NOTE: DD_Node is malloc'd to
* store gid, lid & user data beyond the struct's end.
*/
typedef struct DD_Node {
int owner; /* processor hosting global ID object */
int partition; /* Optional data */
int errcheck; /* Error checking(inconsistent updates) */
DD_NodeIdx next; /* index in nodelist of next DD_Node in
linked list or free node list */
ZOLTAN_ID_TYPE *gid; /* gid used as key for update & lookup */
/* lid starts at gid + dd->gid_length */
/*(user) data starts at */
/* gid + dd->gid_length + dd->lid_length */
int free; /* flag indicating whether node is
free or used */
} DD_Node;
/* The directory structure, Zoltan_DD_Struct, is created by the call
* to Zoltan_DD_Create(). It maintains the state information and storage
* allocation for the distributed directory. Other state information may
* be added in the future. This structure must be passed back to all other
* distributed directory calls: Zoltan_DD_Update(), Zoltan_DD_Find(),
* Zoltan_DD_Destroy(), Zoltan_DD_Set_Hash_Fn(), DD_Update_Local(),
* DD_Find_Local(), DD_Remove_Local(). NOTE: Zoltan_DD_Struct is
* malloc'd for storage beyond the struct's end to hold hash table.
*/
struct Zoltan_DD_Struct {
int my_proc; /* My identity in MPI Comm */
int nproc; /* Number of processors in MPI Comm */
int gid_length; /* = zz->Num_GID -- avoid needing Zoltan_Struct */
int lid_length; /* = zz->Num_LID -- avoid needing Zoltan_Struct */
int max_id_length; /* max(gid_length, lid_length) */
int user_data_length; /* Optional user data length in chars */
int table_length; /* # of heads of linked lists */
size_t nodedata_size; /* Malloc for GID & LID & user storage */
size_t find_msg_size; /* Total allocation for DD_FIND_MSG */
size_t update_msg_size; /* Total allocation for DD_UPDATE_MSG */
size_t remove_msg_size; /* Total allocation for DD_REMOVE_MSG */
int debug_level; /* Determines actions to multiple updates */
DD_Hash_fn *hash; /* Hash function used by this DD */
void *hashdata; /* Either our hash data ... */
ZOLTAN_HASH_FN *hashfn; /* ... Or user's hash function, not both */
DD_Cleanup_fn *cleanup; /* Functioned to free our hash data */
MPI_Comm comm; /* Dup of original MPI Comm(KDD) */
DD_NodeIdx nodecnt; /* Number of nodes used in nodelist */
/* AKA Number of local entries in directory */
DD_Node *nodelist; /* Memory for storing all nodes in the directory */
char *nodedata; /* Memory for storing all data in the directory */
DD_NodeIdx nodelistlen; /* Length of the nodelist. */
DD_NodeIdx nextfreenode;/* Index of first free node in nodelist;
-1 if no nodes are free */
DD_NodeIdx table[1]; /* Hash table heads of the link lists */
};
/*************** DD Communication Messages *********************/
/* Note: These message structures should become MPI datatypes(KDD) */
typedef struct { /* Only used by Zoltan_DD_Update() */
char lid_flag; /* indicates if LID data are present */
char user_flag; /* indicates if USER data are present */
char partition_flag; /* indicates if optional partition data present */
int owner; /* range [0, nproc-1] or -1 */
int partition;
ZOLTAN_ID_TYPE gid[1]; /* struct malloc'd to include gid & lid & user */
/* LID found at gid[dd->gid_length] */
/* USER found at gid[dd->gid_length */
/* + dd->lid_length] if used */
} DD_Update_Msg;
/* A single structure can serve for both the request and its answer(in
* DD_Find_Msg if its memory is sized to hold either a global ID or a
* local ID. On the request direction, the proc field is the
* destination and the id field holds the global ID being located. In
* the return direction, the proc field holds the objects location and
* the id field holds its corresponding local ID. The index field is
* untouched & unused.
*/
typedef struct { /* Only used by Zoltan_DD_Find() */
int proc; /* destination or location */
int partition;
int index; /* to put things back in order afterward */
ZOLTAN_ID_TYPE id[1]; /* allocated as max(Num_GID, Num_LID) */
/* + user data length */
} DD_Find_Msg;
typedef struct { /* Only used by Zoltan_DD_Remove() */
int owner; /* range [0, nproc-1] or -1 */
ZOLTAN_ID_TYPE gid[1]; /* structure malloc'd to include gid */
} DD_Remove_Msg;
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif
#endif

View File

@ -0,0 +1,62 @@
# @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
MEMORY UTILITIES -- Routines for memory allocation and deallocation.
----------------------------------------------------------------
Files compiled into Zoltan:
zoltan_mem.h -- Prototypes for memory allocation and deallocation
routines in mem.c. Definition of Zoltan_MALLOC.
mem.c -- Memory allocation routines Zoltan_Array_Alloc and
Zoltan_Malloc.
Memory deallocation routine Zoltan_Free.
Parameter setting routing Zoltan_Set_Malloc_Param.
----------------------------------------------------------------
Memory test program
mem_main.c -- Stub for a driver program.

View File

@ -0,0 +1,682 @@
/*
* @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
*/
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "zoltan_mem.h"
#include "zoltan_util.h"
#ifdef __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
static int DEBUG_MEMORY = 0; /* Flag for detecting memory leaks */
static size_t bytes_used = 0; /* Sum of active allocations */
static size_t bytes_max = 0; /* Largest total of active allocations */
#ifdef REALLOC_BUG
static size_t max_alloc = 0; /* Largest single allocation */
#endif
static int nmalloc = 0; /* number of calls to malloc */
static int nfree = 0; /* number of calls to free */
/* Macro to get rank information for printing and error messages. */
/* If not using MPI, compile with -DZOLTAN_NO_MPI; all messages */
/* will print with proc = 0. */
#ifdef ZOLTAN_NO_MPI
#define GET_RANK(a) *(a)=0
#else
#include <mpi.h>
#define GET_RANK(a) MPI_Comm_rank(MPI_COMM_WORLD, (a))
#endif
#define MAX_STRING_LEN 50
static struct malloc_debug_data {
int order; /* which malloc call is it? */
size_t size; /* size of malloc invocation */
double *ptr; /* memory location returned */
char file[MAX_STRING_LEN+1]; /* file name */
int line; /* line number */
struct malloc_debug_data *next; /* pointer to next element */
} *top = NULL;
/******************************************************************************/
void Zoltan_Memory_Debug(int new_level) {
/*
* Routine to allow user to set DEBUG_MEMORY level.
*/
DEBUG_MEMORY = new_level;
}
/******************************************************************************/
int Zoltan_Memory_Get_Debug() {
return DEBUG_MEMORY;
}
/******************************************************************************
*
* Dynamic Allocation of Multidimensional Arrays
*-----------------------------------------------------------------------------
*
* Example Usage:
*
* typedef struct
* { int bus1;
* int bus2;
* int dest;
* } POINT;
*
* POINT **points, corner;
*
* points = (POINT **)Zoltan_Array_Alloc(file,lineno,2,x,y,sizeof(POINT));
* ^ ^ ^ ^ ^
* | | | | |
* name of calling file--------* | | | |
* | | | |
* line number of call--------------* | | |
* | | |
* number of dimensions-------------------+ | |
* | |
* first dimension max---------------------+ |
* |
* second dimension max-----------------------+
*
* (points may be now be used as if it were declared
* POINT points[x][y])
*
* This particular version is limited to dimensions of 4 or less.
*
* corner = points[2][3]; (refer to the structure as you would any array)
*
* free (points); (frees the entire structure in one fell swoop)
*
*****************************************************************************/
/******************************************************************************
* The following section is a commented section containing
* an example main code:
*******************************************************************************
*double *Zoltan_Array_Alloc();
*main()
*{
* int ***temp;
* int *temp2;
* int i, j, k;
* int il, jl, kl;
*
* malloc_debug(2);
* il = 2;
* jl = 3;
* kl = 3;
* temp = (int ***) Array_Alloc(__FILE__,__LINE__,3,il,jl,kl,sizeof(int));
* for (i=0; i<il; i++) {
* for (j=0; j<jl; j++) {
* for (k=0; k<kl; k++) temp[i][j][k] = 1;
* }
* }
*
* temp2 = (int *) malloc(10*sizeof(int));
* for (i=0; i<10; i++) temp2[i] = 0;
*
* for (i=0; i<il; i++) {
* for (j=0; j<jl; j++) {
* for (k=0; k<kl; k++) (void) printf(" %d\n", temp[i][j][k]);
* }
* }
* malloc_verify();
*}
******************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
#ifdef __STDC__
double *Zoltan_Array_Alloc(char *file, int lineno, int numdim, ...)
#else
double *Zoltan_Array_Alloc(va_alist)
va_dcl
#endif
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
{
char *yo = "Zoltan_Array_Alloc";
int i, j;
struct dimension {
long index; /* Number of elements in the dimension */
long total; /* Total number of elements */
long size; /* Size of a single element in bytes */
long off; /* offset from beginning of array */
} dim[4]; /* Info about each dimension */
#ifndef __STDC__
char *file; /* Filename of source code from call. */
int lineno; /* Line number of call. */
int numdim; /* Number of dimensions */
#endif
long total; /* Total size of the array */
double *dfield; /* ptr to avoid lint complaints */
char *field; /* The multi-dimensional array */
char **ptr; /* Pointer offset */
char *data; /* Data offset */
va_list va; /* Current pointer in the argument list */
#ifdef __STDC__
va_start(va, numdim);
#else
va_start(va);
file = va_arg(va, char *);
lineno = va_arg(va, int);
numdim = va_arg(va, int);
#endif
if (numdim <= 0) {
fprintf(stderr, "%s (%s: %d) ERROR: number of dimensions, %d, is <=0\n",
yo, file, lineno, numdim);
va_end(va);
return((double *) NULL);
}
else if (numdim > 4) {
fprintf(stderr, "%s (%s: %d) ERROR: number of dimensions, %d, is > 4\n",
yo, file, lineno, numdim);
va_end(va);
return((double *) NULL);
}
dim[0].index = va_arg(va, int);
if (dim[0].index <= 0) {
if (DEBUG_MEMORY > 0) {
fprintf(stderr, "WARNING, %s (%s: %d) called with first "
"dimension <= 0, %ld; will return NULL\n",
yo, file, lineno, dim[0].index);
}
va_end(va);
return((double *) NULL);
}
dim[0].total = dim[0].index;
dim[0].size = sizeof(void *);
dim[0].off = 0;
for (i = 1; i < numdim; i++) {
dim[i].index = va_arg(va, int);
if (dim[i].index <= 0) {
fprintf(stderr, "WARNING: %s (%s: %d) called with dimension %d <= 0, "
"%ld; will return NULL\n",
yo, file, lineno, i+1, dim[i].index);
va_end(va);
return((double *) NULL);
}
dim[i].total = dim[i-1].total * dim[i].index;
dim[i].size = sizeof(void *);
dim[i].off = dim[i-1].off + dim[i-1].total * dim[i-1].size;
}
dim[numdim-1].size = va_arg(va, int);
va_end(va);
/* Round up the last offset value so data is properly aligned. */
dim[numdim-1].off = dim[numdim-1].size *
((dim[numdim-1].off+dim[numdim-1].size-1)/dim[numdim-1].size);
total = dim[numdim-1].off + dim[numdim-1].total * dim[numdim-1].size;
dfield = (double *) Zoltan_Malloc(total, file, lineno);
if (dfield != NULL) {
field = (char *) dfield;
for (i = 0; i < numdim - 1; i++) {
ptr = (char **) (field + dim[i].off);
data = (char *) (field + dim[i+1].off);
for (j = 0; j < dim[i].total; j++) {
ptr[j] = data + j * dim[i+1].size * dim[i+1].index;
}
}
}
return dfield;
} /* Zoltan_Array_Alloc */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
/* Safe version of calloc. */
double *Zoltan_Calloc (size_t num, size_t size, char *filename, int lineno)
{
double *p ;
p = Zoltan_Malloc (num*size, filename, lineno) ;
if (p) memset ((void *) p, '\0', num*size) ;
return p ;
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
/* Safe version of malloc. Does not initialize memory .*/
double *Zoltan_Malloc(size_t n, char *filename, int lineno)
{
char *yo = "Zoltan_Malloc";
struct malloc_debug_data *new_ptr; /* data structure for malloc data */
int proc; /* processor ID for debugging msg */
double *pntr; /* return value */
char *basefile;
if (n > 0) {
#ifdef REALLOC_BUG
if (n > max_alloc){
max_alloc = n;
}
n += sizeof(double);
#endif
pntr = (double *) malloc(n);
if (pntr == NULL) {
GET_RANK(&proc);
fprintf(stderr, "%s (from %s,%d) No space on proc %d - number of bytes "
"requested = %lu\n", yo, filename, lineno, proc,
(unsigned long) n);
return ((double *) NULL);
}
nmalloc++;
#ifdef REALLOC_BUG
pntr[0] = (double)(n - sizeof(double));
++pntr;
#endif
}
else if (n == 0)
pntr = NULL;
else { /* n < 0 */
GET_RANK(&proc);
fprintf(stderr, "%s (from %s,%d) ERROR on proc %d: "
"Negative malloc argument. (%lu)\n", yo, filename, lineno, proc,
(unsigned long) n);
return ((double *) NULL);
}
if (DEBUG_MEMORY > 1 && pntr != NULL) {
/* Add allocation to linked list of active allocations. */
new_ptr = (struct malloc_debug_data *)
malloc(sizeof(struct malloc_debug_data));
if (new_ptr == NULL) {
GET_RANK(&proc);
fprintf(stderr, "WARNING: No space on proc %d for malloc_debug %lu.\n",
proc, (unsigned long) n);
return (pntr);
}
new_ptr->order = nmalloc;
new_ptr->size = n;
new_ptr->ptr = pntr;
#ifdef SHORT_FILE
basefile = strrchr(filename, '/');
basefile = ((basefile != NULL)?basefile:filename-1)+1;
#else
basefile = filename;
#endif /* SHORT_FILE */
strncpy(new_ptr->file, basefile, MAX_STRING_LEN);
new_ptr->line = lineno;
new_ptr->next = top;
top = new_ptr;
bytes_used += n;
if (bytes_used > bytes_max) {
bytes_max = bytes_used;
}
}
if (DEBUG_MEMORY > 2) {
/* Print out details of allocation. */
GET_RANK(&proc);
fprintf(stderr, "Proc %d: order=%d, size=%lu, location=0x%lx, "
"file=%s, line=%d\n",
proc, nmalloc, (unsigned long) n, (long) pntr, filename, lineno);
}
return pntr;
} /* Zoltan_Malloc */
/* Safe version of realloc. Does not initialize memory. */
double *Zoltan_Realloc(void *ptr, size_t n, char *filename, int lineno)
{
char *yo = "Zoltan_Realloc";
struct malloc_debug_data *dbptr; /* loops through debug list */
int proc; /* processor ID */
double *p; /* returned pointer */
#ifdef REALLOC_BUG
int n_old;
#endif
if (ptr == NULL) { /* Previous allocation not important */
if (n == 0) {
p = NULL;
}
else {
p = Zoltan_Malloc(n, filename, lineno);
}
}
else {
if (n == 0) {
Zoltan_Free((void **) &ptr, filename, lineno);
p = NULL;
}
else {
#ifdef REALLOC_BUG
/* Feb 10, 2010: Several platforms show a realloc bug where realloc
* either fails to allocate memory when there is sufficient memory
* or it crashes. If realloc shows this failure, then build Zoltan
* with REALLOC_BUG, and we will call malloc/memcpy/free instead.
*/
p = (double *)ptr;
p--;
n_old = p[0];
if ((n_old < 1) || (n_old > max_alloc)){ /* sanity check */
GET_RANK(&proc);
fprintf(stderr, "%s (from %s,%d) Zoltan_Realloc called on a pointer "
"that was not returned by Zoltan_Malloc (proc %d)\n",
yo, filename, lineno, proc);
return NULL;
}
p = (double *) Zoltan_Malloc(n, filename, lineno);
if (p){
if (n > n_old){
memcpy(p, ptr, n_old);
}
else if (n <= n_old){
memcpy(p, ptr, n);
}
Zoltan_Free((void **) &ptr, filename, lineno);
}
#else
p = (double *) realloc((char *) ptr, n);
if (DEBUG_MEMORY > 1) {
/* Need to replace item in allocation list */
for (dbptr = top; dbptr != NULL && (void *) (dbptr->ptr) != ptr;
dbptr = dbptr->next);
if (dbptr == NULL) { /* previous allocation not found in list. */
GET_RANK(&proc);
fprintf(stderr, "Proc %d: Memory error: "
"In realloc, address not found in debug list (0x%lx)\n",
proc, (long) ptr);
}
else { /* Update entry in allocation list */
bytes_used += (n - dbptr->size);
dbptr->size = n;
dbptr->ptr = p;
if (bytes_used > bytes_max) {
bytes_max = bytes_used;
}
}
}
if (p == NULL) {
GET_RANK(&proc);
fprintf(stderr, "%s (from %s,%d) No space on proc %d - "
"number of bytes requested = %lu\n",
yo, filename, lineno, proc, (unsigned long) n);
}
#endif
}
}
return (p);
} /* Zoltan_Realloc */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
void Zoltan_Free (void **ptr, char *filename, int lineno)
{
struct malloc_debug_data *dbptr; /* loops through debug list */
struct malloc_debug_data **prev; /* holds previous pointer */
int proc; /* processor ID */
#ifdef REALLOC_BUG
double *p=NULL;
#endif
/*
* This version of free calls the system's free function. It doesn't call
* free if ptr is the NULL pointer.
*/
if (ptr == NULL || *ptr == NULL)
return;
nfree++;
if (DEBUG_MEMORY > 1) {
/* Remove allocation of list of active allocations */
prev = &top;
for (dbptr = top; dbptr != NULL && (void *) (dbptr->ptr) != *ptr;
dbptr = dbptr->next) {
prev = &(dbptr->next);
}
if (dbptr == NULL) {
GET_RANK(&proc);
fprintf(stderr, "Proc %d: Memory error: In free, address (0x%lx) "
"not found in debug list. File=%s, line=%d.\n", proc,
(long) *ptr, filename, lineno);
}
else {
*prev = dbptr->next;
bytes_used -= dbptr->size;
free((char *) dbptr);
if (DEBUG_MEMORY > 2){
GET_RANK(&proc);
fprintf(stderr, "Proc %d: free, address (0x%lx) "
"File=%s, line=%d.\n", proc, (long) *ptr, filename, lineno);
}
}
}
#ifdef REALLOC_BUG
p = (double *)*ptr;
free(p-1);
#else
free(*ptr);
#endif
/* Set value of ptr to NULL, to flag further references to it. */
*ptr = NULL;
} /* Zoltan_Free */
/* Free n pointers. Variable number of arguments is allowed. */
#ifdef __STDC__
void Zoltan_Multifree(char *filename, int lineno, int n, ...)
{
int i;
va_list va;
va_start(va, n);
for (i=0; i<n; i++){
Zoltan_Free(va_arg(va, void **), filename, lineno);
}
va_end(va);
}
#else
void Zoltan_Multifree(va_alist)
va_dcl
{
int i, n, lineno;
char *filename;
va_list va;
va_start(va);
filename = va_arg(va, char *);
lineno = va_arg(va, int);
n = va_arg(va, int);
for (i=0; i<n; i++){
Zoltan_Free(va_arg(va, void **), filename, lineno);
}
va_end(va);
}
#endif
/* Print out status of malloc/free calls. Flag any memory leaks. */
void Zoltan_Memory_Stats()
{
struct malloc_debug_data *dbptr; /* loops through debug list */
int proc; /* processor ID */
if (DEBUG_MEMORY == 1) {
GET_RANK(&proc);
fprintf(stderr, "Proc %d: Calls to malloc = %d, Calls to free = %d\n",
proc, nmalloc, nfree);
if (nmalloc > nfree)
fprintf(stderr, "Proc %d: Possible memory error: "
"# malloc > # free.\n", proc);
else if (nfree > nmalloc)
fprintf(stderr, "Proc %d: Possible memory error: "
"# free > # malloc.\n", proc);
}
else if (DEBUG_MEMORY > 1) {
GET_RANK(&proc);
fprintf(stderr, "Proc %d: Calls to malloc = %d, Calls to free = %d, "
"Max bytes = %lu, total bytes = %lu\n",
proc, nmalloc, nfree,
(unsigned long) bytes_max, (unsigned long) bytes_used);
if (nmalloc > nfree)
fprintf(stderr, "Proc %d: Possible memory error: "
"# malloc > # free.\n", proc);
else if (nfree > nmalloc)
fprintf(stderr, "Proc %d: Possible memory error: "
"# free > # malloc.\n", proc);
if (top != NULL) {
fprintf(stderr, "Proc %d: Remaining allocations:\n", proc);
for (dbptr = top; dbptr != NULL; dbptr = dbptr->next) {
fprintf(stderr, " order=%d, size=%lu, location=0x%lx, "
"file=%s, line=%d\n",
dbptr->order, (unsigned long) (dbptr->size),
(long) dbptr->ptr,
dbptr->file, dbptr->line);
}
}
}
} /* Zoltan_Memory_Stats */
int Zoltan_Malloc_Num(void)
{
/* Return number associated with the most recent malloc call. */
return (nmalloc);
} /* Zoltan_Malloc_Num */
size_t Zoltan_Memory_Usage (int type)
{
/* Return memory usage information: total bytes used currently or *
* maximum bytes used at any point. Default is maximum bytes used. */
if (type == ZOLTAN_MEM_STAT_TOTAL)
return bytes_used ;
return bytes_max ;
}
void Zoltan_Memory_Reset (int type)
{
/* Reset total bytes used currently or maximum bytes used at any point
to zero. */
if (type == ZOLTAN_MEM_STAT_TOTAL)
bytes_used = 0;
else
bytes_max = 0;
}
/*****************************************************************************/
/* END of mem.c */
/*****************************************************************************/
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

65
thirdParty/Zoltan/src/Utilities/README vendored Normal file
View File

@ -0,0 +1,65 @@
# @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
Zoltan Utilities
The following utilities are represented in this directory; details of
individual utilities can be found in README files in the appropriate
subdirectories. Each utility builds its own library.
Utility Subdirectory Library Name
----------------------------------------------------------------------------
Memory Management Memory libzoltan_mem.a
Unstructured Communication Communication libzoltan_comm.a
Distributed Directory DDirectory libzoltan_dd.a
A single Makefile builds all the utilities. For directions on building
utilities, type "gmake help" in this directorry.
Configuration files for compilation and linking on various architectures
are included in the directory Config. These configuration files are
shared by Zoltan and the utilities; thus, some fields in the configuration
files are not used by all utilities.

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
TIMER UTILITY -- Routines to implement Zoltan_Time and Zoltan_Timer objects.
----------------------------------------------------------------------------
Files compiled into libzoltan_timer.a and libzoltan.a:
timer.c -- Routines implementing Zoltan_Time.
timer.h -- Prototypes and constants.
zoltan_timer.c -- Implementation of timer object.
zoltan_timer.h -- Interface to timer object.

View File

@ -0,0 +1,144 @@
/*
* @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
*/
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <mpi.h>
#include "timer.h"
#include "zoltan_util.h"
#ifdef __PUMAGON__
#include <nx.h>
#endif
/****************************************
* Machine independent timing utilities.
* ANSI C and MPI are required.
****************************************/
/* Timer routine that returns either CPU or wall-clock time.
The ANSI function clock() may roll over at approx 71.5 minutes,
on some systems so we try to determine the number of rollovers.
*/
double Zoltan_Time(int timer)
{
double t = -1.;
#if !defined(__PUMAGON__) && !defined(__LIBCATAMOUNT__)
clock_t num_ticks;
static clock_t last_num_ticks = 0;
static int clock_rollovers = 0;
static double secs_per_clock = (double) 1./((double) CLOCKS_PER_SEC);
static double clock_width =
((double)(1L<<((int)sizeof(clock_t)*8-2)))*4./((double) CLOCKS_PER_SEC);
static double secs_per_tick = 0.; /* Not necessarily the same as
secs_per_clock; system-dependent; get value from sysconf(). */
#endif
if (timer==ZOLTAN_TIME_WALL)
/* Wall clock */
t = MPI_Wtime();
else if (timer==ZOLTAN_TIME_CPU) {
#if defined(__PUMAGON__) || defined(__LIBCATAMOUNT__)
/* CPU time on ASCI Red and Red Storm. */
t = dclock();
#else
/* CPU time */
num_ticks = clock();
if (num_ticks < last_num_ticks) clock_rollovers++;
t = num_ticks * secs_per_clock;
if (clock_rollovers) t += clock_rollovers * clock_width;
last_num_ticks = num_ticks;
#endif
}
#ifndef NO_TIMES
else if (timer==ZOLTAN_TIME_USER) {
struct tms tm;
if (secs_per_tick == 0.)
secs_per_tick = (double) 1. / ((double) sysconf(_SC_CLK_TCK));
times(&tm);
t = tm.tms_utime * secs_per_tick;
}
#endif
return t;
}
/* Resolution (precision) of timer.
* This is really a lower bound, the actual resolution may be worse.
* If the precision is unknown, -1 is returned.
*/
double Zoltan_Time_Resolution(int timer)
{
double t = -1.;
if (timer==ZOLTAN_TIME_WALL)
t = MPI_Wtick();
else if (timer==ZOLTAN_TIME_CPU)
t = (double) 1. / ((double) CLOCKS_PER_SEC);
#ifndef NO_TIMES
else if (timer==ZOLTAN_TIME_USER)
t = (double) 1. / ((double) sysconf(_SC_CLK_TCK));
#endif
return t;
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

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
*/
#ifndef __TIMER_H
#define __TIMER_H
#include "zoltan_timer.h"
#include <time.h> /* ANSI C; defines clock_t and clock() */
#ifndef CLOCKS_PER_SEC /* Should have been defined in time.h */
#define CLOCKS_PER_SEC 1000000 /* To prevent compile errors, not always the correct value. */
#endif
/*
* POSIX compliant systems should use times() for user timing.
* This is the default in Zoltan. Make Zoltan with -DNO_TIMES if
* your system does not have sys/times.h and times().
* Note: BSD-like systems may use getrusage() instead for user timing,
* but that has not been implemented here.
*/
#if defined(__PUMAGON__) || defined(__LIBCATAMOUNT__) || defined(_WIN32)
/* Tflops with Cougar & Red Storm w/Catamount does not have sysconf() or times() */
/* Microsoft Visual Studio does not have times either */
#define NO_TIMES
#endif /* __PUMAGON__ */
#ifndef NO_TIMES
/* #include <sys/types.h> -- Included by sys/times.h on most systems. */
#include <sys/times.h>
#include <unistd.h> /* Needed for sysconf() and _SC_CLK_TCK */
#endif
#endif

View File

@ -0,0 +1,468 @@
/*
* @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
*/
#include "zoltan_timer.h"
#include "zoltan_types.h"
#include "zoltan_util.h"
#include "zoltan_mem.h"
#ifdef VAMPIR
#include <VT.h>
#endif
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/****************************************************************************/
/*
* Functions that implement a Timer "class," creating a Timer object
* with start, stop and print functions.
*
* This code was designed to be a stand-alone utility, relying only
* on Zoltan_Time, Zoltan error codes, Zoltan utilities, and libzoltan_mem.a.
* Some rearranging of the Zoltan_Time files is necessary to truly make
* this utility a standalone one.
*/
/****************************************************************************/
/* Number of timers initially in Timer object. */
#define INITLENGTH 30
/* Length of character strings naming each timer. */
/* If you change this constant, change the string format */
/* in Zoltan_Timer_Print, too. */
#define MAXNAMELEN 31
/* Flag indicating whether a timer is in use. */
#define INUSE 1
/* Flag indicating whether a timer is running. */
#define RUNNING 2
#define FATALERROR(yo, str) \
{ \
int ppproc; \
MPI_Comm_rank(MPI_COMM_WORLD, &ppproc); \
ZOLTAN_PRINT_ERROR(ppproc, yo, str); \
return ZOLTAN_FATAL; \
}
/* Macro to ensure that a Timer object is non-NULL */
#define TESTTIMER(zt, yo) \
if ((zt) == NULL) FATALERROR(yo, "NULL Zoltan_Timer")
/* Macro to ensure that a given timer index is valid. */
#define TESTINDEX(zt, ts_idx, yo) \
if ((ts_idx) >= (zt)->NextTimeStruct) FATALERROR(yo, "Invalid Timer Index")
/****************************************************************************/
/* Structure that implements an individual timer. */
typedef struct TimeStruct {
double Start_Time; /* Most recent start time;
set by Zoltan_Timer_Start */
double Stop_Time; /* Most recent end time;
set by Zoltan_Timer_Stop */
char Start_File[MAXNAMELEN+1]; /* Filename for most recent Start */
char Stop_File[MAXNAMELEN+1]; /* Filename for most recent Stop */
int Start_Line; /* Line # in Start_File for most recent Start */
int Stop_Line; /* Line # in Stop_File for most recent Stop */
double My_Tot_Time; /* Sum of stop_time-start_time over all invocations
of this timer */
int Use_Barrier; /* Flag indicating whether to perform a barrier
operation before starting the timer. */
int Status; /* Flag indicating status of TimeStruct:
> 0 --> In Use
> 2 --> Running */
char Name[MAXNAMELEN+1];/* String associated (and printed) with timer info */
#ifdef VAMPIR
int vt_handle; /* state handle for vampir traces */
#endif
} ZTIMER_TS;
/* Timer object consisting of many related timers.
* Applications access this structure. */
typedef struct Zoltan_Timer {
int Timer_Flag; /* Zoltan Timer_Flag flag passed to Zoltan_Time */
int Length; /* # of entries allocated in Times */
int NextTimeStruct; /* Index of next unused TimeStruct */
ZTIMER_TS *Times; /* Array of actual timing data -- individual timers */
} ZTIMER;
/****************************************************************************/
ZTIMER *Zoltan_Timer_Copy(ZTIMER *from)
{
ZTIMER *to = NULL;
Zoltan_Timer_Copy_To(&to, from);
return to;
}
/****************************************************************************/
int Zoltan_Timer_Copy_To(ZTIMER **to, ZTIMER *from)
{
ZTIMER *toptr = NULL;
if (!to){
return ZOLTAN_FATAL;
}
if (*to){
Zoltan_Timer_Destroy(to);
}
if (from){
*to = (ZTIMER *)ZOLTAN_MALLOC(sizeof(ZTIMER));
toptr = *to;
toptr->Timer_Flag = from->Timer_Flag;
toptr->Length = from->Length;
toptr->NextTimeStruct = from->NextTimeStruct;
if (toptr->Length > 0){
toptr->Times = (ZTIMER_TS *)ZOLTAN_MALLOC(sizeof(ZTIMER_TS) * toptr->Length);
memcpy(toptr->Times, from->Times, sizeof(ZTIMER_TS) * toptr->Length);
}
else{
toptr->Times = NULL;
}
}
return ZOLTAN_OK;
}
/****************************************************************************/
ZTIMER *Zoltan_Timer_Create(
int timer_flag
)
{
/* Allocates a Timer object for the application; returns a pointer to it.
* Does not start any timers.
*/
ZTIMER *zt;
int i;
zt = (ZTIMER *) ZOLTAN_MALLOC(sizeof(ZTIMER));
zt->Times = (ZTIMER_TS *) ZOLTAN_MALLOC(sizeof(ZTIMER_TS) * INITLENGTH);
zt->Timer_Flag = timer_flag;
zt->Length = INITLENGTH;
zt->NextTimeStruct = 0;
for (i = 0; i < zt->Length; i++)
zt->Times[i].Status = 0;
return zt;
}
/****************************************************************************/
int Zoltan_Timer_Init(
ZTIMER *zt, /* Ptr to Timer object */
int use_barrier, /* Flag indicating whether to perform a
barrier operation before starting the
timer. */
const char *name /* Name of this timer */
)
{
/* Function that returns the index of the next available Timer timer. */
int ret;
static char *yo = "Zoltan_Timer_Init";
TESTTIMER(zt, yo);
ret = zt->NextTimeStruct++;
if (ret >= zt->Length) {
/* Realloc -- need more individual timers */
zt->Length += INITLENGTH;
zt->Times = (ZTIMER_TS *) ZOLTAN_REALLOC(zt->Times, zt->Length * sizeof(ZTIMER_TS));
}
Zoltan_Timer_Reset(zt, ret, use_barrier, name);
#ifdef VAMPIR
if (VT_funcdef(name, VT_NOCLASS, &((zt->Times[ret]).vt_handle)) != VT_OK)
FATALERROR(yo, "VT_funcdef failed.");
#endif
return ret;
}
/****************************************************************************/
int Zoltan_Timer_Reset(
ZTIMER *zt,
int ts_idx, /* Index of the timer to reset */
int use_barrier, /* Flag indicating whether to perform a
barrier operation before starting the
timer. */
const char *name /* Name of this timer */
)
{
/* Initialize a timer for INUSE; reset its values to zero. */
static char *yo = "Zoltan_Timer_Reset";
ZTIMER_TS *ts;
TESTTIMER(zt, yo);
TESTINDEX(zt, ts_idx, yo);
ts = &(zt->Times[ts_idx]);
ts->Status = INUSE;
ts->Start_Time = 0.;
ts->Stop_Time = 0.;
ts->My_Tot_Time = 0.;
ts->Use_Barrier = use_barrier;
strncpy(ts->Name, name, MAXNAMELEN);
ts->Name[MAXNAMELEN] = '\0';
ts->Start_File[0] = '\0';
ts->Start_Line = -1;
ts->Stop_File[0] = '\0';
ts->Stop_Line = -1;
return ZOLTAN_OK;
}
/****************************************************************************/
int Zoltan_Timer_ChangeFlag(
ZTIMER *zt,
int timer
)
{
static char *yo = "Zoltan_Timer_ChangeFlag";
TESTTIMER(zt, yo);
zt->Timer_Flag = timer;
return ZOLTAN_OK;
}
/****************************************************************************/
int Zoltan_Timer_Start(
ZTIMER *zt, /* Ptr to Timer object */
int ts_idx, /* Index of the timer to use */
MPI_Comm comm, /* Communicator to use for synchronization,
if requested */
char *filename, /* Filename of file calling the Start */
int lineno /* Line number where Start was called */
)
{
ZTIMER_TS *ts;
static char *yo = "Zoltan_Timer_Start";
TESTTIMER(zt, yo);
TESTINDEX(zt, ts_idx, yo);
ts = &(zt->Times[ts_idx]);
if (ts->Status > RUNNING) {
char msg[256];
sprintf(msg,
"Cannot start timer %d at %s:%d; timer already running from %s:%d.",
ts_idx, filename, lineno, ts->Start_File, ts->Start_Line);
FATALERROR(yo, msg)
}
ts->Status += RUNNING;
strncpy(ts->Start_File, filename, MAXNAMELEN);
ts->Start_Line = lineno;
if (ts->Use_Barrier)
MPI_Barrier(comm);
ts->Start_Time = Zoltan_Time(zt->Timer_Flag);
#ifdef VAMPIR
if (VT_begin(ts->vt_handle) != VT_OK)
FATALERROR(yo, "VT_begin failed.");
#endif
return ZOLTAN_OK;
}
/****************************************************************************/
int Zoltan_Timer_Stop(
ZTIMER *zt, /* Ptr to Timer object */
int ts_idx, /* Index of the timer to use */
MPI_Comm comm, /* Communicator to use for synchronization,
if requested */
char *filename, /* Filename of file calling the Stop */
int lineno /* Line number where Stop was called */
)
{
/* Function to stop a timer and accrue its information */
ZTIMER_TS *ts;
static char *yo = "Zoltan_Timer_Stop";
double my_time;
TESTTIMER(zt, yo);
TESTINDEX(zt, ts_idx, yo);
ts = &(zt->Times[ts_idx]);
if (ts->Status < RUNNING) {
if (ts->Stop_Line == -1)
FATALERROR(yo, "Cannot stop timer; timer never started.")
else {
char msg[256];
sprintf(msg,
"Cannot stop timer %d at %s:%d; "
"timer already stopped from %s:%d.",
ts_idx, filename, lineno, ts->Stop_File, ts->Stop_Line);
FATALERROR(yo, msg)
}
}
#ifdef VAMPIR
if (VT_end(ts->vt_handle) != VT_OK)
FATALERROR(yo, "VT_end failed.");
#endif
if (ts->Use_Barrier)
MPI_Barrier(comm);
ts->Stop_Time = Zoltan_Time(zt->Timer_Flag);
ts->Status -= RUNNING;
ts->Stop_Line = lineno;
strncpy(ts->Stop_File, filename, MAXNAMELEN);
my_time = ts->Stop_Time - ts->Start_Time;
ts->My_Tot_Time += my_time;
return ZOLTAN_OK;
}
/****************************************************************************/
int Zoltan_Timer_Print(
ZTIMER *zt,
int ts_idx,
int proc, /* Rank of the processor (in comm) that should print the data. */
MPI_Comm comm,
FILE *fp
)
{
/* Accrues a single timer's values across a communicator and prints
* its information. This function must be called by all processors
* within the communicator.
*/
static char *yo = "Zoltan_Timer_Print";
ZTIMER_TS *ts;
int my_proc, nproc;
int restart = 0;
double max_time;
double min_time;
double sum_time;
TESTTIMER(zt, yo);
TESTINDEX(zt, ts_idx, yo);
MPI_Comm_rank(comm, &my_proc);
MPI_Comm_size(comm, &nproc);
ts = &(zt->Times[ts_idx]);
if (ts->Status > RUNNING) {
/* Timer is running; stop it before printing the times.
* Don't want to include print times in timer.
*/
restart = 1;
ZOLTAN_TIMER_STOP(zt, ts_idx, comm);
}
MPI_Allreduce(&(ts->My_Tot_Time), &max_time, 1, MPI_DOUBLE, MPI_MAX, comm);
MPI_Allreduce(&(ts->My_Tot_Time), &min_time, 1, MPI_DOUBLE, MPI_MIN, comm);
MPI_Allreduce(&(ts->My_Tot_Time), &sum_time, 1, MPI_DOUBLE, MPI_SUM, comm);
if (proc == my_proc)
fprintf(fp,
"%3d ZOLTAN_TIMER %3d %23s: MyTime %7.4f "
"MaxTime %7.4f MinTime %7.4f AvgTime %7.4f\n",
proc, ts_idx, ts->Name, ts->My_Tot_Time,
max_time, min_time, sum_time/nproc);
if (restart) {
/* We stopped the timer for printing; restart it now. */
ZOLTAN_TIMER_START(zt, ts_idx, comm);
}
return ZOLTAN_OK;
}
/****************************************************************************/
int Zoltan_Timer_PrintAll(
ZTIMER *zt,
int proc, /* Rank of the processor (in comm) that should print the data. */
MPI_Comm comm,
FILE *fp
)
{
/* Function to print all timer information */
static char *yo = "Zoltan_Timer_PrintAll";
int i, ierr = ZOLTAN_OK;
TESTTIMER(zt, yo);
for (i = 0; i < zt->NextTimeStruct; i++)
if ((ierr = Zoltan_Timer_Print(zt, i, proc, comm, fp)) != ZOLTAN_OK)
break;
return ierr;
}
/****************************************************************************/
void Zoltan_Timer_Destroy(
ZTIMER **zt
)
{
/* Destroy a Timer object */
if (*zt != NULL) {
ZOLTAN_FREE(&((*zt)->Times));
ZOLTAN_FREE(zt);
}
}
/****************************************************************************/
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,83 @@
/*
* @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
*/
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#include <stddef.h>
#include "zoltan_align.h"
#include "zoltan_util.h"
/*****************************************************************************/
/*
* Routines for properly aligning data.
*/
/*****************************************************************************/
/*
* Plauger alignment algorithm, The Standard C Library.
* Forces malloc'ed variable size struct alignment.
* ZOLTAN_ALIGN_VAL is defined in Zoltan/include/zoltan_align.h;
* values are 0,1,3,7U depending upon machine.
*/
int Zoltan_Align(int a)
{
return((ZOLTAN_ALIGN_VAL + a) & ~ZOLTAN_ALIGN_VAL);
}
size_t Zoltan_Align_size_t(size_t a)
{
return((ZOLTAN_ALIGN_VAL + a) & ~ZOLTAN_ALIGN_VAL);
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,192 @@
/*
* @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
*/
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#include <stdio.h>
#include "zoltan_types.h"
#include "zoltan_id.h"
#include "zoltan_util.h"
#include "zoltan_mem.h"
/*****************************************************************************/
/*
* This file contains routines for manipulating
* the global and local IDs used by Zoltan.
*
* Some manipulations are performed via macros. In particular, macros
* specifying whether global or local IDs are to be manipulated are
* provided. Use of these macros is recommended over use of these
* basic functions.
* See zoltan_id.h for definitions of these macros.
*/
/*****************************************************************************/
/*****************************************************************************/
/*
* Routines for allocating and initializing IDs.
*/
ZOLTAN_ID_PTR ZOLTAN_Malloc_ID(int n, char *file, int line)
{
/*
* Allocates an array of size n of ZOLTAN_ID_TYPEs and initializes them.
*/
ZOLTAN_ID_PTR tmp;
char *yo = "ZOLTAN_Malloc_ID";
/*
* Don't use ZOLTAN_MALLOC macro here; prefer to pass file and line
* where ZOLTAN_Malloc_ID was called.
*/
tmp = (ZOLTAN_ID_PTR) Zoltan_Malloc(n * sizeof(ZOLTAN_ID_TYPE), file, line);
if (tmp != NULL) {
ZOLTAN_INIT_ID(n,tmp);
}
else if (n > 0) {
char msg[256];
sprintf(msg, "NULL pointer returned; malloc called from %s, line %d.",
file, line);
ZOLTAN_PRINT_ERROR(-1, yo, msg);
}
return tmp;
}
/*****************************************************************************/
/*****************************************************************************/
/*
* Routines for printing IDs.
*/
void ZOLTAN_PRINT_ID(int n, ZOLTAN_ID_PTR a)
{
/* Prints a single ID. */
int i;
printf("(");
for (i = 0; i < n; i++)
printf( ZOLTAN_ID_SPEC " ",a[i]);
printf(") ");
}
/*****************************************************************************/
/*****************************************************************************/
/*
* Routines to compare Global IDs.
* Functions are provided to test whether two IDs are equal (EQ),
* less than (LT), and greater than (GT).
* The negation operator can be used to test whether two IDs are
* not equal (!ZOLTAN_EQ_ID(n,a,b)), less than or equal (!ZOLTAN_GT_GID(n,a,b))
* or greater than or equal (!ZOLTAN_LT_GID(n,a,b)).
*/
/*****************************************************************************/
int ZOLTAN_EQ_ID(int n, ZOLTAN_ID_PTR a, ZOLTAN_ID_PTR b)
{
/*
* Returns 1 if a == b; 0 otherwise.
* a == b if for all i, a[i] == b[i].
*/
int i;
for (i = 0; i < n; i++)
if (a[i] != b[i])
return(0);
return(1);
}
/*****************************************************************************/
#ifdef ZOLTAN_NEEDED
/* Commented out since never used. */
int ZOLTAN_LT_ID(int n, ZOLTAN_ID_PTR a, ZOLTAN_ID_PTR b)
{
/*
* Returns 1 if a < b; 0 otherwise.
* a < b if for some i, a[i] < b[i] and a[j] == b[j] for all j < i.
*/
int i;
for (i = 0; i < n; i++)
if (a[i] == b[i])
continue;
else if (a[i] > b[i])
return(0);
else /* a[i] < b[i] */
return(1);
return(0); /* because a == b */
}
/*****************************************************************************/
int ZOLTAN_GT_ID(int n, ZOLTAN_ID_PTR a, ZOLTAN_ID_PTR b)
{
/*
* Returns 1 if a < b; 0 otherwise.
* a > b if for some i, a[i] > b[i] and a[j] == b[j] for all j < i.
*/
int i;
for (i = 0; i < n; i++)
if (a[i] == b[i])
continue;
else if (a[i] < b[i])
return(0);
else /* a[i] > b[i] */
return(1);
return(0); /* because a == b */
}
#endif /* ZOLTAN_NEEDED */
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,109 @@
/*
* @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
*/
#ifndef __ZOLTAN_ID_H
#define __ZOLTAN_ID_H
#include "zoltan_types.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/*
* This file contains the data types and comparison functions
* for IDs used by Zoltan and its Utilities. The basic data type
* is ZOLTAN_ID.
*/
/****************************************************************************/
/*
* Default value of ZOLTAN_ID_TYPE;
* IDs allocated with ZOLTAN_MALLOC_ID are initialized with this value.
*/
#define ZOLTAN_ID_DEFAULT 0
/*
* Macros for initializing single IDs.
*/
#define ZOLTAN_INIT_ID(n,id) \
{int ZOLTAN_ID_LOOP; \
for (ZOLTAN_ID_LOOP = 0; ZOLTAN_ID_LOOP < (n); ZOLTAN_ID_LOOP++) \
(id)[ZOLTAN_ID_LOOP] = ZOLTAN_ID_DEFAULT; \
}
/****************************************************************************/
/*
* Macros to copy IDs.
*/
#define ZOLTAN_SET_ID(n,a,b) \
{int ZOLTAN_ID_LOOP; \
for (ZOLTAN_ID_LOOP = 0; ZOLTAN_ID_LOOP < (n); ZOLTAN_ID_LOOP++) \
(a)[ZOLTAN_ID_LOOP] = (b)[ZOLTAN_ID_LOOP]; \
}
/****************************************************************************/
/*
* Prototypes for ID functions in id.c
*/
extern ZOLTAN_ID_PTR ZOLTAN_Malloc_ID(int n, char *file, int line);
extern void ZOLTAN_PRINT_ID(int n, ZOLTAN_ID_PTR a);
extern int ZOLTAN_EQ_ID(int n, ZOLTAN_ID_PTR a, ZOLTAN_ID_PTR b);
#ifdef ZOLTAN_NEEDED
/* Commented out since never used */
extern int ZOLTAN_LT_ID(int n, ZOLTAN_ID_PTR a, ZOLTAN_ID_PTR b);
extern int ZOLTAN_GT_ID(int n, ZOLTAN_ID_PTR a, ZOLTAN_ID_PTR b);
#endif /* ZOLTAN_NEEDED */
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif
#endif

View File

@ -0,0 +1,188 @@
/*
* @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
*/
#ifndef __ZOLTAN_UTIL_H
#define __ZOLTAN_UTIL_H
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/* This block should be executed for Autotools and CMake builds. */
/* The Zoltan classic build defines TRILINOS_NO_CONFIG_H. */
#ifndef TRILINOS_NO_CONFIG_H
#ifdef PACKAGE
#undef PACKAGE
#endif
#ifdef PACKAGE_NAME
#undef PACKAGE_NAME
#endif
#ifdef PACKAGE_BUGREPORT
#undef PACKAGE_BUGREPORT
#endif
#ifdef PACKAGE_STRING
#undef PACKAGE_STRING
#endif
#ifdef PACKAGE_TARNAME
#undef PACKAGE_TARNAME
#endif
#ifdef PACKAGE_VERSION
#undef PACKAGE_VERSION
#endif
#ifdef VERSION
#undef VERSION
#endif
/* This file passes values from configure to the source code. */
#include "Zoltan_config.h"
#ifdef HAVE_PARMETIS
#define ZOLTAN_PARMETIS
#endif
#ifdef HAVE_METIS
#define ZOLTAN_METIS
#endif
#ifdef HAVE_SCOTCH
#define ZOLTAN_SCOTCH
# ifdef HAVE_MPI
# define ZOLTAN_PTSCOTCH
# endif
#endif
#ifdef HAVE_OVIS
#define ZOLTAN_OVIS
#endif
#ifdef HAVE_PATOH
#define ZOLTAN_PATOH
#endif
#ifdef HAVE_CCOLAMD
#define ZOLTAN_CCOLAMD
#endif
#ifdef HAVE_ZOLTAN_HUND
#define ZOLTAN_HUND
#endif
#ifdef HAVE_PARKWAY
#define ZOLTAN_PARKWAY
#endif
#ifdef HAVE_PURIFY
#define ZOLTAN_PURIFY
#define strcmp Zoltan_strcmp
#define strncmp Zoltan_strncmp
#define strcasecmp Zoltan_strcasecmp
#define strncasecmp Zoltan_strncasecmp
#endif
#else /* !AUTOTOOLS_BUILD */
/* With the manual build system we support only Parallel Version of Scotch */
#ifdef ZOLTAN_SCOTCH
#define ZOLTAN_PTSCOTCH
#endif
#endif /* !AUTOTOOLS_BUILD */
/*****************************************************************************/
/*
* Macros and definitions that are common to all Zoltan modules and
* utilities.
*/
/*****************************************************************************/
/*****************************************************************************/
/*
* Macros for consistently printing error and warning messages.
*/
/*****************************************************************************/
void Zoltan_add_back_trace(char *yo);
void Zoltan_remove_back_trace();
void Zoltan_print_trace(int rank);
#define ZOLTAN_PRINT_ERROR(proc,yo,str) { \
fprintf(stderr, "[%d] Zoltan ERROR in %s (line %d of %s): %s\n", \
proc, yo, __LINE__, __FILE__, str); \
Zoltan_print_trace(proc); }
#define ZOLTAN_PRINT_WARN(proc,yo,str) \
fprintf(stderr, "[%d] Zoltan WARNING in %s (line %d of %s): %s\n", \
proc, yo, __LINE__, __FILE__, str);
#define ZOLTAN_TRACE(proc,where,yo,str) \
printf("ZOLTAN (Processor %d) %s %s %s\n", (proc), (where), (yo), \
((str) != NULL ? (char *)(str) : " "));
#define ZOLTAN_TRACE_IN(proc,yo,str) \
ZOLTAN_TRACE((proc),"Entering",(yo),(str));
#define ZOLTAN_TRACE_OUT(proc,yo,str) \
ZOLTAN_TRACE((proc),"Exiting",(yo),(str));
#define ZOLTAN_PRINT_INFO(proc,yo,str) \
printf("ZOLTAN (Processor %d) %s: %s\n", (proc), (yo), \
((str) != NULL ? (char *)(str) : " "));
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif
#endif /* !__ZOLTAN_UTIL_H */

55
thirdParty/Zoltan/src/all/README vendored Normal file
View File

@ -0,0 +1,55 @@
# @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
ALL DIRECTORY -- Routines for memory allocation and deallocation.
----------------------------------------------------------------
Files compiled into Zoltan:
all_allo_const.h -- Prototypes for Zoltan-specific memory allocation and
deallocation routines in all_allo.c.
all_allo.c -- Zoltan-specific Memory routines Zoltan_Special_Malloc and
Zoltan_Special_Free.
Parameter setting routing Zoltan_Set_Malloc_Param.

290
thirdParty/Zoltan/src/all/all_allo.c vendored Normal file
View File

@ -0,0 +1,290 @@
/*
* @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
*/
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#include <stdio.h>
#include <stdlib.h>
#include "zoltan_util.h"
#include "all_allo_const.h"
#include "params_const.h"
/* Fortran memory allocation callback functions */
static ZOLTAN_FORT_MALLOC_INT_FN *Zoltan_Fort_Malloc_int;
static ZOLTAN_FORT_FREE_INT_FN *Zoltan_Fort_Free_int;
static ZOLTAN_FORT_MALLOC_SET_STRUCT_FN *Zoltan_Fort_Malloc_Set_Struct;
int Zoltan_Set_Malloc_Param(
char *name, /* name of variable */
char *val) /* value of variable */
{
int status;
PARAM_UTYPE result; /* value returned from Check_Param */
int index; /* index returned from Check_Param */
PARAM_VARS malloc_params[] = {
{ "DEBUG_MEMORY", NULL, "INT", 0 },
{ NULL, NULL, NULL, 0 }
};
status = Zoltan_Check_Param(name, val, malloc_params, &result, &index);
if (status == 0 && index == 0) {
Zoltan_Memory_Debug(result.ival);
status = 3;
}
return(status);
}
/******************************************************************************
* Special allocation for routines that allocate an array and return pointer.
*
* Zoltan_Special_Malloc allows the allocation to be done from either C or Fortran.
*
* Zoltan_Special_Free frees memory allocated by Zoltan_Special_Malloc
*
* Zoltan_Register_Fort_Malloc is called by the wrappers for the Fortran
* interface to provide pointers to the Fortran allocation/free routines.
*
* int Zoltan_Special_Malloc(ZZ *zz, void **array, int size,
* ZOLTAN_SPECIAL_MALLOC_TYPE type)
*
* zz -- the Zoltan structure in use
* array -- int**; returned as a
* pointer to the allocated space
* size -- number of elements to be allocated in the array
* type -- the type of array; ZOLTAN_SPECIAL_MALLOC_INT, ZOLTAN_SPECIAL_MALLOC_GID,
* or ZOLTAN_SPECIAL_MALLOC_LID
*
* The return value is 1 if the allocation succeeded, 0 if it failed.
*
* int Zoltan_Special_Free(ZZ *zz, void **array,
ZOLTAN_SPECIAL_MALLOC_TYPE type)
*
*****************************************************************************/
void Zoltan_Register_Fort_Malloc(ZOLTAN_FORT_MALLOC_INT_FN *fort_malloc_int,
ZOLTAN_FORT_FREE_INT_FN *fort_free_int,
ZOLTAN_FORT_MALLOC_SET_STRUCT_FN *fort_malloc_set_struct)
{
Zoltan_Fort_Malloc_int = fort_malloc_int;
Zoltan_Fort_Free_int = fort_free_int;
Zoltan_Fort_Malloc_Set_Struct = fort_malloc_set_struct;
}
int Zoltan_Special_Malloc(ZZ *zz, void **array, int size,
ZOLTAN_SPECIAL_MALLOC_TYPE type)
{
int *ret_addr, success;
char *yo = "Zoltan_Special_Malloc";
success = 1;
if (zz->Fortran) {
/* allocation from Fortran */
switch(type) {
case ZOLTAN_SPECIAL_MALLOC_INT:
#ifdef PGI /* special case for PGI Fortran compiler */
Zoltan_Fort_Malloc_int((int *)(array[1]),&size,&ret_addr,array[2]);
#else
#ifdef FUJITSU /* special case for Fujitsu and Lahey Fortran compilers */
Zoltan_Fort_Malloc_int((int *)(array[1]),&size,&ret_addr,array[2],0,0);
#else
Zoltan_Fort_Malloc_int((int *)(array[1]),&size,&ret_addr);
#endif
#endif
if (ret_addr==0) success=0;
break;
case ZOLTAN_SPECIAL_MALLOC_GID:
size *= zz->Num_GID;
#ifdef PGI
Zoltan_Fort_Malloc_int((int *)(array[1]),&size,&ret_addr,array[2]);
#else
#ifdef FUJITSU
Zoltan_Fort_Malloc_int((int *)(array[1]),&size,&ret_addr,array[2],0,0);
#else
Zoltan_Fort_Malloc_int((int *)(array[1]),&size,&ret_addr);
#endif
#endif
if (ret_addr==0) success=0;
break;
case ZOLTAN_SPECIAL_MALLOC_LID:
size *= zz->Num_LID;
#ifdef PGI
Zoltan_Fort_Malloc_int((int *)(array[1]),&size,&ret_addr,array[2]);
#else
#ifdef FUJITSU
Zoltan_Fort_Malloc_int((int *)(array[1]),&size,&ret_addr,array[2],0,0);
#else
Zoltan_Fort_Malloc_int((int *)(array[1]),&size,&ret_addr);
#endif
#endif
if (ret_addr==0) success=0;
break;
default:
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Illegal value passed for type");
success = 0;
}
if (success) {
array[0] = ret_addr;
}else{
array[0] = NULL;
}
}else{
/* allocation from C */
switch(type) {
case ZOLTAN_SPECIAL_MALLOC_INT:
*array = (int *) ZOLTAN_MALLOC(size*sizeof(int));
if (*array==NULL) success=0;
break;
case ZOLTAN_SPECIAL_MALLOC_GID:
*array = ZOLTAN_MALLOC_GID_ARRAY(zz, size);
if (*array==NULL) success=0;
break;
case ZOLTAN_SPECIAL_MALLOC_LID:
*array = ZOLTAN_MALLOC_LID_ARRAY(zz, size);
if (zz->Num_LID > 0 && *array==NULL) success = 0;
break;
default:
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Illegal value passed for type");
*array = NULL;
success = 0;
}
}
return success;
}
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
int Zoltan_Special_Free(ZZ *zz, void **array,
ZOLTAN_SPECIAL_MALLOC_TYPE type)
{
int success;
char *yo = "Zoltan_Special_Free";
success = 1;
if (zz->Fortran) {
/* deallocation from Fortran */
switch(type) {
case ZOLTAN_SPECIAL_MALLOC_INT:
#ifdef PGI /* special case for PGI Fortran compiler */
Zoltan_Fort_Free_int((int *)(array[1]),array[2]);
#else
#ifdef FUJITSU /* special case for Fujitsu and Lahey Fortran compilers */
Zoltan_Fort_Free_int((int *)(array[1]),array[2]);
#else
Zoltan_Fort_Free_int((int *)(array[1]));
#endif
#endif
break;
case ZOLTAN_SPECIAL_MALLOC_GID:
#ifdef PGI
Zoltan_Fort_Free_int((int *)(array[1]),array[2]);
#else
#ifdef FUJITSU
Zoltan_Fort_Free_int((int *)(array[1]),array[2]);
#else
Zoltan_Fort_Free_int((int *)(array[1]));
#endif
#endif
break;
case ZOLTAN_SPECIAL_MALLOC_LID:
#ifdef PGI
Zoltan_Fort_Free_int((int *)(array[1]),array[2]);
#else
#ifdef FUJITSU
Zoltan_Fort_Free_int((int *)(array[1]),array[2]);
#else
Zoltan_Fort_Free_int((int *)(array[1]));
#endif
#endif
break;
default:
ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Illegal value passed for type");
success = 0;
}
}else{
/* deallocation from C */
ZOLTAN_FREE(array);
}
return success;
}
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
int Zoltan_Special_Fort_Malloc_Set_Struct(int *zz_addr_bytes, int **fort_zz)
{
Zoltan_Fort_Malloc_Set_Struct(zz_addr_bytes, fort_zz);
return 1;
}
/*****************************************************************************/
/* END of all_allo.c */
/*****************************************************************************/
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,109 @@
/*
* @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
*/
#ifndef __ALL_ALLO_H
#define __ALL_ALLO_H
#include "zz_const.h"
#include "zoltan_mem.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
extern int Zoltan_Set_Malloc_Param(char *, char *);
/* function prototypes for Fortran allocation functions */
#ifdef PGI
typedef void ZOLTAN_FORT_MALLOC_INT_FN(int *arg, int *size, int **ret, int *hidden);
typedef void ZOLTAN_FORT_FREE_INT_FN(int *arg, int *hidden);
#else
#ifdef FUJITSU
typedef void ZOLTAN_FORT_MALLOC_INT_FN(int *arg, int *size, int **ret, int *hidden, int hidden2, int hidden3);
typedef void ZOLTAN_FORT_FREE_INT_FN(int *arg, int *hidden);
#else
typedef void ZOLTAN_FORT_MALLOC_INT_FN(int *arg, int *size, int **ret);
typedef void ZOLTAN_FORT_FREE_INT_FN(int *arg);
#endif
#endif
/* these are not as complicated - just a simple typedef for all
compilers, since we are not passing any Fortran structures */
typedef void ZOLTAN_FORT_MALLOC_SET_STRUCT_FN(int *arg, int **ret);
/* type selector for Zoltan_Special_Malloc */
enum Zoltan_Special_Malloc_Type {
ZOLTAN_SPECIAL_MALLOC_INT,
ZOLTAN_SPECIAL_MALLOC_GID,
ZOLTAN_SPECIAL_MALLOC_LID
};
typedef enum Zoltan_Special_Malloc_Type ZOLTAN_SPECIAL_MALLOC_TYPE;
/* function declarations for special malloc */
extern int Zoltan_Special_Malloc(ZZ *zz, void **array, int size,
ZOLTAN_SPECIAL_MALLOC_TYPE type);
extern int Zoltan_Special_Free(ZZ *zz, void **array,
ZOLTAN_SPECIAL_MALLOC_TYPE type);
extern void Zoltan_Register_Fort_Malloc(ZOLTAN_FORT_MALLOC_INT_FN *,
ZOLTAN_FORT_FREE_INT_FN *,
ZOLTAN_FORT_MALLOC_SET_STRUCT_FN *);
extern int Zoltan_Special_Fort_Malloc_Set_Struct(int *zz_addr_bytes,
int **fort_zz);
extern int Zoltan_Special_Fort_Free_Struct(int *fort_zz);
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif
#endif

71
thirdParty/Zoltan/src/ch/README vendored Normal file
View File

@ -0,0 +1,71 @@
# @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
CH DIRECTORY -- code for reading Chaco input files.
---------------------------------------------------
Note: This code is not compiled into the Zoltan library,
but is used by the test driver (zdrive).
Most of this code was written by Hendrickson and Leland for reading
Chaco input files.
ch_input_const.h -- Prototypes for chaco_input_graph and chaco_input_geom.
External declarations of global variables.
ch_input_graph.c -- Contains routine chaco_input_graph, which processes
Chaco graph input.
ch_input_geom.c -- Contains routine chaco_input_geom, which processes
Chaco geometry input.
ch_input_assign.c -- Contains routines to read an initial assignment in
Chaco input format.
ch_input_read.c -- Contains routines read_val, read_int, and flush_line,
for reading input files.
ch_dist_graph.c, -- Code for distributing the initial Chaco graph.
ch_init_dist.c, Several different initial distributions are available.
ch_init_dist_const.h

474
thirdParty/Zoltan/src/ch/ch_dist_graph.c vendored Normal file
View File

@ -0,0 +1,474 @@
/*
* @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
*/
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include "ch_input_const.h"
#include "dr_err_const.h"
#include "dr_const.h"
#include "dr_externs.h"
#include "dr_util_const.h"
#include "ch_init_dist_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/*
* Distribute a graph from one processor to all processors.
* The ParMetis format is used for the distributed graph.
* The memory for the graph on the host node is freed
* and fresh memory is allocated for the distributed graph.
*/
int chaco_dist_graph(
MPI_Comm comm, /* MPI Communicator */
PARIO_INFO_PTR pio_info, /* Parallel IO info */
int host_proc, /* processor where all the data is initially */
int *gnvtxs, /* number of vertices in global graph */
int *nvtxs, /* number of vertices in local graph */
int **xadj, /* start of edge list for each vertex */
int **adjncy, /* edge list data */
int *vwgt_dim, /* number of weights per vertex */
float **vwgts, /* vertex weight list data */
int *ewgt_dim, /* number of weights per edge */
float **ewgts, /* edge weight list data */
int *ndim, /* dimension of the geometry */
float **x, /* x-coordinates of the vertices */
float **y, /* y-coordinates of the vertices */
float **z, /* z-coordinates of the vertices */
short **assignments /* assignments from Chaco file; may be NULL */
)
{
const char *yo = "chaco_dist_graph";
int nprocs, myproc, i, j, k, n, p, nedges, nsend, max_nvtxs, v, adj_cnt;
int offset, use_graph, nvtx_edges;
int *old_xadj = NULL, *old_adjncy = NULL, *size = NULL;
int *send_xadj = NULL, *send_adjncy = NULL;
int *vtx_list = NULL;
float *old_x = NULL, *old_y = NULL, *old_z = NULL;
float *send_x = NULL, *send_y = NULL, *send_z = NULL;
float *old_vwgts = NULL, *old_ewgts = NULL;
float *send_vwgts = NULL, *send_ewgts = NULL;
MPI_Status status;
/* Determine number of processors and my rank. */
MPI_Comm_size (comm, &nprocs );
MPI_Comm_rank (comm, &myproc );
DEBUG_TRACE_START(myproc, yo);
/* Initialize */
use_graph = (*xadj != NULL);
/* Handle serial case and return. */
if (nprocs == 1) {
/* Set values expected to be returned by this function. */
/* All array pointers are unchanged. */
*gnvtxs = *nvtxs;
/* Initialize distribution, so other routines using it work. */
ch_dist_init(nprocs, *gnvtxs, pio_info, assignments, host_proc, comm);
return 1;
}
/* Broadcast to all procs */
MPI_Bcast( vwgt_dim, 1, MPI_INT, host_proc, comm);
MPI_Bcast( ewgt_dim, 1, MPI_INT, host_proc, comm);
MPI_Bcast( &use_graph, 1, MPI_INT, host_proc, comm);
MPI_Bcast( ndim, 1, MPI_INT, host_proc, comm);
MPI_Bcast( nvtxs, 1, MPI_INT, host_proc, comm);
*gnvtxs = *nvtxs;
/* Initialize the chaco distribution on all processors */
ch_dist_init(nprocs, *gnvtxs, pio_info, assignments, host_proc, comm);
/* Store pointers to original data */
if (myproc == host_proc) {
old_xadj = *xadj;
*xadj = NULL;
old_adjncy = *adjncy;
*adjncy = NULL;
old_x = *x;
old_y = *y;
old_z = *z;
}
/* Allocate space for new distributed graph data */
n = *nvtxs = ch_dist_num_vtx(myproc, *assignments);
if (use_graph) {
*xadj = (int *) malloc((n+1)*sizeof(int));
if (*xadj == NULL) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
}
if (*vwgt_dim){
old_vwgts = *vwgts;
*vwgts = NULL;
if (n > 0) {
*vwgts = (float *) malloc(n*(*vwgt_dim)*sizeof(float));
if (*vwgts == NULL) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
}
}
if (*ndim > 0) {
*x = (float *) malloc(n*sizeof(float));
if (*ndim > 1) {
*y = (float *) malloc(n*sizeof(float));
if (*ndim > 2) {
*z = (float *) malloc(n*sizeof(float));
}
}
}
/*
* Distribute vertex data (xadj, coordinates, etc ) to all procs
*/
if (myproc == host_proc){
/* Allocate space for send buffers (size = max num vtx per proc ) */
max_nvtxs = ch_dist_max_num_vtx(*assignments);
if (use_graph) {
send_xadj = (int *) malloc((max_nvtxs+1)*sizeof(int));
if (send_xadj == NULL) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
}
if (*vwgt_dim) {
send_vwgts = (float *) malloc(max_nvtxs*(*vwgt_dim)*sizeof(float));
if (send_vwgts == NULL) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
}
if (*ndim > 0) {
send_x = (float *) malloc(max_nvtxs*sizeof(float));
if (send_x == NULL) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
if (*ndim > 1) {
send_y = (float *) malloc(max_nvtxs*sizeof(float));
if (send_y == NULL) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
if (*ndim > 2) {
send_z = (float *) malloc(max_nvtxs*sizeof(float));
if (send_z == NULL) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
}
}
}
/* Allocate space for list of vertices on a given processor */
vtx_list = (int *) malloc(max_nvtxs*sizeof(int));
if (vtx_list == NULL) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
/* Allocate array to accumulate number of edges to be sent to each proc. */
if (use_graph) {
size = (int *) malloc(nprocs*sizeof(int));
if (size == NULL) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
}
/* For each processor, gather its vertex information and send it. */
for (p = 0; p < nprocs; p++){
if (use_graph) size[p] = 0;
/* Get list of vertices to be assigned to processor p */
ch_dist_vtx_list(vtx_list, &nsend, p, *assignments);
if (p == myproc){
/* Loop over vertices assigned to myproc; copy the vertex */
/* data into local arrays. */
if (use_graph) (*xadj)[0] = 0;
for (i = 0; i < nsend; i++) {
v = vtx_list[i];
if (use_graph) {
size[p] += old_xadj[v+1]-old_xadj[v];
(*xadj)[i+1] = (*xadj)[i] + old_xadj[v+1] - old_xadj[v];
}
if (*vwgt_dim){
for (j=0; j<*vwgt_dim; j++)
(*vwgts)[i*(*vwgt_dim)+j] = old_vwgts[v*(*vwgt_dim)+j];
}
if (*ndim > 0) {
(*x)[i] = old_x[v];
if (*ndim > 1) {
(*y)[i] = old_y[v];
if (*ndim > 2) {
(*z)[i] = old_z[v];
}
}
}
}
}
else {
/* Loop over vertices assigned to proc p to gather */
/* vertex data into send buffers */
if (use_graph) send_xadj[0] = 0;
for (i = 0; i < nsend; i++) {
v = vtx_list[i];
if (use_graph) {
size[p] += old_xadj[v+1]-old_xadj[v];
send_xadj[i+1] = send_xadj[i] + old_xadj[v+1] - old_xadj[v];
}
if (*vwgt_dim){
for (j=0; j<*vwgt_dim; j++)
send_vwgts[i*(*vwgt_dim)+j] = old_vwgts[v*(*vwgt_dim)+j];
}
if (*ndim > 0) {
send_x[i] = old_x[v];
if (*ndim > 1) {
send_y[i] = old_y[v];
if (*ndim > 2) {
send_z[i] = old_z[v];
}
}
}
}
/* Send vertex data to proc p. */
if (use_graph)
MPI_Send(send_xadj, nsend+1, MPI_INT, p, 1, comm);
if (*vwgt_dim)
MPI_Send(send_vwgts, nsend*(*vwgt_dim), MPI_FLOAT, p, 2, comm);
if (*ndim > 0) {
MPI_Send(send_x, nsend, MPI_FLOAT, p, 3, comm);
if (*ndim > 1) {
MPI_Send(send_y, nsend, MPI_FLOAT, p, 4, comm);
if (*ndim > 2) {
MPI_Send(send_z, nsend, MPI_FLOAT, p, 5, comm);
}
}
}
}
}
safe_free((void **)(void *) &send_xadj);
safe_free((void **)(void *) &send_vwgts);
safe_free((void **)(void *) &send_x);
safe_free((void **)(void *) &send_y);
safe_free((void **)(void *) &send_z);
}
else {
/* host_proc != myproc; receive vertex data from host_proc */
if (use_graph)
MPI_Recv (*xadj, (*nvtxs)+1, MPI_INT, host_proc, 1, comm, &status);
if (*vwgt_dim)
MPI_Recv (*vwgts, (*nvtxs)*(*vwgt_dim), MPI_FLOAT, host_proc, 2, comm, &status);
if (*ndim > 0) {
MPI_Recv(*x, *nvtxs, MPI_FLOAT, host_proc, 3, comm, &status);
if (*ndim > 1) {
MPI_Recv(*y, *nvtxs, MPI_FLOAT, host_proc, 4, comm, &status);
if (*ndim > 2) {
MPI_Recv(*z, *nvtxs, MPI_FLOAT, host_proc, 5, comm, &status);
}
}
}
}
/*
* Distribute edge data to all procs
*/
if (use_graph) {
if (*ewgt_dim) {
old_ewgts = *ewgts;
*ewgts = NULL;
}
/* Allocate space for edge data */
nedges = (*xadj)[ *nvtxs];
if (nedges > 0) {
*adjncy = (int *) malloc(nedges * sizeof (int));
if (*adjncy == NULL) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
if (*ewgt_dim){
*ewgts = (float *) malloc(nedges*(*ewgt_dim) * sizeof (float));
if (*ewgts == NULL) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
}
}
/* Gather and send/receive edge data */
if (myproc == host_proc){
/* For each processor, gather its edge data and send it. */
for (p = 0; p < nprocs; p++){
if (size[p] == 0) continue;
/* Get list of vertices to be assigned to processor p */
ch_dist_vtx_list(vtx_list, &nsend, p, *assignments);
adj_cnt = 0;
if (p == myproc) {
/* Loop over vertices assigned to myproc copy the edge */
/* data into local arrays. */
for (i = 0; i < nsend; i++) {
v = vtx_list[i];
offset = old_xadj[v];
nvtx_edges = old_xadj[v+1] - old_xadj[v];
for (j = 0; j < nvtx_edges; j++) {
(*adjncy)[adj_cnt] = old_adjncy[offset+j];
if (*ewgt_dim){
for (k=0; k<*ewgt_dim; k++)
(*ewgts)[adj_cnt*(*ewgt_dim)+k] = old_ewgts[(offset+j)*(*ewgt_dim)+k];
}
adj_cnt++;
}
}
}
else { /* p != myproc */
/* allocate send buffers; size = num edges to send to proc p */
nvtx_edges = 0;
for (i = 0; i < nsend; i++) {
v = vtx_list[i];
nvtx_edges += old_xadj[v+1] - old_xadj[v];
}
send_adjncy = (int *) malloc(nvtx_edges * sizeof(int));
if (send_adjncy == NULL) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
if (*ewgt_dim) {
send_ewgts = (float *) malloc(nvtx_edges*(*ewgt_dim) * sizeof(float));
if (send_ewgts == NULL) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
}
/* Loop over vertices assigned to proc p to gather */
/* edge data into send buffers */
for (i = 0; i < nsend; i++) {
v = vtx_list[i];
offset = old_xadj[v];
nvtx_edges = old_xadj[v+1] - old_xadj[v];
for (j = 0; j < nvtx_edges; j++) {
send_adjncy[adj_cnt] = old_adjncy[offset+j];
if (*ewgt_dim){
for (k=0; k<*ewgt_dim; k++)
send_ewgts[adj_cnt*(*ewgt_dim)+k] = old_ewgts[(offset+j)*(*ewgt_dim)+k];
}
adj_cnt++;
}
}
/* Send edge data to proc p. */
MPI_Send(send_adjncy, size[p], MPI_INT, p, 6, comm);
if (*ewgt_dim)
MPI_Send(send_ewgts, size[p]*(*ewgt_dim), MPI_FLOAT, p, 7, comm);
safe_free((void **)(void *) &send_adjncy);
safe_free((void **)(void *) &send_ewgts);
}
}
}
else {
/* host_proc != myproc; receive edge data from host_proc */
if (nedges > 0) {
MPI_Recv (*adjncy, nedges, MPI_INT, host_proc, 6, comm, &status);
if (*ewgt_dim)
MPI_Recv (*ewgts, nedges*(*ewgt_dim), MPI_FLOAT, host_proc, 7, comm, &status);
}
}
}
/* Free space on host proc */
if (myproc == host_proc){
safe_free((void **)(void *) &old_xadj);
safe_free((void **)(void *) &old_adjncy);
safe_free((void **)(void *) &old_vwgts);
safe_free((void **)(void *) &old_ewgts);
safe_free((void **)(void *) &old_x);
safe_free((void **)(void *) &old_y);
safe_free((void **)(void *) &old_z);
safe_free((void **)(void *) &vtx_list);
}
if (size != NULL) safe_free((void **)(void *) &size);
DEBUG_TRACE_END(myproc, yo);
return 1;
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

373
thirdParty/Zoltan/src/ch/ch_init_dist.c vendored Normal file
View File

@ -0,0 +1,373 @@
/*
* @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
*/
#include <stddef.h>
#include "dr_const.h"
#include "dr_input_const.h"
#include "dr_err_const.h"
#include "ch_init_dist_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/*
* Routines to perform initial data distributions for Chaco files.
* To add a new initial distribution, add a new INITIAL_* value to
* ch_init_dist_const.h and add code handling the new case to each
* of the switch statements in this file.
*
* Methods currently implemented:
* INITIAL_FILE: takes assignments from user input file
* (graphname.assign).
* INITIAL_LINEAR: assigns the first n/p vertices to proc 0, the
* next n/p vertices to proc 1, etc.
* INITIAL_OWNER: same as INITIAL_LINEAR; takes on different meaning
* only for hyperedges.
* INITIAL_CYCLIC: deals out the vertices like cards; i.e., proc 0
* gets the first vertex, proc 1 gets the second vertex,
* ..., proc p-1 gets the pth vertex, proc 0 gets the
* (p+1)th vertex, proc 1 gets the (p+2)th vertex, etc.
*
* It is possible to distribute objects to a subset of the
* the procs. The variable Num_Proc_Dist indicates that only
* procs 0 through (Num_Proc_Dist-1) should be assigned any
* vertices, the rest will have no objects.
*/
/*****************************************************************************/
/* Global variables for all routines in this file. These variables
* are set in ch_dist_init and are used in all subsequent queries of
* the chaco distribution.
*/
static ZOLTAN_GNO_TYPE Gnvtxs; /* Global number of vertices (across all procs) */
static int Num_Proc; /* Global number of processors */
static int Num_Proc_Dist; /* Number of processors to distribute data;
Num_Proc_Dist may be < Num_Proc! */
static int Initial_Method; /* Flag indicating which initial decomposition
method to use. */
/*****************************************************************************/
/* Data structures specifically for INITIAL_LINEAR */
static ZOLTAN_GNO_TYPE *Vtxdist; /* Array of size Num_Proc+1 indicating range of
vertices assigned to a processor. It is
assumed that vertices are numbered
consecutively. The values stored in Vtxdist
assume vertex IDs are zero-based (e.g., the
lowest-numbered vertex has ID 0).
Processor p is assigned vertices Vtxdist[p]
through (Vtxdist[p+1]-1), inclusive. */
static void create_Vtxdist();
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
void ch_dist_init(int num_proc, int gnvtxs, PARIO_INFO_PTR pio_info,
short **assignments, int host_proc, MPI_Comm comm)
{
/* Routine to initialize the decomposition. This routine sets the
* global variables to be used in the query routines included in this
* file. It also performs any initializations that a particular method
* may need.
* All processors call this routine prior to the actual distribution of
* graph data.
*/
int proc, i;
int max_assignment, have_assignments;
Num_Proc = num_proc;
Gnvtxs = gnvtxs;
Num_Proc_Dist = pio_info->init_dist_procs;
/* If Num_Proc_Dist has an invalid value, set it to Num_Proc by default */
if ((Num_Proc_Dist <= 0) || (Num_Proc_Dist > Num_Proc))
Num_Proc_Dist = Num_Proc;
/* Broadcast initial assignments if they exist.
* Assignments can be used for partitions and/or processors.
*/
MPI_Comm_rank(MPI_COMM_WORLD, &proc);
/* First, tell other processors whether the assignments array is NULL. */
if (proc == host_proc)
have_assignments = (*assignments != NULL);
MPI_Bcast(&have_assignments, 1, MPI_INT, host_proc, comm);
/* Now send the assignments if they exists. */
if (have_assignments) {
/* Allocate and broadcast the assignments array. */
if (proc != host_proc) {
*assignments = (short *) malloc(gnvtxs * sizeof(short));
if (*assignments == NULL) {
Gen_Error(0, "fatal: insufficient memory");
return;
}
}
MPI_Bcast( *assignments, gnvtxs, MPI_SHORT, host_proc, comm);
for (max_assignment = 0, i = 0; i < gnvtxs; i++)
if ((*assignments)[i] > max_assignment)
max_assignment = (*assignments)[i];
if (max_assignment >= Num_Proc) {
/* Highest partition number in assignment array is greater than
* the number of processors. Assume the assignments are to be
* used ONLY as partition assignments; use INITIAL_LINEAR
* assignment to put vertices on processors.
*/
pio_info->init_dist_type = INITIAL_LINEAR;
}
}
Initial_Method = pio_info->init_dist_type;
switch(Initial_Method) {
case INITIAL_LINEAR:
case INITIAL_OWNER:
/* create the vtxdist array. */
create_Vtxdist();
break;
case INITIAL_FILE:
case INITIAL_CYCLIC:
/* no initialization needed for this method. */
break;
default:
Gen_Error(0, "Invalid Initial Distribution Type in ch_dist_init");
error_report(proc);
return;
}
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
int ch_dist_num_vtx(
int target_proc,
short *assignments
)
{
/* Function that returns the number of vertices assigned to processor
* target_proc.
*/
int num;
switch(Initial_Method) {
case INITIAL_FILE: {
int i;
num = 0;
for (i = 0; i < Gnvtxs; i++)
if (assignments[i] == target_proc) num++;
break;
}
case INITIAL_LINEAR:
case INITIAL_OWNER:
num = Vtxdist[target_proc+1] - Vtxdist[target_proc];
break;
case INITIAL_CYCLIC:
if (target_proc < Num_Proc_Dist){
num = Gnvtxs / Num_Proc_Dist;
if ((Gnvtxs % Num_Proc_Dist) > target_proc)
num++;
}
else
num = 0;
break;
default:
Gen_Error(0, "Invalid Initial Distribution Type in ch_dist_num_vtx");
return(-1);
}
return(num);
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
int ch_dist_max_num_vtx(short *assignments)
{
/* Function that returns the maximum number of vertices assigned to any
* processor.
*/
int i;
int tmp, max = 0;
for (i = 0; i < Num_Proc; i++)
if ((tmp = ch_dist_num_vtx(i,assignments)) > max) max = tmp;
return max;
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
void ch_dist_vtx_list(
int *vtx_list,
int *nvtx,
int target_proc,
short *assignments
)
{
/* Function that returns a list of vertices assigned to proc target_proc.
* The list is returned in vtx_list. The function assumes vertex ID
* numbering is zero-based; e.g., the lowest-numbered vertex has ID 0.
* This convention allows the list entries to be used as array indices
* in the arrays containing chaco input file data.
* The number of entries in the list is returned in nvtx.
*/
int i, proc;
*nvtx = 0;
proc = (ZOLTAN_GNO_TYPE)target_proc;
switch(Initial_Method) {
case INITIAL_FILE:
for (i = 0; i < Gnvtxs; i++)
if (assignments[i] == target_proc)
vtx_list[(*nvtx)++] = i;
break;
case INITIAL_LINEAR:
case INITIAL_OWNER:
for (i = Vtxdist[target_proc]; i < Vtxdist[target_proc+1]; i++)
vtx_list[(*nvtx)++] = i;
break;
case INITIAL_CYCLIC:
if (target_proc < Num_Proc_Dist){
for (i = proc; i < Gnvtxs; i+=Num_Proc_Dist)
vtx_list[(*nvtx)++] = i;
}
break;
default:
Gen_Error(0, "Invalid Initial Distribution Type in ch_dist_vtx_list");
return;
}
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
int ch_dist_proc(int v, short *assignments, int base)
{
/* Function that returns the processor to which a vertex v is assigned.
* The function assumes the vertex numbering is "base"-based (i.e., lowest
* numbered vertex is vertex base); this convention is used since the function
* is called primarily to find adjacent vertices' processor assignments and
* the read-in adjacency information is "base"-based.
* E.g., for Chaco input files, base == 1; vertex comparisons are one-based.
* for HG input files, base may be 0 or 1.
*/
int p;
ZOLTAN_GNO_TYPE b = (ZOLTAN_GNO_TYPE)base;
switch(Initial_Method) {
case INITIAL_FILE:
/* return the appropriate entry from the assignments array. */
p = assignments[v-b];
break;
case INITIAL_LINEAR:
case INITIAL_OWNER:
for (p = 0; p < Num_Proc_Dist; p++)
/* Since v is "base"-based and Vtxdist is 0-based, add base to
* Vtxdist[p+1]. */
if (v < Vtxdist[p+1]+b) break;
break;
case INITIAL_CYCLIC:
/* test for (v-base) as v is "base"-based and
* INITIAL_CYCLIC equations are 0-based */
p = (v-b) % Num_Proc_Dist;
break;
default:
Gen_Error(0, "Invalid Initial Distribution Type in ch_dist_proc");
return -1;
}
return p;
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
static void create_Vtxdist()
{
/* Function that creates Vtxdist for the INITIAL_LINEAR distribution.
* Vtxdist is an array of size Num_Proc+1 indicating range of
* vertices assigned to a processor. It is assumed that vertices are numbered
* consecutively. The values stored in Vtxdist assume vertex IDs are 0-based
* (e.g., the lowest-numbered vertex has ID 0). Proc p is assigned vertices
* Vtxdist[p] through (Vtxdist[p+1]-1), inclusive.
*/
int rest, i, n;
/* Set up Vtxdist data */
if (Vtxdist == NULL){
Vtxdist = (ZOLTAN_GNO_TYPE *) malloc((Num_Proc+1) * sizeof(ZOLTAN_GNO_TYPE));
if (Vtxdist == NULL) {
Gen_Error(0, "fatal: insufficient memory");
return;
}
}
/* Calculate uniform vertex distribution */
Vtxdist[0] = 0;
rest = Gnvtxs;
for (i=0; i<Num_Proc_Dist; i++){
n = rest/(Num_Proc_Dist-i);
Vtxdist[i+1] = Vtxdist[i] + n;
rest -= n;
}
/* Procs >= Num_Proc_Dist get no vertices */
for (i=Num_Proc_Dist; i<Num_Proc; i++){
Vtxdist[i+1] = Vtxdist[i];
}
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,69 @@
/*
* @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
*/
#ifndef CH_INIT_DIST_CONST_H
#define CH_INIT_DIST_CONST_H
#include "dr_const.h"
#include "dr_input_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
extern void ch_dist_init(int, int, PARIO_INFO_PTR, short **, int, MPI_Comm);
extern int ch_dist_num_vtx(int, short *);
extern int ch_dist_max_num_vtx(short *);
extern void ch_dist_vtx_list(int *, int*, int, short *);
extern int ch_dist_proc(int, short *, int);
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif
#endif /* CH_INIT_DIST_CONST_H */

View File

@ -0,0 +1,299 @@
/*
* @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
*/
/* This software was developed by Bruce Hendrickson and Robert Leland *
* at Sandia National Laboratories under US Department of Energy *
* contract DE-AC04-76DP00789 and is copyrighted by Sandia Corporation. */
#include <stdio.h>
#include <string.h>
#include "ch_input_const.h"
#include "dr_externs.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
static int input_assign_normal(ZOLTAN_FILE*, char *, int, short*),
input_assign_inv(ZOLTAN_FILE*, char *, int, short*);
int chaco_input_assign(
ZOLTAN_FILE* finassign, /* input assignment file */
char *inassignname, /* name of input assignment file */
int nvtxs, /* number of vertices to output */
short *assignment) /* values to be printed */
{
int i; /* return value */
if (Chaco_In_Assign_Inv) {
i = input_assign_inv(finassign, inassignname, nvtxs,
assignment);
}
else {
i = input_assign_normal(finassign, inassignname, nvtxs,
assignment);
}
return(i);
}
static int input_assign_normal(
ZOLTAN_FILE* finassign, /* input assignment file */
char *inassignname, /* name of input assignment file */
int nvtxs, /* number of vertices to output */
short *assignment) /* values to be printed */
{
const char *yo = "input_assign_normal";
int flag; /* logical conditional */
int end_flag; /* return flag from read_int() */
int i, j; /* loop counter */
DEBUG_TRACE_START(0, yo);
/* Get the assignment vector one line at a time, checking as you go. */
/* First read past any comments at top. */
end_flag = 1;
while (end_flag == 1) {
assignment[0] = read_int(finassign, &end_flag);
}
if (assignment[0] < 0) {
printf("ERROR: Entry %d in assignment file `%s' less than zero (%d)\n",
1, inassignname, assignment[0]);
ZOLTAN_FILE_close(finassign);
DEBUG_TRACE_END(0, yo);
return (1);
}
if (end_flag == -1) {
printf("ERROR: No values found in assignment file `%s'\n", inassignname);
ZOLTAN_FILE_close(finassign);
DEBUG_TRACE_END(0, yo);
return (1);
}
flag = 0;
if (assignment[0] > nvtxs)
flag = assignment[1];
for (i = 1; i < nvtxs; i++) {
j = ZOLTAN_FILE_scanf(finassign, "%hd", &(assignment[i]));
if (j != 1) {
printf("ERROR: Too few values in assignment file `%s'.\n", inassignname);
ZOLTAN_FILE_close(finassign);
DEBUG_TRACE_END(0, yo);
return (1);
}
if (assignment[i] < 0) {
printf("ERROR: Entry %d in assignment file `%s' less than zero (%d)\n",
i+1, inassignname, assignment[i]);
ZOLTAN_FILE_close(finassign);
DEBUG_TRACE_END(0, yo);
return (1);
}
if (assignment[i] > nvtxs) { /* warn since probably an error */
if (assignment[i] > flag)
flag = assignment[i];
}
}
if (flag && Debug_Chaco_Input) {
printf("WARNING: Possible error in assignment file `%s'\n", inassignname);
printf(" More assignment sets (%d) than vertices (%d)\n", flag, nvtxs);
}
/* Check for spurious extra stuff in file. */
flag = FALSE;
end_flag = 0;
while (!flag && end_flag != -1) {
read_int(finassign, &end_flag);
if (!end_flag)
flag = TRUE;
}
if (flag && Debug_Chaco_Input) {
printf("WARNING: Possible error in assignment file `%s'\n", inassignname);
printf(" Numerical data found after expected end of file\n");
}
ZOLTAN_FILE_close(finassign);
DEBUG_TRACE_END(0, yo);
return (0);
}
static int input_assign_inv(
ZOLTAN_FILE* finassign, /* input assignment file */
char *inassignname, /* name of input assignment file */
int nvtxs, /* number of vertices to output */
short *assignment) /* values to be printed */
{
const char *yo = "input_assign_inv";
int set; /* set number being read */
int size; /* number of vertices in set */
int total; /* total number of vertices read */
int done; /* have I hit end of file yet? */
int end_flag; /* return flag from read_int() */
int i, j, k; /* loop counter */
DEBUG_TRACE_START(0, yo);
/* Get the assignment vector one line at a time, checking as you go. */
/* Initialize assignment to help error detection. */
for (i = 0; i < nvtxs; i++) {
assignment[i] = -1;
}
/* First read past any comments at top. */
total = 0;
set = 0;
end_flag = 1;
while (end_flag == 1) {
size = read_int(finassign, &end_flag);
}
if (end_flag == -1) {
printf("ERROR: In assignment file `%s'\n", inassignname);
printf(" No values found\n");
ZOLTAN_FILE_close(finassign);
DEBUG_TRACE_END(0, yo);
return (1);
}
if (size < 0) {
printf("ERROR: In assignment file `%s'\n", inassignname);
printf(" Size of set %d less than zero (%d)\n", set, size);
ZOLTAN_FILE_close(finassign);
DEBUG_TRACE_END(0, yo);
return (1);
}
if (total + size > nvtxs) {
printf("ERROR: In assignment file `%s'\n", inassignname);
printf(" Total set sizes greater than nvtxs (%d)\n", nvtxs);
ZOLTAN_FILE_close(finassign);
DEBUG_TRACE_END(0, yo);
return (1);
}
done = FALSE;
while (!done && total < nvtxs) {
for (i = 1; i <= size; i++) {
j = ZOLTAN_FILE_scanf(finassign, "%d", &k);
if (j != 1) {
printf("ERROR: Too few values in assignment file `%s'.\n",
inassignname);
ZOLTAN_FILE_close(finassign);
DEBUG_TRACE_END(0, yo);
return (1);
}
if (k <= 0 || k > nvtxs) {
printf("ERROR: In assignment file `%s'\n", inassignname);
printf(" Entry %d of set %d invalid (%d)\n",
total + i, set, k);
ZOLTAN_FILE_close(finassign);
DEBUG_TRACE_END(0, yo);
return (1);
}
if ((int) assignment[k - 1] != -1) {
printf("ERROR: In assignment file `%s'\n", inassignname);
printf(" Vertex %d assigned to multiple sets\n", k);
ZOLTAN_FILE_close(finassign);
DEBUG_TRACE_END(0, yo);
return (1);
}
assignment[k - 1] = (short) set;
}
total += size;
j = ZOLTAN_FILE_scanf(finassign, "%d", &size);
++set;
if (j != 1) {
if (total != nvtxs) {
printf("ERROR: Too few values in assignment file `%s'.\n",
inassignname);
ZOLTAN_FILE_close(finassign);
DEBUG_TRACE_END(0, yo);
return (1);
}
else {
done = TRUE;
size = 0;
}
}
if (size < 0) {
printf("ERROR: In assignment file `%s'\n", inassignname);
printf(" Size of set %d less than zero (%d)\n", set, size);
ZOLTAN_FILE_close(finassign);
DEBUG_TRACE_END(0, yo);
return (1);
}
if (total + size > nvtxs) {
printf("ERROR: In assignment file `%s'\n", inassignname);
printf(" Total set sizes greater than nvtxs (%d)\n", nvtxs);
ZOLTAN_FILE_close(finassign);
DEBUG_TRACE_END(0, yo);
return (1);
}
}
ZOLTAN_FILE_close(finassign);
DEBUG_TRACE_END(0, yo);
return (0);
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,86 @@
/*
* @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
*/
#ifndef __CH_INPUT_CONST_H
#define __CH_INPUT_CONST_H
#include <mpi.h>
#include "dr_const.h"
#include "dr_input_const.h"
#include "dr_compress_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
extern int chaco_input_graph(ZOLTAN_FILE*, char *, int **, int **, int *,
int *, float **, int *, float **);
extern int chaco_input_geom(ZOLTAN_FILE*, char *, int, int *, float **, float **,
float **);
extern int chaco_dist_graph(MPI_Comm, PARIO_INFO_PTR,
int, int *, int *, int **, int **,
int *, float **, int *, float **,
int *, float **, float **, float **, short **);
extern int chaco_input_assign(ZOLTAN_FILE*, char *, int, short *);
extern double read_val(ZOLTAN_FILE*, int *);
extern int read_int(ZOLTAN_FILE*, int *);
#ifndef TRUE
#define FALSE (0)
#define TRUE (1)
#endif /* !TRUE */
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif
#endif

181
thirdParty/Zoltan/src/ch/ch_input_geom.c vendored Normal file
View File

@ -0,0 +1,181 @@
/*
* @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
*/
/* This software was developed by Bruce Hendrickson and Robert Leland *
* at Sandia National Laboratories under US Department of Energy *
* contract DE-AC04-76DP00789 and is copyrighted by Sandia Corporation. */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "ch_input_const.h"
#include "dr_const.h"
#include "dr_externs.h"
#include "dr_compress_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
int chaco_input_geom(
ZOLTAN_FILE *fingeom, /* geometry input file */
char *geomname, /* name of geometry file */
int nvtxs, /* number of coordinates to read */
int *igeom, /* dimensionality of geometry */
float **x, /* coordinates of vertices */
float **y,
float **z
)
{
const char *yo = "chaco_input_geom";
float xc, yc, zc =0; /* first x, y, z coordinate */
int nread; /* number of lines of coordinates read */
int flag; /* any bad data at end of file? */
int line_num; /* counts input lines in file */
int end_flag; /* return conditional */
int ndims; /* number of values in an input line */
int i=0; /* loop counter */
DEBUG_TRACE_START(0, yo);
*x = *y = *z = NULL;
line_num = 0;
end_flag = 1;
while (end_flag == 1) {
xc = read_val(fingeom, &end_flag);
++line_num;
}
if (end_flag == -1) {
printf("No values found in geometry file `%s'\n", geomname);
ZOLTAN_FILE_close(fingeom);
return (1);
}
ndims = 1;
yc = read_val(fingeom, &end_flag);
if (end_flag == 0) {
ndims = 2;
zc = read_val(fingeom, &end_flag);
if (end_flag == 0) {
ndims = 3;
read_val(fingeom, &end_flag);
if (!end_flag) {
printf("Too many values on input line of geometry file `%s'\n",
geomname);
printf(" Maximum dimensionality is 3\n");
ZOLTAN_FILE_close(fingeom);
return (1);
}
}
}
*igeom = ndims;
*x = (float *) malloc((unsigned) nvtxs * sizeof(float));
(*x)[0] = xc;
if (ndims > 1) {
*y = (float *) malloc((unsigned) nvtxs * sizeof(float));
(*y)[0] = yc;
}
if (ndims > 2) {
*z = (float *) malloc((unsigned) nvtxs * sizeof(float));
(*z)[0] = zc;
}
for (nread = 1; nread < nvtxs; nread++) {
++line_num;
if (ndims == 1) {
i = ZOLTAN_FILE_scanf(fingeom, "%f", &((*x)[nread]));
}
else if (ndims == 2) {
i = ZOLTAN_FILE_scanf(fingeom, "%f%f", &((*x)[nread]), &((*y)[nread]));
}
else if (ndims == 3) {
i = ZOLTAN_FILE_scanf(fingeom, "%f%f%f", &((*x)[nread]), &((*y)[nread]),
&((*z)[nread]));
}
if (i == EOF) {
printf("Too few lines of values in geometry file; nvtxs=%d, but only %d read\n",
nvtxs, nread);
ZOLTAN_FILE_close(fingeom);
return (1);
}
else if (i != ndims) {
printf("Wrong number of values in line %d of geometry file `%s'\n",
line_num, geomname);
ZOLTAN_FILE_close(fingeom);
return (1);
}
}
/* Check for spurious extra stuff in file. */
flag = 0;
end_flag = 0;
while (!flag && end_flag != -1) {
read_val(fingeom, &end_flag);
if (!end_flag)
flag = 1;
}
if (flag && Debug_Chaco_Input) {
printf("Warning: possible error in geometry file `%s'\n", geomname);
printf(" Numerical data found after expected end of file\n");
}
ZOLTAN_FILE_close(fingeom);
DEBUG_TRACE_END(0, yo);
return (0);
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,435 @@
/*
* @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
*/
/* This software was developed by Bruce Hendrickson and Robert Leland *
* at Sandia National Laboratories under US Department of Energy *
* contract DE-AC04-76DP00789 and is copyrighted by Sandia Corporation. */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "ch_input_const.h"
#include "dr_const.h"
#include "dr_externs.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
int chaco_input_graph(
ZOLTAN_FILE *fin, /* input file */
char *inname, /* name of input file */
int **start, /* start of edge list for each vertex */
int **adjacency, /* edge list data */
int *nvtxs, /* number of vertices in graph */
int *vwgt_dim, /* # of vertex weights per node */
float **vweights, /* vertex weight list data */
int *ewgt_dim, /* # of edge weights per edge */
float **eweights /* edge weight list data */
)
{
const char *yo = "chaco_input_graph";
int *adjptr; /* loops through adjacency data */
float *ewptr; /* loops through edge weight data */
int narcs; /* number of edges expected in graph */
int nedges; /* twice number of edges really in graph */
int nedge; /* loops through edges for each vertex */
int flag; /* condition indicator */
int found_flag; /* is vertex found in adjacency list? */
int skip_flag; /* should this edge be ignored? */
int end_flag; /* indicates end of line or file */
int vtx; /* vertex in graph */
int line_num; /* line number in input file */
int sum_edges; /* total number of edges read so far */
int option = 0; /* input option */
int using_ewgts; /* are edge weights in input file? */
int using_vwgts; /* are vertex weights in input file? */
int vtxnums; /* are vertex numbers in input file? */
int vertex; /* current vertex being read */
int new_vertex; /* new vertex being read */
float weight; /* weight being read */
float eweight; /* edge weight being read */
int neighbor; /* neighbor of current vertex */
int self_edge; /* is a self edge encountered? */
int ignore_me; /* is this edge being ignored? */
int ignored; /* how many edges are ignored? */
int error_flag; /* error reading input? */
int j; /* loop counters */
DEBUG_TRACE_START(0, yo);
/* Read first line of input (= nvtxs, narcs, option). */
/* The (decimal) digits of the option variable mean: 1's digit not zero => input
edge weights 10's digit not zero => input vertex weights 100's digit not zero
=> include vertex numbers */
*start = NULL;
*adjacency = NULL;
*vweights = NULL;
*eweights = NULL;
error_flag = 0;
line_num = 0;
/* Read any leading comment lines */
end_flag = 1;
while (end_flag == 1) {
*nvtxs = read_int(fin, &end_flag);
++line_num;
}
if (*nvtxs <= 0) {
printf("ERROR in graph file `%s':", inname);
printf(" Invalid number of vertices (%d).\n", *nvtxs);
ZOLTAN_FILE_close(fin);
return(1);
}
narcs = read_int(fin, &end_flag);
if (narcs < 0) {
printf("ERROR in graph file `%s':", inname);
printf(" Invalid number of expected edges (%d).\n", narcs);
ZOLTAN_FILE_close(fin);
return(1);
}
/* Check if vertex or edge weights are used */
if (!end_flag) {
option = read_int(fin, &end_flag);
}
using_ewgts = option - 10 * (option / 10);
option /= 10;
using_vwgts = option - 10 * (option / 10);
option /= 10;
vtxnums = option - 10 * (option / 10);
/* Get weight dimensions from Chaco option */
(*vwgt_dim) = using_vwgts;
(*ewgt_dim) = using_ewgts;
/* Read weight dimensions if they are specified separately */
if (!end_flag && using_vwgts==1){
j = read_int(fin, &end_flag);
if (!end_flag) (*vwgt_dim) = j;
}
if (!end_flag && using_ewgts==1){
j = read_int(fin, &end_flag);
if (!end_flag) (*ewgt_dim) = j;
}
/* Discard rest of line */
while (!end_flag)
j = read_int(fin, &end_flag);
/* Allocate space for rows and columns. */
*start = (int *) malloc((unsigned) (*nvtxs + 1) * sizeof(int));
if (narcs != 0)
*adjacency = (int *) malloc((unsigned) (2 * narcs + 1) * sizeof(int));
else
*adjacency = NULL;
if (using_vwgts)
*vweights = (float *) malloc((unsigned) (*nvtxs) * (*vwgt_dim) * sizeof(float));
else
*vweights = NULL;
if (using_ewgts)
*eweights = (float *)
malloc((unsigned) (2 * narcs + 1) * (*ewgt_dim) * sizeof(float));
else
*eweights = NULL;
adjptr = *adjacency;
ewptr = *eweights;
self_edge = 0;
ignored = 0;
sum_edges = 0;
nedges = 0;
(*start)[0] = 0;
vertex = 0;
vtx = 0;
new_vertex = TRUE;
while ((using_vwgts || vtxnums || narcs) && end_flag != -1) {
++line_num;
/* If multiple input lines per vertex, read vertex number. */
if (vtxnums) {
j = read_int(fin, &end_flag);
if (end_flag) {
if (vertex == *nvtxs)
break;
printf("ERROR in graph file `%s':", inname);
printf(" no vertex number in line %d.\n", line_num);
ZOLTAN_FILE_close(fin);
return (1);
}
if (j != vertex && j != vertex + 1) {
printf("ERROR in graph file `%s':", inname);
printf(" out-of-order vertex number in line %d.\n", line_num);
ZOLTAN_FILE_close(fin);
return (1);
}
if (j != vertex) {
new_vertex = TRUE;
vertex = j;
}
else
new_vertex = FALSE;
}
else
vertex = ++vtx;
if (vertex > *nvtxs)
break;
/* If vertices are weighted, read vertex weight. */
if (using_vwgts && new_vertex) {
for (j=0; j<(*vwgt_dim); j++){
weight = read_val(fin, &end_flag);
if (end_flag) {
printf("ERROR in graph file `%s':", inname);
printf(" not enough weights for vertex %d.\n", vertex);
ZOLTAN_FILE_close(fin);
return (1);
}
if ((weight < 0) && Debug_Chaco_Input) {
printf("ERROR in graph file `%s':", inname);
printf(" negative weight entered for vertex %d.\n", vertex);
ZOLTAN_FILE_close(fin);
return (1);
}
(*vweights)[(vertex-1)*(*vwgt_dim)+j] = weight;
}
}
nedge = 0;
/* Read number of adjacent vertex. */
neighbor = read_int(fin, &end_flag);
while (!end_flag) {
skip_flag = FALSE;
ignore_me = FALSE;
if (Debug_Chaco_Input){
if (neighbor > *nvtxs) {
printf("ERROR in graph file `%s':", inname);
printf(" nvtxs=%d, but edge (%d,%d) was input.\n",
*nvtxs, vertex, neighbor);
ZOLTAN_FILE_close(fin);
return (1);
}
if (neighbor < 0) {
printf("ERROR in graph file `%s':", inname);
printf(" negative vertex in edge (%d,%d).\n",
vertex, neighbor);
ZOLTAN_FILE_close(fin);
return (1);
}
if (neighbor == vertex) {
if (!self_edge && Debug_Chaco_Input) {
printf("WARNING: Self edge (%d, %d) being ignored.\n",
vertex, vertex);
}
skip_flag = TRUE;
++self_edge;
}
/* Check if adjacency is repeated. */
if (!skip_flag) {
found_flag = FALSE;
for (j = (*start)[vertex - 1]; !found_flag && j < sum_edges + nedge; j++) {
if ((*adjacency)[j] == neighbor)
found_flag = TRUE;
}
if (found_flag) {
printf("WARNING: Multiple occurences of edge (%d,%d) ignored\n",
vertex, neighbor);
skip_flag = TRUE;
if (!ignore_me) {
ignore_me = TRUE;
++ignored;
}
}
}
}
if (using_ewgts) { /* Read edge weight if it's being input. */
for (j=0; j<(*ewgt_dim); j++){
eweight = read_val(fin, &end_flag);
if (end_flag) {
printf("ERROR in graph file `%s':", inname);
printf(" not enough weights for edge (%d,%d).\n", vertex, neighbor);
ZOLTAN_FILE_close(fin);
return (1);
}
if (eweight <= 0 && Debug_Chaco_Input) {
printf("WARNING: Bad weight entered for edge (%d,%d). Edge ignored.\n",
vertex, neighbor);
skip_flag = TRUE;
if (!ignore_me) {
ignore_me = TRUE;
++ignored;
}
}
else {
*ewptr++ = eweight;
}
}
}
if (Debug_Chaco_Input){
/* Check for edge only entered once. */
if (neighbor < vertex && !skip_flag) {
found_flag = FALSE;
for (j = (*start)[neighbor - 1]; !found_flag && j < (*start)[neighbor]; j++) {
if ((*adjacency)[j] == vertex)
found_flag = TRUE;
}
if (!found_flag) {
printf("ERROR in graph file `%s':", inname);
printf(" Edge (%d, %d) entered but not (%d, %d)\n",
vertex, neighbor, neighbor, vertex);
error_flag = 1;
}
}
}
/* Add edge to data structure. */
if (!skip_flag) {
if (++nedges > 2*narcs) {
printf("ERROR in graph file `%s':", inname);
printf(" at least %d adjacencies entered, but nedges = %d\n",
nedges, narcs);
ZOLTAN_FILE_close(fin);
return (1);
}
*adjptr++ = neighbor;
nedge++;
}
/* Read number of next adjacent vertex. */
neighbor = read_int(fin, &end_flag);
}
sum_edges += nedge;
(*start)[vertex] = sum_edges;
}
/* Make sure there's nothing else in file. */
flag = FALSE;
while (!flag && end_flag != -1) {
read_int(fin, &end_flag);
if (!end_flag)
flag = TRUE;
}
if (flag && Debug_Chaco_Input) {
printf("WARNING: Possible error in graph file `%s'\n", inname);
printf(" Data found after expected end of file\n");
}
(*start)[*nvtxs] = sum_edges;
if (self_edge > 1 && Debug_Chaco_Input) {
printf("WARNING: %d self edges were read and ignored.\n", self_edge);
}
if (vertex != 0) { /* Normal file was read. */
if (narcs) {
/* Make sure narcs was reasonable. */
if (nedges + 2 * self_edge != 2 * narcs &&
nedges + 2 * self_edge + ignored != 2 * narcs &&
nedges + self_edge != 2 * narcs &&
nedges + self_edge + ignored != 2 * narcs &&
nedges != 2 * narcs &&
nedges + ignored != 2 * narcs &&
Debug_Chaco_Input) {
printf("WARNING: I expected %d edges entered twice, but I only count %d.\n",
narcs, nedges);
}
}
else { /* no edges, but did have vertex weights or vertex numbers */
free(*start);
*start = NULL;
if (*adjacency != NULL)
free(*adjacency);
*adjacency = NULL;
if (*eweights != NULL)
free(*eweights);
*eweights = NULL;
}
}
else {
/* Graph was empty */
free(*start);
if (*adjacency != NULL)
free(*adjacency);
if (*vweights != NULL)
free(*vweights);
if (*eweights != NULL)
free(*eweights);
*start = NULL;
*adjacency = NULL;
}
ZOLTAN_FILE_close(fin);
DEBUG_TRACE_END(0, yo);
return (error_flag);
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

267
thirdParty/Zoltan/src/ch/ch_input_read.c vendored Normal file
View File

@ -0,0 +1,267 @@
/*
* @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
*/
/* This software was developed by Bruce Hendrickson and Robert Leland *
* at Sandia National Laboratories under US Department of Energy *
* contract DE-AC04-76DP00789 and is copyrighted by Sandia Corporation. */
#include "ch_input_const.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#define LINE_LENGTH 200
static char line[LINE_LENGTH]; /* space to hold values */
static int offset = 0; /* offset into line for next data */
static int break_pnt = LINE_LENGTH; /* place in sequence to pause */
static int save_pnt; /* place in sequence to save */
static void flush_line(ZOLTAN_FILE*);
double read_val(
ZOLTAN_FILE* infile, /* file to read value from */
int *end_flag /* 0 => OK, 1 => EOL, -1 => EOF */
)
{
double val; /* return value */
char *ptr; /* ptr to next string to read */
char *ptr2; /* ptr to next string to read */
int length; /* length of line to read */
int length_left; /* length of line still around */
int white_seen; /* have I detected white space yet? */
int done; /* checking for end of scan */
int i; /* loop counter */
*end_flag = 0;
if (offset == 0 || offset >= break_pnt) {
if (offset >= break_pnt) { /* Copy rest of line back to beginning. */
length_left = LINE_LENGTH - save_pnt - 1;
ptr2 = line;
ptr = &line[save_pnt];
for (i=length_left; i; i--) *ptr2++ = *ptr++;
length = save_pnt + 1;
}
else {
length = LINE_LENGTH;
length_left = 0;
}
/* Now read next line, or next segment of current one. */
ptr2 = ZOLTAN_FILE_gets(&line[length_left], length, infile);
if (ptr2 == (char *) NULL) { /* We've hit end of file. */
*end_flag = -1;
return((double) 0.0);
}
if ((line[LINE_LENGTH - 2] != '\n') && (line[LINE_LENGTH - 2] != '\f')
&& (strlen(line) == LINE_LENGTH - 1)){
/* Line too long. Find last safe place in line. */
break_pnt = LINE_LENGTH - 1;
save_pnt = break_pnt;
white_seen = FALSE;
done = FALSE;
while (!done) {
--break_pnt;
if (line[break_pnt] != '\0') {
if (isspace((int)(line[break_pnt]))) {
if (!white_seen) {
save_pnt = break_pnt + 1;
white_seen = TRUE;
}
}
else if (white_seen) {
done= TRUE;
}
}
}
}
else {
break_pnt = LINE_LENGTH;
}
offset = 0;
}
while (isspace((int)(line[offset])) && offset < LINE_LENGTH) offset++;
if (line[offset] == '%' || line[offset] == '#') {
*end_flag = 1;
if (break_pnt < LINE_LENGTH) {
flush_line(infile);
}
return((double) 0.0);
}
ptr = &(line[offset]);
val = strtod(ptr, &ptr2);
if (ptr2 == ptr) { /* End of input line. */
offset = 0;
*end_flag = 1;
return((double) 0.0);
}
else {
offset = (int) (ptr2 - line) / sizeof(char);
}
return(val);
}
int read_int(
ZOLTAN_FILE *infile, /* file to read value from */
int *end_flag /* 0 => OK, 1 => EOL, -1 => EOF */
)
{
int val; /* return value */
char *ptr; /* ptr to next string to read */
char *ptr2; /* ptr to next string to read */
int length; /* length of line to read */
int length_left; /* length of line still around */
int white_seen; /* have I detected white space yet? */
int done; /* checking for end of scan */
int i; /* loop counter */
*end_flag = 0;
if (offset == 0 || offset >= break_pnt) {
if (offset >= break_pnt) { /* Copy rest of line back to beginning. */
length_left = LINE_LENGTH - save_pnt - 1;
ptr2 = line;
ptr = &line[save_pnt];
for (i=length_left; i; i--) *ptr2++ = *ptr++;
length = save_pnt + 1;
}
else {
length = LINE_LENGTH;
length_left = 0;
}
/* Now read next line, or next segment of current one. */
ptr2 = ZOLTAN_FILE_gets(&line[length_left], length, infile);
if (ptr2 == (char *) NULL) { /* We've hit end of file. */
*end_flag = -1;
return(0);
}
if ((line[LINE_LENGTH - 2] != '\n') && (line[LINE_LENGTH - 2] != '\f')
&& (strlen(line) == LINE_LENGTH - 1)){
/* Line too long. Find last safe place in line. */
break_pnt = LINE_LENGTH - 1;
save_pnt = break_pnt;
white_seen = FALSE;
done = FALSE;
while (!done) {
--break_pnt;
if (line[break_pnt] != '\0') {
if (isspace((int)(line[break_pnt]))) {
if (!white_seen) {
save_pnt = break_pnt + 1;
white_seen = TRUE;
}
}
else if (white_seen) {
done= TRUE;
}
}
}
}
else {
break_pnt = LINE_LENGTH;
}
offset = 0;
}
while (isspace((int)(line[offset])) && offset < LINE_LENGTH) offset++;
if (line[offset] == '%' || line[offset] == '#') {
*end_flag = 1;
if (break_pnt < LINE_LENGTH) {
flush_line(infile);
}
return(0);
}
ptr = &(line[offset]);
val = (int) strtol(ptr, &ptr2, 10);
if (ptr2 == ptr) { /* End of input line. */
offset = 0;
*end_flag = 1;
return(0);
}
else {
offset = (int) (ptr2 - line) / sizeof(char);
}
return(val);
}
static void flush_line(
ZOLTAN_FILE *infile /* file to read value from */
)
{
char c; /* character being read */
c = ZOLTAN_FILE_getc(infile);
while (c != '\n' && c != '\f')
c = ZOLTAN_FILE_getc(infile);
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

180
thirdParty/Zoltan/src/coloring/bucket.c vendored Normal file
View File

@ -0,0 +1,180 @@
/*
* @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
*/
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include "zoltan_mem.h"
#include "bucket.h"
void Zoltan_Bucket_Insert(Bucket* bs, int id, int value)
{
#if 0
assert (bs != NULL);
assert (value >= 0);
assert (value <= bs->max_value);
assert (id >= 0);
assert (id < bs->nb_elements);
#endif
bs->values[id] = value;
bs->elements[id].prev = NULL;
bs->elements[id].next = bs->buckets[value];
if (bs->buckets[value] != NULL)
bs->buckets[value]->prev = &(bs->elements[id]);
else if (bs->current_min_value > value)
bs->current_min_value = value;
bs->buckets[value] = &(bs->elements[id]);
}
void Zoltan_Bucket_Update(Bucket* bs, int id, int new_value)
{
int old_value = bs->values[id];
if (old_value == INT_MAX)
return;
#if 0
assert (bs != NULL);
assert (new_value >= 0);
assert (new_value <= bs->max_value);
assert (id >= 0);
assert (id < bs->nb_elements);
#endif
bs->values[id] = new_value;
if (bs->elements[id].prev == NULL)
bs->buckets[old_value] = bs->elements[id].next;
else
bs->elements[id].prev->next = bs->elements[id].next;
if (bs->elements[id].next != NULL)
bs->elements[id].next->prev = bs->elements[id].prev;
Zoltan_Bucket_Insert(bs, id, new_value);
}
int Zoltan_Bucket_PopMin(Bucket* bs)
{
int id;
#if 0
assert (bs != NULL);
assert (bs->current_min_value >= 0);
#endif
for (; bs->current_min_value<=bs->max_value; bs->current_min_value++) {
if (bs->buckets[bs->current_min_value] != NULL) {
id = bs->buckets[bs->current_min_value] - bs->elements;
bs->buckets[bs->current_min_value] = bs->buckets[bs->current_min_value]->next;
if (bs->buckets[bs->current_min_value] != NULL) {
bs->buckets[bs->current_min_value]->prev = NULL;
}
bs->values[id] = INT_MAX;
return id;
}
}
return -1;
}
Bucket Zoltan_Bucket_Initialize(int max_value, int nb_element)
{
Bucket bs;
int i;
#if 0
assert (max_value>=0);
assert (nb_element>=0);
#endif
bs.buckets = (Bucket_element **)ZOLTAN_MALLOC(sizeof(Bucket_element *)*(max_value+1));
bs.elements = (Bucket_element *)ZOLTAN_MALLOC(sizeof(Bucket_element)*nb_element);
bs.values = (int *) ZOLTAN_MALLOC(sizeof(int)*nb_element);
bs.max_value = max_value;
bs.nb_elements = nb_element;
if (bs.buckets == NULL || bs.elements == NULL || bs.values == NULL) {
ZOLTAN_FREE(&(bs.values));
ZOLTAN_FREE(&(bs.buckets));
ZOLTAN_FREE(&(bs.elements));
} else {
for (i=0; i<=max_value; i++)
bs.buckets[i] = NULL;
for (i=0; i<nb_element; i++) {
bs.elements[i].prev = NULL;
bs.elements[i].next = NULL;
}
}
bs.current_min_value = max_value+1;
return bs;
}
void Zoltan_Bucket_Free(Bucket* bs)
{
ZOLTAN_FREE(&(bs->values));
ZOLTAN_FREE(&(bs->buckets));
ZOLTAN_FREE(&(bs->elements));
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

99
thirdParty/Zoltan/src/coloring/bucket.h vendored Normal file
View File

@ -0,0 +1,99 @@
/*
* @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
*/
#ifndef __BUCKET__H
#define __BUCKET__H
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/* This is ID-less bucket datastructure to save memory
and hence speed up bucket updates. It assumes IDs are
0-based indices without any gap */
typedef struct S
{
struct S* prev;
struct S* next;
} Bucket_element;
typedef struct arg
{
Bucket_element **buckets; /* actual pointers to bucket heads */
Bucket_element *elements; /* for direct access to bucket elements
elements[id] is the id-th element */
int nb_elements;
int max_value;
int *values; /* needed for update, incase bucket head
changed. */
int current_min_value;
} Bucket;
/* value == INT_MAX means not present in bucket */
void Zoltan_Bucket_Insert(Bucket* bs, int id, int value);
void Zoltan_Bucket_Update(Bucket* bs, int id, int new_value);
#define Zoltan_Bucket_DecVal(bs, id) Zoltan_Bucket_Update(bs, id, (bs)->values[id]-1)
/*returns -1 if empty*/
int Zoltan_Bucket_PopMin(Bucket* bs);
Bucket Zoltan_Bucket_Initialize(int max_value, int nb_element);
void Zoltan_Bucket_Free(Bucket* bs);
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif
#endif

View File

@ -0,0 +1,340 @@
/*
* @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
*/
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#include <limits.h>
#include <ctype.h>
#include "zoltan_mem.h"
#include "zz_const.h"
#include "coloring.h"
#include "g2l_hash.h"
#include "params_const.h"
#include "zz_util_const.h"
#include "graph.h"
#include "all_allo_const.h"
/*****************************************************************************/
/* Parameters structure for Color method. Used in */
/* Zoltan_Color_Set_Param and Zoltan_Color. */
static PARAM_VARS Color_params[] = {
{ "COLORING_PROBLEM", NULL, "STRING", 0 },
{ "SUPERSTEP_SIZE", NULL, "INT", 0},
{ "COMM_PATTERN", NULL, "CHAR", 0 },
{ "VERTEX_VISIT_ORDER", NULL, "CHAR", 0 },
{ "COLORING_METHOD", NULL, "CHAR", 0},
{ NULL, NULL, NULL, 0 } };
/*****************************************************************************/
/* Interface routine for Graph Coloring Testing */
int Zoltan_Color_Test(
ZZ *zz, /* Zoltan structure */
int *num_gid_entries, /* # of entries for a global id */
int *num_lid_entries, /* # of entries for a local id */
int num_obj, /* Input: number of objects */
ZOLTAN_ID_PTR global_ids, /* Input: global ids of the vertices */
/* The application must allocate enough space */
ZOLTAN_ID_PTR local_ids, /* Input: local ids of the vertices */
/* The application must allocate enough space */
int *color_exp /* Input: Colors assigned to local vertices */
)
{
static char *yo = "color_test_fn";
int nvtx = num_obj; /* number of vertices */
int i, j;
int ierr = ZOLTAN_OK;
int ferr = ZOLTAN_OK; /* final error signal */
char coloring_problem; /* Input: which coloring to perform;
currently only supports D1, D2 coloring and variants */
char coloring_problemStr[MAX_PARAM_STRING_LEN]; /* string version coloring problem name */
int ss=100;
char comm_pattern='S', coloring_order='I', coloring_method='F';
int comm[2],gcomm[2];
int *color=NULL;
int *adjproc=NULL, *xadj=NULL;
ZOLTAN_GNO_TYPE gvtx; /* number of global vertices */
ZOLTAN_GNO_TYPE *vtxdist=NULL, *adjncy=NULL;
ZG graph;
ZOLTAN_GNO_TYPE *requested_GNOs = NULL; /* Return GNOs of
the requested GIDs. */
int *loc_partialD2 = NULL; /* local binary array showing which vertices to be colored */
int *partialD2 = NULL; /* global binary array showing which vertices to be colored */
struct Zoltan_DD_Struct *dd_color; /* DDirectory for colors */
ZOLTAN_GNO_TYPE *local_GNOs = NULL;
ZOLTAN_GNO_TYPE *global_GNOs = NULL;
memset (&graph, 0, sizeof(ZG));
/* PARAMETER SETTINGS */
Zoltan_Bind_Param(Color_params, "COLORING_PROBLEM", (void *) &coloring_problemStr);
Zoltan_Bind_Param(Color_params, "SUPERSTEP_SIZE", (void *) &ss);
Zoltan_Bind_Param(Color_params, "COMM_PATTERN", (void *) &comm_pattern);
Zoltan_Bind_Param(Color_params, "VERTEX_VISIT_ORDER", (void *) &coloring_order);
Zoltan_Bind_Param(Color_params, "COLORING_METHOD", (void *) &coloring_method);
strncpy(coloring_problemStr, "distance-1", MAX_PARAM_STRING_LEN);
Zoltan_Assign_Param_Vals(zz->Params, Color_params, zz->Debug_Level, zz->Proc,
zz->Debug_Proc);
/* Check validity of parameters - they should be consistent with Zoltan_Color */
if (!strcasecmp(coloring_problemStr, "distance-1"))
coloring_problem = '1';
else if (!strcasecmp(coloring_problemStr, "distance-2"))
coloring_problem = '2';
else if (!strcasecmp(coloring_problemStr, "partial-distance-2")
|| !strcasecmp(coloring_problemStr, "bipartite"))
coloring_problem = 'P';
else {
ZOLTAN_PRINT_WARN(zz->Proc, yo, "Unknown coloring requested. Using Distance-1 coloring.");
coloring_problem = '1';
}
if (ss == 0) {
ZOLTAN_PRINT_WARN(zz->Proc, yo, "Invalid superstep size. Using default value 100.");
ss = 100;
}
if (comm_pattern != 'S' && comm_pattern != 'A') {
ZOLTAN_PRINT_WARN(zz->Proc, yo, "Invalid communication pattern. Using synchronous communication (S).");
comm_pattern = 'S';
}
if (comm_pattern == 'A' && (coloring_problem == '2' || coloring_problem == 'P')) {
ZOLTAN_PRINT_WARN(zz->Proc, yo, "Asynchronous communication pattern is not implemented for distance-2 coloring and its variants. Using synchronous communication (S).");
comm_pattern = 'S';
}
if (coloring_order != 'I' && coloring_order != 'B' && coloring_order != 'U' && coloring_order != 'L' && coloring_order != 'N' && coloring_order != 'S') {
ZOLTAN_PRINT_WARN(zz->Proc, yo, "Invalid coloring order. Using internal first coloring order (I).");
coloring_order = 'I';
}
if (coloring_order == 'U' && (coloring_problem == '2' || coloring_problem == 'P')) {
ZOLTAN_PRINT_WARN(zz->Proc, yo, "Interleaved coloring order is not implemented for distance-2 coloring and its variants. Using internal first coloring order (I).");
coloring_order = 'I';
}
if (coloring_method !='F') {
ZOLTAN_PRINT_WARN(zz->Proc, yo, "Invalid coloring method. Using first fit method (F).");
coloring_method = 'F';
}
/* Compute Max number of array entries per ID over all processors.
This is a sanity-maintaining step; we don't want different
processors to have different values for these numbers. */
comm[0] = zz->Num_GID;
comm[1] = zz->Num_LID;
MPI_Allreduce(comm, gcomm, 2, MPI_INT, MPI_MAX, zz->Communicator);
zz->Num_GID = *num_gid_entries = gcomm[0];
zz->Num_LID = *num_lid_entries = gcomm[1];
/* Return if this processor is not in the Zoltan structure's
communicator. */
if (ZOLTAN_PROC_NOT_IN_COMMUNICATOR(zz))
return ZOLTAN_OK;
/* BUILD THE GRAPH */
/* Check that the user has allocated space for the return args. */
if (!color_exp)
ZOLTAN_COLOR_ERROR(ZOLTAN_FATAL, "Color argument is NULL. Please give colors of local vertices.");
requested_GNOs = (ZOLTAN_GNO_TYPE *) ZOLTAN_MALLOC(num_obj *
sizeof(ZOLTAN_GNO_TYPE));
Zoltan_ZG_Build (zz, &graph, 0, 1, num_obj,
global_ids, requested_GNOs);
Zoltan_ZG_Export (zz, &graph,
&gvtx, &nvtx, NULL, NULL,
&vtxdist, &xadj, &adjncy, &adjproc,
NULL, NULL);
if (gvtx > (ZOLTAN_GNO_TYPE)INT_MAX){
if (zz->Proc == 0){
fprintf(stderr,
"Zoltan_Color_Test assumes number of vertices (%ld) is less than INT_MAX\n",gvtx);
}
ierr = ZOLTAN_FATAL;
goto End;
}
/* Exchange global color information */
if (vtxdist[zz->Num_Proc] && !(color = (int *) ZOLTAN_CALLOC(vtxdist[zz->Num_Proc], sizeof(int))))
MEMORY_ERROR;
if (nvtx && !(local_GNOs = (ZOLTAN_GNO_TYPE *) ZOLTAN_MALLOC(nvtx * sizeof(ZOLTAN_GNO_TYPE))))
MEMORY_ERROR;
for (i=0; i<nvtx; ++i)
local_GNOs[i] = i+vtxdist[zz->Proc];
if (vtxdist[zz->Num_Proc] && !(global_GNOs = (ZOLTAN_GNO_TYPE *) ZOLTAN_MALLOC(vtxdist[zz->Num_Proc] * sizeof(ZOLTAN_GNO_TYPE))))
MEMORY_ERROR;
for (i=0; i<vtxdist[zz->Num_Proc]; ++i)
global_GNOs[i] = i;
ierr = Zoltan_DD_Create (&dd_color, zz->Communicator,
sizeof(ZOLTAN_GNO_TYPE)/sizeof(ZOLTAN_ID_TYPE), 0, 0, num_obj, 0);
if (ierr != ZOLTAN_OK)
ZOLTAN_COLOR_ERROR(ierr, "Cannot construct DDirectory.");
/* Put req obs with 1 but first inialize the rest with 0 */
ierr = Zoltan_DD_Update (dd_color, (ZOLTAN_ID_PTR)local_GNOs, NULL,
NULL, color, nvtx);
if (ierr != ZOLTAN_OK)
ZOLTAN_COLOR_ERROR(ierr, "Cannot update DDirectory.");
ierr = Zoltan_DD_Update (dd_color, (ZOLTAN_ID_PTR)requested_GNOs, NULL,
NULL, color_exp, num_obj);
if (ierr != ZOLTAN_OK)
ZOLTAN_COLOR_ERROR(ierr, "Cannot update DDirectory.");
/* Get requested colors from the DDirectory. */
ierr = Zoltan_DD_Find (dd_color, (ZOLTAN_ID_PTR)global_GNOs, NULL, NULL,
color, vtxdist[zz->Num_Proc], NULL);
if (ierr != ZOLTAN_OK)
ZOLTAN_COLOR_ERROR(ierr, "Cannot find object in DDirectory.");
/* Free DDirectory */
Zoltan_DD_Destroy(&dd_color);
ZOLTAN_FREE(&local_GNOs);
ZOLTAN_FREE(&global_GNOs);
if (coloring_problem == 'P' || coloring_problem == '2') {
if (vtxdist[zz->Num_Proc] && !(partialD2 = (int *) ZOLTAN_CALLOC(vtxdist[zz->Num_Proc], sizeof(int))))
MEMORY_ERROR;
if (vtxdist[zz->Num_Proc] && !(loc_partialD2 = (int *) ZOLTAN_CALLOC(vtxdist[zz->Num_Proc], sizeof(int))))
MEMORY_ERROR;
if (coloring_problem == 'P') {
for (i=0; i<num_obj; ++i) {
int gno=requested_GNOs[i];
loc_partialD2[gno] = 1;
}
MPI_Allreduce(loc_partialD2, partialD2, vtxdist[zz->Num_Proc], MPI_INT, MPI_LOR, zz->Communicator);
} else {
for (i=0; i<vtxdist[zz->Num_Proc]; ++i)
partialD2[i] = 1;
}
}
/* Check if there is an error in coloring */
if (coloring_problem == '1') {
for (i=0; i<nvtx; i++) {
int gno = i + (int)vtxdist[zz->Proc];
if (color[gno] <= 0) { /* object i is not colored properly */
ierr = ZOLTAN_FATAL;
printf("Error in coloring! u:%d, cu:%d\n", gno, color[gno]);
break;
}
for (j = xadj[i]; j < xadj[i+1]; ++j) {
int v = (int)adjncy[j];
if (color[gno] == color[v]) { /* neighbors have the same color */
ierr = ZOLTAN_FATAL;
printf("Error in coloring! u:%d, v:%d, cu:%d, cv:%d\n", gno, v, color[gno], color[v]);
break;
}
}
if (ierr == ZOLTAN_FATAL)
break;
}
} else if (coloring_problem == '2' || coloring_problem == 'P') {
for (i=0; i<nvtx; i++) {
int gno = i + (int)vtxdist[zz->Proc];
if (partialD2[gno] && color[gno] <= 0) { /* object i is not colored properly */
ierr = ZOLTAN_FATAL;
printf("Error in coloring! u:%d, cu:%d\n", gno, color[gno]);
break;
}
for (j = xadj[i]; j < xadj[i+1]; ++j) {
int v = (int)adjncy[j], k;
if (partialD2[v] && color[v] <= 0) {
ierr = ZOLTAN_FATAL;
printf("Error in coloring! d1-neigh: u:%d, v:%d, cu:%d, cv:%d pu:%d pv:%d\n", gno, v, color[gno], color[v], partialD2[gno], partialD2[v]);
break;
}
if (partialD2[gno] && partialD2[v] && color[gno] == color[v]) { /* d-1 neighbors have the same color */
ierr = ZOLTAN_FATAL;
printf("Error in coloring! d1-neigh: u:%d, v:%d, cu:%d, cv:%d pu:%d pv:%d\n", gno, v, color[gno], color[v], partialD2[gno], partialD2[v]);
break;
}
for (k = j+1; k < xadj[i+1]; ++k) {
int w = (int)adjncy[k];
if (partialD2[v] && partialD2[w] && color[v] == color[w]) { /* d-2 neighbors have the same color */
ierr = ZOLTAN_FATAL;
printf("Error in coloring! d2-neigh: v:%d, w:%d, cv:%d, cw:%d pv:%d pw:%d\n", v, w, color[v], color[w], partialD2[v], partialD2[w]);
break;
}
}
}
if (ierr == ZOLTAN_FATAL)
break;
}
} else
ZOLTAN_COLOR_ERROR(ZOLTAN_WARN, "Zoltan_Color_Test is only implemented for distance-1 and distance-2 coloring. Unknown coloring, skipping verification.");
End:
if (ierr==ZOLTAN_FATAL)
ierr = 2;
MPI_Allreduce(&ierr, &ferr, 1, MPI_INT, MPI_MAX, zz->Communicator);
if (ferr == 2)
ierr = ZOLTAN_FATAL;
else
ierr = ZOLTAN_OK;
Zoltan_ZG_Free (&graph);
ZOLTAN_FREE(&local_GNOs);
ZOLTAN_FREE(&global_GNOs);
ZOLTAN_FREE(&adjproc);
ZOLTAN_FREE(&color);
ZOLTAN_FREE(&requested_GNOs);
ZOLTAN_FREE(&partialD2);
ZOLTAN_FREE(&loc_partialD2);
return ierr;
}

2571
thirdParty/Zoltan/src/coloring/coloring.c vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,74 @@
/*
* @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
*/
#ifndef __COLORING_H
#define __COLORING_H
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#include <ctype.h>
#include "zz_const.h"
#include "zz_util_const.h"
#include "coloring_const.h"
/* Metis also has a swap */
#ifdef SWAP
#undef SWAP
#endif
#define SWAP(a,b) tmp=(a);(a)=(b);(b)=tmp;
/* Macros for error handling */
#define ZOLTAN_COLOR_ERROR(error,str) {ierr = error ; \
ZOLTAN_PRINT_ERROR(zz->Proc, yo, str) ; goto End ;}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,63 @@
/*
* @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
*/
#ifndef __COLORING_CONST_H
#define __COLORING_CONST_H
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
extern int Zoltan_Color_Set_Param(char *, char *);
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif
#endif

View File

@ -0,0 +1,267 @@
/*
* @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
*/
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#include "zoltan_util.h"
#include "coloring.h"
#include "g2l_hash.h"
/*****************************************************************************/
/* Returns a prime number larger than (or equal to) stopafter,
hopefully close to stopafter. If stopafter is larger than
2147483647. 2147483647 will be returned.
*/
#define MAX_PRIME 193
int Zoltan_GenPrime(int stopafter, int *prime_num)
{
static const int primes[MAX_PRIME]=
{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 37, 41, 47, 53, 59, 67, 79, 89,
101, 113, 127, 149, 167, 191, 211, 233, 257, 283, 313, 347, 383, 431,
479, 541, 599, 659, 727, 809, 907, 1009, 1117, 1229, 1361, 1499, 1657,
1823, 2011, 2213, 2437, 2683, 2953, 3251, 3581, 3943, 4339, 4783,
5273, 5801, 6389, 7039, 7753, 8537, 9391, 10331, 11369, 12511, 13763,
15149, 16673, 18341, 20177, 22229, 24469, 26921, 29629, 32603, 35869,
39461, 43411, 47777, 52561, 57829, 63617, 69991, 76991, 84691, 93169,
102497, 112757, 124067, 136481, 150131, 165161, 181693, 199873,
219871, 241861, 266051, 292661, 321947, 354143, 389561, 428531,
471389, 518533, 570389, 627433, 690187, 759223, 835207, 918733,
1010617, 1111687, 1222889, 1345207, 1479733, 1627723, 1790501,
1969567, 2166529, 2383219, 2621551, 2883733, 3172123, 3489347,
3838283, 4222117, 4644329, 5108767, 5619667, 6181639, 6799811,
7479803, 8227787, 9050599, 9955697, 10951273, 12046403, 13251047,
14576161, 16033799, 17637203, 19400929, 21341053, 23475161, 25822679,
28404989, 31245491, 34370053, 37807061, 41587807, 45746593, 50321261,
55353391, 60888739, 66977621, 73675391, 81042947, 89147249, 98061979,
107868203, 118655027, 130520531, 143572609, 157929907, 173722907,
191095213, 210204763, 231225257, 254347801, 279782593, 307760897,
338536987, 372390691, 409629809, 450592801, 495652109, 545217341,
599739083, 659713007, 725684317, 798252779, 878078057, 965885863,
1062474559, 1168722059, 1285594279, 1414153729, 1555569107,
1711126033, 1882238639, 2070462533, 2147483647};
int uplimit=MAX_PRIME-1;
int botlimit=0;
int j;
int result=primes[uplimit];
while(1) {
if (uplimit-botlimit < 5) {
for (j = botlimit; primes[j]<= stopafter && j <= uplimit; j++);
result = (j==MAX_PRIME) ? j-1 : j;
break;
}
if (primes[botlimit + (uplimit - botlimit) / 2] < stopafter)
botlimit = botlimit + (uplimit-botlimit) / 2;
else
uplimit = uplimit - (uplimit-botlimit) / 2;
}
*prime_num = primes[result];
return ZOLTAN_OK;
}
#undef MAX_PRIME
int Zoltan_G2LHash_Create(G2LHash *hash, int maxsize, ZOLTAN_GNO_TYPE base, int nlvtx)
{
if (maxsize == 0) /* to avoid memory allocation errors */
maxsize = 1;
if (Zoltan_GenPrime(maxsize , &(hash->maxsize))==ZOLTAN_MEMERR)
return ZOLTAN_MEMERR;
hash->table = NULL;
hash->nodes = NULL;
hash->base = base;
hash->baseend = base+nlvtx-1;
hash->nlvtx = nlvtx;
hash->size = 0;
hash->num_gid_entries = sizeof(ZOLTAN_GNO_TYPE) / sizeof(ZOLTAN_ID_TYPE);
hash->table = (G2LHashNode **) ZOLTAN_CALLOC((size_t) hash->maxsize, sizeof(G2LHashNode *));
hash->nodes = (G2LHashNode *) ZOLTAN_MALLOC((size_t) hash->maxsize * (size_t) sizeof(G2LHashNode));
if (!hash->table || !hash->nodes) {
Zoltan_G2LHash_Destroy(hash);
return ZOLTAN_MEMERR;
}
return ZOLTAN_OK;
}
int Zoltan_G2LHash_Destroy(G2LHash *hash)
{
ZOLTAN_FREE(&hash->table);
ZOLTAN_FREE(&hash->nodes);
return ZOLTAN_OK;
}
int Zoltan_G2LHash_Insert(G2LHash *hash, ZOLTAN_GNO_TYPE gno)
{
int i, lno;
G2LHashNode *ptr;
if (gno<hash->base || gno>hash->baseend) {
i = Zoltan_Hash((ZOLTAN_ID_PTR) (void *)&gno, hash->num_gid_entries, (unsigned int) hash->maxsize);
for (ptr=hash->table[i]; ptr && ptr->gno!=gno; ptr = ptr->next);
if (!ptr) {
if (hash->size >= hash->maxsize) {
char st[2048];
sprintf(st, "Hash is full! #entries=%d maxsize=%d", hash->size, hash->maxsize);
ZOLTAN_PRINT_ERROR(-1, "Zoltan_G2LHash_G2L", st);
return -1;
}
ptr = &(hash->nodes[hash->size]);
ptr->gno = gno;
lno = ptr->lno = hash->nlvtx + hash->size;
ptr->next = hash->table[i];
hash->table[i] = ptr;
++hash->size;
} else
lno = ptr->lno;
} else
return gno-hash->base;
return lno;
}
int Zoltan_G2LHash_G2L(G2LHash *hash, ZOLTAN_GNO_TYPE gno)
{
int i;
G2LHashNode *ptr;
if (gno<hash->base || gno>hash->baseend) {
i = Zoltan_Hash((ZOLTAN_ID_PTR) (void *)&gno, hash->num_gid_entries, (unsigned int) hash->maxsize);
for (ptr=hash->table[i]; ptr && ptr->gno!=gno; ptr = ptr->next);
if (!ptr)
return -1;
else
return ptr->lno;
} else
return gno-hash->base;
}
/* --------------------------- KVHash -------------------------------- */
int Zoltan_KVHash_Create(KVHash *hash, int maxsize)
{
if (maxsize == 0) /* to avoid memory allocation errors */
maxsize = 1;
if (Zoltan_GenPrime(maxsize , &(hash->maxsize))==ZOLTAN_MEMERR)
return ZOLTAN_MEMERR;
hash->table = NULL;
hash->nodes = NULL;
hash->size = 0;
hash->num_gid_entries = sizeof(ZOLTAN_GNO_TYPE) / sizeof(ZOLTAN_ID_TYPE);
hash->table = (G2LHashNode **) ZOLTAN_CALLOC(hash->maxsize, sizeof(G2LHashNode *));
hash->nodes = (G2LHashNode *) ZOLTAN_MALLOC(hash->maxsize * sizeof(G2LHashNode));
if (!hash->table || !hash->nodes) {
Zoltan_G2LHash_Destroy(hash);
return ZOLTAN_MEMERR;
}
return ZOLTAN_OK;
}
int Zoltan_KVHash_Destroy(KVHash *hash)
{
ZOLTAN_FREE(&hash->table);
ZOLTAN_FREE(&hash->nodes);
return ZOLTAN_OK;
}
int Zoltan_KVHash_Insert(KVHash *hash, ZOLTAN_GNO_TYPE key, int value)
{
int i;
G2LHashNode *ptr;
i = Zoltan_Hash((ZOLTAN_ID_PTR) (void *)&key, hash->num_gid_entries, (unsigned int) hash->maxsize);
for (ptr=hash->table[i]; ptr && ptr->gno!=key; ptr = ptr->next);
if (!ptr) {
if (hash->size >= hash->maxsize) {
ZOLTAN_PRINT_ERROR(-1, "Zoltan_KVHash_Insert", "Hash is full!");
return -1;
}
ptr = &(hash->nodes[hash->size]);
ptr->gno = key;
ptr->lno = value;
ptr->next = hash->table[i];
hash->table[i] = ptr;
++hash->size;
} else
value = ptr->lno;
return value;
}
int Zoltan_KVHash_GetValue(KVHash *hash, ZOLTAN_GNO_TYPE key)
{
int i;
G2LHashNode *ptr;
i = Zoltan_Hash((ZOLTAN_ID_PTR) (void *) &key, hash->num_gid_entries, (unsigned int) hash->maxsize);
for (ptr=hash->table[i]; ptr && ptr->gno!=key; ptr = ptr->next);
if (!ptr)
return -1;
else
return ptr->lno;
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,104 @@
/*
* @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
*/
#ifndef _G2L_HASH_H_
#define _G2L_HASH_H_
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/* Structure used for hashing */
struct G2L_Hash_Node {
ZOLTAN_GNO_TYPE gno; /* Global number */
int lno; /* Mapped id of gno*/
struct G2L_Hash_Node * next;
};
typedef struct G2L_Hash_Node G2LHashNode;
struct G2L_Hash {
int maxsize;
int size; /* number of ids stored in the hash */
ZOLTAN_GNO_TYPE base, baseend; /* base and baseend are inclusive gno's of local vertices */
int nlvtx; /* it is #localy owened vertices: simply equal to "baseend-base+1" */
int num_gid_entries; /* multiple of ZOLTAN_ID_TYPEs in a key */
G2LHashNode **table;
G2LHashNode *nodes;
};
typedef struct G2L_Hash G2LHash;
int Zoltan_G2LHash_Create(G2LHash *hash, int maxsize, ZOLTAN_GNO_TYPE base, int nlvtx);
int Zoltan_G2LHash_Destroy(G2LHash *hash);
int Zoltan_G2LHash_G2L(G2LHash *hash, ZOLTAN_GNO_TYPE gno);
/*
if gno exist it returns lno, if it does not exist,
it inserts andr returns newly assigned lno */
int Zoltan_G2LHash_Insert(G2LHash *hash, ZOLTAN_GNO_TYPE gno);
#define Zoltan_G2LHash_L2G(hash, lno) ((lno<(hash)->nlvtx) ? (hash)->base+lno : (hash)->nodes[lno-(hash)->nlvtx].gno)
/* Key&Value hash functions using same data structure above
the only difference will be the insert function */
typedef struct G2L_Hash KVHash;
int Zoltan_KVHash_Create(KVHash *hash, int maxsize);
int Zoltan_KVHash_Destroy(KVHash *hash);
int Zoltan_KVHash_Insert(KVHash *hash, ZOLTAN_GNO_TYPE key, int value);
int Zoltan_KVHash_GetValue(KVHash *hash, ZOLTAN_GNO_TYPE key);
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif
#endif

View File

@ -0,0 +1,102 @@
SET(COMMON_DRIVER_SRC
dr_err.c
dr_input.c
dr_par_util.c
dr_util.c
dr_elem.c
dr_setfixed.c
dr_output.c
dr_chaco_io.c
dr_random_io.c
dr_elem_util.c
dr_eval.c
dr_gnuplot.c
dr_hg_io.c
dr_hg_readfile.c
dr_mm_readfile.c
dr_mmio.c
${PACKAGE_SOURCE_DIR}/src/ch/ch_dist_graph.c
${PACKAGE_SOURCE_DIR}/src/ch/ch_input_assign.c
${PACKAGE_SOURCE_DIR}/src/ch/ch_input_graph.c
${PACKAGE_SOURCE_DIR}/src/ch/ch_init_dist.c
${PACKAGE_SOURCE_DIR}/src/ch/ch_input_geom.c
${PACKAGE_SOURCE_DIR}/src/ch/ch_input_read.c
)
IF (${PACKAGE_NAME}_ENABLE_Zlib)
APPEND_SET(COMMON_DRIVER_SRC
dr_compress.c
)
ENDIF()
SET(COMMON_DRIVER_HDRS
dr_compress_const.h
dr_hg_readfile.h
dr_const.h
dr_externs.h
dr_input_const.h
dr_util_const.h
dr_err_const.h
dr_par_util_const.h
dr_elem_const.h
dr_elem_util_const.h
dr_maps_const.h
dr_eval_const.h
dr_loadbal_const.h
dr_mmio.h
dr_output_const.h
dr_param_file.h
dr_dd.h
${PACKAGE_SOURCE_DIR}/src/ch/ch_input_const.h
${PACKAGE_SOURCE_DIR}/src/ch/ch_init_dist_const.h
)
SET(ZDRIVE_SOURCES
${COMMON_DRIVER_SRC}
dr_main.c
dr_exoII_io.c
dr_loadbal.c
dr_migrate.c
dr_maps.c
dr_dd.c
dr_param_file.c
order_test.c
)
SET(ZCPPDRIVE_SOURCES
${COMMON_DRIVER_SRC}
dr_mainCPP.cpp
dr_exoII_ioCPP.cpp
dr_loadbalCPP.cpp
dr_migrateCPP.cpp
dr_mapsCPP.cpp
dr_ddCPP.cpp
dr_param_fileCPP.cpp
)
TRIBITS_INCLUDE_DIRECTORIES(REQUIRED_DURING_INSTALLATION_TESTING ${CMAKE_CURRENT_SOURCE_DIR})
TRIBITS_INCLUDE_DIRECTORIES(REQUIRED_DURING_INSTALLATION_TESTING ${PACKAGE_SOURCE_DIR}/src/ch)
TRIBITS_ADD_EXECUTABLE(
zdrive
NOEXEPREFIX
SOURCES ${COMMON_DRIVER_HDRS} ${ZDRIVE_SOURCES}
COMM serial mpi
CATEGORIES BASIC PERFORMANCE
)
IF (${PACKAGE_NAME}_ENABLE_CPPDRIVER)
TRIBITS_ADD_EXECUTABLE(
zCPPdrive
NOEXEPREFIX
SOURCES ${COMMON_DRIVER_HDRS} ${ZCPPDRIVE_SOURCES}
COMM serial mpi
)
ENDIF()

131
thirdParty/Zoltan/src/driver/Makefile.am vendored Normal file
View File

@ -0,0 +1,131 @@
# @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
include $(top_builddir)/Makefile.export.zoltan
EXPORT_LIBS = $(ZOLTAN_LIBS)
EXPORT_INC_PATH = $(ZOLTAN_INCLUDES)
AM_CPPFLAGS = $(EXPORT_INC_PATH)
EXEEXT = .exe
#ZOLTAN_C_TEST_DRIVER = zdrive
if HAVE_ZOLTAN_CPPDRIVER
ZOLTAN_CPP_TEST_DRIVER = zCPPdrive
endif
noinst_PROGRAMS = zdrive $(ZOLTAN_CPP_TEST_DRIVER)
COMMON_DRIVER_SRC = \
$(srcdir)/dr_err.c $(srcdir)/dr_input.c $(srcdir)/dr_par_util.c \
$(srcdir)/dr_util.c $(srcdir)/dr_elem.c $(srcdir)/dr_setfixed.c \
$(srcdir)/dr_output.c $(srcdir)/dr_chaco_io.c \
$(srcdir)/dr_random_io.c $(srcdir)/dr_elem_util.c $(srcdir)/dr_eval.c \
$(srcdir)/dr_gnuplot.c $(srcdir)/dr_hg_io.c \
$(srcdir)/dr_hg_readfile.c $(srcdir)/dr_mm_readfile.c \
$(srcdir)/dr_mmio.c \
$(top_srcdir)/src/ch/ch_dist_graph.c \
$(top_srcdir)/src/ch/ch_input_assign.c \
$(top_srcdir)/src/ch/ch_input_graph.c \
$(top_srcdir)/src/ch/ch_init_dist.c \
$(top_srcdir)/src/ch/ch_input_geom.c \
$(top_srcdir)/src/ch/ch_input_read.c
if BUILD_GZIP
COMMON_DRIVER_SRC += $(srcdir)/dr_compress.c
endif
# List headers here that are used for both the C and C++ drivers.
COMMON_DRIVER_HDRS = \
$(srcdir)/dr_compress_const.h $(srcdir)/dr_hg_readfile.h \
$(srcdir)/dr_externs.h $(srcdir)/dr_const.h $(srcdir)/dr_input_const.h \
$(srcdir)/dr_util_const.h $(srcdir)/dr_err_const.h \
$(srcdir)/dr_par_util_const.h $(srcdir)/dr_elem_const.h \
$(srcdir)/dr_elem_util_const.h $(srcdir)/dr_maps_const.h \
$(srcdir)/dr_eval_const.h $(srcdir)/dr_loadbal_const.h \
$(srcdir)/dr_mmio.h $(srcdir)/dr_output_const.h \
$(srcdir)/dr_param_file.h $(srcdir)/dr_dd.h \
$(top_srcdir)/src/ch/ch_input_const.h \
$(top_srcdir)/src/ch/ch_init_dist_const.h
zdrive_SOURCES = \
$(COMMON_DRIVER_SRC) $(srcdir)/dr_main.c $(srcdir)/dr_exoII_io.c \
$(srcdir)/dr_loadbal.c $(srcdir)/dr_migrate.c $(srcdir)/dr_maps.c \
$(srcdir)/dr_dd.c $(srcdir)/dr_param_file.c $(srcdir)/order_test.c
# List headers here used for the C driver, but not the C++ driver.
# Headers for both are listed under COMMON_DRIVER_HDRS.
#zdrive_HDRS =
zCPPdrive_SOURCES = \
$(COMMON_DRIVER_SRC) $(srcdir)/dr_mainCPP.cpp \
$(srcdir)/dr_exoII_ioCPP.cpp $(srcdir)/dr_loadbalCPP.cpp \
$(srcdir)/dr_migrateCPP.cpp $(srcdir)/dr_mapsCPP.cpp \
$(srcdir)/dr_ddCPP.cpp $(srcdir)/dr_param_fileCPP.cpp
# List headers here used for the C++ driver, but not the C driver.
# Headers for both are listed under COMMON_DRIVER_HDRS.
zCPPdrive_HDRS = \
$(srcdir)/dr_param_fileCPP.h
zdrive_DEPENDENCIES = \
$(ZOLTAN_DEPS)
zCPPdrive_DEPENDENCIES = \
$(ZOLTAN_DEPS)
zdrive_CPPFLAGS = $(EXPORT_INC_PATH) -I$(srcdir)/ -I$(top_srcdir)/src/ch/
zCPPdrive_CPPFLAGS = $(EXPORT_INC_PATH) -I$(srcdir)/ -I$(top_srcdir)/src/ch/
zdrive_LDADD = $(EXPORT_LIBS)
zCPPdrive_LDADD = $(EXPORT_LIBS)
EXTRA_DIST = $(COMMON_DRIVER_HDRS) $(zCPPdrive_HDRS) $(zdrive_HDRS) \
$(srcdir)/dr_compress.c
# Dummy for new export makefiles
#LIBS =

1607
thirdParty/Zoltan/src/driver/Makefile.in vendored Normal file

File diff suppressed because it is too large Load Diff

135
thirdParty/Zoltan/src/driver/README vendored Normal file
View File

@ -0,0 +1,135 @@
# @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
DRIVER DIRECTORY -- Zoltan test driver application source code.
------------------------------------------------------------------------
NOTE: a well documented example input driver is included with the documentation
in the file Zoltan/docs/Zoltan_html/dev_html/zdrive.inp.
dr_const.h -- Main data structures and defines for driver.
dr_elem.c -- Routines that return information about exodus-based
elements. This file was taken from nem_slice, and
is used when reading nemesis/exodus files.
dr_elem_const.h -- Element type enumeration, and function prototypes
for functions in dr_elem.c.
dr_err.c -- Error reporting functions. Errors are stored with
a call to Gen_Error(), and then all errors and
warnings are printed with a call to error_report()
before exiting.
dr_err_const.h -- Definitions of structures and functions for error
reporting.
dr_exoII_io.c -- Exodus/nemesis file interface. The routines in this
file read exodus/nemesis files and use that information
to fill the problem, mesh and element data structures.
dr_input.c -- Functions to read, check and broadcast command file
information.
dr_input_const.h -- Contains the definition of the Parallel_IO struct,
as well as the prototypes for functions in dr_input.c.
The Parallel_IO struct contains all of the information
about the parallel disk structure and the input
filename.
dr_loadbal.c -- Main interface with the Zoltan load balance functions.
All of the loadbalance callback functions are in this
file. This file also contains run_zoltan(), which is
where the LB_Balance function is actually called.
dr_loadbal_const.h -- Prototypes for functions in dr_loadbal.c.
dr_main.c -- The main function for the driver, and a small function
that will print the command parameters to the screen.
dr_migrate.c -- Main interface with the Zoltan migration functions.
All of the migration callback functions are in this
file.
dr_output.c -- Function that outputs the results after Zoltan is
called. Currently, output is limited to printing out an
ascii file for each processor that contains a list of
the global ids for elements on that processor.
dr_par_util.c -- Contains parallel utilities. Currently only contains
print_sync_start() and print_sync_end() routines.
Utility functions that work in parallel should be
included in this file.
dr_par_util_const.h -- Prototype for functions in dr_par_util.c.
dr_util.c -- Utility functions, such as sort and search routines.
Functions in this file should only need system header
files.
dr_util_const.h -- Prototypes for functions in dr_util.c.
dr_maps.c -- Routines to build element communication maps after
data migration.
dr_maps_const.h -- Prototypes for functions in dr_maps.c.
dr_eval.c -- Code for evaluating partitions using the driver's
data structures.
dr_eval_const.h -- Prototypes for functions in dr_eval.c.
dr_elem_util.c -- Routines for allocating and freeing elements.
dr_elem_util_const.h-- Prototypes for functions in dr_elem_util.c.
dr_chaco_io.c -- Interface between Chaco input functions and driver
data structures.
dr_param_file.c -- Routines that read a secondary parameter file for
zdrive. These allow hierarchical balancing parameters
to be specified and provide the callbacks needed
by hierarchical balancing.
dr_param_file.h -- Prototypes for functions in dr_param_file.c

View File

@ -0,0 +1,576 @@
/*
* @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
*/
#include <mpi.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include "dr_const.h"
#include "dr_externs.h"
#include "dr_input_const.h"
#include "dr_util_const.h"
#include "dr_par_util_const.h"
#include "dr_err_const.h"
#include "dr_output_const.h"
#include "dr_elem_util_const.h"
#include "dr_maps_const.h"
#include "ch_input_const.h"
#include "ch_init_dist_const.h"
#include "dr_compress_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#ifndef MAX_STR_LENGTH
#define MAX_STR_LENGTH 80
#endif
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
int read_chaco_file(int Proc,
int Num_Proc,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
MESH_INFO_PTR mesh)
{
/* Local declarations. */
const char *yo = "read_chaco_mesh";
char cmesg[256];
char chaco_fname[FILENAME_MAX + 8];
int nvtxs,base;
int vwgt_dim=0, ewgt_dim=0;
int ndim = 0;
int *start = NULL, *adj = NULL;
int no_geom = FALSE;
int gnvtxs;
float *ewgts = NULL, *vwgts = NULL;
float *x = NULL, *y = NULL, *z = NULL;
short *assignments = NULL;
ZOLTAN_FILE *fp = NULL;
int file_error;
/***************************** BEGIN EXECUTION ******************************/
DEBUG_TRACE_START(Proc, yo);
/* Set Debug_Chaco_Input */
if (Debug_Driver > 2) Debug_Chaco_Input = 1;
if (Proc == 0) {
/* Open and read the Chaco graph file. */
sprintf(chaco_fname, "%s.graph", pio_info->pexo_fname);
fp = ZOLTAN_FILE_open(chaco_fname, "r", pio_info->file_comp);
file_error = (fp == NULL);
}
MPI_Bcast(&file_error, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (file_error) {
sprintf(cmesg, "fatal: Could not open Chaco graph file %s",
chaco_fname);
Gen_Error(0, cmesg);
return 0;
}
if (Proc == 0) {
/* read the array in on processor 0 */
if (chaco_input_graph(fp, chaco_fname, &start, &adj, &nvtxs,
&vwgt_dim, &vwgts, &ewgt_dim, &ewgts) != 0) {
Gen_Error(0, "fatal: Error returned from chaco_input_graph");
return 0;
}
base = 1; // chaco files are one-based
/* Read Chaco geometry file, if provided. */
sprintf(chaco_fname, "%s.coords", pio_info->pexo_fname);
fp = ZOLTAN_FILE_open(chaco_fname, "r", pio_info->file_comp);
if (fp == NULL) {
no_geom = TRUE;
sprintf(cmesg, "warning: Could not open Chaco geometry file %s; "
"no geometry data will be read",
chaco_fname);
Gen_Error(0, cmesg);
}
else {
/* read the coordinates in on processor 0 */
if (chaco_input_geom(fp, chaco_fname, nvtxs, &ndim, &x, &y, &z) != 0) {
Gen_Error(0, "fatal: Error returned from chaco_input_geom");
return 0;
}
}
#ifdef MESS_UP_POINTS
/* Try to create a geometry that isn't nicely symmetric */
{
int i, j;
double min[3], max[3], a[3], b[3];
min[0] = max[0] = x[0];
if (ndim > 1){
min[1] = max[1] = y[0];
if (ndim > 2)
min[2] = max[2] = z[0];
}
for (i=1; i<nvtxs; i++) {
if (x[i] < min[0]) min[0] = x[i];
else if (x[i] > max[0]) max[0] = x[i];
if (ndim > 1){
if (y[i] < min[1]) min[1] = y[i];
else if (y[i] > max[1]) max[1] = y[i];
if (ndim > 2){
if (z[i] < min[2]) min[2] = z[i];
else if (z[i] > max[2]) max[2] = z[i];
}
}
}
for (i=0; i<ndim; i++) /* point inside but near edge of geometry */
a[i] = ((max[i] - min[i]) * .1) + min[i];
for (i=0; i<nvtxs; i++) { /* move 2/3 of points much closer to "a" */
if (i%3 == 0) continue;
b[0] = x[i];
if (ndim > 1){
b[1] = y[i];
if (ndim > 2){
b[2] = z[i];
}
}
for (j=0; j<ndim; j++){
b[j] = a[j] + ((b[j] - a[j])*.1);
}
x[i] = b[0];
if (ndim > 1){
y[i] = b[1];
if (ndim > 2){
z[i] = b[2];
}
}
}
}
#endif
/* Read Chaco assignment file, if requested */
if (pio_info->init_dist_type == INITIAL_FILE) {
sprintf(chaco_fname, "%s.assign", pio_info->pexo_fname);
if (pio_info->file_comp == GZIP)
sprintf(chaco_fname, "%s.gz", chaco_fname);
fp = ZOLTAN_FILE_open(chaco_fname, "r", pio_info->file_comp);
if (fp == NULL) {
sprintf(cmesg, "Error: Could not open Chaco assignment file %s; "
"initial distribution cannot be read",
chaco_fname);
Gen_Error(0, cmesg);
return 0;
}
else {
/* read the coordinates in on processor 0 */
assignments = (short *) malloc(nvtxs * sizeof(short));
if (!assignments) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
if (chaco_input_assign(fp, chaco_fname, nvtxs, assignments) != 0) {
Gen_Error(0, "fatal: Error returned from chaco_input_assign");
return 0;
}
}
}
}
/* Distribute graph */
if (!chaco_dist_graph(MPI_COMM_WORLD, pio_info, 0, &gnvtxs, &nvtxs,
&start, &adj, &vwgt_dim, &vwgts, &ewgt_dim, &ewgts,
&ndim, &x, &y, &z, &assignments)) {
Gen_Error(0, "fatal: Error returned from chaco_dist_graph");
return 0;
}
MPI_Bcast(&base, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (!chaco_setup_mesh_struct(Proc, Num_Proc, prob, mesh, pio_info, gnvtxs, nvtxs,
start, adj, vwgt_dim, vwgts, ewgt_dim, ewgts,
ndim, x, y, z, assignments, base, no_geom)) {
Gen_Error(0, "fatal: Error returned from chaco_setup_mesh_struct");
return 0;
}
safe_free((void **)(void *) &adj);
safe_free((void **)(void *) &vwgts);
safe_free((void **)(void *) &ewgts);
safe_free((void **)(void *) &start);
safe_free((void **)(void *) &x);
safe_free((void **)(void *) &y);
safe_free((void **)(void *) &z);
safe_free((void **)(void *) &assignments);
DEBUG_TRACE_END(Proc, yo);
return 1;
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
int chaco_setup_mesh_struct(
int Proc,
int Num_Proc,
PROB_INFO_PTR prob, /* problem description */
MESH_INFO_PTR mesh, /* mesh information for the problem */
PARIO_INFO_PTR pio_info, /* element distribution info*/
int gnvtxs, /* global number of vertices across all procs*/
int nvtxs, /* number of vertices in local graph */
int *start, /* start of edge list for each vertex */
int *adj, /* edge list data */
int vwgt_dim, /* # of weights per vertex */
float *vwgts, /* vertex weight list data */
int ewgt_dim, /* # of weights per edge */
float *ewgts, /* edge weight list data */
int ndim, /* dimension of the geometry */
float *x, /* x-coordinates of the vertices */
float *y, /* y-coordinates of the vertices */
float *z, /* z-coordinates of the vertices */
short *assignments, /* assignments from Chaco file; may be NULL */
int base, /* smallest vertex number to use;
base == 1 for Chaco;
may be 0 or 1 for HG files. */
int no_geom /* flag indicating whether coords are avail. */
)
{
const char *yo = "chaco_setup_mesh_struct";
int i;
DEBUG_TRACE_START(Proc, yo);
/* Initialize mesh structure for Chaco mesh. */
mesh->data_type = ZOLTAN_GRAPH;
mesh->vwgt_dim = vwgt_dim;
mesh->ewgt_dim = ewgt_dim;
mesh->num_elems = nvtxs;
mesh->elem_array_len = mesh->num_elems + 5;
mesh->num_dims = ndim;
mesh->num_el_blks = 1;
mesh->eb_etypes = (int *) malloc (4 * mesh->num_el_blks * sizeof(int));
if (!mesh->eb_etypes) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
mesh->eb_ids = mesh->eb_etypes + mesh->num_el_blks;
mesh->eb_nnodes = mesh->eb_ids + mesh->num_el_blks;
mesh->eb_nattrs = mesh->eb_nnodes + mesh->num_el_blks;
mesh->eb_cnts = (ZOLTAN_ID_TYPE *) malloc (mesh->num_el_blks * sizeof(ZOLTAN_ID_TYPE));
if (!mesh->eb_cnts) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
mesh->eb_names = (char **) malloc (mesh->num_el_blks * sizeof(char *));
if (!mesh->eb_names) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
mesh->eb_etypes[0] = -1;
mesh->eb_ids[0] = 1;
mesh->eb_cnts[0] = (ZOLTAN_ID_TYPE)nvtxs;
mesh->eb_nattrs[0] = 0;
mesh->hindex = (int *) malloc(sizeof(int));
mesh->hindex[0] = 0;
/*
* Each element has one set of coordinates (i.e., node) if a coords file
* was provided; zero otherwise.
*/
MPI_Bcast( &no_geom, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (no_geom)
mesh->eb_nnodes[0] = 0;
else
mesh->eb_nnodes[0] = 1;
/* allocate space for name */
mesh->eb_names[0] = (char *) malloc((MAX_STR_LENGTH+1) * sizeof(char));
if (!mesh->eb_names[0]) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
strcpy(mesh->eb_names[0], "chaco");
/* allocate the element structure array */
mesh->elements = (ELEM_INFO_PTR) malloc (mesh->elem_array_len
* sizeof(ELEM_INFO));
if (!(mesh->elements)) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
/*
* intialize all of the element structs as unused by
* setting the globalID to -1
*/
for (i = 0; i < mesh->elem_array_len; i++)
initialize_element(&(mesh->elements[i]));
/*
* now fill the element structure array with the
* information from the Chaco file
*/
if (!chaco_fill_elements(Proc, Num_Proc, prob, mesh, pio_info, gnvtxs, nvtxs,
start, adj, vwgt_dim, vwgts, ewgt_dim, ewgts,
ndim, x, y, z, assignments, base))
{
Gen_Error(0, "fatal: Error returned from chaco_fill_elements");
return 0;
}
DEBUG_TRACE_END(Proc, yo);
return 1;
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
int chaco_fill_elements(
int Proc,
int Num_Proc,
PROB_INFO_PTR prob, /* problem description */
MESH_INFO_PTR mesh, /* mesh information for the problem */
PARIO_INFO_PTR pio_info, /* element distribution info*/
int gnvtxs, /* global number of vertices across all procs*/
int nvtxs, /* number of vertices in local graph */
int *start, /* start of edge list for each vertex */
int *adj, /* edge list data */
int vwgt_dim, /* # of weights per vertex */
float *vwgts, /* vertex weight list data */
int ewgt_dim, /* # of weights per edge */
float *ewgts, /* edge weight list data */
int ndim, /* dimension of the geometry */
float *x, /* x-coordinates of the vertices */
float *y, /* y-coordinates of the vertices */
float *z, /* z-coordinates of the vertices */
short *assignments, /* assignments from Chaco file; may be NULL */
int base /* smallest vertex number to use; */
)
{
/* Local declarations. */
int i, j, k, *local_ids = NULL;
int num_vtx;
int elem_id;
int min_vtx, max_vtx;
int *vtx_list = NULL;
const char *yo = "chaco_fill_elements";
/***************************** BEGIN EXECUTION ******************************/
DEBUG_TRACE_START(Proc, yo);
chaco_init_local_ids(&local_ids, &vtx_list, &min_vtx, &max_vtx, &num_vtx,
assignments, base);
for (i = 0; i < num_vtx; i++) {
mesh->elements[i].globalID = vtx_list[i]+base; /* GlobalIDs are 1-based
in Chaco; may be 0-based
or 1-based in HG files */
if (vwgts != NULL){
for (j=0; j<vwgt_dim; j++) {
mesh->elements[i].cpu_wgt[j] = vwgts[i*vwgt_dim+j];
}
}
else
mesh->elements[i].cpu_wgt[0] = 1.0;
mesh->elements[i].elem_blk = 0; /* only one elem block for all vertices */
if (assignments)
mesh->elements[i].my_part = (int)assignments[vtx_list[i]];
else
mesh->elements[i].my_part = Proc; /* Init partition is starting proc.*/
if (mesh->num_dims > 0) {
/* One set of coords per element. */
mesh->elements[i].connect = (ZOLTAN_ID_TYPE *) malloc(sizeof(ZOLTAN_ID_TYPE));
mesh->elements[i].connect[0] = mesh->elements[i].globalID;
mesh->elements[i].coord = (float **) malloc(sizeof(float *));
mesh->elements[i].coord[0] = (float *) calloc(mesh->num_dims,
sizeof(float));
mesh->elements[i].coord[0][0] = x[i];
mesh->elements[i].avg_coord[0] = x[i];
if (mesh->num_dims > 1) {
mesh->elements[i].coord[0][1] = y[i];
mesh->elements[i].avg_coord[1] = y[i];
if (mesh->num_dims > 2) {
mesh->elements[i].coord[0][2] = z[i];
mesh->elements[i].avg_coord[2] = z[i];
}
}
}
}
for (i = 0; i < num_vtx; i++) {
/* now start with the adjacencies */
if (start != NULL)
mesh->elements[i].nadj = start[i+1] - start[i];
else
mesh->elements[i].nadj = 0;
if (mesh->elements[i].nadj > 0) {
mesh->elements[i].adj_len = mesh->elements[i].nadj;
mesh->elements[i].adj = (ZOLTAN_ID_TYPE *) malloc (mesh->elements[i].nadj * sizeof(ZOLTAN_ID_TYPE));
mesh->elements[i].adj_proc = (int *) malloc (mesh->elements[i].nadj * sizeof(int));
if (!(mesh->elements[i].adj) || !(mesh->elements[i].adj_proc)) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
if (ewgts != NULL) {
mesh->elements[i].edge_wgt = (float *) malloc (mesh->elements[i].nadj * sizeof(float));
if (!(mesh->elements[i].edge_wgt)) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
}
else
mesh->elements[i].edge_wgt = NULL;
for (j = 0; j < mesh->elements[i].nadj; j++) {
#if 0
elem_id = adj[start[i] + j] - (1-base); /* Chaco is 1-based;
HG may be 0 or 1 based. */
#else
/* when called from hypergraph build, the line above gives the wrong
* value for the adjacency. (it is one too low). I'm guessing that
* this is the fix. Works for hypergraph & chaco files in testing.
*/
elem_id = adj[start[i] + j];
#endif
/* determine which processor the adjacent vertex is on */
k = ch_dist_proc(elem_id, assignments, base);
/*
* if the adjacent element is on this processor
* then find the local id for that element
*/
if (k == Proc)
mesh->elements[i].adj[j] = (ZOLTAN_ID_TYPE)local_ids[elem_id-base-min_vtx];
else /* use the global id */
mesh->elements[i].adj[j] = (ZOLTAN_ID_TYPE)elem_id;
mesh->elements[i].adj_proc[j] = k;
if (ewgts != NULL)
mesh->elements[i].edge_wgt[j] = ewgts[start[i] + j];
}
} /* End: "if (mesh->elements[i].nadj > 0)" */
} /* End: "for (i = 0; i < mesh->num_elems; i++)" */
safe_free((void **)(void *) &vtx_list);
safe_free((void **)(void *) &local_ids);
if (!build_elem_comm_maps(Proc, mesh)) {
Gen_Error(0, "Fatal: error building initial elem comm maps");
return 0;
}
if (Debug_Driver > 3)
print_distributed_mesh(Proc, Num_Proc, mesh);
DEBUG_TRACE_END(Proc, yo);
return 1;
}
/****************************************************************************/
void chaco_init_local_ids(
int **local_ids,
int **vtx_list,
int *min_vtx,
int *max_vtx,
int *num_vtx,
short *assignments,
int base
)
{
/* Initialize an array of local IDs for vertices for quick search. */
int i;
int Proc;
MPI_Comm_rank(MPI_COMM_WORLD, &Proc);
*num_vtx = ch_dist_max_num_vtx(assignments);
*vtx_list = (int *) malloc(((int)*num_vtx) * sizeof(int));
ch_dist_vtx_list(*vtx_list, num_vtx, Proc, assignments);
if (*num_vtx > 0) {
*min_vtx = INT_MAX;
*max_vtx = -1;
for (i = 0; i < *num_vtx; i++) {
if ((*vtx_list)[i] > *max_vtx) *max_vtx = (*vtx_list)[i];
if ((*vtx_list)[i] < *min_vtx) *min_vtx = (*vtx_list)[i];
}
*local_ids = (int *) malloc((*max_vtx - *min_vtx + 1) * sizeof(int));
}
for (i = 0; i < *num_vtx; i++)
(*local_ids)[(*vtx_list)[i] - (*min_vtx)] = i;
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,541 @@
/*
* @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
*/
#include <mpi.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "dr_const.h"
#include "dr_input_const.h"
#include "dr_util_const.h"
#include "dr_par_util_const.h"
#include "dr_err_const.h"
#include "dr_output_const.h"
#include "dr_elem_util_const.h"
#include "dr_maps_const.h"
#include "ch_input_const.h"
#include "ch_init_dist_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#ifndef MAX_STR_LENGTH
#define MAX_STR_LENGTH 80
#endif
/****************************************************************************/
/* ALTERNATE FILE FOR SHOCKSTEM ADAPTIVE MESH REFINEMENT EXPERIMENTS ONLY. */
/* DO NOT COMMIT AS A REGULAR DRIVER FILE. */
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
int read_chaco_file(int Proc,
int Num_Proc,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
MESH_INFO_PTR mesh,
MESH_INFO_PTR previous_mesh)
{
/* Local declarations. */
const char *yo = "read_chaco_mesh";
char cmesg[256];
char chaco_fname[FILENAME_MAX + 8];
int nvtxs, gnvtxs;
int vwgt_dim=0, ewgt_dim=0;
int ndim = 0;
int *start = NULL, *adj = NULL;
int no_geom = FALSE;
float *ewgts = NULL, *vwgts = NULL;
float *x = NULL, *y = NULL, *z = NULL;
short *assignments = NULL;
FILE *fp;
int file_error = 0;
/***************************** BEGIN EXECUTION ******************************/
DEBUG_TRACE_START(Proc, yo);
/* Set Debug_Chaco_Input */
if (Debug_Driver > 2) Debug_Chaco_Input = 1;
if (Proc == 0) {
/* Open and read the Chaco graph file. */
sprintf(chaco_fname, "%s.graph", pio_info->pexo_fname);
fp = fopen(chaco_fname, "r");
file_error = (fp == NULL);
}
MPI_Bcast(&file_error, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (file_error) {
sprintf(cmesg, "fatal: Could not open Chaco graph file %s",
chaco_fname);
Gen_Error(0, cmesg);
return 0;
}
if (Proc == 0) {
/* read the array in on processor 0 */
if (chaco_input_graph(fp, chaco_fname, &start, &adj, &nvtxs,
&vwgt_dim, &vwgts, &ewgt_dim, &ewgts) != 0) {
Gen_Error(0, "fatal: Error returned from chaco_input_graph");
return 0;
}
/* Read Chaco geometry file, if provided. */
sprintf(chaco_fname, "%s.coords", pio_info->pexo_fname);
fp = fopen(chaco_fname, "r");
if (fp == NULL) {
no_geom = TRUE;
sprintf(cmesg, "warning: Could not open Chaco geometry file %s; "
"no geometry data will be read",
chaco_fname);
Gen_Error(0, cmesg);
}
else {
/* read the coordinates in on processor 0 */
if (chaco_input_geom(fp, chaco_fname, nvtxs, &ndim, &x, &y, &z) != 0) {
Gen_Error(0, "fatal: Error returned from chaco_input_geom");
return 0;
}
}
}
/* Read Chaco assignment file, if requested */
if (pio_info->init_dist_type == INITIAL_FILE) {
if (previous_mesh) {
if (Proc == 0) {
/* Read mapping to nearest point in previous_mesh. */
int *mapping = (int *) malloc(2 * nvtxs * sizeof(int));
int *intassignments = mapping + nvtxs;
int i;
sprintf(chaco_fname, "%s.nearest", pio_info->pexo_fname);
fp = fopen(chaco_fname, "r");
printf("%d KDDKDD NEARESTSFILE %s\n", Proc, chaco_fname); fflush(stdout);
if (!mapping) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
for (i = 0; i < nvtxs; i++) fscanf(fp, "%d", &(mapping[i]));
fclose(fp);
/* use Zoltan_DD to find proc assignment of each point in mapping */
/* Assumes previous_mesh data is migrated to new processors. */
/* Assumes number of parts == number of processors. */
Zoltan_DD_Find(previous_mesh->dd, mapping, NULL, NULL, NULL, nvtxs,
intassignments);
/* Copy results into array for use in chaco_dist_graph */
assignments = (short *) malloc(nvtxs * sizeof(short));
if (!assignments) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
for (i = 0; i < nvtxs; i++) assignments[i] = (short) intassignments[i];
safe_free((void **) &mapping);
}
else {
/* All procs call Zoltan_DD_Find() */
Zoltan_DD_Find(previous_mesh->dd, NULL, NULL, NULL, NULL, 0, NULL);
}
}
else {
if (Proc == 0) {
sprintf(chaco_fname, "%s.assign", pio_info->pexo_fname);
fp = fopen(chaco_fname, "r");
if (fp == NULL) {
sprintf(cmesg, "Error: Could not open Chaco assignment file %s; "
"initial distribution cannot be read",
chaco_fname);
Gen_Error(0, cmesg);
return 0;
}
else {
/* read the coordinates in on processor 0 */
assignments = (short *) malloc(nvtxs * sizeof(short));
if (!assignments) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
if (chaco_input_assign(fp, chaco_fname, nvtxs, assignments) != 0) {
Gen_Error(0, "fatal: Error returned from chaco_input_assign");
return 0;
}
}
}
}
}
/* Distribute graph */
if (!chaco_dist_graph(MPI_COMM_WORLD, pio_info, 0, &gnvtxs, &nvtxs,
&start, &adj, &vwgt_dim, &vwgts, &ewgt_dim, &ewgts,
&ndim, &x, &y, &z, &assignments) != 0) {
Gen_Error(0, "fatal: Error returned from chaco_dist_graph");
return 0;
}
if (!chaco_setup_mesh_struct(Proc, Num_Proc, prob, mesh, gnvtxs, nvtxs,
start, adj, vwgt_dim, vwgts, ewgt_dim, ewgts,
ndim, x, y, z, assignments, 1, no_geom)) {
Gen_Error(0, "fatal: Error returned from chaco_setup_mesh_struct");
return 0;
}
safe_free((void **) &adj);
safe_free((void **) &vwgts);
safe_free((void **) &ewgts);
safe_free((void **) &start);
safe_free((void **) &x);
safe_free((void **) &y);
safe_free((void **) &z);
safe_free((void **) &assignments);
DEBUG_TRACE_END(Proc, yo);
return 1;
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
int chaco_setup_mesh_struct(
int Proc,
int Num_Proc,
PROB_INFO_PTR prob, /* problem description */
MESH_INFO_PTR mesh, /* mesh information for the problem */
int gnvtxs, /* global number of vertices across all procs*/
int nvtxs, /* number of vertices in local graph */
int *start, /* start of edge list for each vertex */
int *adj, /* edge list data */
int vwgt_dim, /* # of weights per vertex */
float *vwgts, /* vertex weight list data */
int ewgt_dim, /* # of weights per edge */
float *ewgts, /* edge weight list data */
int ndim, /* dimension of the geometry */
float *x, /* x-coordinates of the vertices */
float *y, /* y-coordinates of the vertices */
float *z, /* z-coordinates of the vertices */
short *assignments, /* assignments from Chaco file; may be NULL */
int base, /* smallest vertex number to use;
base == 1 for Chaco;
may be 0 or 1 for HG files. */
int no_geom /* flag indicating whether coords are avail. */
)
{
const char *yo = "chaco_setup_mesh_struct";
int i;
DEBUG_TRACE_START(Proc, yo);
/* Initialize mesh structure for Chaco mesh. */
mesh->data_type = ZOLTAN_GRAPH;
mesh->vwgt_dim = vwgt_dim;
mesh->ewgt_dim = ewgt_dim;
mesh->num_elems = nvtxs;
mesh->elem_array_len = mesh->num_elems + 5;
mesh->num_dims = ndim;
mesh->num_el_blks = 1;
mesh->eb_etypes = (int *) malloc (5 * mesh->num_el_blks * sizeof(int));
if (!mesh->eb_etypes) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
mesh->eb_ids = mesh->eb_etypes + mesh->num_el_blks;
mesh->eb_cnts = mesh->eb_ids + mesh->num_el_blks;
mesh->eb_nnodes = mesh->eb_cnts + mesh->num_el_blks;
mesh->eb_nattrs = mesh->eb_nnodes + mesh->num_el_blks;
mesh->eb_names = (char **) malloc (mesh->num_el_blks * sizeof(char *));
if (!mesh->eb_names) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
mesh->eb_etypes[0] = -1;
mesh->eb_ids[0] = 1;
mesh->eb_cnts[0] = nvtxs;
mesh->eb_nattrs[0] = 0;
mesh->hindex = (int *) malloc(sizeof(int));
mesh->hindex[0] = 0;
/*
* Each element has one set of coordinates (i.e., node) if a coords file
* was provided; zero otherwise.
*/
MPI_Bcast( &no_geom, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (no_geom)
mesh->eb_nnodes[0] = 0;
else
mesh->eb_nnodes[0] = 1;
/* allocate space for name */
mesh->eb_names[0] = (char *) malloc((MAX_STR_LENGTH+1) * sizeof(char));
if (!mesh->eb_names[0]) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
strcpy(mesh->eb_names[0], "chaco");
/* allocate the element structure array */
mesh->elements = (ELEM_INFO_PTR) malloc (mesh->elem_array_len
* sizeof(ELEM_INFO));
if (!(mesh->elements)) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
/*
* intialize all of the element structs as unused by
* setting the globalID to -1
*/
for (i = 0; i < mesh->elem_array_len; i++)
initialize_element(&(mesh->elements[i]));
/*
* now fill the element structure array with the
* information from the Chaco file
*/
if (!chaco_fill_elements(Proc, Num_Proc, prob, mesh, gnvtxs, nvtxs,
start, adj, vwgt_dim, vwgts, ewgt_dim, ewgts,
ndim, x, y, z, assignments, 1)) {
Gen_Error(0, "fatal: Error returned from chaco_fill_elements");
return 0;
}
DEBUG_TRACE_END(Proc, yo);
return 1;
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
int chaco_fill_elements(
int Proc,
int Num_Proc,
PROB_INFO_PTR prob, /* problem description */
MESH_INFO_PTR mesh, /* mesh information for the problem */
int gnvtxs, /* global number of vertices across all procs*/
int nvtxs, /* number of vertices in local graph */
int *start, /* start of edge list for each vertex */
int *adj, /* edge list data */
int vwgt_dim, /* # of weights per vertex */
float *vwgts, /* vertex weight list data */
int ewgt_dim, /* # of weights per edge */
float *ewgts, /* edge weight list data */
int ndim, /* dimension of the geometry */
float *x, /* x-coordinates of the vertices */
float *y, /* y-coordinates of the vertices */
float *z, /* z-coordinates of the vertices */
short *assignments, /* assignments from Chaco file; may be NULL */
int base /* smallest vertex number to use;
base == 1 for Chaco;
may be 0 or 1 for HG files. */
)
{
/* Local declarations. */
int i, j, k, elem_id, *local_ids = NULL;
int num_vtx, min_vtx, max_vtx;
int *vtx_list = NULL;
const char *yo = "chaco_fill_elements";
/***************************** BEGIN EXECUTION ******************************/
DEBUG_TRACE_START(Proc, yo);
chaco_init_local_ids(&local_ids, &vtx_list, &min_vtx, &max_vtx, &num_vtx,
gnvtxs, assignments, base);
for (i = 0; i < num_vtx; i++) {
mesh->elements[i].globalID = vtx_list[i]+base; /* GlobalIDs are 1-based
in Chaco; may be 0-based
or 1-based in HG files */
if (vwgts != NULL){
for (j=0; j<vwgt_dim; j++) {
mesh->elements[i].cpu_wgt[j] = vwgts[i*vwgt_dim+j];
}
}
else
mesh->elements[i].cpu_wgt[0] = 1.0;
mesh->elements[i].elem_blk = 0; /* only one elem block for all vertices */
if (assignments)
mesh->elements[i].my_part = assignments[vtx_list[i]];
else
mesh->elements[i].my_part = Proc; /* Init partition is starting proc.*/
if (mesh->num_dims > 0) {
/* One set of coords per element. */
mesh->elements[i].connect = (int *) malloc(sizeof(int));
mesh->elements[i].connect[0] = mesh->elements[i].globalID;
mesh->elements[i].coord = (float **) malloc(sizeof(float *));
mesh->elements[i].coord[0] = (float *) calloc(mesh->num_dims,
sizeof(float));
mesh->elements[i].coord[0][0] = x[i];
mesh->elements[i].avg_coord[0] = x[i];
if (mesh->num_dims > 1) {
mesh->elements[i].coord[0][1] = y[i];
mesh->elements[i].avg_coord[1] = y[i];
if (mesh->num_dims > 2) {
mesh->elements[i].coord[0][2] = z[i];
mesh->elements[i].avg_coord[2] = z[i];
}
}
}
}
for (i = 0; i < num_vtx; i++) {
/* now start with the adjacencies */
if (start != NULL)
mesh->elements[i].nadj = start[i+1] - start[i];
else
mesh->elements[i].nadj = 0;
if (mesh->elements[i].nadj > 0) {
mesh->elements[i].adj_len = mesh->elements[i].nadj;
mesh->elements[i].adj = (int *) malloc (mesh->elements[i].nadj * sizeof(int));
mesh->elements[i].adj_proc = (int *) malloc (mesh->elements[i].nadj * sizeof(int));
if (!(mesh->elements[i].adj) || !(mesh->elements[i].adj_proc)) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
if (ewgts != NULL) {
mesh->elements[i].edge_wgt = (float *) malloc (mesh->elements[i].nadj * sizeof(float));
if (!(mesh->elements[i].edge_wgt)) {
Gen_Error(0, "fatal: insufficient memory");
return 0;
}
}
else
mesh->elements[i].edge_wgt = NULL;
for (j = 0; j < mesh->elements[i].nadj; j++) {
elem_id = adj[start[i] + j] - (1-base); /* Chaco is 1-based;
HG may be 0 or 1 based. */
/* determine which processor the adjacent vertex is on */
k = ch_dist_proc(elem_id, assignments, base);
/*
* if the adjacent element is on this processor
* then find the local id for that element
*/
if (k == Proc)
mesh->elements[i].adj[j] = local_ids[elem_id-base-min_vtx];
else /* use the global id */
mesh->elements[i].adj[j] = elem_id;
mesh->elements[i].adj_proc[j] = k;
if (ewgts != NULL)
mesh->elements[i].edge_wgt[j] = ewgts[start[i] + j];
}
} /* End: "if (mesh->elements[i].nadj > 0)" */
} /* End: "for (i = 0; i < mesh->num_elems; i++)" */
safe_free((void **) &vtx_list);
safe_free((void **) &local_ids);
if (!build_elem_comm_maps(Proc, mesh)) {
Gen_Error(0, "Fatal: error building initial elem comm maps");
return 0;
}
if (Debug_Driver > 3)
print_distributed_mesh(Proc, Num_Proc, mesh);
DEBUG_TRACE_END(Proc, yo);
return 1;
}
/****************************************************************************/
void chaco_init_local_ids(
int **local_ids,
int **vtx_list,
int *min_vtx,
int *max_vtx,
int *num_vtx,
int gnvtxs,
short *assignments,
int base
)
{
/* Initialize an array of local IDs for vertices for quick search. */
int i;
int Proc;
MPI_Comm_rank(MPI_COMM_WORLD, &Proc);
*num_vtx = ch_dist_max_num_vtx(assignments);
*vtx_list = (int *) malloc(*num_vtx * sizeof(int));
ch_dist_vtx_list(*vtx_list, num_vtx, Proc, assignments);
if (*num_vtx > 0) {
*min_vtx = gnvtxs+1;
*max_vtx = -1;
for (i = 0; i < *num_vtx; i++) {
if ((*vtx_list)[i] > *max_vtx) *max_vtx = (*vtx_list)[i];
if ((*vtx_list)[i] < *min_vtx) *min_vtx = (*vtx_list)[i];
}
*local_ids = (int *) malloc((*max_vtx - *min_vtx + 1) * sizeof(int));
}
for (i = 0; i < *num_vtx; i++)
(*local_ids)[(*vtx_list)[i] - (*min_vtx)] = i;
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,368 @@
/*
* @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
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dr_const.h"
#include "dr_compress_const.h"
#include "dr_util_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#define BUFF_SIZE 3*1024*1024
#define FILE_NAME_SIZE 256
#define EXTENSION_SIZE 4
#ifndef __USE_ISOC99
int vfscanf(FILE * stream, const char * format,
va_list arg);
int vscanf(const char * format, va_list arg);
int vsscanf(const char * s, const char * format,
va_list arg);
#endif /* __USE_ISOC99 */
ZOLTAN_FILE* ZOLTAN_FILE_open(const char *path, const char *mode, const ZOLTAN_FILETYPE type)
{
ZOLTAN_FILE* file;
char truemode[10];
char filename[FILE_NAME_SIZE+EXTENSION_SIZE+1];
int error = 1;
int i;
file = (ZOLTAN_FILE*) malloc(sizeof(ZOLTAN_FILE));
if (file == NULL) return (NULL);
file->type = type;
file->pos = -1;
file->size = 0;
if (type != STANDARD) {
if (!strstr(mode, "b"))
sprintf(truemode, "%sb", mode);
else
strcpy(truemode, mode);
}
strncpy (filename, path, FILE_NAME_SIZE);
for (i=0; (error != 0) && (i <2) ; ++i) {
if (i == 0) { /* Try the classical compressed version */
char append[EXTENSION_SIZE+1];
switch (type) {
#ifdef ZOLTAN_GZIP
case GZIP:
strncpy (append, ".gz", EXTENSION_SIZE);
break;
#endif
#ifdef ZOLTAN_BZ2
case BZIP2:
strncpy (append, ".bz2", EXTENSION_SIZE);
break;
#endif
#ifdef ZOLTAN_LZMA
case LZMA:
strncpy (append, ".lz", EXTENSION_SIZE);
break;
#endif
default:
append[0] = '\0';
break;
}
strncat(filename, append, EXTENSION_SIZE);
}
else
strncpy(filename, path, FILE_NAME_SIZE);
switch (type) {
case STANDARD:
file->strm.fileunc = fopen(filename, mode);
error = (file->strm.fileunc == NULL);
break;
#ifdef ZOLTAN_GZIP
case GZIP:
file->strm.filegz = gzopen(filename, truemode);
error = (file->strm.filegz == NULL);
break;
#endif
#ifdef ZOLTAN_BZ2
case BZIP2:
file->strm.filebz2 = BZ2_bzopen(filename, truemode);
error = (file->strm.filebz2 == NULL);
break;
#endif
#ifdef ZOLTAN_LZMA
case LZMA:
break;
#endif
default:
break;
}
}
if (error) {
safe_free((void **)(void *) &file);
return (NULL);
}
if (type != STANDARD) {
file->buffer = (char*) malloc(BUFF_SIZE);
if (file->buffer == NULL) {
safe_free((void **)(void *) &file);
return (NULL);
}
}
return (file);
}
ssize_t ZOLTAN_FILE_read(char* ptr, size_t size, size_t nitems, ZOLTAN_FILE *file)
{
int toread = 0;
int nbrdone = 0;
if (file->type == STANDARD)
return fread(ptr, size, nitems, file->strm.fileunc);
toread = nitems;
do {
int tocpy = 0;
tocpy = MIN(file->size - file->pos, toread);
if ((tocpy > 0) && (file->pos >= 0)) {
memcpy (ptr + nbrdone, file->buffer + file->pos, tocpy);
file->pos += tocpy;
toread -= tocpy;
nbrdone += tocpy;
}
else {
switch(file->type) {
#ifdef ZOLTAN_GZIP
case GZIP:
file->size = gzread(file->strm.filegz, file->buffer, BUFF_SIZE);
break;
#endif
default:
return (-1);
}
if (file->size < BUFF_SIZE) /* Nothing else to read on next call */
toread = MIN(file->size, toread);
if (file->size <= 0)
return (nbrdone);
file->pos = 0;
}
} while (toread);
return (nbrdone);
}
char* ZOLTAN_FILE_gets(char * buf, int len, ZOLTAN_FILE* file)
{
ssize_t size;
char * end = NULL;
ssize_t offset = 0;
if (file->type == STANDARD) return (fgets(buf, len, file->strm.fileunc));
if ((file->pos >= 0) &&( file->size > 0))
offset = file->size - file->pos;
if (offset > 0) {
end = (char *) memchr(file->buffer + file->pos, '\n', MIN(offset, len - 1));
}
if (end != NULL) { /* End of line found */
size = end - (file->buffer + file->pos) + 1;
memcpy (buf, file->buffer + file->pos, size);
buf[size] = '\0';
file->pos += size;
return (buf);
}
/* No new line */
size = ZOLTAN_FILE_read(buf, 1, len - 1, file);
if (size == 0)
return (NULL);
buf[size] = '\0';
end = (char *) memchr(buf, '\n', size);
if (end == NULL) {
return (buf);
}
end[1] = '\0';
file->pos = (end-buf) - offset + 1;
return (buf);
}
/* int ZOLTAN_FILE_putc(int c, ZOLTAN_FILE file) */
/* { */
/* switch (file.type) { */
/* case STANDARD: */
/* return (fputc(c, file.fileunc)); */
/* #ifdef ZOLTAN_GZIP */
/* case GZIP: */
/* return (gzputc(file.filegz, c)); */
/* #endif */
/* default: */
/* break; */
/* } */
/* return (0); */
/* } */
int ZOLTAN_FILE_getc(ZOLTAN_FILE* file)
{
int read;
if (file->type == STANDARD)
return (fgetc(file->strm.fileunc));
if (ZOLTAN_FILE_read((char*)&read, 1, 1, file) == 0)
return (EOF);
return (read);
}
int ZOLTAN_FILE_ungetc(int c, ZOLTAN_FILE* file)
{
if (file->type == STANDARD)
return (ungetc(c, file->strm.fileunc));
file->pos --;
if (file->pos < 0) {
file->size = 0;
#ifdef ZOLTAN_GZIP
if (file->type == GZIP)
return (gzungetc(c, file->strm.filegz));
#endif
}
file->buffer[file->pos] = (char)c;
return (c);
}
int ZOLTAN_FILE_flush(ZOLTAN_FILE* file)
{
switch (file->type) {
case STANDARD:
return (fflush(file->strm.fileunc));
#ifdef ZOLTAN_GZIP
case GZIP:
return (gzflush(file->strm.filegz, Z_SYNC_FLUSH));
#endif
default:
break;
}
return (0);
}
int ZOLTAN_FILE_close(ZOLTAN_FILE* file)
{
int retval = 0;
if (file == NULL)
return (0);
if (file->type == STANDARD)
retval = fclose(file->strm.fileunc);
else {
switch (file->type) {
#ifdef ZOLTAN_GZIP
case GZIP:
retval = gzclose(file->strm.filegz);
#endif
default:
retval = 1;
break;
}
safe_free((void **)(void *) (&file->buffer));
}
safe_free((void **)(void *) &file);
return (retval);
}
void ZOLTAN_FILE_rewind(ZOLTAN_FILE* file)
{
switch (file->type) {
case STANDARD:
rewind(file->strm.fileunc);
return;
#ifdef ZOLTAN_GZIP
case GZIP:
gzrewind(file->strm.filegz);
file->pos = -1;
return;
#endif
default:
break;
}
}
/*** Implemented as a macro as "vfscanf" or "vsscanf" are C99 only ***/
int ZOLTAN_FILE_scanf (ZOLTAN_FILE* stream, const char * format, ... )
{
int retval = 0;
va_list argp;
va_start(argp, format);
if (stream->type == STANDARD) {
retval = (vfscanf(stream->strm.fileunc, format, argp));
}
else {
char buff[1024];
if (ZOLTAN_FILE_gets(buff, 1024, (stream)) != NULL)
retval = vsscanf(buff, format, argp);
}
va_end(argp);
return (retval);
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,157 @@
/*
* @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
*/
#ifndef _DR_COMPRESS_CONST_H
#define _DR_COMPRESS_CONST_H
#include "zoltan.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "dr_const.h"
#if (defined ZOLTAN_GZIP)||(defined ZOLTAN_BZ2)||(defined ZOLTAN_LZMA)
#define ZOLTAN_COMPRESS
#endif
#ifdef ZOLTAN_GZIP
#include <zlib.h>
#endif /* ZOLTAN_GZIP */
#ifdef ZOLTAN_BZ2
#include <bzlib.h>
#endif /* ZOLTAN_BZ2 */
#ifdef ZOLTAN_LZMA
#include <lzma.h>
#endif /* ZOLTAN_LZMA */
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/*****************************************************************************
* Definitions for the File wrapper program
*****************************************************************************/
typedef enum ZOLTAN_FILETYPE_ {
STANDARD = 0,
GZIP = 1,
BZIP2 = 2,
LZMA = 3
} ZOLTAN_FILETYPE;
#ifdef ZOLTAN_COMPRESS
typedef struct ZOLTAN_FILE_ {
ZOLTAN_FILETYPE type;
char * buffer;
ssize_t size; /* size & pos should be off_t, but because of their use */
ssize_t pos; /* they need to be signed (pos is initialized to -1). */
union {
FILE * fileunc;
#ifdef ZOLTAN_GZIP
gzFile filegz;
#endif /* ZOLTAN_GZIP */
#ifdef ZOLTAN_BZ2
BZFILE * filebz;
#endif /* ZOLTAN_BZ2 */
} strm ;
} ZOLTAN_FILE;
#else /* ZOLTAN_COMPRESS */
typedef FILE ZOLTAN_FILE;
#endif /* ZOLTAN_COMPRESS */
ZOLTAN_FILE* ZOLTAN_FILE_open(const char *path, const char *mode, const ZOLTAN_FILETYPE type);
int ZOLTAN_FILE_printf(ZOLTAN_FILE* file, const char * format, ...);
int ZOLTAN_FILE_scanf(ZOLTAN_FILE* stream, const char * format, ... );
int ZOLTAN_FILE_puts(char *s, ZOLTAN_FILE* file);
char* ZOLTAN_FILE_gets(char * buf, int len, ZOLTAN_FILE* file);
int ZOLTAN_FILE_putc(int c, ZOLTAN_FILE* file);
int ZOLTAN_FILE_getc(ZOLTAN_FILE* file);
int ZOLTAN_FILE_ungetc(int c, ZOLTAN_FILE* file);
int ZOLTAN_FILE_flush(ZOLTAN_FILE* file);
int ZOLTAN_FILE_close(ZOLTAN_FILE* file);
void ZOLTAN_FILE_rewind(ZOLTAN_FILE* stream);
ssize_t ZOLTAN_FILE_read(char* ptr, size_t size, size_t nitems, ZOLTAN_FILE *file);
#ifndef ZOLTAN_COMPRESS
#define ZOLTAN_FILE_open(path, mode, type) fopen(path, mode)
/* #define ZOLTAN_FILE_printf(file, format ...) fprintf(file, ## format) */
#define ZOLTAN_FILE_printf fprintf
/* #define ZOLTAN_FILE_scanf(retval, stream, format ... ) (*(retval) = fscanf((stream), ## format)) */
#define ZOLTAN_FILE_scanf fscanf
#define ZOLTAN_FILE_puts(s, file) fputs(s,file)
#define ZOLTAN_FILE_gets(buf, len, file) fgets((buf), (len), (file))
#define ZOLTAN_FILE_putc(c, file) fputc((c), (file))
#define ZOLTAN_FILE_getc(file) fgetc(file)
#define ZOLTAN_FILE_ungetc(c, file) ungetc((c), (file))
#define ZOLTAN_FILE_flush(file) fflush(file)
#define ZOLTAN_FILE_close(file) fclose(file)
#define ZOLTAN_FILE_rewind(stream) rewind(stream)
#define ZOLTAN_FILE_read(ptr, size, nitems, file) fread((ptr), (size), (nitems), (file))
#else /* ZOLTAN_COMPRESS */
/* /\*** Implemented as a macro as "vfscanf" or "vsscanf" are C99 only ***\/ */
/* #define ZOLTAN_FILE_scanf2(retval, stream, format ... )\ */
/* do { \ */
/* char buff[1024]; \ */
/* if (stream->type == STANDARD) { \ */
/* *(retval) = (fscanf((stream)->strm.fileunc, ## format)); \ */
/* } \ */
/* else { if (ZOLTAN_FILE_gets(buff, 1024, (stream)) == NULL) \ */
/* *(retval) = 0; \ */
/* *(retval) = sscanf(buff, ## format); }\ */
/* } while(0) */
#endif /* ZOLTAN_COMPRESS */
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif
#endif /* _DR_CONST_H */

382
thirdParty/Zoltan/src/driver/dr_const.h vendored Normal file
View File

@ -0,0 +1,382 @@
/*
* @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
*/
#ifndef _DR_CONST_H
#define _DR_CONST_H
#include "zoltan.h"
#include <stdio.h>
#include <stdlib.h>
#define MIN(A,B) (((A) < (B)) ? (A) : (B))
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/******** Trilinos Build Environment *******/
/* This block should only be executed for an Autotools build. */
#ifndef TRILINOS_NO_CONFIG_H
/*
* The macros PACKAGE, PACKAGE_NAME, etc, get defined for
* each package and need to
* be undef'd here to avoid warnings when this file is included
* from another package.
* KL 11/25/02
*/
#ifdef PACKAGE
#undef PACKAGE
#endif
#ifdef PACKAGE_NAME
#undef PACKAGE_NAME
#endif
#ifdef PACKAGE_BUGREPORT
#undef PACKAGE_BUGREPORT
#endif
#ifdef PACKAGE_STRING
#undef PACKAGE_STRING
#endif
#ifdef PACKAGE_TARNAME
#undef PACKAGE_TARNAME
#endif
#ifdef PACKAGE_VERSION
#undef PACKAGE_VERSION
#endif
#ifdef VERSION
#undef VERSION
#endif
/* This file passes values from configure to the source code. */
#include "Zoltan_config.h"
#ifdef HAVE_PARMETIS
#define ZOLTAN_PARMETIS
#endif
#ifdef HAVE_METIS
#define ZOLTAN_METIS
#endif
#ifdef HAVE_SCOTCH
#define ZOLTAN_SCOTCH
#endif
#ifdef HAVE_OVIS
#define ZOLTAN_OVIS
#endif
#ifdef ZHAVE_GZIP
#define ZOLTAN_GZIP
#endif
#ifdef HAVE_PATOH
#define ZOLTAN_PATOH
#endif
#ifdef HAVE_PARKWAY
#define ZOLTAN_PARKWAY
#endif
#ifdef HAVE_NEMESIS_EXODUS
#define ZOLTAN_NEMESIS
#endif
#ifdef HAVE_PURIFY
#define ZOLTAN_PURIFY
#define strcmp Zoltan_strcmp
#define strncmp Zoltan_strncmp
#define strcasecmp Zoltan_strcasecmp
#define strncasecmp Zoltan_strncasecmp
#endif
#endif /* TRILINOS_NO_CONFIG_H */
/*****************************************************************************
* Definitions for the LB library driver program.
*****************************************************************************/
#define DRIVER_NAME "zdrive"
#define VER_STR "1.0"
/* If it doesn't get defined in stdio.h then use this as a default */
#ifndef FILENAME_MAX
#define FILENAME_MAX 1024
#endif
/* Maximum defined by the NIST standard */
#define MATRIX_MARKET_MAX_LINE 1024
#define MAX_NP_ELEM 27 /* max nodes per element */
#define MAX_DIM 3 /* max number of coordinate dimensions */
#define MAX_CPU_WGTS 10 /* max number of cpu weights */
enum LISTS { /* NULL lists to pass to Zoltan_Migrate */
NO_NULL_LISTS = 0,
IMPORT_LISTS,
EXPORT_LISTS
};
enum DATA_TYPE {
MESH = 0,
ZOLTAN_GRAPH,
ZOLTAN_HYPERGRAPH
};
enum PARTITIONING_TYPE {
HYPERGRAPH_PARTITIONING= 0,
GRAPH_PARTITIONING,
OBJECT_PARTITIONING
};
/*
* Structure used to describe an element. Each processor will
* allocate an array of these structures.
*/
struct Element_Description
{
int border; /* set to 1 if this element is a border element */
ZOLTAN_ID_TYPE globalID; /* Global ID of this element, the local ID is the
position in the array of elements */
int elem_blk; /* element block number which this element is in */
int my_part; /* Partition to which the element is assigned;
default is processor number. */
int fixed_part; /* Partition to which the element should be fixed;
this may not be equal to my_part before partitioning,
but a correct partitioning should assign the
element to fixed_part. fixed_part = -1 if the
element is not to be assigned to a fixed partition.*/
int perm_value; /* Value for this element in permutation vector
generated by Zoltan_Order.
Default is -1 (no ordering done). */
int invperm_value;/* Value for this element in inverse permutation vector
generated by Zoltan_Order.
Default is -1 (no ordering done). */
float cpu_wgt[MAX_CPU_WGTS]; /* the computational weight(s) associated with the elem */
float mem_wgt; /* the memory weight associated with the elem */
double avg_coord[3];/* average coordinates (centroid) for the element */
float **coord; /* array for the coordinates of the element.
for Nemesis meshes, nodal coordinates are stored;
for Chaco graphs with geometry, one set of coords
is stored. */
ZOLTAN_ID_TYPE *connect; /* list of nodes that make up this element, the node
numbers in this list are global and not local */
ZOLTAN_ID_TYPE *adj; /* list of adjacent elements .
For Nemesis input, the list is ordered by
side number, to encode side-number info needed to
rebuild communication maps. Value -1 represents
sides with no neighboring element (e.g., along mesh
boundaries). Chaco doesn't have "sides," so the
ordering is irrelevent for Chaco input. */
/* KDD 1/22/15: Using ZOLTAN_ID_TYPE == unsigned int
breaks the Exodus interface which uses -1 to indicate
sides without neighbors. The solution is to NOT use
ZOLTAN_ID_TYPE for this field (and others); instead,
type int should be used. In general, we wouldn't
expect an application to use ZOLTAN_ID_TYPE.
However, this bug is not important enough to fix at
this time. See bug 6278 and comment in dr_loadbal.c. */
int *adj_proc; /* list of processors for adjacent elements */
int *adj_blank; /* NULL if not blanking, else 1/0 for blanked/not */
float *edge_wgt; /* edge weights for adjacent elements */
int nadj; /* number of entries in adj */
int adj_len; /* allocated length of adj/adj_proc/edge_wgt arrays */
};
typedef struct Element_Description ELEM_INFO;
typedef struct Element_Description *ELEM_INFO_PTR;
/*
* structure for general mesh information
*/
/*pStructure used to store information about the mesh */
struct Mesh_Description
{
struct Zoltan_DD_Struct *dd; /* Only used C and Fortran test driver */
enum DATA_TYPE data_type; /* Type of data stored in this data structure,
based on input file type.
Valid types are MESH, GRAPH, or HYPERGRAPH.*/
int vwgt_dim; /* number of weights per element. */
int ewgt_dim; /* number of weights per graph edge. */
int num_nodes; /* number of nodes on this processor. */
int num_elems; /* number of elements on this processor. */
int num_dims; /* number of dimensions for the mesh */
int num_el_blks; /* number of element blocks in the mesh */
int num_node_sets; /* number of node sets in the mesh */
int num_side_sets; /* number of side sets in the mesh */
char **eb_names; /* element block element names */
int *eb_etypes; /* element block element types */
int *eb_ids; /* element block ids */
ZOLTAN_ID_TYPE *eb_cnts; /* number of elements in each element block */
int *eb_nnodes; /* number of nodes per element in each
element block
for Nemesis meshes, this value depends
on element type;
for Chaco graphs, only one "node" per
element. */
int *eb_nattrs; /* number of attributes per element in each
element block */
int necmap; /* number of elemental communication maps. */
int *ecmap_id; /* IDs of each elemental communication map. */
int *ecmap_cnt; /* number of elements in each elemental
communication map. */
int *ecmap_elemids; /* element ids of elements for all elemental
communication maps. (local numbering) */
int *ecmap_sideids; /* side ids of elements for all elemental
communication maps. */
ZOLTAN_ID_TYPE *ecmap_neighids; /* elements ids of neighboring elements
for all elemental communication maps.
(global numbering) */
int elem_array_len; /* length that the ELEM_INFO array is
allocated for. Need to know this when array
is not completely filled during migration */
ELEM_INFO_PTR elements; /* array of elements that are in the mesh. */
int *blank; /* 1 if my element is blanked, 0 if not */
int blank_count; /* number of my elements that are blanked */
ZOLTAN_ID_TYPE global_blank_count; /* number of all elements that are blanked */
ZOLTAN_ID_TYPE gnhedges; /* for hypergraphs, the number of global
hyperedges.*/
int hewgt_dim; /* for hypergraphs, the number of weights per
hyperedge. */
/* The following fields usually supply the
pins in the hyperedges (rows). But if
"format" indicates columns instead of rows,
we store vertices and their pins here. */
int format; /* rows (edges) or columns (vertices) */
int nhedges; /* # local edges (if cols: # pin vertices) */
ZOLTAN_ID_TYPE *hgid; /* Global number for edges (or pin vertices),
derived implicitly from order pins
are read from file. Numbering is 0-based. */
int *hindex; /* for hypergraphs, an entry for each
edge (or vertex), giving the starting index
into hvertex for hyperedge (or vertex).*/
ZOLTAN_ID_TYPE *hvertex; /* row storage: global number for each pin
vertex, col storage: global number for
each pin hyperedge */
int *hvertex_proc; /* row storage: array listing the processor
owning vertices in hvertex, or NULL if
don't care. col storage: NULL */
int heNumWgts; /* number of edges for which we have weights */
ZOLTAN_ID_TYPE *heWgtId; /* global edge ID of the heNumWgts edges,
if NULL it's the same as hgid */
float *hewgts; /* for hypergraphs, an array of hyperedge
weights; size = hewgt_dim * heNumWgts; */
ZOLTAN_ID_TYPE visible_nvtx; /* #vertices to use, may be < num_elems */
int proc; /* my rank, want to know if adj elements are on my proc */
};
typedef struct Mesh_Description MESH_INFO;
typedef struct Mesh_Description *MESH_INFO_PTR;
/* Structure for the problem description. */
struct Parameter_Description {
char Name[128]; /* parameter name */
char Val[128]; /* parameter value */
int Index; /* index for vector params */
};
typedef struct Parameter_Description Parameter_Pair;
struct Problem_Description
{
char method[32]; /* this is the method string that will
be passed unchanged to Zoltan */
int num_params; /* number of parameters read. */
Parameter_Pair *params; /* parameter array to be passed to
Zoltan. Parameters are specified as
pairs of strings:
param_str = value_str */
char zoltanParams_file[FILENAME_MAX]; /* file name to get more
Zoltan parameters from separate
file (for hier support) */
};
typedef struct Problem_Description PROB_INFO;
typedef struct Problem_Description *PROB_INFO_PTR;
/* Structure for driver flags for various test options. */
struct Test_Flags {
int DDirectory; /* Exercises data directories */
int Local_Parts; /* Sets NUM_LOCAL_PARTS parameter in various
ways. */
int Fixed_Objects; /* Registers functions for assigning fixed
objects; sets fixed_part within elements in
various way; sets RETURN_LISTS to
"PARTITION ASSIGNMENTS" */
int Drops; /* Exercises point- and box-assign. */
int RCB_Box; /* Exercises Zoltan_RCB_Box. */
int Multi_Callbacks; /* Exercises list-based callback functions. */
int Graph_Callbacks; /* Register and test graph callbacks */
int Hypergraph_Callbacks; /* Register and test hypergraph callbacks */
int No_Global_Objects; /* Test case where there are no objects on any process */
int Gen_Files; /* Exercise output file generation. */
int Null_Lists; /* Exercises null import or export lists to
Zoltan_Migrate. */
float Dynamic_Weights; /* Perturb weights between iterations. */
float Dynamic_Graph; /* Graph pertubation between iterations. */
int Vtx_Inc; /* Increment #vertices for each iteration. */
};
/* Structure for output flags for various types of output. */
struct Output_Flags {
int Text;
int Gnuplot;
int Nemesis;
int Plot_Partition;
int Mesh_Info_File;
};
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif
#endif /* _DR_CONST_H */

129
thirdParty/Zoltan/src/driver/dr_dd.c vendored Normal file
View File

@ -0,0 +1,129 @@
/*
* @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
*/
#include "dr_const.h"
#include "dr_util_const.h"
#include "dr_err_const.h"
#include "dr_dd.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/****************************************************************************/
int build_elem_dd(MESH_INFO_PTR mesh)
{
/* Create a distributed directory of the elements so we can track their
* processor assignment after migrations.
*/
int maxelems;
MPI_Allreduce(&(mesh->num_elems), &maxelems, 1, MPI_INT, MPI_MAX,
MPI_COMM_WORLD);
if (Zoltan_DD_Create(&(mesh->dd), MPI_COMM_WORLD, 1, 0, 0, maxelems, 0) != 0){
Gen_Error(0, "fatal: NULL returned from Zoltan_DD_Create()\n");
return 0;
}
return update_elem_dd(mesh);
}
/****************************************************************************/
int update_elem_dd(MESH_INFO_PTR mesh)
{
/* Update a distributed directory of the elements with processor
* assignments initially and after migration.
*/
ELEM_INFO_PTR current_elem;
ZOLTAN_ID_PTR gids;
int *parts;
int i, j;
gids = (ZOLTAN_ID_PTR) malloc(mesh->num_elems * sizeof(ZOLTAN_ID_TYPE));
parts = (int *) malloc(mesh->num_elems * sizeof(int));
for (j = 0, i = 0; i < mesh->elem_array_len; i++) {
current_elem = &(mesh->elements[i]);
if (current_elem->globalID != ZOLTAN_ID_INVALID) {
gids[j] = (ZOLTAN_ID_TYPE)current_elem->globalID;
parts[j] = current_elem->my_part;
j++;
}
}
if (Zoltan_DD_Update(mesh->dd, gids, NULL,NULL, parts, mesh->num_elems)!=0) {
Gen_Error(0, "fatal: NULL returned from Zoltan_DD_Update()\n");
return 0;
}
safe_free((void **)(void *) &gids);
safe_free((void **)(void *) &parts);
return 1;
}
/****************************************************************************/
int update_hvertex_proc(MESH_INFO_PTR mesh)
{
int npins;
npins = mesh->hindex[mesh->nhedges];
if (Zoltan_DD_Find(mesh->dd, mesh->hvertex, NULL, NULL, NULL, npins, mesh->hvertex_proc) != 0) {
Gen_Error(0, "fatal: NULL returned from Zoltan_DD_Find()\n");
return 0;
}
return 1;
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

64
thirdParty/Zoltan/src/driver/dr_dd.h vendored Normal file
View File

@ -0,0 +1,64 @@
/*
* @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
*/
#ifndef __DR_DD_H
#define __DR_DD_H
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
void destroy_elem_dd();
#endif
extern int build_elem_dd(MESH_INFO_PTR);
extern int update_elem_dd(MESH_INFO_PTR);
extern int update_hvertex_proc(MESH_INFO_PTR);
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif
#endif /* __DR_DD_H */

View File

@ -0,0 +1,118 @@
/*
* @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
*/
#include "dr_const.h"
#include "dr_util_const.h"
#include "dr_err_const.h"
#include "dr_dd.h"
#include "zoltan_dd_cpp.h"
static Zoltan_DD *dd = NULL;
/****************************************************************************/
int build_elem_dd(MESH_INFO_PTR mesh)
{
destroy_elem_dd();
dd = new Zoltan_DD(MPI_COMM_WORLD, 1, 0, 0, 0, 0);
return update_elem_dd(mesh);
}
/****************************************************************************/
void destroy_elem_dd()
{
if (dd)
{
delete dd;
dd = NULL;
}
}
/****************************************************************************/
int update_elem_dd(MESH_INFO_PTR mesh)
{
/* Update a distributed directory of the elements with processor
* assignments initially and after migration.
*/
ZOLTAN_ID_PTR gids = new ZOLTAN_ID_TYPE [mesh->num_elems];
int *parts = new int [mesh->num_elems];
int i, j;
for (j = 0, i = 0; i < mesh->elem_array_len; i++) {
ELEM_INFO_PTR current_elem = &(mesh->elements[i]);
if (current_elem->globalID != ZOLTAN_ID_INVALID) {
gids[j] = current_elem->globalID;
parts[j] = current_elem->my_part;
j++;
}
}
int rc = 1;
if (dd->Update(gids, NULL,NULL, parts, mesh->num_elems)!=0) {
Gen_Error(0, "fatal: NULL returned from Zoltan_DD::Update()\n");
rc = 0;
}
delete [] gids;
delete [] parts;
return rc;
}
/****************************************************************************/
int update_hvertex_proc(MESH_INFO_PTR mesh)
{
if (dd->Find(mesh->hvertex, NULL, NULL, NULL,
mesh->hindex[mesh->nhedges], mesh->hvertex_proc) != 0) {
Gen_Error(0, "fatal: NULL returned from Zoltan_DD::Find()\n");
return 0;
}
return 1;
}

1710
thirdParty/Zoltan/src/driver/dr_elem.c vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,127 @@
/*
* @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
*/
#ifndef _DR_ELM_CONST_H
#define _DR_ELM_CONST_H
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/* Define element types */
typedef enum {E_TYPE_ERROR=-1, SPHERE, BAR1, BAR2, QUAD1, S_QUAD2, QUAD2,
SHELL1, SHELL2, TRI1, TRI2, TSHELL1, TSHELL2, HEX1,
S_HEX2, HEX2, TET1, TET2, WEDGE1, WEDGE2,
HEXSHELL, NULL_EL} E_Type;
extern
E_Type get_elem_type(
char *elem_name, /* ExodusII element name */
const int num_nodes, /* Number of nodes in the element */
const int num_dim /* Number of dimensions of the mesh */
);
extern
const char *get_elem_name(
int itype /* ExodusII element type */
);
extern
int get_elem_info(
const int info, /* The requested information */
const E_Type elem_type, /* The element type */
const ZOLTAN_ID_TYPE sid /* side id (to get number of side nodes) */
);
extern
int get_side_id(
E_Type etype, /* The element type */
const ZOLTAN_ID_TYPE *conn, /* The element connectivity */
const int nsnodes, /* The number of side nodes */
int side_nodes[] /* The list of side node IDs */
);
extern
int ss_to_node_list(
const E_Type etype, /* The element type */
const ZOLTAN_ID_TYPE *connect, /* The element connectivity */
int side_num, /* The element side number */
int ss_node_list[] /* The list of side node IDs */
);
extern
ZOLTAN_ID_TYPE get_ss_mirror(
const E_Type etype, /* The element type */
const ZOLTAN_ID_TYPE *ss_node_list, /* The list of side node IDs */
ZOLTAN_ID_TYPE side_num, /* The element side number */
ZOLTAN_ID_TYPE mirror_node_list[] /* The list of the mirror side node IDs */
);
/* Define element info requests */
#define NNODES 0
#define NQUAD 1
#define NDIM 2
#define NQUAD_SURF 3
#define NSNODES 4
#define NSIDES 5
/* Define for the maximum number of nodes on an element side/face */
#define MAX_SIDE_NODES 9
/*
* Define for the maximum number of sides (and hence communications
* entries) that an element can have
*/
#define MAX_ELEM_SIDES 6
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif
#endif /* _DR_ELM_CONST_H */

View File

@ -0,0 +1,164 @@
/*
* @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
*/
#include "dr_const.h"
#include "dr_elem_util_const.h"
#include "dr_util_const.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* Utility functions for element initialization, etc.
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void initialize_element(ELEM_INFO *elem)
{
int i; /* loop counter */
/*
* Initializes all fields of an element.
*/
elem->globalID = ZOLTAN_ID_INVALID;
elem->border = 0;
elem->elem_blk = 0;
elem->my_part = -1;
elem->fixed_part = -1;
elem->perm_value = -1;
elem->invperm_value = -1;
for (i=0; i<MAX_CPU_WGTS; i++)
elem->cpu_wgt[i] = 0;
elem->mem_wgt = 0;
elem->nadj = 0;
elem->adj_len = 0;
elem->avg_coord[0] = elem->avg_coord[1] = elem->avg_coord[2] = 0.;
elem->coord = NULL;
elem->connect = NULL;
elem->adj = NULL;
elem->adj_proc = NULL;
elem->adj_blank = NULL;
elem->edge_wgt = NULL;
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
void free_element_arrays(ELEM_INFO *elem, MESH_INFO_PTR mesh)
{
/*
* Frees all memory malloc'ed for an individual element.
*/
int j;
if (elem->coord != NULL) {
for (j = 0; j < mesh->eb_nnodes[elem->elem_blk]; j++)
safe_free((void **)(void *) &(elem->coord[j]));
safe_free((void **)(void *) &(elem->coord));
}
safe_free((void **)(void *) &(elem->connect));
safe_free((void **)(void *) &(elem->adj));
safe_free((void **)(void *) &(elem->adj_proc));
safe_free((void **)(void *) &(elem->adj_blank));
safe_free((void **)(void *) &(elem->edge_wgt));
elem->avg_coord[0] = elem->avg_coord[1] = elem->avg_coord[2] = 0.;
elem->globalID = ZOLTAN_ID_INVALID;
elem->border = 0;
elem->my_part = -1;
elem->fixed_part = -1;
elem->perm_value = -1;
elem->invperm_value = -1;
elem->nadj = 0;
elem->adj_len = 0;
elem->elem_blk = -1;
for (j=0; j<MAX_CPU_WGTS; j++)
elem->cpu_wgt[j] = 0;
elem->mem_wgt = 0;
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
void free_mesh_arrays(MESH_INFO_PTR mesh)
{
int i;
for (i = 0; i < mesh->elem_array_len; i++)
free_element_arrays(&(mesh->elements[i]), mesh);
safe_free((void **)(void *) &(mesh->elements));
safe_free((void **)(void *) &(mesh->blank));
for (i = 0; i < mesh->num_el_blks; i++)
safe_free((void **)(void *) &(mesh->eb_names[i]));
safe_free((void **)(void *) &(mesh->eb_names));
safe_free((void **)(void *) &(mesh->eb_etypes));
safe_free((void **)(void *) &(mesh->eb_cnts));
safe_free((void **)(void *) &(mesh->ecmap_id));
safe_free((void **)(void *) &(mesh->ecmap_cnt));
safe_free((void **)(void *) &(mesh->ecmap_elemids));
safe_free((void **)(void *) &(mesh->ecmap_sideids));
safe_free((void **)(void *) &(mesh->ecmap_neighids));
safe_free((void **)(void *) &(mesh->hgid));
safe_free((void **)(void *) &(mesh->hindex));
safe_free((void **)(void *) &(mesh->hvertex));
safe_free((void **)(void *) &(mesh->hvertex_proc));
safe_free((void **)(void *) &(mesh->heWgtId));
safe_free((void **)(void *) &(mesh->hewgts));
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,68 @@
/*
* @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
*/
#ifndef _DR_ELEM_UTIL_CONST_H_
#define _DR_ELEM_UTIL_CONST_H_
#include "dr_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/* Function prototypes */
extern void initialize_element(ELEM_INFO *elem);
extern void free_mesh_arrays(MESH_INFO_PTR mesh);
extern void free_element_arrays(ELEM_INFO *elem, MESH_INFO_PTR mesh);
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif
#endif

179
thirdParty/Zoltan/src/driver/dr_err.c vendored Normal file
View File

@ -0,0 +1,179 @@
/*
* @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
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dr_err_const.h"
#include "dr_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* Author(s): Gary L. Hennigan (SNL 9221)
*----------------------------------------------------------------------------
* Functions contained in this file:
* error_add()
* error_report()
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
static int error_cnt = 0;
static int error_lev = 3;
static ERROR_MSG_PTR error_info;
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
/* This function adds the specified error message to the array of error
* structures.
*
* A level 0 error indicates a fatal error, otherwise it's a warning.
*****************************************************************************/
void error_add(int level, const char *message, const char *filename, int line_no)
{
if(error_cnt == 0)
{
error_info = (ERROR_MSG_PTR)malloc(sizeof(ERROR_MSG));
if(!error_info)
{
fprintf(stderr, "no memory for error message\n");
return;
}
}
else
{
error_info = (ERROR_MSG_PTR)realloc(error_info,
(error_cnt+1)*sizeof(ERROR_MSG));
if(!error_info)
{
fprintf(stderr, "no memory for error message\n");
return;
}
}
/* Store the requested error message */
(error_info+error_cnt)->level = level;
(error_info+error_cnt)->err_mesg = (char *)malloc((strlen(message)+1)*
sizeof(char));
if(!((error_info+error_cnt)->err_mesg))
{
error_info = (ERROR_MSG_PTR)realloc(error_info,
error_cnt*sizeof(ERROR_MSG));
fprintf(stderr, "no memory for error message\n");
return;
}
strcpy((error_info+error_cnt)->err_mesg, message);
/* Store the line number info */
(error_info+error_cnt)->line_no = line_no;
/* Store the name of the file in which the error occured */
(error_info+error_cnt)->filename =
(char *) malloc((strlen(filename)+1)*sizeof(char));
if(!((error_info+error_cnt)->filename))
{
fprintf(stderr, "insufficient memory for entire error message\n");
error_cnt++;
return;
}
strcpy((error_info+error_cnt)->filename, filename);
error_cnt++;
return;
} /*----------------End error_msg()------------------*/
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
/* This function outputs the accumulated error messages to stderr
*****************************************************************************/
void error_report(int Proc)
{
int i, iflag=0;
if(error_lev >= 1)
{
for(i=0; i < error_cnt; i++)
{
if((error_info+i)->level == 0 || error_lev > 1)
{
if(iflag == 0)
{
fprintf(stderr, "========================="
"messages from Proc %d"
"=========================\n", Proc);
iflag = 1;
}
fprintf(stderr, "Proc %d: \t%s\n", Proc, (error_info+i)->err_mesg);
if(error_lev >= 2)
fprintf(stderr, "Proc %d: \t\tin file %s\n",
Proc, (error_info+i)->filename);
if(error_lev >= 3)
fprintf(stderr, "Proc %d: \t\t\tat line %d\n",
Proc, (error_info+i)->line_no);
}
}
}
MPI_Abort(MPI_COMM_WORLD, -1);
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,92 @@
/*
* @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
*/
#ifndef _DR_ERR_CONST_H_
#define _DR_ERR_CONST_H_
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#define MAX_ERR_MSG 1024
/* Structure to store an error message */
struct error_message
{
int level;
char *err_mesg;
int line_no;
char *filename;
};
typedef struct error_message ERROR_MSG;
typedef struct error_message *ERROR_MSG_PTR;
/* Macro used in the code to add an error message */
#define Gen_Error(a,b) (error_add(a, b, __FILE__, __LINE__))
/* Function prototype for error functions */
extern
void error_add(
int level,
const char *message, /* The message to add to the error list */
const char *filename, /* The filename in which the error occured */
int line /* The line number in filename where the error
* was reported */
);
extern
void error_report(int proc);
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif
#endif /* _DR_ERR_CONST_H_ */

118
thirdParty/Zoltan/src/driver/dr_eval.c vendored Normal file
View File

@ -0,0 +1,118 @@
/*
* @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
*/
#include "dr_const.h"
#include "dr_eval_const.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* Utility functions for evaluating a partition.
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void driver_eval(MESH_INFO_PTR mesh)
{
/*
* Function to evaluate a partition. Largely duplicates functionality
* of Zoltan_LB_Eval, but provides sanity checking.
*
* Currently uses only the first cpu weight.
*/
int i;
int proc;
double load = 0.;
ZOLTAN_ID_TYPE cuts = 0;
ZOLTAN_ID_TYPE gsumcuts, gmaxcuts, gmincuts, elemcount;
ZOLTAN_ID_TYPE gsumelems, gmaxelems, gminelems;
double gsumload, gmaxload, gminload;
MPI_Comm_rank(MPI_COMM_WORLD, &proc);
for (i = 0; i < mesh->necmap; i++) {
cuts += mesh->ecmap_cnt[i];
}
for (i = 0; i < mesh->num_elems; i++) {
if (mesh->blank_count && (mesh->blank[i] == 1)) continue;
load += mesh->elements[i].cpu_wgt[0];
}
MPI_Allreduce(&cuts, &gsumcuts, 1, ZOLTAN_ID_MPI_TYPE, MPI_SUM, MPI_COMM_WORLD);
MPI_Allreduce(&cuts, &gmaxcuts, 1, ZOLTAN_ID_MPI_TYPE, MPI_MAX, MPI_COMM_WORLD);
MPI_Allreduce(&cuts, &gmincuts, 1, ZOLTAN_ID_MPI_TYPE, MPI_MIN, MPI_COMM_WORLD);
elemcount = mesh->num_elems - mesh->blank_count;
MPI_Allreduce(&elemcount, &gsumelems, 1, ZOLTAN_ID_MPI_TYPE, MPI_SUM, MPI_COMM_WORLD);
MPI_Allreduce(&elemcount, &gmaxelems, 1, ZOLTAN_ID_MPI_TYPE, MPI_MAX, MPI_COMM_WORLD);
MPI_Allreduce(&elemcount, &gminelems, 1, ZOLTAN_ID_MPI_TYPE, MPI_MIN, MPI_COMM_WORLD);
MPI_Allreduce(&load, &gsumload, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
MPI_Allreduce(&load, &gmaxload, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
MPI_Allreduce(&load, &gminload, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD);
if (proc == 0) {
printf("DRIVER EVAL: load: max %f min %f sum %f\n",
gmaxload, gminload, gsumload);
printf("DRIVER EVAL: objs: max " ZOLTAN_ID_SPEC " min " ZOLTAN_ID_SPEC " sum " ZOLTAN_ID_SPEC "\n",
gmaxelems, gminelems, gsumelems);
printf("DRIVER EVAL: cuts: max " ZOLTAN_ID_SPEC " min " ZOLTAN_ID_SPEC " sum " ZOLTAN_ID_SPEC "\n",
gmaxcuts, gmincuts, gsumcuts);
}
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,64 @@
/*
* @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
*/
#ifndef _DR_EVAL_H_
#define _DR_EVAL_H_
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/* Function prototypes */
extern void driver_eval(MESH_INFO_PTR);
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif
#endif

1104
thirdParty/Zoltan/src/driver/dr_exoII_io.c vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,81 @@
/*
* @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
*/
#ifndef _DR_EXTERNS_H
#define _DR_EXTERNS_H
#include "dr_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/* Global variables for driver */
extern int Debug_Driver;
extern int Debug_Chaco_Input;
extern int Number_Iterations;
extern int Driver_Action;
extern int Chaco_In_Assign_Inv;
extern struct Test_Flags Test;
extern struct Output_Flags Output;
extern double Total_Partition_Time;
#define DEBUG_TRACE_START(proc,yo) \
if (((proc) == 0 && Debug_Driver > 1) || (Debug_Driver > 2)) \
printf("%d DRIVER ENTERING %s\n", (proc), yo);
#define DEBUG_TRACE_END(proc,yo) \
if (((proc) == 0 && Debug_Driver > 1) || (Debug_Driver > 2)) \
printf("%d DRIVER LEAVING %s\n", (proc), yo);
#define DEBUG_TRACE_DETAIL(proc,yo,str) \
if (Debug_Driver > 2) \
printf("%d DRIVER %s: %s\n", proc,yo, str);
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif
#endif /* _DR_EXTERNS_H */

View File

@ -0,0 +1,378 @@
/*
* @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
*/
#include "dr_const.h"
#include "dr_externs.h"
#include "dr_util_const.h"
#include "dr_par_util_const.h"
#include "dr_err_const.h"
#include "dr_output_const.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
extern void Zoltan_quicksort_pointer_inc_int_int(int*, int*, int*, int, int);
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
static void printcoord(FILE *fp, int ndims, char *str, ELEM_INFO *elem)
{
switch (ndims) {
case 1:
fprintf(fp, "%s%e\n", str,
elem->coord[0][0]);
break;
case 2:
fprintf(fp, "%s%e %e\n", str,
elem->coord[0][0], elem->coord[0][1]);
break;
case 3:
default:
fprintf(fp, "%s%e %e %e\n", str,
elem->coord[0][0], elem->coord[0][1], elem->coord[0][2]);
break;
}
}
/*--------------------------------------------------------------------------*/
/* Purpose: Output the element assignments in gnuplot format. */
/*--------------------------------------------------------------------------*/
int output_gnu(const char *cmd_file,
const char *tag,
int Proc,
int Num_Proc,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
MESH_INFO_PTR mesh)
/*
* For 2D problems, output files that can be read by gnuplot for looking at
* results.
* We'll do 3D problems later.
*
* One gnuplot file is written for each part.
* When number of part == number of processors, there is one file per
* processor.
*
* For Chaco input files, the file written contains coordinates of owned
* nodes and all nodes in that part connected to the owned nodes. When
* drawn "with linespoints", the subdomains are drawn, but lines connecting the
* subdomains are not drawn.
*
* For Nemesis input files, the file written contains the coordinates of
* each node of owned elements. When drawn "with lines", the element outlines
* for each owned element are drawn.
*
* In addition, processor 0 writes a gnuplot command file telling gnuplot how
* to process the individual coordinate files written. This file can be used
* with the gnuplot "load" command to simplify generation of the gnuplot.
*/
{
/* Local declarations. */
const char *yo = "output_gnu";
char par_out_fname[FILENAME_MAX+1], ctemp[FILENAME_MAX+1];
ELEM_INFO *current_elem, *nbor_elem;
int nbor, num_nodes;
const char *datastyle = NULL;
int i, j, nelems;
int prev_part = -1;
int max_part = -1;
float locMaxX = (float)INT_MIN;
float locMinX = (float)INT_MAX;
float locMaxY = (float)INT_MIN;
float locMinY = (float)INT_MAX;
float globMaxX = (float)INT_MIN;
float globMinX = (float)INT_MAX;
float globMaxY = (float)INT_MIN;
float globMinY = (float)INT_MAX;
int gmax_part = Num_Proc-1;
int gnum_part = Num_Proc;
int *parts = NULL;
int *index = NULL;
int *elem_index = NULL;
FILE *fp = NULL;
/***************************** BEGIN EXECUTION ******************************/
if(Output.Gnuplot < 0)
{
Gen_Error(0,
"warning: 'gnuplot output' parameter set to invalid value.");
return 0;
}
DEBUG_TRACE_START(Proc, yo);
if (mesh->eb_nnodes[0] == 0) {
/* No coordinate information is available. */
Gen_Error(0, "warning: cannot generate gnuplot data when no coordinate"
" input is given.");
DEBUG_TRACE_END(Proc, yo);
return 0;
}
/*
* Build arrays of part number to sort by. Index and elem_index arrays
* will be used even when plotting by processor numbers (for generality),
* so build it regardless.
*/
nelems = mesh->num_elems - mesh->blank_count;
if (nelems > 0) {
parts = (int *) malloc(3 * nelems * sizeof(int));
index = parts + nelems;
elem_index = index + nelems;
for (j = 0, i = 0; i < mesh->elem_array_len; i++) {
current_elem = &(mesh->elements[i]);
if (current_elem->globalID != ZOLTAN_ID_INVALID) {
if (mesh->blank_count && (mesh->blank[i] == 1)) continue;
if (current_elem->my_part > max_part) max_part = current_elem->my_part;
parts[j] = (Output.Plot_Partition ? current_elem->my_part : Proc);
index[j] = j;
elem_index[j] = i;
j++;
}
}
}
if (Output.Plot_Partition) {
/* Sort by part numbers. Assumes # parts >= # proc. */
if (nelems > 0)
Zoltan_quicksort_pointer_inc_int_int(index, parts, NULL, 0, nelems-1);
MPI_Allreduce(&max_part, &gmax_part, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
gnum_part = gmax_part + 1;
}
/* generate the parallel filename for this processor */
strcpy(ctemp, pio_info->pexo_fname);
strcat(ctemp, ".");
strcat(ctemp, tag);
strcat(ctemp, ".gnu");
if (pio_info->file_type == CHACO_FILE ||
pio_info->file_type == NO_FILE_POINTS ||
pio_info->file_type == NO_FILE_TRIANGLES ||
pio_info->file_type == HYPERGRAPH_FILE) {
/*
* For each node of Chaco graph, print the coordinates of the node.
* Then, for each neighboring node on the processor, print the neighbor's
* coordinates.
*/
datastyle = "points";
for (i = 0; i < nelems; i++) {
current_elem = &(mesh->elements[elem_index[index[i]]]);
if (parts[index[i]] != prev_part) {
if (fp != NULL) fclose(fp);
gen_par_filename(ctemp, par_out_fname, pio_info,
parts[index[i]], Num_Proc);
fp = fopen(par_out_fname, "w");
prev_part = parts[index[i]];
}
/* Include the point itself, so that even if there are no edges,
* the point will appear. */
printcoord(fp, mesh->num_dims, "\n", current_elem);
/* save max and min x/y coords */
if(current_elem->coord[0][0] < locMinX)
{
locMinX = current_elem->coord[0][0];
}
if(current_elem->coord[0][0] > locMaxX)
{
locMaxX = current_elem->coord[0][0];
}
if(current_elem->coord[0][1] < locMinY)
{
locMinY = current_elem->coord[0][1];
}
if(current_elem->coord[0][1] > locMaxY)
{
locMaxY = current_elem->coord[0][1];
}
if (Output.Gnuplot>1)
{
datastyle = "linespoints";
for (j = 0; j < current_elem->nadj; j++) {
if (current_elem->adj_proc[j] == Proc) { /* Nbor is on same proc */
if (mesh->blank_count && (mesh->blank[current_elem->adj[j]] == 1))
continue;
if (!Output.Plot_Partition ||
mesh->elements[current_elem->adj[j]].my_part ==
current_elem->my_part) {
/* Not plotting parts, or nbor is in same part */
/* Plot the edge. Need to include current point and nbor point
* for each edge. */
printcoord(fp, mesh->num_dims, "\n", current_elem);
nbor = current_elem->adj[j];
nbor_elem = &(mesh->elements[nbor]);
printcoord(fp, mesh->num_dims, "", nbor_elem);
}
}
}
}
}
MPI_Reduce(&locMinX,&globMinX,1,MPI_FLOAT,MPI_MIN,0,MPI_COMM_WORLD);
MPI_Reduce(&locMinY,&globMinY,1,MPI_FLOAT,MPI_MIN,0,MPI_COMM_WORLD);
MPI_Reduce(&locMaxX,&globMaxX,1,MPI_FLOAT,MPI_MAX,0,MPI_COMM_WORLD);
MPI_Reduce(&locMaxY,&globMaxY,1,MPI_FLOAT,MPI_MAX,0,MPI_COMM_WORLD);
}
else if (pio_info->file_type == NEMESIS_FILE) { /* Nemesis input file */
/*
* For each element of Nemesis input file, print the coordinates of its
* nodes. No need to follow neighbors, as decomposition is by elements.
*/
double sum[2];
if (mesh->num_dims > 2) {
Gen_Error(0,
"warning: cannot generate gnuplot for 3D NEMESIS_FILE problems yet.");
DEBUG_TRACE_END(Proc, yo);
return 0;
}
datastyle = "lines";
for (i = 0; i < nelems; i++) {
current_elem = &(mesh->elements[elem_index[index[i]]]);
if (parts[index[i]] != prev_part) {
if (fp != NULL) fclose(fp);
gen_par_filename(ctemp, par_out_fname, pio_info,
parts[index[i]], Num_Proc);
fp = fopen(par_out_fname, "w");
prev_part = parts[index[i]];
}
num_nodes = mesh->eb_nnodes[current_elem->elem_blk];
sum[0] = sum[1] = 0.0;
for (j = 0; j < num_nodes; j++) {
fprintf(fp, "%e %e\n",
current_elem->coord[j][0], current_elem->coord[j][1]);
sum[0] += current_elem->coord[j][0];
sum[1] += current_elem->coord[j][1];
}
fprintf(fp, "%e %e\n", current_elem->coord[0][0],
current_elem->coord[0][1]);
fprintf(fp, "\n");
/* Print small + in center of element */
sum[0] /= num_nodes;
sum[1] /= num_nodes;
fprintf(fp, "%e %e\n", sum[0] - 0.001, sum[1]);
fprintf(fp, "%e %e\n\n", sum[0] + 0.001, sum[1]);
fprintf(fp, "%e %e\n", sum[0], sum[1] - 0.001);
fprintf(fp, "%e %e\n\n", sum[0], sum[1] + 0.001);
}
}
if (nelems == 0 && !Output.Plot_Partition) {
/* Open a file just so one exists; satisfies the gnuload file. */
gen_par_filename(ctemp, par_out_fname, pio_info, Proc, Num_Proc);
fp = fopen(par_out_fname, "w");
}
if (fp != NULL) fclose(fp);
safe_free((void **)(void *) &parts);
if (Proc == 0) {
/* Write gnu master file with gnu commands for plotting */
strcpy(ctemp, pio_info->pexo_fname);
strcat(ctemp, ".");
strcat(ctemp, tag);
strcat(ctemp, ".gnuload");
fp = fopen(ctemp, "w");
fprintf(fp, "set nokey\n");
fprintf(fp, "set nolabel\n");
fprintf(fp, "set noxzeroaxis\n");
fprintf(fp, "set noyzeroaxis\n");
fprintf(fp, "set noxtics\n");
fprintf(fp, "set noytics\n");
fprintf(fp, "set style data %s\n", datastyle);
/* resize range so that there is a 5% border around data */
fprintf(fp, "set xrange [%f:%f] \n ",globMinX-(globMaxX-globMinX)/20
,globMaxX+(globMaxX-globMinX)/20);
fprintf(fp, "set yrange [%f:%f] \n ",globMinY-(globMaxY-globMinY)/20
,globMaxY+(globMaxY-globMinY)/20);
if (mesh->num_dims < 3)
fprintf(fp, "plot ");
else
fprintf(fp, "splot ");
strcpy(ctemp, pio_info->pexo_fname);
strcat(ctemp, ".");
strcat(ctemp, tag);
strcat(ctemp, ".gnu");
for (i = 0; i < gnum_part; i++) {
gen_par_filename(ctemp, par_out_fname, pio_info, i, Num_Proc);
fprintf(fp, "\"%s\"", par_out_fname);
if (i != gnum_part-1) {
fprintf(fp, ",\\\n");
}
}
fprintf(fp, "\n");
fclose(fp);
}
DEBUG_TRACE_END(Proc, yo);
return 1;
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

2259
thirdParty/Zoltan/src/driver/dr_hg_io.c vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,240 @@
/*
* @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
*/
#include <stdlib.h>
#include <ctype.h>
#include "zoltan.h"
#include "dr_const.h"
#include "dr_hg_readfile.h"
#include "dr_util_const.h"
#include "dr_compress_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#define BUF_LEN 1000
#define ERROR(proc,yo,msg,err) \
{printf("Proc(%d) From(%s): %s\n",proc,yo,msg);return(err);}
static int readfile (int, ZOLTAN_FILE*, int*, int*, int*, int**, int**, int*,
float**, int*, float**, int*);
static int nextstr (ZOLTAN_FILE* f, char *string);
/* These routines work with multiple (vector) vertex and hyperedge weights */
/*****************************************************************************/
int HG_readfile (
int Proc,
ZOLTAN_FILE* f,
int *nVtx, int *nEdge, int *nPins,
int **hindex, int **hvertex,
int *vwgt_dim, float **vwgt,
int *ewgt_dim, float **ewgt,
int *base)
{
char string[BUF_LEN];
const char *yo = "HG_readfile";
int i, code;
/* Initialize return values in case of error. */
*nVtx = *nEdge = *nPins = *vwgt_dim = *ewgt_dim = *base = 0;
*hindex = *hvertex = NULL;
*vwgt = *ewgt = NULL;
/* Skip comments. */
while (1) {
ZOLTAN_FILE_gets (string, BUF_LEN-1, f);
if (*string != '%')
break;
}
/* Extended format: nVtx nEdge nPins NM where both N&M are [0,9]. N is the
* number of dimension for vertex weights and M is number of dimensions for
* the edge weights. */
if (sscanf(string, "%d %d %d %d", nVtx,nEdge,nPins,&code) != 4)
ERROR(Proc, yo, "Unrecognized file format.", ZOLTAN_FATAL);
if (*nVtx <= 1) { /* wrong guess if nVtx really is one! */
i = sscanf(string, "%d %d %d %d %d %d",
base, nVtx, nEdge, nPins, &code, vwgt_dim);
if (i == 4)
code = 0;
else if (i < 4)
ERROR(Proc, yo, "Error in PaToH file format.", ZOLTAN_FATAL);
switch (code) {
case 0: /* No weights */
*vwgt_dim = 0;
*ewgt_dim = 0;
break;
case 1: /* Vwgts only; default is 1 vwgt unless 6 ints on input line */
if (i == 5) *vwgt_dim = 1;
*ewgt_dim = 0;
break;
case 2: /* Ewgts only; PaToH supports only one ewgt. */
*vwgt_dim = 0;
*ewgt_dim = 1;
break;
case 3: /* Ewgts & vwgts; default is 1 vwgt unless 6 ints on input line */
if (i == 5) *vwgt_dim = 1;
*ewgt_dim = 1;
break;
default: /* Invalid code */
ERROR(Proc, yo, "Error in PaToH file format: Illegal PaToH code.",
ZOLTAN_FATAL);
break;
}
return readfile(Proc, f, nVtx, nEdge, nPins, hindex, hvertex, vwgt_dim,
vwgt, ewgt_dim, ewgt, base); /* patoh format */
}
else {
*base = 1;
if (sscanf(string, "%d %d %d %1d%1d",
nVtx,nEdge,nPins,vwgt_dim,ewgt_dim) != 5)
ERROR(Proc, yo, "Error in HG file format.", ZOLTAN_FATAL);
return readfile(Proc, f, nVtx, nEdge, nPins, hindex, hvertex, vwgt_dim,
vwgt, ewgt_dim, ewgt, base); /* IBM format */
}
}
/*****************************************************************************/
/* Read IBM & Patoh formats */
static int readfile (
int Proc,
ZOLTAN_FILE* f,
int *nVtx, int *nEdge, int *nPins,
int **index, int **vertex,
int *vwgt_dim, float **vwgt,
int *ewgt_dim, float **ewgt,
int *base)
{
int i, j, pin;
char string[BUF_LEN];
float *p;
const char *yo = "readfile";
if (!(*index = (int*) malloc ((*nEdge+1) * sizeof(int)))
|| !(*vertex = (int*) malloc ((*nPins * sizeof(int)))))
ERROR (Proc, yo, "Insufficient memory", ZOLTAN_MEMERR);
if (*vwgt_dim > 0
&& !(*vwgt = (float*) malloc (*nVtx * *vwgt_dim * sizeof (float))))
ERROR (Proc, yo, "Insufficient memory", ZOLTAN_MEMERR)
if (*ewgt_dim > 0
&& !(*ewgt = (float*) malloc (*nEdge * *ewgt_dim * sizeof (float))))
ERROR (Proc, yo, "Insufficient memory", ZOLTAN_MEMERR)
pin = 0;
p = *ewgt;
for (i = 0; i < *nEdge; i++) {
(*index)[i] = pin;
for (j = 0; j < *ewgt_dim; j++) {
if (nextstr (f, string) != 1)
ERROR (Proc, yo, "Wrong number of edge weights", ZOLTAN_FATAL)
*p++ = atof (string);
}
while (nextstr (f,string) == 1)
(*vertex)[pin++] = atoi(string);
}
(*index)[i] = pin;
if (pin != *nPins)
ERROR (Proc, yo, "Assertion Error in readfile.", ZOLTAN_FATAL);
p = *vwgt;
if (*vwgt_dim > 0)
for (i = 0; i < *nVtx; i++) {
for (j = 0; nextstr (f, string) == 1 && j < *vwgt_dim; j++)
*p++ = atof (string);
if (j != *vwgt_dim)
ERROR (Proc, yo, "Wrong number of vertex weights", ZOLTAN_FATAL)
}
if (nextstr (f, string) == 1)
ERROR (Proc, yo, "Input file is longer than expected", ZOLTAN_FATAL)
return ZOLTAN_OK;
}
/*****************************************************************************/
/* Uses character reads to read arbitrary long hyperedge definition lines. */
static int nextstr (ZOLTAN_FILE* f, char *string)
{
char ch;
*string = 0;
while (1) {
ch = ZOLTAN_FILE_getc(f);
if (ch == EOF) return 0;
if (ch == '\n') return -1;
if (isspace(ch) == 0) break;
}
while (1) {
if (ch == EOF || isspace(ch)) {
*string = 0;
ZOLTAN_FILE_ungetc (ch, f); /* ??? */
return 1;
}
*string++ = ch;
ch = ZOLTAN_FILE_getc(f);
}
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,73 @@
/*
* @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
*/
#ifndef _ZOLTAN_HG_READFILE_CONST_H_
#define _ZOLTAN_HG_READFILE_CONST_H_
#include <stdio.h>
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#include "dr_input_const.h"
#include "dr_compress_const.h"
/* Hypergraph read from file */
int HG_readfile (int, ZOLTAN_FILE*, int*, int*, int*, int**, int**, int*,
float**, int*, float**, int*);
/* MatrixMarket read from file */
int MM_readfile (int, int, ZOLTAN_FILE*, PARIO_INFO_PTR, int*, int*, int*, int**, int**, int*,
float**, int*, float**, int**, int**, int*, float**, int*, int*);
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif
#endif

869
thirdParty/Zoltan/src/driver/dr_input.c vendored Normal file
View File

@ -0,0 +1,869 @@
/*
* @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
*/
#include <mpi.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include "dr_const.h"
#include "dr_externs.h"
#include "dr_input_const.h"
#include "dr_util_const.h"
#include "dr_err_const.h"
#include "ch_init_dist_const.h"
#include "dr_compress_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#define SKIPW "%*[,\t ]" /* eat up white space amd comma */
#define SKIPEQ " = " /* eat up white space and req'd = sign */
#define BIGSKIP "%*[={()},\t ]" /* eat up list starts, stops, white space */
#define NEXTARG "%*[,\t ]%[^=\t ]" /* argument w/o comma, whitespace */
#define LASTARG SKIPEQ "%[^,=\t\n ]" /* last arg w/o comma, whitespace */
#define NEXTLIST BIGSKIP "%[^,)}=\t\n ]"
/* Purpose: Determine file types for command files and read in the parallel
* ExodusII command file. Taken from nemesis utilites nem_spread and nem_join.
*/
int read_cmd_file (
const char *filename, /* The name of the command file. */
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info, /* pio_info - parallel I/O information. */
UNDEFINED_INFO_PTR undef) /* optional list for unrecognized commands */
{
FILE *file_cmd;
char line[MAX_INPUT_STR_LN + 1], *pline, *pmax;
char original_line[MAX_INPUT_STR_LN + 1]; /* preserved upper/lower cases */
char string[MAX_INPUT_STR_LN], value[MAX_INPUT_STR_LN];
char dummy[MAX_INPUT_STR_LN];
int i, n, nv, nread, keepreading;
/* Open the file */
if ((file_cmd = fopen (filename, "r")) == NULL) {
return 0;
}
/* Begin parsing the input file */
strcpy(prob->zoltanParams_file, "");
if (undef){
undef->list_size = 0;
}
prob->num_params = 0;
prob->params = (Parameter_Pair*) malloc (sizeof(Parameter_Pair));
while (fgets (line, MAX_INPUT_STR_LN, file_cmd)) {
strcpy(original_line, line); /* used when upper/lower case matters */
pmax = line + strlen (line);
for (pline = line; pline < pmax; pline++)
*pline = tolower (*pline);
if (line[0] == '#' || line[0] == '\n')
continue; /* skip blank lines and comment lines */
else if (sscanf(line, " chaco input assignment inverse" SKIPEQ "%d",
&Chaco_In_Assign_Inv) == 1) /* ??? Is this used anymore? */
continue;
else if (sscanf(line," decomposition method" SKIPEQ "%s", prob->method)== 1)
continue;
else if (sscanf(line, " file name" SKIPEQ "%s", pio_info->pexo_fname) == 1)
sscanf(original_line, "%*[^=]= %s", pio_info->pexo_fname); /*save case*/
else if (sscanf(line, " compression" SKIPEQ "%s", value) == 1) {
if (!strcmp(value, "uncompressed")) {
pio_info->file_comp = STANDARD;
continue;
}
if (!strcmp(value, "gzip")) {
pio_info->file_comp = GZIP;
continue;
}
}
else if (sscanf(line, " zoltan memory debug level" SKIPEQ "%s", value) == 1) {
if (strcmp(value, "1")) {
Zoltan_Memory_Debug(1);
}
else if (strcmp(value, "2")) {
Zoltan_Memory_Debug(2);
}
else {
Zoltan_Memory_Debug(3); /* highest level */
}
continue;
}
else if (sscanf(line, " file type" LASTARG "%n", value, &n) == 1) {
if ((!strcmp(value, "chaco")) || (!strcmp(value, "graph"))) {
pio_info->file_type = CHACO_FILE;
pio_info->init_dist_type = INITIAL_LINEAR;
pio_info->init_dist_procs = -1;
pline = line;
while (pline+n < pmax) {
i = sscanf(pline += n, SKIPW "initial" NEXTARG LASTARG "%n", string,
value, &n);
if (i != 2)
break;
if (!strcmp(string, "distribution")) {
if (!strcmp(value, "linear")) i = INITIAL_LINEAR;
else if (!strcmp(value, "block")) i = INITIAL_LINEAR;
else if (!strcmp(value, "cyclic")) i = INITIAL_CYCLIC;
else if (!strcmp(value, "file")) i = INITIAL_FILE;
else if (!strcmp(value, "owner")) i = INITIAL_OWNER;
else {
Gen_Error(0, "fatal: bad initial distribution argument");
return 0;
}
pio_info->init_dist_type = i;
}
else if (!strcmp(string, "procs")) {
if (sscanf(value, " %d%n", &pio_info->init_dist_procs, &nv) != 1) {
Gen_Error(0, "fatal: initial procs value must be integal");
return 0;
}
}
else {
Gen_Error(0, "fatal: unrecognizable file type arguments");
return 0;
}
}
}
else if ((strcmp(value, "hypergraph") == 0)
|| (strcmp(value, "matrixmarket") == 0)
|| (strcmp(value, "matrixmarket+") == 0)) {
if (strcmp(value, "hypergraph") == 0){
pio_info->file_type = HYPERGRAPH_FILE;
pio_info->init_dist_type = INITIAL_LINEAR;
pio_info->init_dist_pins = INITIAL_ROW;
}
else if (strcmp(value, "matrixmarket") == 0){
pio_info->file_type = MATRIXMARKET_FILE;
pio_info->init_dist_type = INITIAL_LINEAR;
pio_info->init_dist_pins = INITIAL_ROW;
}
else if (strcmp(value, "matrixmarket+") == 0){
pio_info->file_type = MATRIXMARKET_PLUS_FILE;
pio_info->init_dist_type = INITIAL_LINEAR;
pio_info->init_dist_pins = INITIAL_ROW;
}
pio_info->init_dist_procs = -1;
pio_info->matrix_obj = COLUMNS;
pline = line;
keepreading = 1; /* dummy value to enter loop */
while ((pline+n < pmax) && keepreading) {
/* Check for options starting with "initial" */
keepreading = 0; /* only keep reading if we found new options */
pline += n; /* update pline based on previous token */
n = 0; /* no. of chars read. set to zero in case sscanf fails */
nread = sscanf(pline, SKIPW "initial" NEXTARG LASTARG "%n", string,
value, &n);
keepreading += nread;
if (nread == 2){
if (!strcmp(string, "read")) {
if ((value[0] == 'c') && (value[1] == 'h') &&
(value[2] == 'u') &&(value[3] == 'n') &&(value[4] == 'k')){
pio_info->chunk_reader = 1;
}
}
else if (!strcmp(string, "distribution")) {
if (!strcmp(value, "linear")) i = INITIAL_LINEAR;
else if (!strcmp(value, "block")) i = INITIAL_LINEAR;
else if (!strcmp(value, "cyclic")) i = INITIAL_CYCLIC;
else if (!strcmp(value, "owner")) i = INITIAL_OWNER;
else if (!strcmp(value, "file")) i = INITIAL_FILE;
else {
Gen_Error(0, "fatal: bad initial distribution argument");
return 0;
}
pio_info->init_dist_type = i;
}
else if (!strcmp(string, "pins")) {
if (!strcmp(value, "linear")) i = INITIAL_LINEAR;
else if (!strcmp(value, "block")) i = INITIAL_LINEAR;
else if (!strcmp(value, "cyclic")) i = INITIAL_CYCLIC;
else if (!strcmp(value, "file")) i = INITIAL_FILE;
else if (!strcmp(value, "zero")) i = INITIAL_ZERO;
else if (!strcmp(value, "row")) i = INITIAL_ROW;
else if (!strcmp(value, "rows")) i = INITIAL_ROW;
else if (!strcmp(value, "column")) i = INITIAL_COL;
else if (!strcmp(value, "columns")) i = INITIAL_COL;
else if (!strcmp(value, "col")) i = INITIAL_COL;
else if (!strcmp(value, "cols")) i = INITIAL_COL;
else {
Gen_Error(0, "fatal: bad initial pins argument");
return 0;
}
pio_info->init_dist_pins = i;
}
else if (!strcmp(string, "procs")) {
if (sscanf(value, " %d%n", &pio_info->init_dist_procs, &nv) != 1){
Gen_Error(0, "fatal: initial procs value must be integal");
return 0;
}
}
else {
Gen_Error(0, "fatal: unrecognizable file type arguments");
return 0;
}
}
/* Check for options without "initial" */
pline += n; /* update pline based on previous token */
n = 0; /* set to zero in case sscanf fails */
i = 0;
if (pline < pmax){
nread = sscanf(pline, NEXTARG LASTARG "%n", string,
value, &n);
keepreading += nread;
if (nread == 2){
if (!strcmp(string, "objects")) {
if (!strcmp(value, "rows")) i = ROWS;
else if (!strcmp(value, "columns")) i = COLUMNS;
else if (!strcmp(value, "nonzeros")) i = NONZEROS;
else {
Gen_Error(0, "fatal: bad objects type argument");
return 0;
}
pio_info->matrix_obj = i;
if (pio_info->matrix_obj != COLUMNS &&
pio_info->file_type == MATRIXMARKET_PLUS_FILE) {
Gen_Error(0, "fatal: objects != COLUMNS not supported "
"for MATRIXMARKET_PLUS");
return 0;
}
}
else {
Gen_Error(0, "fatal: unrecognizable file type arguments");
return 0;
}
}
}
}
}
else if (strcmp(value, "create-a-graph") == 0){
pio_info->file_type = NO_FILE_GRAPH; /* zdrive creates a graph */
strcpy(pio_info->pexo_fname, "zdrive-created-graph");
pio_info->init_dist_type = INITIAL_NO_DIST; /* it's already distributed */
pio_info->init_size = 10000; /* default */
pio_info->init_dim = 3; /* default */
pio_info->init_vwgt_dim = 1; /* default */
pline = line;
while (pline+n < pmax &&
sscanf(pline += n, NEXTARG LASTARG "%n", string, value, &n)==2) {
if (!strcmp(string, "dimension")
&& sscanf(value, "%d%n", &pio_info->init_dim, &nv) == 1)
continue;
else if (!strcmp(string, "obj_weight_dim")
&& sscanf(value, "%d%n", &pio_info->init_vwgt_dim, &nv) == 1)
continue;
else if (!strcmp(string, "size")
&& sscanf(value, ZOLTAN_ID_SPEC "%n", &pio_info->init_size, &nv) == 1)
continue;
else {
Gen_Error(0, "fatal: bad create-a-graph file parameters");
return 0;
}
}
}
else if (strcmp(value, "nemesisi") == 0) {
pio_info->file_type = NEMESIS_FILE;
pio_info->init_dist_type = INITIAL_FILE;
}
else if ((strcmp(value, "random-triangles") == 0) || (strcmp(value, "random") == 0)) {
/* No input file; generate random coordinates. */
if (strcmp(value, "random-triangles") == 0){
pio_info->file_type = NO_FILE_TRIANGLES;
strcpy(pio_info->pexo_fname, "random-triangles");
}
else{
pio_info->file_type = NO_FILE_POINTS;
strcpy(pio_info->pexo_fname, "random");
}
pio_info->init_dist_type = INITIAL_LINEAR;
pio_info->init_dist_procs = -1;
pio_info->init_size = 100; /* default */
pio_info->init_dim = 3; /* default */
pio_info->init_vwgt_dim = 1; /* default */
pline = line;
while (pline+n < pmax &&
sscanf(pline += n, NEXTARG LASTARG "%n", string, value, &n)==2) {
if (!strcmp(string, "dimension")
&& sscanf(value, "%d%n", &pio_info->init_dim, &nv) == 1)
continue;
else if (!strcmp(string, "obj_weight_dim")
&& sscanf(value, "%d%n", &pio_info->init_vwgt_dim, &nv) == 1)
continue;
else if (!strcmp(string, "size")
&& sscanf(value, ZOLTAN_ID_SPEC "%n", &pio_info->init_size, &nv) == 1)
continue;
else {
Gen_Error(0, "fatal: bad file type = random file parameters");
return 0;
}
}
}
else {
Gen_Error(0, "fatal: bad file type parameter");
return 0;
}
}
else if (sscanf(line, " text output" SKIPEQ "%d", &Output.Text) == 1)
continue; /* Generate text output */
else if (sscanf(line, " gnuplot output" SKIPEQ "%d", &Output.Gnuplot) == 1)
continue; /* Generate GNUplot output */
else if (sscanf(line, " nemesis output" SKIPEQ "%d", &Output.Nemesis) == 1)
continue; /* Generate Nemesis output */
else if (sscanf(line, " number of iterations" SKIPEQ "%d",
&Number_Iterations) == 1)
continue; /* The Number of iterations of the balancer to perform */
else if (sscanf(line, " parallel disk info %[= \t\n]%n", dummy, &n) == 1) {
pline = line;
if (sscanf(pline += n, " number = %d%n", &i, &n) != 1) {
Gen_Error(0, "fatal: First sup-option for disk info must be number");
return 0;
}
if (i < 0) {
Gen_Error(0, "fatal: Invalid value for # of raid controllers.");
return 0;
}
pio_info->num_dsk_ctrlrs = i;
/* if number_dsk_ctrlrs = 0, then the input file(s) is in the root */
/* directory given by the parallel disk info, or it is in the same */
/* directory as the executable if nothing is given for the root */
/* infomation. So, no other options can be given when = 0 */
if (pio_info->num_dsk_ctrlrs == 0)
continue;
while (pline+n < pmax) {
i = sscanf(pline += n, NEXTLIST "%n", string, &n) ;
if (i != 1)
break;
if (strcmp(string, "zeros") == 0)
pio_info->zeros = 1;
else if (strcmp(string, "offset") == 0) {
if (sscanf(pline += n, " =%d%n", &pio_info->pdsk_add_fact, &n) != 1
|| pio_info->pdsk_add_fact < 0) {
Gen_Error(0, "fatal: Invalid value for offset.");
return 0;
}
}
else if (strcmp(string, "list") == 0) {
pio_info->dsk_list_cnt = pio_info->num_dsk_ctrlrs;
pio_info->num_dsk_ctrlrs = -1;
/* allocate memory for to hold the values */
pio_info->dsk_list=(int*)malloc(pio_info->dsk_list_cnt*sizeof(int));
for (i = 0; i < pio_info->dsk_list_cnt; i++)
if (pline+n < pmax && sscanf(pline += n, BIGSKIP "%d%n",
&pio_info->dsk_list[i], &n) == 1)
continue;
else {
Gen_Error(0, "Unknown parameter for parallel disk information");
return 0;
}
}
}
}
else if (sscanf(line," parallel file location %[=]%n", dummy, &n)==1) {
pline = line;
while (pline+n < pmax) {
i = sscanf(pline += n, NEXTARG LASTARG "%n", string, value, &n);
if (i != 2)
break;
sscanf(original_line + (pline-line), NEXTARG LASTARG, dummy, value); /* reread value from orig line to preserve case */
if (strcmp(string, "root") == 0)
strcpy(pio_info->pdsk_root, value);
if (strcmp(string, "subdir") == 0) {
strcpy(pio_info->pdsk_subdir, value);
if (value [strlen(value)-1] != '/') {
pio_info->pdsk_subdir [strlen(value)] = '/';
pio_info->pdsk_subdir [strlen(value)+1] = 0;
}
}
}
}
else if (sscanf(line, " plot partitions" SKIPEQ "%d%n",
&Output.Plot_Partition, &n) == 1)
continue; /* Plot processor numbers or partitions? */
else if (sscanf(line, " plot partition" SKIPEQ "%d%n",
&Output.Plot_Partition, &n) == 1)
continue; /* Plot processor numbers or partitions? */
else if (sscanf(line, " print mesh info file" SKIPEQ "%d%n",
&Output.Mesh_Info_File, &n) == 1)
continue; /* Generate ASCII mesh file? */
else if (sscanf(line, " test ddirectory" SKIPEQ "%d%n",
&Test.DDirectory, &n) == 1)
continue; /* DDirectory testing flag */
else if (sscanf(line, " test drops" SKIPEQ "%d%n", &Test.Drops, &n) == 1)
continue; /* Box- and Point-drop testing flag */
else if (sscanf (line, " test rcb box" SKIPEQ "%d", &Test.RCB_Box) == 1)
continue; /* Zoltan_RCB_Box testing flag */
else if (sscanf(line, " test generate files" SKIPEQ "%d%n",
&Test.Gen_Files, &n) == 1)
continue; /* file generation testing flag */
else if (sscanf(line, " test generate file" SKIPEQ "%d%n",
&Test.Gen_Files, &n) == 1)
continue; /* file generation testing flag */
else if (sscanf(line, " test local partitions" SKIPEQ "%d%n",
&Test.Local_Parts, &n) == 1)
continue; /* Unusual Partition generation testing flag */
else if (sscanf(line, " test local partition" SKIPEQ "%d%n",
&Test.Local_Parts, &n) == 1)
continue; /* Unusual Partition generation testing flag */
else if (sscanf(line, " test fixed objects" SKIPEQ "%d%n",
&Test.Fixed_Objects, &n) == 1)
continue; /* Fixed objects test flag */
else if (sscanf(line, " test fixed object" SKIPEQ "%d%n",
&Test.Fixed_Objects, &n) == 1)
continue; /* Fixed objects test flag */
else if (sscanf(line, " test dynamic weights" SKIPEQ "%f%n",
&Test.Dynamic_Weights, &n) == 1)
continue; /* Dynamic weights; changes between iter. */
else if (sscanf(line, " test dynamic graph" SKIPEQ "%f%n",
&Test.Dynamic_Graph, &n) == 1)
continue; /* Dynamic graph; edges/verts change between iter. */
else if (sscanf(line, " test vertex increment" SKIPEQ "%i%n",
&Test.Vtx_Inc, &n) == 1)
continue; /* Add more vertices in each iteration. */
else if (sscanf(line, " test multi callbacks" SKIPEQ "%d%n",
&Test.Multi_Callbacks, &n) == 1)
continue; /* List-based (MULTI) callback function testing */
else if (sscanf(line, " test multi callback" SKIPEQ "%d%n",
&Test.Multi_Callbacks, &n) == 1)
continue; /* List-based (MULTI) callback function testing */
else if (sscanf(line, " test graph callbacks" SKIPEQ "%d%n",
&Test.Graph_Callbacks, &n) == 1)
continue; /* Graph-based callback function testing */
else if (sscanf(line, " test graph callback" SKIPEQ "%d%n",
&Test.Graph_Callbacks, &n) == 1)
continue; /* Graph-based callback function testing */
else if (sscanf(line, " test hypergraph callbacks" SKIPEQ "%d%n",
&Test.Hypergraph_Callbacks, &n) == 1)
continue; /* HyperGraph-based callback function testing */
else if (sscanf(line, " test hypergraph callback" SKIPEQ "%d%n",
&Test.Hypergraph_Callbacks, &n) == 1)
continue; /* HyperGraph-based callback function testing */
else if (sscanf(line, " test no global objects" SKIPEQ "%d%n",
&Test.No_Global_Objects, &n) == 1)
continue; /* HyperGraph-based callback function testing */
else if (sscanf(line, " test null export lists" SKIPEQ "%d%n", &i,&n)==1) {
if (i == 1) /* Null export lists to Help_Migrate testing */
Test.Null_Lists = EXPORT_LISTS;
}
else if (sscanf(line, " test null export list" SKIPEQ "%d%n", &i,&n) == 1) {
if (i == 1) /* Null export lists to Help_Migrate testing */
Test.Null_Lists = EXPORT_LISTS;
}
else if (sscanf(line, " test null import lists" SKIPEQ "%d%n", &i,&n) == 1){
if (i == 1) /* Null import lists to Help_Migrate testing */
Test.Null_Lists = IMPORT_LISTS;
}
else if (sscanf(line, " test null import list" SKIPEQ "%d%n", &i,&n) == 1) {
if (i == 1) /* Null import lists to Help_Migrate testing */
Test.Null_Lists = IMPORT_LISTS;
}
else if (sscanf(line," zdrive action" SKIPEQ "%d%n",&Driver_Action,&n) == 1)
continue; /* zdrive action: Do coloring, load-balancing or ordering? */
else if (sscanf(line," zdrive debug level" SKIPEQ "%d%n",
&Debug_Driver,&n)==1)
continue; /* The Debug reporting level */
else if (sscanf(line, " zoltan parameter%*[^=]%[=]%n", string, &n) == 1) {
pline = line;
while (pline+n < pmax && sscanf(pline += n, NEXTARG LASTARG "%n",
prob->params[prob->num_params].Name,
prob->params[prob->num_params].Val, &n)==2) {
prob->params[prob->num_params++].Index = -1;
prob->params = (Parameter_Pair*) realloc(prob->params,
(prob->num_params+1) * sizeof(Parameter_Pair));
if (prob->params == NULL) {
Gen_Error(0, "fatal: realloc failed for Zoltan Parameters");
return 0;
}
}
}
else if (sscanf(line," zoltan vector parameters" LASTARG "%n",string,&n)==1
|| sscanf(line," zoltan vector parameter" LASTARG "%n",string,&n)==1
|| sscanf(line," zoltan parameter vectors" LASTARG "%n",string,&n)==1
|| sscanf(line," zoltan parameter vector" LASTARG "%n",string,&n)==1)
{
pline = line;
i = 0;
while (pline+n < pmax && sscanf(pline += n, BIGSKIP "%[^,\t\n) ]%n",
prob->params[prob->num_params].Val, &n)==1) {
prob->params[prob->num_params].Index = i++;
strcpy(prob->params[prob->num_params++].Name, string);
prob->params = (Parameter_Pair*) realloc(prob->params,
(prob->num_params+1) * sizeof(Parameter_Pair));
if (prob->params == NULL) {
Gen_Error(0, "fatal, realloc failed for Zoltan Parameters");
return 0;
}
}
}
else if (sscanf(line, " zoltanparams file" SKIPEQ "%s", string) == 1) {
/* specify zoltanParams-format filename to be read later --
included to support hierarchical balancing tests */
strcpy(prob->zoltanParams_file, string);
}
else {
if (undef){
if (undef->list_size < UNDEFINED_LIST_MAX){
strncpy((char *)(undef->line + undef->list_size), line,
UNDEFINED_LENGTH_MAX-1);
undef->list_size++;
}
else{
char buffer[200];
sprintf (buffer,
"fatal error, too many unrecognized commands: %s\n", line);
Gen_Error(0, buffer);
return 0;
}
}
else{
printf("Warning: ignoring unrecognized line in input file:\n\t%s\n",
line);
}
}
}
if (prob->num_params == 0) {
free (prob->params);
prob->params = NULL;
}
fclose (file_cmd);
return 1;
}
int check_inp (
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info
)
{
/* check for the parallel Nemesis file for proc 0 */
if (strlen(pio_info->pexo_fname) <= 0) {
Gen_Error (0, "fatal: must specify file base name");
return 0;
}
/* default file type is nemesis */
if (pio_info->file_type < 0)
pio_info->file_type = NEMESIS_FILE;
#ifndef ZOLTAN_NEMESIS
/* if not compiling with the ZOLTAN_NEMESIS flag (i.e., not linking with */
/* Nemesis library), can't use NEMESIS_FILE file type. */
if (pio_info->file_type == NEMESIS_FILE) {
Gen_Error(0, "fatal: must compile for and link with Nemesis libraries for"
"Nemesis file types");
return 0;
}
#endif
/* check that there is a list of disks, or a number of raids */
if ((pio_info->dsk_list_cnt <= 0) && (pio_info->num_dsk_ctrlrs < 0))
pio_info->num_dsk_ctrlrs = 0; /* default to single directory */
/* default is not to have preceeding 0's in the disk names */
if (pio_info->zeros < 0)
pio_info->zeros = 0;
/* most systems that we deal with start their files systems with 1 not 0 */
if (pio_info->pdsk_add_fact < 0)
pio_info->pdsk_add_fact = 1;
/* if there are parallel disks, then specify the root and subdir locations */
if (pio_info->num_dsk_ctrlrs > 0 || pio_info->dsk_list_cnt > 0) {
if (strlen(pio_info->pdsk_root) == 0) {
Gen_Error(0, "fatal: must specify parallel disk root name");
return 0;
}
if (strlen(pio_info->pdsk_subdir) == 0) {
Gen_Error(0, "fatal: must specify parallel disk subdirectory");
return 0;
}
}
else
if (strlen(pio_info->pdsk_root) == 0)
strcpy(pio_info->pdsk_root, "."); /* default is execution directory */
/* Check Zoltan specs to insure a load-balancing method is selected */
if (strlen(prob->method) == 0) {
Gen_Error(0, "fatal: load balance method must be specified");
return 0;
}
return 1;
}
/* Broadcast commands to all processes.
NOTE: This requires manual updating when a new field
is added to a struct, like Test!
*/
void brdcst_cmd_info (
int Proc,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
MESH_INFO_PTR mesh
)
{
int ctrl_id, j, k;
int size;
int int_params[20]; /* Make sure this array is large enough */
float float_params[2]; /* Make sure this array is large enough */
k = 0;
float_params[k++] = Test.Dynamic_Weights;
float_params[k++] = Test.Dynamic_Graph;
MPI_Bcast (float_params, k, MPI_FLOAT, 0, MPI_COMM_WORLD);
k = 0;
Test.Dynamic_Weights = float_params[k++];
Test.Dynamic_Graph = float_params[k++];
j = 0;
int_params[j++] = Debug_Driver;
int_params[j++] = Test.DDirectory;
int_params[j++] = Test.Local_Parts;
int_params[j++] = Test.Fixed_Objects;
int_params[j++] = Test.Multi_Callbacks;
int_params[j++] = Test.Graph_Callbacks;
int_params[j++] = Test.Hypergraph_Callbacks;
int_params[j++] = Test.No_Global_Objects;
int_params[j++] = Test.Null_Lists;
int_params[j++] = Output.Text;
int_params[j++] = Output.Gnuplot;
int_params[j++] = Output.Nemesis;
int_params[j++] = Output.Plot_Partition;
int_params[j++] = Output.Mesh_Info_File;
int_params[j++] = Number_Iterations;
int_params[j++] = Driver_Action;
int_params[j++] = Test.Drops;
int_params[j++] = Test.RCB_Box;
int_params[j++] = Test.Gen_Files;
int_params[j++] = Test.Vtx_Inc;
MPI_Bcast (int_params, j, MPI_INT, 0, MPI_COMM_WORLD);
j = 0;
Debug_Driver = int_params[j++];
Test.DDirectory = int_params[j++];
Test.Local_Parts = int_params[j++];
Test.Fixed_Objects = int_params[j++];
Test.Multi_Callbacks = int_params[j++];
Test.Graph_Callbacks = int_params[j++];
Test.Hypergraph_Callbacks = int_params[j++];
Test.No_Global_Objects = int_params[j++];
Test.Null_Lists = int_params[j++];
Output.Text = int_params[j++];
Output.Gnuplot = int_params[j++];
Output.Nemesis = int_params[j++];
Output.Plot_Partition = int_params[j++];
Output.Mesh_Info_File = int_params[j++];
Number_Iterations = int_params[j++];
Driver_Action = int_params[j++];
Test.Drops = int_params[j++];
Test.RCB_Box = int_params[j++];
Test.Gen_Files = int_params[j++];
Test.Vtx_Inc = int_params[j++];
MPI_Bcast (pio_info, sizeof(PARIO_INFO), MPI_BYTE, 0, MPI_COMM_WORLD);
switch (pio_info->file_type) {
case CHACO_FILE:
case NO_FILE_POINTS:
case NO_FILE_TRIANGLES:
mesh->data_type = ZOLTAN_GRAPH;
break;
case NEMESIS_FILE:
mesh->data_type = MESH;
break;
case HYPERGRAPH_FILE:
case MATRIXMARKET_FILE:
case MATRIXMARKET_PLUS_FILE:
mesh->data_type = ZOLTAN_HYPERGRAPH;
break;
}
if (pio_info->dsk_list_cnt > 0) {
if (Proc != 0)
pio_info->dsk_list = (int*) malloc (pio_info->dsk_list_cnt*sizeof(int));
MPI_Bcast (pio_info->dsk_list, pio_info->dsk_list_cnt, MPI_INT, 0,
MPI_COMM_WORLD);
}
/* and broadcast the problem specifications */
MPI_Bcast (prob, sizeof(PROB_INFO), MPI_BYTE, 0, MPI_COMM_WORLD);
if (prob->num_params > 0) {
size = prob->num_params * sizeof(Parameter_Pair);
if (Proc != 0)
prob->params = (Parameter_Pair*) malloc(size);
MPI_Bcast (prob->params, size, MPI_CHAR, 0, MPI_COMM_WORLD);
}
/* now calculate where the file for this processor is */
if (pio_info->dsk_list_cnt <= 0) {
if (pio_info->num_dsk_ctrlrs > 0) {
ctrl_id = (Proc % pio_info->num_dsk_ctrlrs);
pio_info->rdisk = ctrl_id + pio_info->pdsk_add_fact;
}
}
else {
ctrl_id = Proc % pio_info->dsk_list_cnt;
pio_info->rdisk = pio_info->dsk_list[ctrl_id];
}
}
/*----------------------------------------------------------------------------
* Function which generates the name of a parallel file for a
* particular processor. The function does this by appending
* "N.p" to the end of the input parameter "scalar_fname", where:
*
* N - The number of processors utilized
* p - The processor ID.
*
* In addition, the location of the parallel disk system is prepended
* to each file name.
*---------------------------------------------------------------------------
* Example:
*
* scalar_fname = "Parallel-exoII-" (Input)
* par_fname = "/raid/io_01/tmp/rf_crew/Parallel-exoII-8.0" (Output)
*
* where, for this example:
*
* N = 8 processors
* p = 0 particular processor ID
*
*----------------------------------------------------------------------------
* Determine the number of digits needed to specify the processor ID.
* This allows
* numbers like 01-99, i.e., prepending zeros to the name to preserve proper
* alphabetic sorting of the files. Comments by Gary Hennigan (1421) */
void gen_par_filename (
char *scalar_fname,
char *par_fname,
PARIO_INFO_PTR pio_info,
int myproc,
int nprocs
)
{
double dnprocs = (double)nprocs;
double dndisks = (double)pio_info->num_dsk_ctrlrs;
if (pio_info->num_dsk_ctrlrs <= 0)
sprintf(par_fname, "%s/%s.%d.%0*d", pio_info->pdsk_root, scalar_fname,
nprocs, 1+(int)log10(dnprocs), myproc);
else if (pio_info->zeros)
sprintf(par_fname, "%s%0*d/%s%s.%d.%0*d", pio_info->pdsk_root,
pio_info->num_dsk_ctrlrs<9 ? 2 : 1+(int)log10(dndisks),
pio_info->rdisk, pio_info->pdsk_subdir, scalar_fname, nprocs,
1 + (int) log10(dnprocs), myproc);
else
sprintf(par_fname, "%s%d/%s/%s.%d.%0*d", pio_info->pdsk_root,
pio_info->rdisk, pio_info->pdsk_subdir, scalar_fname, nprocs,
1 + (int) log10(dnprocs), myproc);
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,797 @@
/*
* @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
*/
#include <mpi.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include "dr_const.h"
#include "dr_input_const.h"
#include "dr_util_const.h"
#include "dr_err_const.h"
#include "ch_init_dist_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/****************************************************************************/
/* ALTERNATE FILE FOR SHOCKSTEM ADAPTIVE MESH REFINEMENT EXPERIMENTS ONLY. */
/* DO NOT COMMIT AS A REGULAR DRIVER FILE. */
/****************************************************************************/
#define SKIPW "%*[,\t ]" /* eat up white space amd comma */
#define SKIPEQ " = " /* eat up white space and req'd = sign */
#define BIGSKIP "%*[={()},\t ]" /* eat up list starts, stops, white space */
#define NEXTARG "%*[,\t ]%[^=\t ]" /* argument w/o comma, whitespace */
#define LASTARG SKIPEQ "%[^,=\t\n ]" /* last arg w/o comma, whitespace */
#define NEXTLIST BIGSKIP "%[^,)}=\t\n ]"
/* Purpose: Determine file types for command files and read in the parallel
* ExodusII command file. Taken from nemesis utilites nem_spread and nem_join.
*/
int read_cmd_file (
const char *filename, /* The name of the command file. */
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info, /* pio_info - parallel I/O information. */
UNDEFINED_INFO_PTR undef) /* optional list for unrecognized commands */
{
FILE *file_cmd;
char line[MAX_INPUT_STR_LN + 1], *pline, *pmax;
char original_line[MAX_INPUT_STR_LN + 1]; /* preserved upper/lower cases */
char string[MAX_INPUT_STR_LN], value[MAX_INPUT_STR_LN];
char dummy[MAX_INPUT_STR_LN];
int i, n, nv, nread, keepreading;
/* Open the file */
if ((file_cmd = fopen (filename, "r")) == NULL) {
return 0;
}
/* Begin parsing the input file */
strcpy(prob->zoltanParams_file, "");
if (undef){
undef->list_size = 0;
}
prob->num_params = 0;
prob->params = (Parameter_Pair*) malloc (sizeof(Parameter_Pair));
while (fgets (line, MAX_INPUT_STR_LN, file_cmd)) {
strcpy(original_line, line); /* used when upper/lower case matters */
pmax = line + strlen (line);
for (pline = line; pline < pmax; pline++)
*pline = tolower (*pline);
if (line[0] == '#' || line[0] == '\n')
continue; /* skip blank lines and comment lines */
else if (sscanf(line, " chaco input assignment inverse" SKIPEQ "%d",
&Chaco_In_Assign_Inv) == 1) /* ??? Is this used anymore? */
continue;
else if (sscanf(line," decomposition method" SKIPEQ "%s", prob->method)== 1)
continue;
else if (sscanf(line, " file name" SKIPEQ "%s", pio_info->pexo_fname) == 1)
sscanf(original_line, "%*[^=]= %s", pio_info->pexo_fname); /*save case*/
else if (sscanf(line, " file type" LASTARG "%n", value, &n) == 1) {
if ((!strcmp(value, "chaco")) || (!strcmp(value, "graph"))) {
pio_info->file_type = CHACO_FILE;
pio_info->init_dist_type = INITIAL_LINEAR;
pio_info->init_dist_procs = -1;
pline = line;
while (pline+n < pmax) {
i = sscanf(pline += n, SKIPW "initial" NEXTARG LASTARG "%n", string,
value, &n);
if (i != 2)
break;
if (!strcmp(string, "distribution")) {
if (!strcmp(value, "linear")) i = INITIAL_LINEAR;
else if (!strcmp(value, "block")) i = INITIAL_LINEAR;
else if (!strcmp(value, "cyclic")) i = INITIAL_CYCLIC;
else if (!strcmp(value, "file")) i = INITIAL_FILE;
else if (!strcmp(value, "owner")) i = INITIAL_OWNER;
else {
Gen_Error(0, "fatal: bad initial distribution argument");
return 0;
}
pio_info->init_dist_type = i;
}
else if (!strcmp(string, "procs")) {
if (sscanf(value, " %d%n", &pio_info->init_dist_procs, &nv) != 1) {
Gen_Error(0, "fatal: initial procs value must be integal");
return 0;
}
}
else {
Gen_Error(0, "fatal: unrecognizable file type arguments");
return 0;
}
}
}
else if ((strcmp(value, "hypergraph") == 0)
|| (strcmp(value, "matrixmarket") == 0)
|| (strcmp(value, "matrixmarket+") == 0)) {
if (strcmp(value, "hypergraph") == 0){
pio_info->file_type = HYPERGRAPH_FILE;
pio_info->init_dist_type = INITIAL_LINEAR;
pio_info->init_dist_pins = INITIAL_ROW;
}
else if (strcmp(value, "matrixmarket") == 0){
pio_info->file_type = MATRIXMARKET_FILE;
pio_info->init_dist_type = INITIAL_LINEAR;
pio_info->init_dist_pins = INITIAL_ROW;
}
else if (strcmp(value, "matrixmarket+") == 0){
pio_info->file_type = MATRIXMARKET_PLUS_FILE;
pio_info->init_dist_type = INITIAL_LINEAR;
pio_info->init_dist_pins = INITIAL_ROW;
}
pio_info->init_dist_procs = -1;
pio_info->matrix_obj = COLUMNS;
pline = line;
keepreading = 1; /* dummy value to enter loop */
while ((pline+n < pmax) && keepreading) {
/* Check for options starting with "initial" */
keepreading = 0; /* only keep reading if we found new options */
pline += n; /* update pline based on previous token */
n = 0; /* no. of chars read. set to zero in case sscanf fails */
nread = sscanf(pline, SKIPW "initial" NEXTARG LASTARG "%n", string,
value, &n);
keepreading += nread;
if (nread == 2){
if (!strcmp(string, "read")) {
if ((value[0] == 'c') && (value[1] == 'h') &&
(value[2] == 'u') &&(value[3] == 'n') &&(value[4] == 'k')){
pio_info->chunk_reader = 1;
}
}
else if (!strcmp(string, "distribution")) {
if (!strcmp(value, "linear")) i = INITIAL_LINEAR;
else if (!strcmp(value, "block")) i = INITIAL_LINEAR;
else if (!strcmp(value, "cyclic")) i = INITIAL_CYCLIC;
else if (!strcmp(value, "owner")) i = INITIAL_OWNER;
else if (!strcmp(value, "file")) i = INITIAL_FILE;
else {
Gen_Error(0, "fatal: bad initial distribution argument");
return 0;
}
pio_info->init_dist_type = i;
}
else if (!strcmp(string, "pins")) {
if (!strcmp(value, "linear")) i = INITIAL_LINEAR;
else if (!strcmp(value, "block")) i = INITIAL_LINEAR;
else if (!strcmp(value, "cyclic")) i = INITIAL_CYCLIC;
else if (!strcmp(value, "file")) i = INITIAL_FILE;
else if (!strcmp(value, "zero")) i = INITIAL_ZERO;
else if (!strcmp(value, "row")) i = INITIAL_ROW;
else if (!strcmp(value, "rows")) i = INITIAL_ROW;
else if (!strcmp(value, "column")) i = INITIAL_COL;
else if (!strcmp(value, "columns")) i = INITIAL_COL;
else if (!strcmp(value, "col")) i = INITIAL_COL;
else if (!strcmp(value, "cols")) i = INITIAL_COL;
else {
Gen_Error(0, "fatal: bad initial pins argument");
return 0;
}
pio_info->init_dist_pins = i;
}
else if (!strcmp(string, "procs")) {
if (sscanf(value, " %d%n", &pio_info->init_dist_procs, &nv) != 1){
Gen_Error(0, "fatal: initial procs value must be integal");
return 0;
}
}
else {
Gen_Error(0, "fatal: unrecognizable file type arguments");
return 0;
}
}
/* Check for options without "initial" */
pline += n; /* update pline based on previous token */
n = 0; /* set to zero in case sscanf fails */
i = 0;
if (pline < pmax){
nread = sscanf(pline, NEXTARG LASTARG "%n", string,
value, &n);
keepreading += nread;
if (nread == 2){
if (!strcmp(string, "objects")) {
if (!strcmp(value, "rows")) i = ROWS;
else if (!strcmp(value, "columns")) i = COLUMNS;
else if (!strcmp(value, "nonzeros")) i = NONZEROS;
else {
Gen_Error(0, "fatal: bad objects type argument");
return 0;
}
pio_info->matrix_obj = i;
if (pio_info->matrix_obj != COLUMNS &&
pio_info->file_type == MATRIXMARKET_PLUS_FILE) {
Gen_Error(0, "fatal: objects != COLUMNS not supported "
"for MATRIXMARKET_PLUS");
return 0;
}
}
else {
Gen_Error(0, "fatal: unrecognizable file type arguments");
return 0;
}
}
}
}
}
else if (strcmp(value, "nemesisi") == 0) {
pio_info->file_type = NEMESIS_FILE;
pio_info->init_dist_type = INITIAL_FILE;
}
else if ((strcmp(value, "random-triangles") == 0) || (strcmp(value, "random") == 0)) {
/* No input file; generate random coordinates. */
if (strcmp(value, "random-triangles") == 0){
pio_info->file_type = NO_FILE_TRIANGLES;
strcpy(pio_info->pexo_fname, "random-triangles");
}
else{
pio_info->file_type = NO_FILE_POINTS;
strcpy(pio_info->pexo_fname, "random");
}
pio_info->init_dist_type = INITIAL_LINEAR;
pio_info->init_dist_procs = -1;
pio_info->init_size = 100; /* default */
pio_info->init_dim = 3; /* default */
pio_info->init_vwgt_dim = 1; /* default */
pline = line;
while (pline+n < pmax &&
sscanf(pline += n, NEXTARG LASTARG "%n", string, value, &n)==2) {
if (!strcmp(string, "dimension")
&& sscanf(value, "%d%n", &pio_info->init_dim, &nv) == 1)
continue;
else if (!strcmp(string, "obj_weight_dim")
&& sscanf(value, "%d%n", &pio_info->init_vwgt_dim, &nv) == 1)
continue;
else if (!strcmp(string, "size")
&& sscanf(value, "%d%n", &pio_info->init_size, &nv) == 1)
continue;
else {
Gen_Error(0, "fatal: bad file type = random file parameters");
return 0;
}
}
}
else {
Gen_Error(0, "fatal: bad file type parameter");
return 0;
}
}
else if (sscanf(line, " text output" SKIPEQ "%d", &Output.Text) == 1)
continue; /* Generate text output */
else if (sscanf(line, " gnuplot output" SKIPEQ "%d", &Output.Gnuplot) == 1)
continue; /* Generate GNUplot output */
else if (sscanf(line, " nemesis output" SKIPEQ "%d", &Output.Nemesis) == 1)
continue; /* Generate Nemesis output */
else if (sscanf(line, " number of iterations" SKIPEQ "%d",
&Number_Iterations) == 1)
continue; /* The Number of iterations of the balancer to perform */
else if (sscanf(line, " parallel disk info %[= \t\n]%n", dummy, &n) == 1) {
pline = line;
if (sscanf(pline += n, " number = %d%n", &i, &n) != 1) {
Gen_Error(0, "fatal: First sup-option for disk info must be number");
return 0;
}
if (i < 0) {
Gen_Error(0, "fatal: Invalid value for # of raid controllers.");
return 0;
}
pio_info->num_dsk_ctrlrs = i;
/* if number_dsk_ctrlrs = 0, then the input file(s) is in the root */
/* directory given by the parallel disk info, or it is in the same */
/* directory as the executable if nothing is given for the root */
/* infomation. So, no other options can be given when = 0 */
if (pio_info->num_dsk_ctrlrs == 0)
continue;
while (pline+n < pmax) {
i = sscanf(pline += n, NEXTLIST "%n", string, &n) ;
if (i != 1)
break;
if (strcmp(string, "zeros") == 0)
pio_info->zeros = 1;
else if (strcmp(string, "offset") == 0) {
if (sscanf(pline += n, " =%d%n", &pio_info->pdsk_add_fact, &n) != 1
|| pio_info->pdsk_add_fact < 0) {
Gen_Error(0, "fatal: Invalid value for offset.");
return 0;
}
}
else if (strcmp(string, "list") == 0) {
pio_info->dsk_list_cnt = pio_info->num_dsk_ctrlrs;
pio_info->num_dsk_ctrlrs = -1;
/* allocate memory for to hold the values */
pio_info->dsk_list=(int*)malloc(pio_info->dsk_list_cnt*sizeof(int));
for (i = 0; i < pio_info->dsk_list_cnt; i++)
if (pline+n < pmax && sscanf(pline += n, BIGSKIP "%d%n",
&pio_info->dsk_list[i], &n) == 1)
continue;
else {
Gen_Error(0, "Unknown parameter for parallel disk information");
return 0;
}
}
}
}
else if (sscanf(line," parallel file location %[=]%n", dummy, &n)==1) {
pline = line;
while (pline+n < pmax) {
i = sscanf(pline += n, NEXTARG LASTARG "%n", string, value, &n);
if (i != 2)
break;
sscanf(original_line + (pline-line), NEXTARG LASTARG, dummy, value); /* reread value from orig line to preserve case */
if (strcmp(string, "root") == 0)
strcpy(pio_info->pdsk_root, value);
if (strcmp(string, "subdir") == 0) {
strcpy(pio_info->pdsk_subdir, value);
if (value [strlen(value)-1] != '/') {
pio_info->pdsk_subdir [strlen(value)] = '/';
pio_info->pdsk_subdir [strlen(value)+1] = 0;
}
}
}
}
else if (sscanf(line, " plot partitions" SKIPEQ "%d%n",
&Output.Plot_Partitions, &n) == 1)
continue; /* Plot processor numbers or partitions? */
else if (sscanf(line, " plot partition" SKIPEQ "%d%n",
&Output.Plot_Partitions, &n) == 1)
continue; /* Plot processor numbers or partitions? */
else if (sscanf(line, " print mesh info file" SKIPEQ "%d%n",
&Output.Mesh_Info_File, &n) == 1)
continue; /* Generate ASCII mesh file? */
else if (sscanf(line, " test ddirectory" SKIPEQ "%d%n",
&Test.DDirectory, &n) == 1)
continue; /* DDirectory testing flag */
else if (sscanf(line, " test drops" SKIPEQ "%d%n", &Test.Drops, &n) == 1)
continue; /* Box- and Point-drop testing flag */
else if (sscanf (line, " test rcb box" SKIPEQ "%d", &Test.RCB_Box) == 1)
continue; /* Zoltan_RCB_Box testing flag */
else if (sscanf(line, " test generate files" SKIPEQ "%d%n",
&Test.Gen_Files, &n) == 1)
continue; /* file generation testing flag */
else if (sscanf(line, " test generate file" SKIPEQ "%d%n",
&Test.Gen_Files, &n) == 1)
continue; /* file generation testing flag */
else if (sscanf(line, " test local partitions" SKIPEQ "%d%n",
&Test.Local_Partitions, &n) == 1)
continue; /* Unusual Partition generation testing flag */
else if (sscanf(line, " test local partition" SKIPEQ "%d%n",
&Test.Local_Partitions, &n) == 1)
continue; /* Unusual Partition generation testing flag */
else if (sscanf(line, " test fixed objects" SKIPEQ "%d%n",
&Test.Fixed_Objects, &n) == 1)
continue; /* Fixed objects test flag */
else if (sscanf(line, " test fixed object" SKIPEQ "%d%n",
&Test.Fixed_Objects, &n) == 1)
continue; /* Fixed objects test flag */
else if (sscanf(line, " test dynamic weights" SKIPEQ "%f%n",
&Test.Dynamic_Weights, &n) == 1)
continue; /* Dynamic weights; changes between iter. */
else if (sscanf(line, " test dynamic graph" SKIPEQ "%f%n",
&Test.Dynamic_Graph, &n) == 1)
continue; /* Dynamic graph; edges/verts change between iter. */
else if (sscanf(line, " test multi callbacks" SKIPEQ "%d%n",
&Test.Multi_Callbacks, &n) == 1)
continue; /* List-based (MULTI) callback function testing */
else if (sscanf(line, " test multi callback" SKIPEQ "%d%n",
&Test.Multi_Callbacks, &n) == 1)
continue; /* List-based (MULTI) callback function testing */
else if (sscanf(line, " test graph callbacks" SKIPEQ "%d%n",
&Test.Graph_Callbacks, &n) == 1)
continue; /* Graph-based callback function testing */
else if (sscanf(line, " test graph callback" SKIPEQ "%d%n",
&Test.Graph_Callbacks, &n) == 1)
continue; /* Graph-based callback function testing */
else if (sscanf(line, " test hypergraph callbacks" SKIPEQ "%d%n",
&Test.Hypergraph_Callbacks, &n) == 1)
continue; /* HyperGraph-based callback function testing */
else if (sscanf(line, " test hypergraph callback" SKIPEQ "%d%n",
&Test.Hypergraph_Callbacks, &n) == 1)
continue; /* HyperGraph-based callback function testing */
else if (sscanf(line, " test no global objects" SKIPEQ "%d%n",
&Test.No_Global_Objects, &n) == 1)
continue; /* HyperGraph-based callback function testing */
else if (sscanf(line, " test null export lists" SKIPEQ "%d%n", &i,&n)==1) {
if (i == 1) /* Null export lists to Help_Migrate testing */
Test.Null_Lists = EXPORT_LISTS;
}
else if (sscanf(line, " test null export list" SKIPEQ "%d%n", &i,&n) == 1) {
if (i == 1) /* Null export lists to Help_Migrate testing */
Test.Null_Lists = EXPORT_LISTS;
}
else if (sscanf(line, " test null import lists" SKIPEQ "%d%n", &i,&n) == 1){
if (i == 1) /* Null import lists to Help_Migrate testing */
Test.Null_Lists = IMPORT_LISTS;
}
else if (sscanf(line, " test null import list" SKIPEQ "%d%n", &i,&n) == 1) {
if (i == 1) /* Null import lists to Help_Migrate testing */
Test.Null_Lists = IMPORT_LISTS;
}
else if (sscanf(line," zdrive action" SKIPEQ "%d%n",&Driver_Action,&n) == 1)
continue; /* zdrive action: Do coloring, load-balancing or ordering? */
else if (sscanf(line," zdrive debug level" SKIPEQ "%d%n",
&Debug_Driver,&n)==1)
continue; /* The Debug reporting level */
else if (sscanf(line, " zoltan parameter%*[^=]%[=]%n", string, &n) == 1) {
pline = line;
while (pline+n < pmax && sscanf(pline += n, NEXTARG LASTARG "%n",
prob->params[prob->num_params].Name,
prob->params[prob->num_params].Val, &n)==2) {
prob->params[prob->num_params++].Index = -1;
prob->params = (Parameter_Pair*) realloc(prob->params,
(prob->num_params+1) * sizeof(Parameter_Pair));
if (prob->params == NULL) {
Gen_Error(0, "fatal: realloc failed for Zoltan Parameters");
return 0;
}
}
}
else if (sscanf(line," zoltan vector parameters" LASTARG "%n",string,&n)==1
|| sscanf(line," zoltan vector parameter" LASTARG "%n",string,&n)==1
|| sscanf(line," zoltan parameter vectors" LASTARG "%n",string,&n)==1
|| sscanf(line," zoltan parameter vector" LASTARG "%n",string,&n)==1)
{
pline = line;
i = 0;
while (pline+n < pmax && sscanf(pline += n, BIGSKIP "%[^,\t\n) ]%n",
prob->params[prob->num_params].Val, &n)==1) {
prob->params[prob->num_params].Index = i++;
strcpy(prob->params[prob->num_params++].Name, string);
prob->params = (Parameter_Pair*) realloc(prob->params,
(prob->num_params+1) * sizeof(Parameter_Pair));
if (prob->params == NULL) {
Gen_Error(0, "fatal, realloc failed for Zoltan Parameters");
return 0;
}
}
}
else if (sscanf(line, " zoltanparams file" SKIPEQ "%s", string) == 1) {
/* specify zoltanParams-format filename to be read later --
included to support hierarchical balancing tests */
strcpy(prob->zoltanParams_file, string);
}
else {
if (undef){
if (undef->list_size < UNDEFINED_LIST_MAX){
strncpy((char *)(undef->line + undef->list_size), line,
UNDEFINED_LENGTH_MAX-1);
undef->list_size++;
}
else{
char buffer[200];
sprintf (buffer,
"fatal error, too many unrecognized commands: %s\n", line);
Gen_Error(0, buffer);
return 0;
}
}
else{
printf("Warning: ignoring unrecognized line in input file:\n\t%s\n",
line);
}
}
}
if (prob->num_params == 0) {
free (prob->params);
prob->params = NULL;
}
fclose (file_cmd);
return 1;
}
int check_inp (
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info
)
{
/* check for the parallel Nemesis file for proc 0 */
if (strlen(pio_info->pexo_fname) <= 0) {
Gen_Error (0, "fatal: must specify file base name");
return 0;
}
/* default file type is nemesis */
if (pio_info->file_type < 0)
pio_info->file_type = NEMESIS_FILE;
#ifndef ZOLTAN_NEMESIS
/* if not compiling with the ZOLTAN_NEMESIS flag (i.e., not linking with */
/* Nemesis library), can't use NEMESIS_FILE file type. */
if (pio_info->file_type == NEMESIS_FILE) {
Gen_Error(0, "fatal: must compile for and link with Nemesis libraries for"
"Nemesis file types");
return 0;
}
#endif
/* check that there is a list of disks, or a number of raids */
if ((pio_info->dsk_list_cnt <= 0) && (pio_info->num_dsk_ctrlrs < 0))
pio_info->num_dsk_ctrlrs = 0; /* default to single directory */
/* default is not to have preceeding 0's in the disk names */
if (pio_info->zeros < 0)
pio_info->zeros = 0;
/* most systems that we deal with start their files systems with 1 not 0 */
if (pio_info->pdsk_add_fact < 0)
pio_info->pdsk_add_fact = 1;
/* if there are parallel disks, then specify the root and subdir locations */
if (pio_info->num_dsk_ctrlrs > 0 || pio_info->dsk_list_cnt > 0) {
if (strlen(pio_info->pdsk_root) == 0) {
Gen_Error(0, "fatal: must specify parallel disk root name");
return 0;
}
if (strlen(pio_info->pdsk_subdir) == 0) {
Gen_Error(0, "fatal: must specify parallel disk subdirectory");
return 0;
}
}
else
if (strlen(pio_info->pdsk_root) == 0)
strcpy(pio_info->pdsk_root, "."); /* default is execution directory */
/* Check Zoltan specs to insure a load-balancing method is selected */
if (strlen(prob->method) == 0) {
Gen_Error(0, "fatal: load balance method must be specified");
return 0;
}
return 1;
}
void brdcst_cmd_info (
int Proc,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
MESH_INFO_PTR mesh
)
{
int ctrl_id, j, k;
int size;
int int_params[19]; /* Make sure this array is large enough */
float float_params[2]; /* Make sure this array is large enough */
k = 0;
float_params[k++] = Test.Dynamic_Weights;
float_params[k++] = Test.Dynamic_Graph;
MPI_Bcast (float_params, k, MPI_FLOAT, 0, MPI_COMM_WORLD);
k = 0;
Test.Dynamic_Weights = float_params[k++];
Test.Dynamic_Graph = float_params[k++];
j = 0;
int_params[j++] = Debug_Driver;
int_params[j++] = Test.DDirectory;
int_params[j++] = Test.Local_Partitions;
int_params[j++] = Test.Fixed_Objects;
int_params[j++] = Test.Multi_Callbacks;
int_params[j++] = Test.Graph_Callbacks;
int_params[j++] = Test.Hypergraph_Callbacks;
int_params[j++] = Test.No_Global_Objects;
int_params[j++] = Test.Null_Lists;
int_params[j++] = Output.Text;
int_params[j++] = Output.Gnuplot;
int_params[j++] = Output.Nemesis;
int_params[j++] = Output.Plot_Partitions;
int_params[j++] = Output.Mesh_Info_File;
int_params[j++] = Number_Iterations;
int_params[j++] = Driver_Action;
int_params[j++] = Test.Drops;
int_params[j++] = Test.RCB_Box;
int_params[j++] = Test.Gen_Files;
MPI_Bcast (int_params, j, MPI_INT, 0, MPI_COMM_WORLD);
j = 0;
Debug_Driver = int_params[j++];
Test.DDirectory = int_params[j++];
Test.Local_Partitions = int_params[j++];
Test.Fixed_Objects = int_params[j++];
Test.Multi_Callbacks = int_params[j++];
Test.Graph_Callbacks = int_params[j++];
Test.Hypergraph_Callbacks = int_params[j++];
Test.No_Global_Objects = int_params[j++];
Test.Null_Lists = int_params[j++];
Output.Text = int_params[j++];
Output.Gnuplot = int_params[j++];
Output.Nemesis = int_params[j++];
Output.Plot_Partitions = int_params[j++];
Output.Mesh_Info_File = int_params[j++];
Number_Iterations = int_params[j++];
Driver_Action = int_params[j++];
Test.Drops = int_params[j++];
Test.RCB_Box = int_params[j++];
Test.Gen_Files = int_params[j++];
MPI_Bcast (pio_info, sizeof(PARIO_INFO), MPI_BYTE, 0, MPI_COMM_WORLD);
if (pio_info->dsk_list_cnt > 0) {
if (Proc != 0)
pio_info->dsk_list = (int*) malloc (pio_info->dsk_list_cnt*sizeof(int));
MPI_Bcast (pio_info->dsk_list, pio_info->dsk_list_cnt, MPI_INT, 0,
MPI_COMM_WORLD);
}
/* and broadcast the problem specifications */
MPI_Bcast (prob, sizeof(PROB_INFO), MPI_BYTE, 0, MPI_COMM_WORLD);
if (prob->num_params > 0) {
size = prob->num_params * sizeof(Parameter_Pair);
if (Proc != 0)
prob->params = (Parameter_Pair*) malloc(size);
MPI_Bcast (prob->params, size, MPI_CHAR, 0, MPI_COMM_WORLD);
}
/* now calculate where the file for this processor is */
if (pio_info->dsk_list_cnt <= 0) {
if (pio_info->num_dsk_ctrlrs > 0) {
ctrl_id = (Proc % pio_info->num_dsk_ctrlrs);
pio_info->rdisk = ctrl_id + pio_info->pdsk_add_fact;
}
}
else {
ctrl_id = Proc % pio_info->dsk_list_cnt;
pio_info->rdisk = pio_info->dsk_list[ctrl_id];
}
}
/*----------------------------------------------------------------------------
* Function which generates the name of a parallel file for a
* particular processor. The function does this by appending
* "N.p" to the end of the input parameter "scalar_fname", where:
*
* N - The number of processors utilized
* p - The processor ID.
*
* In addition, the location of the parallel disk system is prepended
* to each file name.
*---------------------------------------------------------------------------
* Example:
*
* scalar_fname = "Parallel-exoII-" (Input)
* par_fname = "/raid/io_01/tmp/rf_crew/Parallel-exoII-8.0" (Output)
*
* where, for this example:
*
* N = 8 processors
* p = 0 particular processor ID
*
*----------------------------------------------------------------------------
* Determine the number of digits needed to specify the processor ID.
* This allows
* numbers like 01-99, i.e., prepending zeros to the name to preserve proper
* alphabetic sorting of the files. Comments by Gary Hennigan (1421) */
void gen_par_filename (
char *scalar_fname,
char *par_fname,
PARIO_INFO_PTR pio_info,
int myproc,
int nprocs
)
{
double dnprocs = (double)nprocs;
double dndisks = (double)pio_info->num_dsk_ctrlrs;
if (pio_info->num_dsk_ctrlrs <= 0)
sprintf(par_fname, "%s/%s.%d.%0*d", pio_info->pdsk_root, scalar_fname,
nprocs, 1+(int)log10(dnprocs), myproc);
else if (pio_info->zeros)
sprintf(par_fname, "%s%0*d/%s%s.%d.%0*d", pio_info->pdsk_root,
pio_info->num_dsk_ctrlrs<9 ? 2 : 1+(int)log10(dndisks),
pio_info->rdisk, pio_info->pdsk_subdir, scalar_fname, nprocs,
1 + (int) log10(dnprocs), myproc);
else
sprintf(par_fname, "%s%d/%s/%s.%d.%0*d", pio_info->pdsk_root,
pio_info->rdisk, pio_info->pdsk_subdir, scalar_fname, nprocs,
1 + (int) log10(dnprocs), myproc);
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,281 @@
/*
* @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
*/
#ifndef _DR_INPUT_CONST_H_
#define _DR_INPUT_CONST_H_
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#ifndef _DR_CONST_H
#include "dr_const.h"
#endif
#include "dr_compress_const.h"
/* define the input file types */
#define NO_FILE_POINTS 0
#define NO_FILE_TRIANGLES 1
#define NO_FILE_GRAPH 2
#define NEMESIS_FILE 3
#define CHACO_FILE 4
#define HYPERGRAPH_FILE 5
#define MATRIXMARKET_FILE 6
#define MATRIXMARKET_PLUS_FILE 7
/* define matrix_obj options */
#define ROWS 0
#define COLUMNS 1
#define NONZEROS 2
/* define the initial distribution types - for Chaco file vertices
and for hypergraph file pins */
#define INITIAL_FILE 0 /* Chaco vertices or hypergraph pins */
#define INITIAL_LINEAR 1 /* Chaco vertices or hypergraph pins */
#define INITIAL_CYCLIC 2 /* Chaco vertices or hypergraph pins */
#define INITIAL_OWNER 3 /* Chaco vertices */
#define INITIAL_ROW 4 /* hypergraph pins */
#define INITIAL_COL 5 /* hypergraph pins */
#define INITIAL_ZERO 6 /* hypergraph pins */
#define INITIAL_NO_DIST 7 /* distribution not necessary */
#define MAX_INPUT_STR_LN 4096 /* maximum string length for read_string() */
/* Structure used to store the information necessary for parallel I/O. */
struct Parallel_IO
{
int dsk_list_cnt;
int *dsk_list;
int rdisk;
int num_dsk_ctrlrs; /* The number of disk controllers. */
int pdsk_add_fact; /* The offset from zero used by the */
/* the target machine. */
int zeros; /* 1 - if the target machine uses leading zeros when */
/* designating the disk number (eg - the paragon */
/* uses /pfs/io_01) */
/* 0 - if it does not (eg - the tflop uses */
/* /pfs/tmp_1) */
int file_type; /* input file type */
ZOLTAN_FILETYPE file_comp; /* whether the file is compressed and how */
int chunk_reader; /* for very large matrix market files */
int init_dist_type; /* Flag indicating how input objects
should be initially distributed. */
int init_dist_procs; /* How many procs to use in
the initial distribution. */
ZOLTAN_ID_TYPE init_size; /* For NO_FILE_* (random) input, the
no. of objects to be created. */
int init_dim; /* For NO_FILE_* (random) input, the
dimension of the problem (1, 2, or 3D) */
int init_vwgt_dim; /* For NO_FILE_* (random) input, the
no. of weights per object. */
int matrix_obj; /* What are the objects to be balanced
for a sparse matrix? (ROWS, COLUMNS) */
int init_dist_pins; /* For hypergraphs, how should pins be
initially distributed. */
/* The root location of the parallel disks */
char pdsk_root[FILENAME_MAX+1];
/* The subdirectory to write files to */
char pdsk_subdir[FILENAME_MAX+1];
/* The base name of the input file. */
char pexo_fname[FILENAME_MAX+1];
};
typedef struct Parallel_IO PARIO_INFO;
typedef struct Parallel_IO *PARIO_INFO_PTR;
/*
* Generic list of options for programs that want to use
* zdrive style of input file.
*/
#define UNDEFINED_LIST_MAX 20
#define UNDEFINED_LENGTH_MAX 128
struct ParameterList
{
int list_size;
char line[UNDEFINED_LIST_MAX][UNDEFINED_LENGTH_MAX];
};
typedef struct ParameterList UNDEFINED_INFO;
typedef struct ParameterList *UNDEFINED_INFO_PTR;
/* Function prototypes */
extern int read_cmd_file(
const char *filename,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
UNDEFINED_INFO_PTR undef
);
extern int check_inp(
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info
);
extern void brdcst_cmd_info(
int Proc,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
MESH_INFO_PTR mesh
);
extern void gen_par_filename(
char *scalar_fname,
char *par_fname,
PARIO_INFO_PTR pio_info,
int proc_for,
int nprocs
);
extern int read_exoII_file(
int Proc,
int Num_Proc,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
MESH_INFO_PTR mesh
);
extern int write_elem_vars(
int Proc,
MESH_INFO_PTR mesh,
PARIO_INFO_PTR pio_info,
int num_exp,
ZOLTAN_ID_PTR exp_gids,
int *exp_procs,
int *exp_to_part
);
extern int read_chaco_file(
int Proc,
int Num_Proc,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
MESH_INFO_PTR mesh
);
extern int read_hypergraph_file(
int Proc,
int Num_Proc,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
MESH_INFO_PTR mesh
);
extern int read_mm_file(
int Proc,
int Num_Proc,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
MESH_INFO_PTR mesh
);
extern void mm_cleanup(MESH_INFO_PTR);
extern int read_mtxplus_file(
int Proc,
int Num_Proc,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
MESH_INFO_PTR mesh
);
extern int create_random_triangles(
int Proc,
int Num_Proc,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
MESH_INFO_PTR mesh
);
extern int create_random_input(
int Proc,
int Num_Proc,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
MESH_INFO_PTR mesh
);
extern int create_a_graph(
int Proc,
int Num_Proc,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
MESH_INFO_PTR mesh
);
extern int chaco_fill_elements(int, int, PROB_INFO_PTR,
MESH_INFO_PTR, PARIO_INFO_PTR,
int, int, int *,
int *, int, float *, int, float *, int,
float *, float *, float *, short *, int);
extern int chaco_setup_mesh_struct(int, int, PROB_INFO_PTR,
MESH_INFO_PTR, PARIO_INFO_PTR ,
int, int, int *,
int *, int, float *, int, float *, int,
float *, float *, float *, short *, int, int);
extern void chaco_init_local_ids(int **, int **, int *, int *, int *,
short *, int);
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif
#endif /* _DR_INPUT_CONST_H_ */

View File

@ -0,0 +1,277 @@
/*
* @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
*/
#ifndef _DR_INPUT_CONST_H_
#define _DR_INPUT_CONST_H_
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#ifndef _DR_CONST_H
#include "dr_const.h"
#endif
/****************************************************************************/
/* ALTERNATE FILE FOR SHOCKSTEM ADAPTIVE MESH REFINEMENT EXPERIMENTS ONLY. */
/* DO NOT COMMIT AS A REGULAR DRIVER FILE. */
/****************************************************************************/
/* define the input file types */
#define NO_FILE_POINTS 0
#define NO_FILE_TRIANGLES 1
#define NEMESIS_FILE 2
#define CHACO_FILE 3
#define HYPERGRAPH_FILE 4
#define MATRIXMARKET_FILE 5
#define MATRIXMARKET_PLUS_FILE 6
/* define matrix_obj options */
#define ROWS 0
#define COLUMNS 1
#define NONZEROS 2
/* define the matrix partitioning approach for LB_METHOD=sparse_matrix */
#define MP_ROWS 1
#define MP_COLS 2
/* define the initial distribution types - for Chaco file vertices
and for hypergraph file pins */
#define INITIAL_FILE 0 /* Chaco vertices or hypergraph pins */
#define INITIAL_LINEAR 1 /* Chaco vertices or hypergraph pins */
#define INITIAL_CYCLIC 2 /* Chaco vertices or hypergraph pins */
#define INITIAL_OWNER 3 /* Chaco vertices */
#define INITIAL_ROW 4 /* hypergraph pins */
#define INITIAL_COL 5 /* hypergraph pins */
#define INITIAL_ZERO 6 /* hypergraph pins */
#define MAX_INPUT_STR_LN 4096 /* maximum string length for read_string() */
/* Structure used to store the information necessary for parallel I/O. */
struct Parallel_IO
{
int dsk_list_cnt;
int *dsk_list;
int rdisk;
int num_dsk_ctrlrs; /* The number of disk controllers. */
int pdsk_add_fact; /* The offset from zero used by the */
/* the target machine. */
int zeros; /* 1 - if the target machine uses leading zeros when */
/* designating the disk number (eg - the paragon */
/* uses /pfs/io_01) */
/* 0 - if it does not (eg - the tflop uses */
/* /pfs/tmp_1) */
int file_type; /* input file type */
int file_comp; /* wether the file is compressed and how */
int chunk_reader; /* for very large matrix market files */
int init_dist_type; /* Flag indicating how input objects
should be initially distributed. */
int init_dist_procs; /* How many procs to use in
the initial distribution. */
int init_size; /* For NO_FILE_* (random) input, the
no. of objects to be created. */
int init_dim; /* For NO_FILE_* (random) input, the
dimension of the problem (1, 2, or 3D) */
int init_vwgt_dim; /* For NO_FILE_* (random) input, the
no. of weights per object. */
int matrix_obj; /* What are the objects to be balanced
for a sparse matrix? (ROWS, COLUMNS) */
int init_dist_pins; /* For hypergraphs, how should pins be
initially distributed. */
/* The root location of the parallel disks */
char pdsk_root[FILENAME_MAX+1];
/* The subdirectory to write files to */
char pdsk_subdir[FILENAME_MAX+1];
/* The base name of the input file. */
char pexo_fname[FILENAME_MAX+1];
};
typedef struct Parallel_IO PARIO_INFO;
typedef struct Parallel_IO *PARIO_INFO_PTR;
/*
* Generic list of options for programs that want to use
* zdrive style of input file.
*/
#define UNDEFINED_LIST_MAX 20
#define UNDEFINED_LENGTH_MAX 128
struct ParameterList
{
int list_size;
char line[UNDEFINED_LIST_MAX][UNDEFINED_LENGTH_MAX];
};
typedef struct ParameterList UNDEFINED_INFO;
typedef struct ParameterList *UNDEFINED_INFO_PTR;
/* Function prototypes */
extern int read_cmd_file(
const char *filename,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
UNDEFINED_INFO_PTR undef
);
extern int check_inp(
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info
);
extern void brdcst_cmd_info(
int Proc,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
MESH_INFO_PTR mesh
);
extern void gen_par_filename(
char *scalar_fname,
char *par_fname,
PARIO_INFO_PTR pio_info,
int proc_for,
int nprocs
);
extern int read_exoII_file(
int Proc,
int Num_Proc,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
MESH_INFO_PTR mesh
);
extern int write_elem_vars(
int Proc,
MESH_INFO_PTR mesh,
PARIO_INFO_PTR pio_info,
int num_exp,
ZOLTAN_ID_PTR exp_gids,
int *exp_procs,
int *exp_to_part
);
extern int read_chaco_file(
int Proc,
int Num_Proc,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
MESH_INFO_PTR mesh,
MESH_INFO_PTR previous_mesh
);
extern int read_hypergraph_file(
int Proc,
int Num_Proc,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
MESH_INFO_PTR mesh
);
extern int read_mm_file(
int Proc,
int Num_Proc,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
MESH_INFO_PTR mesh
);
extern int read_mtxplus_file(
int Proc,
int Num_Proc,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
MESH_INFO_PTR mesh
);
extern int create_random_triangles(
int Proc,
int Num_Proc,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
MESH_INFO_PTR mesh
);
extern int create_random_input(
int Proc,
int Num_Proc,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
MESH_INFO_PTR mesh
);
extern int chaco_fill_elements(int, int, PROB_INFO_PTR,
MESH_INFO_PTR, int, int, int *,
int *, int, float *, int, float *, int,
float *, float *, float *, short *, int);
extern int chaco_setup_mesh_struct(int, int, PROB_INFO_PTR,
MESH_INFO_PTR, int, int, int *,
int *, int, float *, int, float *, int,
float *, float *, float *, short *, int, int);
extern void chaco_init_local_ids(int **, int **, int *, int *, int *, int,
short *, int);
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif
#endif /* _DR_INPUT_CONST_H_ */

2612
thirdParty/Zoltan/src/driver/dr_loadbal.c vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,89 @@
/*
* @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
*/
#ifndef _DR_LOADBAL_CONST_H_
#define _DR_LOADBAL_CONST_H_
#include "dr_input_const.h"
#ifdef __cplusplus
#include "zoltan_cpp.h"
#define ZOLTAN_STRUCT Zoltan &
extern "C" {
#else
#define ZOLTAN_STRUCT struct Zoltan_Struct *
#endif
extern int setup_zoltan(ZOLTAN_STRUCT, int, PROB_INFO_PTR, MESH_INFO_PTR,
PARIO_INFO_PTR);
extern void setup_fixed_obj(MESH_INFO_PTR, int);
extern int run_zoltan(ZOLTAN_STRUCT, int, PROB_INFO_PTR, MESH_INFO_PTR,
PARIO_INFO_PTR);
extern int migrate_elements(int, MESH_INFO_PTR, ZOLTAN_STRUCT,
int, int,
int, ZOLTAN_ID_PTR, ZOLTAN_ID_PTR, int *, int *,
int, ZOLTAN_ID_PTR, ZOLTAN_ID_PTR, int *, int *);
extern ELEM_INFO *search_by_global_id(MESH_INFO *, ZOLTAN_ID_TYPE, int *);
extern ZOLTAN_OBJ_SIZE_FN migrate_elem_size;
extern ZOLTAN_OBJ_SIZE_MULTI_FN migrate_elem_size_multi;
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif
#endif /* _DR_LOADBAL_CONST_H_ */

916
thirdParty/Zoltan/src/driver/dr_main.c vendored Normal file
View File

@ -0,0 +1,916 @@
/*
* @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
*/
#include <mpi.h>
/*--------------------------------------------------------------------------*/
/* Purpose: Driver for dynamic load-balance library, ZOLTAN. */
/* */
/*--------------------------------------------------------------------------*/
/* Author(s): Matthew M. St.John (9226) */
/*--------------------------------------------------------------------------*/
/* Revision History: */
/* */
/* 30 March 1999: Date of creation */
/*--------------------------------------------------------------------------*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include "dr_const.h"
#include "dr_input_const.h"
#include "dr_loadbal_const.h"
#include "dr_util_const.h"
#include "dr_output_const.h"
#include "dr_err_const.h"
#include "dr_elem_util_const.h"
#include "dr_dd.h"
#include "dr_compress_const.h"
/* #define IGNORE_FIRST_ITERATION_STATS */
/* #define RANDOM_DIST */
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
extern void Zoltan_write_linux_meminfo(int append, char *msg, int committedOnly);
int Debug_Driver = 1;
int Number_Iterations = 1;
int Driver_Action = 1; /* Flag indicating coloring, load-balancing or ordering. */
int Debug_Chaco_Input = 0;
int Chaco_In_Assign_Inv = 0;
struct Test_Flags Test;
struct Output_Flags Output;
double Total_Partition_Time = 0.0; /* Total over Number_Iterations */
int CITESEER[200]; /* Hack for Citeseer Vtx_Inc experiments */
static int read_mesh(int, int, PROB_INFO_PTR, PARIO_INFO_PTR, MESH_INFO_PTR);
static void print_input_info(FILE *, int, PROB_INFO_PTR, PARIO_INFO_PTR, float );
static void initialize_mesh(MESH_INFO_PTR, int proc);
static void remove_random_vertices(MESH_INFO_PTR mesh, int iter, float factor);
#ifdef DEBUG_READ_MESH
static void print_mesh(int proc, MESH_INFO_PTR m, int *tp, int *the, int *tv);
#endif
int my_rank=-1;
void meminfo_signal_handler(int sig)
{
char msg[128];
sprintf(msg,"(%d) Received signal %d\n",my_rank,sig);
/* Signal handler for Linux that helps us to understand */
/* whether failure was due to insufficient memory. */
signal(SIGINT, SIG_IGN);
signal(SIGTERM, SIG_IGN);
signal(SIGABRT, SIG_IGN);
signal(SIGSEGV, SIG_IGN);
signal(SIGFPE, SIG_IGN);
Zoltan_write_linux_meminfo(0, msg,0);
exit(sig);
}
#ifdef VAMPIR
#include <VT.h>
#endif
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
int main(int argc, char *argv[])
{
/* Local declarations. */
struct Zoltan_Struct *zz = NULL;
char *cmd_file;
char cmesg[256]; /* for error messages */
float version;
int Proc, Num_Proc;
int iteration;
int error, gerror;
int print_output = 1;
MESH_INFO mesh; /* mesh information struct */
PARIO_INFO pio_info;
PROB_INFO prob;
/***************************** BEGIN EXECUTION ******************************/
/* initialize MPI */
MPI_Init(&argc, &argv);
#ifdef VAMPIR
VT_initialize(&argc, &argv);
#endif
/* get some machine information */
MPI_Comm_rank(MPI_COMM_WORLD, &Proc);
MPI_Comm_size(MPI_COMM_WORLD, &Num_Proc);
my_rank = Proc;
#ifdef HOST_LINUX
signal(SIGSEGV, meminfo_signal_handler);
signal(SIGINT, meminfo_signal_handler);
signal(SIGTERM, meminfo_signal_handler);
signal(SIGABRT, meminfo_signal_handler);
signal(SIGFPE, meminfo_signal_handler);
#endif
#ifdef ZOLTAN_PURIFY
printf("%d of %d ZDRIVE LAUNCH pid = %d file = %s\n",
Proc, Num_Proc, getpid(), argv[1]);
#endif
/* Initialize flags */
Test.DDirectory = 0;
Test.Local_Parts = 0;
Test.Fixed_Objects = 0;
Test.Drops = 0;
Test.RCB_Box = 0;
Test.Multi_Callbacks = 0;
Test.Graph_Callbacks = 1;
Test.Hypergraph_Callbacks = 1;
Test.Gen_Files = 0;
Test.Null_Lists = NO_NULL_LISTS;
Test.Dynamic_Weights = .0;
Test.Dynamic_Graph = .0;
Test.Vtx_Inc = 0;
Output.Text = 1;
Output.Gnuplot = 0;
Output.Nemesis = 0;
Output.Plot_Partition = 0;
Output.Mesh_Info_File = 0;
/* Interpret the command line */
switch(argc)
{
case 1:
cmd_file = "zdrive.inp";
break;
case 2:
cmd_file = argv[1];
break;
default:
fprintf(stderr, "MAIN: ERROR in command line,");
if(Proc == 0)
{
fprintf(stderr, " usage:\n");
fprintf(stderr, "\t%s [command file]", DRIVER_NAME);
}
exit(1);
break;
}
/* initialize Zoltan */
if ((error = Zoltan_Initialize(argc, argv, &version)) != ZOLTAN_OK) {
sprintf(cmesg, "fatal: Zoltan_Initialize returned error code, %d", error);
Gen_Error(0, cmesg);
error_report(Proc);
print_output = 0;
goto End;
}
/* initialize some variables */
initialize_mesh(&mesh, Proc);
pio_info.dsk_list_cnt = -1;
pio_info.file_comp = STANDARD;
pio_info.num_dsk_ctrlrs = -1;
pio_info.pdsk_add_fact = -1;
pio_info.zeros = -1;
pio_info.file_type = -1;
pio_info.chunk_reader = 0;
pio_info.init_dist_type = -1;
pio_info.init_size = ZOLTAN_ID_INVALID;
pio_info.init_dim = -1;
pio_info.init_vwgt_dim = -1;
pio_info.init_dist_pins = -1;
pio_info.pdsk_root[0] = '\0';
pio_info.pdsk_subdir[0] = '\0';
pio_info.pexo_fname[0] = '\0';
prob.method[0] = '\0';
prob.num_params = 0;
prob.params = NULL;
/* Read in the ascii input file */
error = gerror = 0;
if (Proc == 0) {
printf("\n\nReading the command file, %s\n", cmd_file);
if (!read_cmd_file(cmd_file, &prob, &pio_info, NULL)) {
sprintf(cmesg,"fatal: Could not read in the command file"
" \"%s\"!\n", cmd_file);
Gen_Error(0, cmesg);
error_report(Proc);
print_output = 0;
error = 1;
}
if (!check_inp(&prob, &pio_info)) {
Gen_Error(0, "fatal: Error in user specified parameters.\n");
error_report(Proc);
print_output = 0;
error = 1;
}
print_input_info(stdout, Num_Proc, &prob, &pio_info, version);
}
MPI_Allreduce(&error, &gerror, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
if (gerror) goto End;
/* broadcast the command info to all of the processor */
brdcst_cmd_info(Proc, &prob, &pio_info, &mesh);
Zoltan_Set_Param(NULL, "DEBUG_MEMORY", "1");
print_output = Output.Text;
/*
* Create a Zoltan structure.
*/
if ((zz = Zoltan_Create(MPI_COMM_WORLD)) == NULL) {
Gen_Error(0, "fatal: NULL returned from Zoltan_Create()\n");
return 0;
}
if (!setup_zoltan(zz, Proc, &prob, &mesh, &pio_info)) {
Gen_Error(0, "fatal: Error returned from setup_zoltan\n");
error_report(Proc);
print_output = 0;
goto End;
}
/* srand(Proc); Different seeds on different procs. */
srand(1); /* Same seed everywhere. */
if (Test.Dynamic_Weights){
/* Set obj weight dim to 1; can be overridden by user parameter */
Zoltan_Set_Param(zz, "OBJ_WEIGHT_DIM", "1");
}
/* Loop over read and balance for a number of iterations */
/* (Useful for testing REUSE parameters in Zoltan.) */
for (iteration = 1; iteration <= Number_Iterations; iteration++) {
if (Proc == 0) {
printf("Starting iteration %d\n", iteration);
fflush(stdout);
}
/*
* now read in the mesh and element information.
* This is the only function call to do this. Upon return,
* the mesh struct and the elements array should be filled.
*/
if (iteration == 1) {
if (!read_mesh(Proc, Num_Proc, &prob, &pio_info, &mesh)) {
Gen_Error(0, "fatal: Error returned from read_mesh\n");
error_report(Proc);
print_output = 0;
goto End;
}
/*
* Create a Zoltan DD for tracking elements during repartitioning.
*/
if (mesh.data_type == ZOLTAN_HYPERGRAPH && !build_elem_dd(&mesh)) {
Gen_Error(0, "fatal: Error returned from build_elem_dd\n");
error_report(Proc);
print_output = 0;
goto End;
}
}
#ifdef KDDKDD_COOL_TEST
/* KDD Cool test of changing number of partitions */
sprintf(cmesg, "%d", Num_Proc * iteration);
Zoltan_Set_Param(zz, "NUM_GLOBAL_PARTS", cmesg);
#endif
/*
* Produce files to verify input.
*/
if (iteration == 1) {
if (Debug_Driver > 2) {
if (!output_results(cmd_file,"in",Proc,Num_Proc,&prob,&pio_info,&mesh)){
Gen_Error(0, "fatal: Error returned from output_results\n");
error_report(Proc);
}
if (Output.Gnuplot)
if (!output_gnu(cmd_file,"in",Proc,Num_Proc,&prob,&pio_info,&mesh)) {
Gen_Error(0, "warning: Error returned from output_gnu\n");
error_report(Proc);
}
}
if (Test.Vtx_Inc<0){
/* Read Citeseer data from file */
FILE *fp;
int i=0;
if (Proc==0){
fp = fopen("months.txt", "r");
if (!fp)
printf("ERROR: Couldn't open file months.txt\n");
while (fscanf(fp, "%d", &CITESEER[i])==1){
++i;
}
fclose(fp);
}
MPI_Bcast (CITESEER, 200, MPI_INT, 0, MPI_COMM_WORLD);
}
}
if (Test.Dynamic_Graph > 0.0){
if (mesh.data_type == ZOLTAN_GRAPH) {
remove_random_vertices(&mesh, iteration, Test.Dynamic_Graph);
}
else{
Gen_Error(0, "fatal: \"test dynamic graph\" only works on graphs, not hypergraphs\n");
error_report(Proc);
print_output = 0;
goto End;
}
}
if (Test.Vtx_Inc){
if (mesh.data_type == ZOLTAN_HYPERGRAPH ) {
if (Test.Vtx_Inc>0)
mesh.visible_nvtx += Test.Vtx_Inc; /* Increment uniformly */
else
mesh.visible_nvtx = CITESEER[iteration-1]; /* Citeseer document matrix. */
}
else{
Gen_Error(0, "fatal: \"vertex increment\" only works on hypergraphs\n");
error_report(Proc);
print_output = 0;
goto End;
}
}
/*
* now run Zoltan to get a new load balance and perform
* the migration
*/
#ifdef IGNORE_FIRST_ITERATION_STATS
if (iteration == 1) {
/* Exercise partitioner once on Tbird because first run is slow. */
/* Lee Ann suspects Tbird is loading shared libraries. */
struct Zoltan_Struct *zzcopy;
zzcopy = Zoltan_Copy(zz);
/* Don't do any migration or accumulate any stats. */
if (Proc == 0) printf("%d KDDKDD IGNORING FIRST ITERATION STATS\n", Proc);
Zoltan_Set_Param(zzcopy, "RETURN_LISTS", "NONE");
Zoltan_Set_Param(zzcopy, "FINAL_OUTPUT", "0");
Zoltan_Set_Param(zzcopy, "USE_TIMERS", "0");
if (!run_zoltan(zzcopy, Proc, &prob, &mesh, &pio_info)) {
Gen_Error(0, "fatal: Error returned from run_zoltan\n");
error_report(Proc);
print_output = 0;
goto End;
}
Zoltan_Destroy(&zzcopy);
}
#endif /* IGNORE_FIRST_ITERATION_STATS */
#ifdef RANDOM_DIST
if (iteration % 2 == 0) {
char LB_METHOD[1024];
if (Proc == 0) printf("%d CCCC Randomizing the input\n", Proc);
strcpy(LB_METHOD, prob.method);
strcpy(prob.method, "RANDOM");
Zoltan_Set_Param(zz, "LB_METHOD", "RANDOM");
Zoltan_Set_Param(zz, "RETURN_LISTS", "ALL");
if (!run_zoltan(zz, Proc, &prob, &mesh, &pio_info)) {
Gen_Error(0, "fatal: Error returned from run_zoltan\n");
error_report(Proc);
print_output = 0;
goto End;
}
Zoltan_Set_Param(zz, "RETURN_LISTS", "NONE");
Zoltan_Set_Param(zz, "LB_METHOD", LB_METHOD);
strcpy(prob.method, LB_METHOD);
if (Proc == 0) printf("%d CCCC Randomizing the input -- END\n", Proc);
}
#endif /* RANDOM_DIST */
if (!run_zoltan(zz, Proc, &prob, &mesh, &pio_info)) {
Gen_Error(0, "fatal: Error returned from run_zoltan\n");
error_report(Proc);
print_output = 0;
goto End;
}
/* Reset the mesh data structure for next iteration. */
if (iteration < Number_Iterations) {
int i, j;
float tmp;
float twiddle = 0.01;
char str[32];
/* Perturb coordinates of mesh */
if (mesh.data_type == ZOLTAN_GRAPH){
for (i = 0; i < mesh.num_elems; i++) {
for (j = 0; j < mesh.num_dims; j++) {
/* tmp = ((float) rand())/RAND_MAX; *//* Equiv. to sjplimp's test */
tmp = (float) (i % 10) / 10.;
mesh.elements[i].coord[0][j] += twiddle * (2.0*tmp-1.0);
mesh.elements[i].avg_coord[j] = mesh.elements[i].coord[0][j];
}
}
/* Increase weights in some parts */
if (Test.Dynamic_Weights){
/* Randomly pick 10% of parts to "refine" */
/* Note: Assumes at least 10 parts! */
/* Increase vertex weight, and also edge weights? TODO */
j = (int) ((10.0*rand())/RAND_MAX + .5);
for (i = 0; i < mesh.num_elems; i++) {
if ((mesh.elements[i].my_part%10) == j){
mesh.elements[i].cpu_wgt[0] = Test.Dynamic_Weights*(1+rand()%5);
}
}
}
}
/* change the ParMETIS Seed */
sprintf(str, "%d", iteration);
#ifdef ZOLTAN_PARMETIS
Zoltan_Set_Param(zz, "PARMETIS_SEED", str);
#endif
}
} /* End of loop over read and balance */
if (Proc == 0) {
printf("FILE %s: Total: %e seconds in Partitioning\n",
cmd_file, Total_Partition_Time);
printf("FILE %s: Average: %e seconds per Iteration\n",
cmd_file, Total_Partition_Time/Number_Iterations);
}
End:
Zoltan_Destroy(&zz);
if (mesh.dd) Zoltan_DD_Destroy(&(mesh.dd));
Zoltan_Memory_Stats();
/*
* output the results
*/
if (print_output) {
if (!output_results(cmd_file,"out",Proc,Num_Proc,&prob,&pio_info,&mesh)) {
Gen_Error(0, "fatal: Error returned from output_results\n");
error_report(Proc);
}
if (Output.Gnuplot) {
if (!output_gnu(cmd_file,"out",Proc,Num_Proc,&prob,&pio_info,&mesh)) {
Gen_Error(0, "warning: Error returned from output_gnu\n");
error_report(Proc);
}
}
}
free_mesh_arrays(&mesh);
if (prob.params != NULL) free(prob.params);
MPI_Finalize();
#ifdef VAMPIR
VT_finalize();
#endif
return 0;
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
/* This function determines which input file type is being used,
* and calls the appropriate read function. If a new type of input
* file is added to the driver, then a section needs to be added for
* it here.
*---------------------------------------------------------------------------*/
static int read_mesh(
int Proc,
int Num_Proc,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
MESH_INFO_PTR mesh)
{
#ifdef DEBUG_READ_MESH
int i, tpins, the, tverts, pins, he, verts;
#endif
/* local declarations */
/*-----------------------------Execution Begins------------------------------*/
if (pio_info->file_type == CHACO_FILE) {
if (!read_chaco_file(Proc, Num_Proc, prob, pio_info, mesh)) {
Gen_Error(0, "fatal: Error returned from read_chaco_mesh\n");
return 0;
}
}
else if (pio_info->file_type == NEMESIS_FILE) {
if (!read_exoII_file(Proc, Num_Proc, prob, pio_info, mesh)) {
Gen_Error(0, "fatal: Error returned from read_exoII_mesh\n");
return 0;
}
}
else if (pio_info->file_type == HYPERGRAPH_FILE) {
if (!read_hypergraph_file(Proc, Num_Proc, prob, pio_info, mesh)) {
Gen_Error(0, "fatal: Error returned from read_hypergraph_file\n");
return 0;
}
}
else if (pio_info->file_type == MATRIXMARKET_FILE) {
if (!read_mm_file(Proc, Num_Proc, prob, pio_info, mesh)) {
Gen_Error(0, "fatal: Error returned from read_mm_file\n");
return 0;
}
mm_cleanup(mesh);
}
else if (pio_info->file_type == MATRIXMARKET_PLUS_FILE) {
if (!read_mtxplus_file(Proc, Num_Proc, prob, pio_info, mesh)) {
Gen_Error(0, "fatal: Error returned from read_mtxplus_file\n");
return 0;
}
/* KDDKDD 3/26/10:
* Eventually, we should do cleanup here to address bug 3346.
* but doing so will change the answer files.
* mm_cleanup(mesh);
*/
}
else if (pio_info->file_type == NO_FILE_POINTS) {
if (!create_random_input(Proc, Num_Proc, prob, pio_info, mesh)) {
Gen_Error(0, "fatal: Error returned from create_random_input\n");
return 0;
}
}
else if (pio_info->file_type == NO_FILE_TRIANGLES) {
if (!create_random_triangles(Proc, Num_Proc, prob, pio_info, mesh)) {
Gen_Error(0, "fatal: Error returned from create_random_triangles\n");
return 0;
}
}
else if (pio_info->file_type == NO_FILE_GRAPH) {
if (!create_a_graph(Proc, Num_Proc, prob, pio_info, mesh)) {
Gen_Error(0, "fatal: Error returned from create_a_graph\n");
return 0;
}
}
else {
Gen_Error(0, "fatal: Invalid file type.\n");
return 0;
}
#ifdef DEBUG_READ_MESH
for (i=0; i<Num_Proc; i++){
if (i == Proc){
printf("Process %d:\n",i);
print_mesh(Proc, mesh, &pins, &he, &verts);
}
MPI_Barrier(MPI_COMM_WORLD);
}
MPI_Reduce(&pins, &tpins, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce(&he, &the, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce(&verts, &tverts, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
if (Proc == 0){
if (mesh->format == ZOLTAN_COMPRESSED_EDGE){
printf("Total pins %d, total vertices %d, total rows %d\n",
tpins, tverts, the);
}
else{
printf("Total pins %d, total vertices %d, total columns %d\n",
tpins, tverts, the);
}
}
#endif
return 1;
}
/*****************************************************************************/
/*****************************************************************************/
static void print_input_info(FILE *fp, int Num_Proc, PROB_INFO_PTR prob,
PARIO_INFO_PTR pio, float zoltan_version)
{
int i;
int idtypesize;
char *idtypename;
fprintf(fp, "Input values:\n");
fprintf(fp, " Zoltan version %g\n",zoltan_version);
fprintf(fp, " %s version %s\n", DRIVER_NAME, VER_STR);
fprintf(fp, " Total number of Processors = %d\n", Num_Proc);
idtypesize = Zoltan_get_global_id_type(&idtypename);
fprintf(fp, " ZOLTAN_ID_TYPE size %d name %s\n", idtypesize, idtypename);
fprintf(fp, "\n Performing load balance using %s.\n", prob->method);
fprintf(fp, "\tParameters:\n");
for (i = 0; i < prob->num_params; i++)
fprintf(fp, "\t\t%s %s\n", prob->params[i].Name, prob->params[i].Val);
if ((pio->init_dist_procs > 0) && (pio->init_dist_procs != Num_Proc)){
fprintf(fp, "\n Distribute input objects to only %d processes initially.\n",
pio->init_dist_procs);
}
if (pio->chunk_reader > 0){
fprintf(fp, "\n Initially read input file in chunks (due to file size)\n");
}
if (pio->init_dist_type >= 0){
fprintf(fp, "\n Initially distribute input objects");
switch (pio->init_dist_type){
case INITIAL_FILE:
case INITIAL_OWNER:
fprintf(fp," according to assignments in file.");
break;
case INITIAL_LINEAR:
fprintf(fp," in linear fashion (first n/p to process 0, etc).");
break;
case INITIAL_CYCLIC:
fprintf(fp," in cyclic (round robin) fashion.");
break;
case INITIAL_NO_DIST:
fprintf(fp," not at all. They are created as distributed.");
break;
}
fprintf(fp, "\n");
}
if (pio->init_dist_pins >= 0){
fprintf(fp, "\n Distribute pins");
switch (pio->init_dist_pins){
case INITIAL_FILE:
fprintf(fp," according to assignments in file.");
break;
case INITIAL_LINEAR:
fprintf(fp," in linear fashion (first n/p to process 0, etc).");
break;
case INITIAL_CYCLIC:
fprintf(fp," in cyclic (round robin) fashion.");
break;
case INITIAL_ROW:
fprintf(fp," so each process gets full rows.");
break;
case INITIAL_COL:
fprintf(fp," so each process gets full columns.");
break;
case INITIAL_ZERO:
fprintf(fp," all to process zero.");
break;
}
fprintf(fp, "\n");
}
fprintf(fp, "##########################################################\n");
}
/*****************************************************************************/
/*****************************************************************************/
static void initialize_mesh(MESH_INFO_PTR mesh, int proc)
{
/* Initializes mesh variables */
mesh->dd = NULL;
mesh->data_type = MESH;
mesh->gnhedges = mesh->global_blank_count = 0;
mesh->num_elems = mesh->num_nodes
= mesh->num_dims
= mesh->num_el_blks
= mesh->num_node_sets
= mesh->num_side_sets
= mesh->necmap
= mesh->elem_array_len
= mesh->nhedges
= mesh->vwgt_dim
= mesh->ewgt_dim
= mesh->hewgt_dim
= mesh->blank_count
= 0;
mesh->eb_names = NULL;
mesh->eb_etypes = NULL;
mesh->eb_ids = NULL;
mesh->eb_cnts = NULL;
mesh->eb_nnodes = NULL;
mesh->eb_nattrs = NULL;
mesh->ecmap_id = NULL;
mesh->ecmap_cnt = NULL;
mesh->ecmap_elemids = NULL;
mesh->ecmap_sideids = NULL;
mesh->ecmap_neighids = NULL;
mesh->elements = NULL;
mesh->blank = NULL;
mesh->format = ZOLTAN_COMPRESSED_EDGE;
mesh->hgid = NULL;
mesh->hindex = NULL;
mesh->hvertex = NULL;
mesh->hvertex_proc = NULL;
mesh->heWgtId = NULL;
mesh->hewgts = NULL;
mesh->proc = proc;
mesh->visible_nvtx = 0;
}
static void remove_random_vertices(MESH_INFO_PTR mesh, int iteration,
float blank_factor)
{
int i, j, blankmine = (mesh->proc % 2) == (iteration % 2);
ZOLTAN_ID_TYPE tmp, total_vertices;
ELEM_INFO *elem;
for (i=0; i < mesh->num_elems; i++){
safe_free((void **)(void *)&(mesh->elements[i].adj_blank));
}
safe_free((void **)(void *)&mesh->blank);
mesh->blank_count = 0;
mesh->global_blank_count = 0;
/*
* Mark some portion of vertices as blanked. The graph callbacks
* will not report blanked vertices.
*/
if ((blank_factor <= 0.0) || (blank_factor >= 1.0)){
return;
}
mesh->blank = (int *)calloc(sizeof(int) , mesh->elem_array_len);
if (mesh->elem_array_len && !mesh->blank){
Gen_Error(0, "memory allocation in remove_random_vertices");
error_report(mesh->proc);
return;
}
for (i=0; i < mesh->num_elems; i++){
/* Each vertex (element) has probability given by
* by blank_factor of being blanked. The blanked vertices should
* vary somewhat in each iteration.
*/
elem = mesh->elements + i;
srand((long int)(elem->globalID * iteration));
if (blankmine && (((double)rand()/RAND_MAX) <= (double)blank_factor)){
mesh->blank[i] = 1.0;
mesh->blank_count++;
}
/* adj_blank marks each off processor adjacent vertex as
* either blanked (1) or not blanked (0).
*/
elem->adj_blank = (int *)calloc(sizeof(int), elem->nadj);
if (elem->nadj){
if (!elem->adj_blank){
Gen_Error(0, "memory allocation in remove_random_vertices");
error_report(mesh->proc);
return;
}
for (j=0; j<elem->nadj; j++){
if (elem->adj_proc[j] != mesh->proc){
srand((long int)(elem->adj[j] * iteration));
if (((elem->adj_proc[j] % 2) == (iteration % 2) ) && (((double)rand()/RAND_MAX) <= (double)blank_factor)){
elem->adj_blank[j] = 1.0;
}
}
}
}
}
MPI_Allreduce(&mesh->blank_count, &mesh->global_blank_count, 1, ZOLTAN_ID_MPI_TYPE, MPI_SUM, MPI_COMM_WORLD);
tmp = (ZOLTAN_ID_TYPE)mesh->num_elems;
MPI_Reduce(&tmp, &total_vertices, 1, ZOLTAN_ID_MPI_TYPE, MPI_SUM, 0, MPI_COMM_WORLD);
if (mesh->proc == 0){
printf("Dynamic graph factor %0.4f, " ZOLTAN_ID_SPEC " vertices, " ZOLTAN_ID_SPEC " blanked (%0.2f%%)\n",
blank_factor, total_vertices, mesh->global_blank_count,
((double)mesh->global_blank_count*100.0/total_vertices));
}
fflush(stdout);
if (Debug_Driver > 1) {
MPI_Barrier(MPI_COMM_WORLD);
if (mesh->num_elems){
printf("Proc %d: %d vertices, %d blanked (%0.2f%%)\n",
mesh->proc, mesh->num_elems, mesh->blank_count,
((float)mesh->blank_count*100.0/mesh->num_elems));
}
else{
printf("Proc %d: 0 vertices\n", mesh->proc);
}
fflush(stdout);
MPI_Barrier(MPI_COMM_WORLD);
}
}
#ifdef DEBUG_READ_MESH
static void print_mesh(int proc, MESH_INFO_PTR m, int *tp, int *the, int *tv)
{
int i, j, ii;
ZOLTAN_ID_TYPE globalID, adj;
ELEM_INFO_PTR el;
printf("Global number of hyperedges " ZOLTAN_ID_SPEC "\n",m->gnhedges);
if (m->format == ZOLTAN_COMPRESSED_EDGE){
printf("Pins: %d edges\n",m->nhedges);
}
else{
printf("Pins: %d vertices\n",m->nhedges);
}
for (i=0; i<m->nhedges; i++){
printf(" " ZOLTAN_ID_SPEC ": ", m->hgid[i]);
for (j=m->hindex[i],ii=0; j<m->hindex[i+1]; j++,ii++){
if (ii && (ii%15==0)) printf("\n ");
printf(ZOLTAN_ID_SPEC " ", m->hvertex[j]);
}
printf("\n");
}
printf("Total pins: %d\n", m->hindex[m->nhedges]);
printf("%d vertices: ", m->num_elems);
el = m->elements;
for (i=0; i<m->num_elems; i++){
printf(ZOLTAN_ID_SPEC " (%d adj: ", el->globalID, el->nadj);
for (j=0; j<el->nadj; j++){
adj = el->adj[j];
if (el->adj_proc[j] == proc){
globalID = m->elements[adj].globalID;
}
else{
globalID = adj;
}
if (j && (j%15==0)) printf("\n ");
printf(ZOLTAN_ID_SPEC " ",globalID);
}
printf(")\n");
el++;
}
printf("\n");
fflush(stdout);
*tp = m->hindex[m->nhedges];
*the = m->nhedges;
*tv = m->num_elems;
}
#endif
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,793 @@
/*
* @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
*/
#include <mpi.h>
/*--------------------------------------------------------------------------*/
/* Purpose: Driver for dynamic load-balance library, ZOLTAN. */
/* */
/*--------------------------------------------------------------------------*/
/* Author(s): Matthew M. St.John (9226) */
/*--------------------------------------------------------------------------*/
/* Supported Environment(s): Intel Paragon */
/* Intel Teraflop */
/*--------------------------------------------------------------------------*/
/* Revision History: */
/* */
/* 30 March 1999: Date of creation */
/*--------------------------------------------------------------------------*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include "dr_const.h"
#include "dr_input_const.h"
#include "dr_loadbal_const.h"
#include "dr_output_const.h"
#include "dr_err_const.h"
#include "dr_elem_util_const.h"
#include "dr_dd.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
/****************************************************************************/
/* ALTERNATE FILE FOR SHOCKSTEM ADAPTIVE MESH REFINEMENT EXPERIMENTS ONLY. */
/* DO NOT COMMIT AS A REGULAR DRIVER FILE. */
/****************************************************************************/
#ifndef MAX_STR_LENGTH
#define MAX_STR_LENGTH 80
#endif
int Debug_Driver = 1;
int Number_Iterations = 1;
int Driver_Action = 1; /* Flag indicating coloring, load-balancing or ordering. */
int Debug_Chaco_Input = 0;
int Chaco_In_Assign_Inv = 0;
struct Test_Flags Test;
struct Output_Flags Output;
double Total_Partition_Time = 0.0; /* Total over Number_Iterations */
static int read_mesh(int, int, PROB_INFO_PTR, PARIO_INFO_PTR, MESH_INFO_PTR, MESH_INFO_PTR);
static void print_input_info(FILE *, int, PROB_INFO_PTR, PARIO_INFO_PTR, float );
static void initialize_mesh(MESH_INFO_PTR, int proc);
static void remove_random_vertices(MESH_INFO_PTR mesh, int iter, float factor);
#ifdef DEBUG_READ_MESH
static void print_mesh(int proc, MESH_INFO_PTR m, int *tp, int *the, int *tv);
#endif
extern void safe_free(void **ptr);
#include <unistd.h>
#ifdef VAMPIR
#include <VT.h>
#endif
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
int main(int argc, char *argv[])
{
/* Local declarations. */
struct Zoltan_Struct *zz = NULL;
char *cmd_file;
char cmesg[256]; /* for error messages */
float version;
int Proc, Num_Proc;
int iteration;
int error, gerror;
int print_output = 1;
MESH_INFO *mesh=NULL; /* mesh information struct for iteration */
MESH_INFO *previous_mesh=NULL; /* mesh information struct for iteration-1 */
PARIO_INFO pio_info;
PROB_INFO prob;
char base_fname[MAX_STR_LENGTH+1];
/***************************** BEGIN EXECUTION ******************************/
/* initialize MPI */
MPI_Init(&argc, &argv);
#ifdef VAMPIR
VT_initialize(&argc, &argv);
#endif
/* get some machine information */
MPI_Comm_rank(MPI_COMM_WORLD, &Proc);
MPI_Comm_size(MPI_COMM_WORLD, &Num_Proc);
#ifdef ZOLTAN_PURIFY
printf("%d of %d ZDRIVE LAUNCH pid = %d file = %s\n",
Proc, Num_Proc, getpid(), argv[1]);
#endif
/* Initialize flags */
Test.DDirectory = 0;
Test.Local_Partitions = 0;
Test.Fixed_Objects = 0;
Test.Drops = 0;
Test.RCB_Box = 0;
Test.Multi_Callbacks = 0;
Test.Graph_Callbacks = 1;
Test.Hypergraph_Callbacks = 1;
Test.Gen_Files = 0;
Test.Null_Lists = NONE;
Test.Dynamic_Weights = .0;
Test.Dynamic_Graph = .0;
Output.Text = 1;
Output.Gnuplot = 0;
Output.Nemesis = 0;
Output.Plot_Partitions = 0;
Output.Mesh_Info_File = 0;
/* Interpret the command line */
switch(argc)
{
case 1:
cmd_file = "zdrive.inp";
break;
case 2:
cmd_file = argv[1];
break;
default:
fprintf(stderr, "MAIN: ERROR in command line,");
if(Proc == 0)
{
fprintf(stderr, " usage:\n");
fprintf(stderr, "\t%s [command file]", DRIVER_NAME);
}
exit(1);
break;
}
/* initialize Zoltan */
if ((error = Zoltan_Initialize(argc, argv, &version)) != ZOLTAN_OK) {
sprintf(cmesg, "fatal: Zoltan_Initialize returned error code, %d", error);
Gen_Error(0, cmesg);
error_report(Proc);
print_output = 0;
goto End;
}
/* initialize some variables */
pio_info.dsk_list_cnt = -1;
pio_info.num_dsk_ctrlrs = -1;
pio_info.pdsk_add_fact = -1;
pio_info.zeros = -1;
pio_info.file_type = -1;
pio_info.chunk_reader = 0;
pio_info.init_dist_type = -1;
pio_info.init_size = -1;
pio_info.init_dim = -1;
pio_info.init_vwgt_dim = -1;
pio_info.init_dist_pins = -1;
pio_info.pdsk_root[0] = '\0';
pio_info.pdsk_subdir[0] = '\0';
pio_info.pexo_fname[0] = '\0';
prob.method[0] = '\0';
prob.num_params = 0;
prob.params = NULL;
/* Read in the ascii input file */
error = gerror = 0;
if (Proc == 0) {
printf("\n\nReading the command file, %s\n", cmd_file);
if (!read_cmd_file(cmd_file, &prob, &pio_info, NULL)) {
sprintf(cmesg,"fatal: Could not read in the command file"
" \"%s\"!\n", cmd_file);
Gen_Error(0, cmesg);
error_report(Proc);
print_output = 0;
error = 1;
}
if (!check_inp(&prob, &pio_info)) {
Gen_Error(0, "fatal: Error in user specified parameters.\n");
error_report(Proc);
print_output = 0;
error = 1;
}
print_input_info(stdout, Num_Proc, &prob, &pio_info, version);
}
MPI_Allreduce(&error, &gerror, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
if (gerror) goto End;
/* broadcast the command info to all of the processor */
brdcst_cmd_info(Proc, &prob, &pio_info, mesh);
Zoltan_Set_Param(NULL, "DEBUG_MEMORY", "1");
print_output = Output.Text;
/*
* Create a Zoltan structure.
*/
if ((zz = Zoltan_Create(MPI_COMM_WORLD)) == NULL) {
Gen_Error(0, "fatal: NULL returned from Zoltan_Create()\n");
return 0;
}
/* srand(Proc); Different seeds on different procs. */
srand(1); /* Same seed everywhere. */
/* Save the base filename; we'll modify pexo_fname with file number. */
strcpy(base_fname,pio_info.pexo_fname);
/* Loop over read and balance for a number of iterations */
/* (Useful for testing REUSE parameters in Zoltan.) */
for (iteration = 0; iteration <= Number_Iterations; iteration++) {
mesh = (MESH_INFO*) malloc(sizeof(MESH_INFO));
initialize_mesh(mesh, Proc);
if (!setup_zoltan(zz, Proc, &prob, mesh, &pio_info)) {
Gen_Error(0, "fatal: Error returned from setup_zoltan\n");
error_report(Proc);
print_output = 0;
goto End;
}
switch (pio_info.file_type) {
case CHACO_FILE:
case NO_FILE_POINTS:
case NO_FILE_TRIANGLES:
mesh->data_type = ZOLTAN_GRAPH;
break;
case NEMESIS_FILE:
mesh->data_type = MESH;
break;
case HYPERGRAPH_FILE:
case MATRIXMARKET_FILE:
case MATRIXMARKET_PLUS_FILE:
mesh->data_type = HYPERGRAPH;
break;
}
/* Modify pexo_fname with file number */
sprintf(pio_info.pexo_fname, "%s.%d", base_fname, iteration);
if (Proc == 0) {
printf("%d KDDKDD Reading file %s\n", Proc, pio_info.pexo_fname);
fflush(stdout);
}
/* Modify init_dist_type for iterations > 0 */
if (iteration) pio_info.init_dist_type = INITIAL_FILE;
/*
* now read in the mesh and element information.
* This is the only function call to do this. Upon return,
* the mesh struct and the elements array should be filled.
*/
if (!read_mesh(Proc, Num_Proc, &prob, &pio_info, mesh, previous_mesh)) {
Gen_Error(0, "fatal: Error returned from read_mesh\n");
error_report(Proc);
print_output = 0;
goto End;
}
if (previous_mesh) {
if (previous_mesh->dd) Zoltan_DD_Destroy(&(previous_mesh->dd));
free_mesh_arrays(previous_mesh);
safe_free((void **) &previous_mesh);
}
previous_mesh = mesh;
/*
* Create a Zoltan DD for tracking elements during repartitioning.
*/
if (!build_elem_dd(mesh)) {
Gen_Error(0, "fatal: Error returned from build_elem_dd\n");
error_report(Proc);
print_output = 0;
goto End;
}
/*
* Produce files to verify input.
*/
if (iteration == 1)
if (Debug_Driver > 2) {
if (!output_results(cmd_file,"in",Proc,Num_Proc,&prob,&pio_info,mesh)){
Gen_Error(0, "fatal: Error returned from output_results\n");
error_report(Proc);
}
if (Output.Gnuplot)
if (!output_gnu(cmd_file,"in",Proc,Num_Proc,&prob,&pio_info,mesh)) {
Gen_Error(0, "warning: Error returned from output_gnu\n");
error_report(Proc);
}
}
/*
* now run Zoltan to get a new load balance and perform
* the migration
*/
#ifdef IGNORE_FIRST_ITERATION_STATS
if (iteration == 1) {
/* Exercise partitioner once on Tbird because first run is slow. */
/* Lee Ann suspects Tbird is loading shared libraries. */
struct Zoltan_Struct *zzcopy;
zzcopy = Zoltan_Copy(zz);
/* Don't do any migration or accumulate any stats. */
if (Proc == 0) printf("%d KDDKDD IGNORING FIRST ITERATION STATS\n", Proc);
Zoltan_Set_Param(zzcopy, "RETURN_LISTS", "NONE");
Zoltan_Set_Param(zzcopy, "FINAL_OUTPUT", "0");
Zoltan_Set_Param(zzcopy, "USE_TIMERS", "0");
if (!run_zoltan(zzcopy, Proc, &prob, mesh, &pio_info)) {
Gen_Error(0, "fatal: Error returned from run_zoltan\n");
error_report(Proc);
print_output = 0;
goto End;
}
Zoltan_Destroy(&zzcopy);
}
#endif /* IGNORE_FIRST_ITERATION_STATS */
if (!run_zoltan(zz, Proc, &prob, mesh, &pio_info)) {
Gen_Error(0, "fatal: Error returned from run_zoltan\n");
error_report(Proc);
print_output = 0;
goto End;
}
} /* End of loop over read and balance */
if (Proc == 0) {
printf("FILE %s: Total: %e seconds in Partitioning\n",
cmd_file, Total_Partition_Time);
printf("FILE %s: Average: %e seconds per Iteration\n",
cmd_file, Total_Partition_Time/Number_Iterations);
}
End:
Zoltan_Destroy(&zz);
if (mesh->dd) Zoltan_DD_Destroy(&(mesh->dd));
Zoltan_Memory_Stats();
/*
* output the results
*/
if (print_output) {
if (!output_results(cmd_file,"out",Proc,Num_Proc,&prob,&pio_info,mesh)) {
Gen_Error(0, "fatal: Error returned from output_results\n");
error_report(Proc);
}
if (Output.Gnuplot) {
if (!output_gnu(cmd_file,"out",Proc,Num_Proc,&prob,&pio_info,mesh)) {
Gen_Error(0, "warning: Error returned from output_gnu\n");
error_report(Proc);
}
}
}
free_mesh_arrays(mesh);
safe_free((void **) &mesh);
if (prob.params != NULL) free(prob.params);
MPI_Finalize();
#ifdef VAMPIR
VT_finalize();
#endif
return 0;
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
/* This function determines which input file type is being used,
* and calls the appropriate read function. If a new type of input
* file is added to the driver, then a section needs to be added for
* it here.
*---------------------------------------------------------------------------*/
static int read_mesh(
int Proc,
int Num_Proc,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
MESH_INFO_PTR mesh,
MESH_INFO_PTR previous_mesh)
{
#ifdef DEBUG_READ_MESH
int i, tpins, the, tverts, pins, he, verts;
#endif
/* local declarations */
/*-----------------------------Execution Begins------------------------------*/
if (pio_info->file_type == CHACO_FILE) {
if (!read_chaco_file(Proc, Num_Proc, prob, pio_info, mesh, previous_mesh)) {
Gen_Error(0, "fatal: Error returned from read_chaco_mesh\n");
return 0;
}
}
else if (pio_info->file_type == NEMESIS_FILE) {
if (!read_exoII_file(Proc, Num_Proc, prob, pio_info, mesh)) {
Gen_Error(0, "fatal: Error returned from read_exoII_mesh\n");
return 0;
}
}
else if (pio_info->file_type == HYPERGRAPH_FILE) {
if (!read_hypergraph_file(Proc, Num_Proc, prob, pio_info, mesh)) {
Gen_Error(0, "fatal: Error returned from read_hypergraph_file\n");
return 0;
}
}
else if (pio_info->file_type == MATRIXMARKET_FILE) {
if (!read_mm_file(Proc, Num_Proc, prob, pio_info, mesh)) {
Gen_Error(0, "fatal: Error returned from read_mm_file\n");
return 0;
}
}
else if (pio_info->file_type == MATRIXMARKET_PLUS_FILE) {
if (!read_mtxplus_file(Proc, Num_Proc, prob, pio_info, mesh)) {
Gen_Error(0, "fatal: Error returned from read_mtxplus_file\n");
return 0;
}
}
else if (pio_info->file_type == NO_FILE_POINTS) {
if (!create_random_input(Proc, Num_Proc, prob, pio_info, mesh)) {
Gen_Error(0, "fatal: Error returned from create_random_input\n");
return 0;
}
}
else if (pio_info->file_type == NO_FILE_TRIANGLES) {
if (!create_random_triangles(Proc, Num_Proc, prob, pio_info, mesh)) {
Gen_Error(0, "fatal: Error returned from create_random_triangles\n");
return 0;
}
}
else {
Gen_Error(0, "fatal: Invalid file type.\n");
return 0;
}
#ifdef DEBUG_READ_MESH
for (i=0; i<Num_Proc; i++){
if (i == Proc){
printf("Process %d:\n",i);
print_mesh(Proc, mesh, &pins, &he, &verts);
}
MPI_Barrier(MPI_COMM_WORLD);
}
MPI_Reduce(&pins, &tpins, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce(&he, &the, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce(&verts, &tverts, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
if (Proc == 0){
if (mesh->format == ZOLTAN_COMPRESSED_EDGE){
printf("Total pins %d, total vertices %d, total rows %d\n",
tpins, tverts, the);
}
else{
printf("Total pins %d, total vertices %d, total columns %d\n",
tpins, tverts, the);
}
}
#endif
return 1;
}
/*****************************************************************************/
/*****************************************************************************/
static void print_input_info(FILE *fp, int Num_Proc, PROB_INFO_PTR prob,
PARIO_INFO_PTR pio, float zoltan_version)
{
int i;
fprintf(fp, "Input values:\n");
fprintf(fp, " Zoltan version %g\n",zoltan_version);
fprintf(fp, " %s version %s\n", DRIVER_NAME, VER_STR);
fprintf(fp, " Total number of Processors = %d\n", Num_Proc);
fprintf(fp, "\n Performing load balance using %s.\n", prob->method);
fprintf(fp, "\tParameters:\n");
for (i = 0; i < prob->num_params; i++)
fprintf(fp, "\t\t%s %s\n", prob->params[i].Name, prob->params[i].Val);
if ((pio->init_dist_procs > 0) && (pio->init_dist_procs != Num_Proc)){
fprintf(fp, "\n Distribute input objects to only %d processes initially.\n",
pio->init_dist_procs);
}
if (pio->chunk_reader > 0){
fprintf(fp, "\n Initially read input file in chunks (due to file size)\n");
}
if (pio->init_dist_type >= 0){
fprintf(fp, "\n Initially distribute input objects");
switch (pio->init_dist_type){
case INITIAL_FILE:
case INITIAL_OWNER:
fprintf(fp," according to assignments in file.");
break;
case INITIAL_LINEAR:
fprintf(fp," in linear fashion (first n/p to process 0, etc).");
break;
case INITIAL_CYCLIC:
fprintf(fp," in cyclic (round robin) fashion.");
break;
}
fprintf(fp, "\n");
}
if (pio->init_dist_pins >= 0){
fprintf(fp, "\n Distribute pins");
switch (pio->init_dist_pins){
case INITIAL_FILE:
fprintf(fp," according to assignments in file.");
break;
case INITIAL_LINEAR:
fprintf(fp," in linear fashion (first n/p to process 0, etc).");
break;
case INITIAL_CYCLIC:
fprintf(fp," in cyclic (round robin) fashion.");
break;
case INITIAL_ROW:
fprintf(fp," so each process gets full rows.");
break;
case INITIAL_COL:
fprintf(fp," so each process gets full columns.");
break;
case INITIAL_ZERO:
fprintf(fp," all to process zero.");
break;
}
fprintf(fp, "\n");
}
fprintf(fp, "##########################################################\n");
}
/*****************************************************************************/
/*****************************************************************************/
static void initialize_mesh(MESH_INFO_PTR mesh, int proc)
{
/* Initializes mesh variables */
mesh->dd = NULL;
mesh->data_type = MESH;
mesh->num_elems = mesh->num_nodes
= mesh->num_dims
= mesh->num_el_blks
= mesh->num_node_sets
= mesh->num_side_sets
= mesh->necmap
= mesh->elem_array_len
= mesh->gnhedges
= mesh->nhedges
= mesh->vwgt_dim
= mesh->ewgt_dim
= mesh->hewgt_dim
= mesh->blank_count
= mesh->global_blank_count
= mesh->visible_nvtx
= 0;
mesh->eb_names = NULL;
mesh->eb_etypes = NULL;
mesh->eb_ids = NULL;
mesh->eb_cnts = NULL;
mesh->eb_nnodes = NULL;
mesh->eb_nattrs = NULL;
mesh->ecmap_id = NULL;
mesh->ecmap_cnt = NULL;
mesh->ecmap_elemids = NULL;
mesh->ecmap_sideids = NULL;
mesh->ecmap_neighids = NULL;
mesh->elements = NULL;
mesh->blank = NULL;
mesh->format = ZOLTAN_COMPRESSED_EDGE;
mesh->hgid = NULL;
mesh->hindex = NULL;
mesh->hvertex = NULL;
mesh->hvertex_proc = NULL;
mesh->heWgtId = NULL;
mesh->hewgts = NULL;
mesh->proc = proc;
}
static void remove_random_vertices(MESH_INFO_PTR mesh, int iteration,
float blank_factor)
{
int i, j, total_vertices, blankmine = (mesh->proc % 2) == (iteration % 2);
ELEM_INFO *elem;
for (i=0; i < mesh->num_elems; i++){
safe_free((void **)&(mesh->elements[i].adj_blank));
}
safe_free((void **)&mesh->blank);
mesh->blank_count = 0;
mesh->global_blank_count = 0;
/*
* Mark some portion of vertices as blanked. The graph callbacks
* will not report blanked vertices.
*/
if ((blank_factor <= 0.0) || (blank_factor >= 1.0)){
return;
}
mesh->blank = (int *)calloc(sizeof(int) , mesh->elem_array_len);
if (mesh->elem_array_len && !mesh->blank){
Gen_Error(0, "memory allocation in remove_random_vertices");
error_report(mesh->proc);
return;
}
for (i=0; i < mesh->num_elems; i++){
/* Each vertex (element) has probability given by
* by blank_factor of being blanked. The blanked vertices should
* vary somewhat in each iteration.
*/
elem = mesh->elements + i;
srand48((long int)(elem->globalID * iteration));
if (blankmine && (drand48() <= (double)blank_factor)){
mesh->blank[i] = 1.0;
mesh->blank_count++;
}
/* adj_blank marks each off processor adjacent vertex as
* either blanked (1) or not blanked (0).
*/
elem->adj_blank = (int *)calloc(sizeof(int), elem->nadj);
if (elem->nadj){
if (!elem->adj_blank){
Gen_Error(0, "memory allocation in remove_random_vertices");
error_report(mesh->proc);
return;
}
for (j=0; j<elem->nadj; j++){
if (elem->adj_proc[j] != mesh->proc){
srand48((long int)(elem->adj[j] * iteration));
if (((elem->adj_proc[j] % 2) == (iteration % 2) ) && (drand48() <= (double)blank_factor)){
elem->adj_blank[j] = 1.0;
}
}
}
}
}
MPI_Allreduce(&mesh->blank_count, &mesh->global_blank_count,
1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
MPI_Reduce(&mesh->num_elems, &total_vertices,
1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
if (mesh->proc == 0){
printf("Dynamic graph factor %0.4f, %d vertices, %d blanked (%0.2f%%)\n",
blank_factor, total_vertices, mesh->global_blank_count,
((float)mesh->global_blank_count*100.0/total_vertices));
}
fflush(stdout);
if (Debug_Driver > 1) {
MPI_Barrier(MPI_COMM_WORLD);
if (mesh->num_elems){
printf("Proc %d: %d vertices, %d blanked (%0.2f%%)\n",
mesh->proc, mesh->num_elems, mesh->blank_count,
((float)mesh->blank_count*100.0/mesh->num_elems));
}
else{
printf("Proc %d: 0 vertices\n", mesh->proc);
}
fflush(stdout);
MPI_Barrier(MPI_COMM_WORLD);
}
}
#ifdef DEBUG_READ_MESH
static void print_mesh(int proc, MESH_INFO_PTR m, int *tp, int *the, int *tv)
{
int i, j, ii, adj, globalID;
ELEM_INFO_PTR el;
printf("Global number of hyperedges %d\n",m->gnhedges);
if (m->format == ZOLTAN_COMPRESSED_EDGE){
printf("Pins: %d edges\n",m->nhedges);
}
else{
printf("Pins: %d vertices\n",m->nhedges);
}
for (i=0; i<m->nhedges; i++){
printf(" %d: ", m->hgid[i]);
for (j=m->hindex[i],ii=0; j<m->hindex[i+1]; j++,ii++){
if (ii && (ii%15==0)) printf("\n ");
printf("%d ", m->hvertex[j]);
}
printf("\n");
}
printf("Total pins: %d\n", m->hindex[m->nhedges]);
printf("%d vertices: ", m->num_elems);
el = m->elements;
for (i=0; i<m->num_elems; i++){
printf("%d (%d adj: ", el->globalID, el->nadj);
for (j=0; j<el->nadj; j++){
adj = el->adj[j];
if (el->adj_proc[j] == proc){
globalID = m->elements[adj].globalID;
}
else{
globalID = adj;
}
if (j && (j%15==0)) printf("\n ");
printf("%d ",globalID);
}
printf(")\n");
el++;
}
printf("\n");
fflush(stdout);
*tp = m->hindex[m->nhedges];
*the = m->nhedges;
*tv = m->num_elems;
}
#endif
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

View File

@ -0,0 +1,541 @@
/*
* @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
*/
#include <mpi.h> // must appear before stdio or iostream
#ifdef TFLOP
#include <iostream.h>
#include <ostream.h>
#else
#include <iostream>
#include <ostream>
using namespace std;
#endif
#include "dr_const.h"
#include "dr_input_const.h"
#include "dr_loadbal_const.h"
#include "dr_output_const.h"
#include "dr_err_const.h"
#include "dr_elem_util_const.h"
#include "dr_dd.h"
#include "dr_compress_const.h"
#include "zoltan_cpp.h"
int Debug_Driver = 1;
int Number_Iterations = 1;
int Driver_Action = 1; /* Flag indicating coloring, load-balancing or ordering. */
int Debug_Chaco_Input = 0;
int Chaco_In_Assign_Inv = 0;
struct Test_Flags Test;
struct Output_Flags Output;
double Total_Partition_Time = 0.0; /* Total over Number_Iterations */
static int read_mesh(int, int, PROB_INFO_PTR, PARIO_INFO_PTR, MESH_INFO_PTR);
static void initialize_mesh(MESH_INFO_PTR);
static void print_input_info(ostream &os, int Num_Proc, PROB_INFO_PTR prob,
PARIO_INFO_PTR pio, float zoltan_version);
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
int main(int argc, char *argv[])
{
/* Local declarations. */
const char *cmd_file;
char cmesg[256]; /* for error messages */
int error, gerror;
int print_output = 1;
/***************************** BEGIN EXECUTION ******************************/
/* Initialize MPI */
// We must use the C bindings to MPI because the C++ bindings are
// are not available or not complete on some of our platforms.
MPI_Init(&argc, &argv);
/* get some machine information */
int Proc = 0, Num_Proc = 0;
MPI_Comm_rank(MPI_COMM_WORLD, &Proc);
MPI_Comm_size(MPI_COMM_WORLD, &Num_Proc);
/* Initialize flags */
Test.DDirectory = 0;
Test.Local_Parts = 0;
Test.Drops = 0;
Test.RCB_Box = 0;
Test.Multi_Callbacks = 0;
Test.Gen_Files = 0;
Test.Fixed_Objects = 0;
Test.Null_Lists = NO_NULL_LISTS;
Output.Text = 1;
Output.Gnuplot = 0;
Output.Nemesis = 0;
Output.Plot_Partition = 0;
Output.Mesh_Info_File = 0;
/* Interpret the command line */
switch(argc)
{
case 1:
cmd_file = "zdrive.inp";
break;
case 2:
cmd_file = argv[1];
break;
default:
cerr << "MAIN: ERROR in command line " ;
if (Proc == 0)
{
cerr << "usage:" << endl;
cerr << "\t" << DRIVER_NAME << " [command file]";
}
cerr << endl;
exit(1);
break;
}
/* Initialize Zoltan
* Not part of C++ interface at this time. (C++ wishlist)
*/
float version;
if ((error = Zoltan_Initialize(argc, argv, &version)) != ZOLTAN_OK) {
sprintf(cmesg, "fatal: Zoltan_Initialize returned error code, %d", error);
Gen_Error(0, cmesg);
error_report(Proc);
MPI_Finalize();
return 1;
}
/*
* Create a Zoltan structure.
* No exception handling at this time. (C++ wishlist)
* We must dynamically create the object so that we can delete it
* before MPI_Finalize(). (If zz is created on the stack, it will
* be deleted atexit, after MPI_Finalize(). Zoltan_Destroy calls
* MPI functions.)
*/
Zoltan *zz = NULL;
zz = new Zoltan();
/* initialize some variables */
MESH_INFO mesh;
initialize_mesh(&mesh);
PARIO_INFO pio_info;
pio_info.dsk_list_cnt = -1;
pio_info.num_dsk_ctrlrs = -1;
pio_info.pdsk_add_fact = -1;
pio_info.zeros = -1;
pio_info.file_type = -1;
pio_info.init_dist_type = -1;
pio_info.init_size = ZOLTAN_ID_INVALID;
pio_info.init_dim = -1;
pio_info.init_vwgt_dim = -1;
pio_info.init_dist_pins = -1;
pio_info.pdsk_root[0] = '\0';
pio_info.pdsk_subdir[0] = '\0';
pio_info.pexo_fname[0] = '\0';
pio_info.file_comp = STANDARD;
PROB_INFO prob;
prob.method[0] = '\0';
prob.num_params = 0;
prob.params = NULL;
/* Read in the ascii input file */
error = 0;
if (Proc == 0) {
cout << "\n\nReading the command file, " << cmd_file << endl;
if (!read_cmd_file(cmd_file, &prob, &pio_info, NULL)) {
sprintf(cmesg,"fatal: Could not read in the command file"
" \"%s\"!\n", cmd_file);
Gen_Error(0, cmesg);
error_report(Proc);
print_output = 0;
error = 1;
}
if (!check_inp(&prob, &pio_info)) {
Gen_Error(0, "fatal: Error in user specified parameters.\n");
error_report(Proc);
print_output = 0;
error = 1;
}
print_input_info(cout, Num_Proc, &prob, &pio_info, version);
}
MPI_Allreduce(&error, &gerror, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
if (gerror) goto End;
/* broadcast the command info to all of the processor */
brdcst_cmd_info(Proc, &prob, &pio_info, &mesh);
zz->Set_Param("DEBUG_MEMORY", "1");
print_output = Output.Text;
if (!setup_zoltan(*zz, Proc, &prob, &mesh, &pio_info)) {
Gen_Error(0, "fatal: Error returned from setup_zoltan\n");
error_report(Proc);
print_output = 0;
goto End;
}
srand(Proc);
/* Loop over read and balance for a number of iterations */
/* (Useful for testing REUSE parameters in Zoltan.) */
for (int iteration = 1; iteration <= Number_Iterations; iteration++) {
/*
* now read in the mesh and element information.
* This is the only function call to do this. Upon return,
* the mesh struct and the elements array should be filled.
*/
if (iteration == 1) {
if (!read_mesh(Proc, Num_Proc, &prob, &pio_info, &mesh)) {
Gen_Error(0, "fatal: Error returned from read_mesh\n");
error_report(Proc);
print_output = 0;
goto End;
}
/*
* Create a Zoltan DD for tracking elements during repartitioning.
*/
if (mesh.data_type == ZOLTAN_HYPERGRAPH && !build_elem_dd(&mesh)) {
Gen_Error(0, "fatal: Error returned from build_elem_dd\n");
error_report(Proc);
print_output = 0;
goto End;
}
}
#ifdef KDDKDD_COOL_TEST
/* KDD Cool test of changing number of partitions */
sprintf(cmesg, "%d", Num_Proc * iteration);
zz->Set_Param("NUM_GLOBAL_PARTS", cmesg);
#endif
/*
* Produce files to verify input.
*/
if (iteration == 1)
if (Debug_Driver > 2) {
if (!output_results(cmd_file,"in",Proc,Num_Proc,&prob,&pio_info,&mesh)){
Gen_Error(0, "fatal: Error returned from output_results\n");
error_report(Proc);
}
if (Output.Gnuplot)
if (!output_gnu(cmd_file,"in",Proc,Num_Proc,&prob,&pio_info,&mesh)) {
Gen_Error(0, "warning: Error returned from output_gnu\n");
error_report(Proc);
}
}
/*
* now run Zoltan to get a new load balance and perform
* the migration
*/
if (!run_zoltan(*zz, Proc, &prob, &mesh, &pio_info)) {
Gen_Error(0, "fatal: Error returned from run_zoltan\n");
error_report(Proc);
print_output = 0;
goto End;
}
/* Reset the mesh data structure for next iteration. */
if (iteration < Number_Iterations) {
float twiddle = 0.01;
char str[32];
/* Perturb coordinates of mesh */
if (mesh.data_type == ZOLTAN_GRAPH)
for (int i = 0; i < mesh.num_elems; i++) {
for (int j = 0; j < mesh.num_dims; j++) {
/* tmp = ((float) rand())/RAND_MAX; *//* Equiv. to sjplimp's test */
float tmp = (float) (i % 10) / 10.;
mesh.elements[i].coord[0][j] += twiddle * (2.0*tmp-1.0);
mesh.elements[i].avg_coord[j] = mesh.elements[i].coord[0][j];
}
}
/* change the ParMETIS Seed */
sprintf(str, "%d", iteration%10000);
#ifdef ZOLTAN_PARMETIS
zz->Set_Param("PARMETIS_SEED", str);
#endif
}
} /* End of loop over read and balance */
if (Proc == 0) {
cout << "FILE " << cmd_file << ": Total: " ;
cout << Total_Partition_Time << " seconds in Partitioning" << endl;
cout << "FILE " << cmd_file << ": Average: ";
cout << Total_Partition_Time/Number_Iterations << " seconds per Iteration";
cout << endl;
}
End:
if (mesh.data_type == ZOLTAN_HYPERGRAPH)
{
destroy_elem_dd();
}
delete zz;
Zoltan_Memory_Stats();
/*
* output the results
*/
if (print_output) {
if (!output_results(cmd_file,"out",Proc,Num_Proc,&prob,&pio_info,&mesh)) {
Gen_Error(0, "fatal: Error returned from output_results\n");
error_report(Proc);
}
if (Output.Gnuplot) {
if (!output_gnu(cmd_file,"out",Proc,Num_Proc,&prob,&pio_info,&mesh)) {
Gen_Error(0, "warning: Error returned from output_gnu\n");
error_report(Proc);
}
}
}
free_mesh_arrays(&mesh);
if (prob.params != NULL) free(prob.params);
MPI_Finalize();
return 0;
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
/* This function determines which input file type is being used,
* and calls the appropriate read function. If a new type of input
* file is added to the driver, then a section needs to be added for
* it here.
*---------------------------------------------------------------------------*/
static int read_mesh(
int Proc,
int Num_Proc,
PROB_INFO_PTR prob,
PARIO_INFO_PTR pio_info,
MESH_INFO_PTR mesh)
{
/* local declarations */
/*-----------------------------Execution Begins------------------------------*/
if (pio_info->file_type == CHACO_FILE) {
if (!read_chaco_file(Proc, Num_Proc, prob, pio_info, mesh)) {
Gen_Error(0, "fatal: Error returned from read_chaco_mesh\n");
return 0;
}
}
else if (pio_info->file_type == NEMESIS_FILE) {
if (!read_exoII_file(Proc, Num_Proc, prob, pio_info, mesh)) {
Gen_Error(0, "fatal: Error returned from read_exoII_mesh\n");
return 0;
}
}
else if (pio_info->file_type == HYPERGRAPH_FILE) {
if (!read_hypergraph_file(Proc, Num_Proc, prob, pio_info, mesh)) {
Gen_Error(0, "fatal: Error returned from read_hypergraph_file\n");
return 0;
}
}
else if (pio_info->file_type == MATRIXMARKET_FILE) {
if (!read_mm_file(Proc, Num_Proc, prob, pio_info, mesh)) {
Gen_Error(0, "fatal: Error returned from read_mm_file\n");
return 0;
}
}
else if (pio_info->file_type == MATRIXMARKET_PLUS_FILE) {
if (!read_mtxplus_file(Proc, Num_Proc, prob, pio_info, mesh)) {
Gen_Error(0, "fatal: Error returned from read_mtxplus_file\n");
}
}
else if (pio_info->file_type == NO_FILE_POINTS) {
if (!create_random_input(Proc, Num_Proc, prob, pio_info, mesh)) {
Gen_Error(0, "fatal: Error returned from create_random_input\n");
return 0;
}
}
else {
Gen_Error(0, "fatal: Invalid file type.\n");
return 0;
}
return 1;
}
/*****************************************************************************/
/*****************************************************************************/
static void print_input_info(ostream &os, int Num_Proc, PROB_INFO_PTR prob,
PARIO_INFO_PTR pio, float zoltan_version)
{
int i;
os << "Input values: " << endl;
os << " Zoltan version " << zoltan_version << endl;
os << DRIVER_NAME << " version " << VER_STR << endl;
os << " Total number of Processors = " << Num_Proc << endl;
os << endl << " Performing load balance using " << prob->method << endl;
os << "\tParameters:\n" ;
for (i = 0; i < prob->num_params; i++)
os << "\t\t" << prob->params[i].Name << " " << prob->params[i].Val << endl;
if ((pio->init_dist_procs > 0) && (pio->init_dist_procs != Num_Proc)){
os << "\n Distribute input objects to only " << pio->init_dist_procs;
os << " processes initially.\n";
}
if (pio->init_dist_type >= 0){
os << "\n Initially distribute input objects" ;
switch (pio->init_dist_type){
case INITIAL_FILE:
case INITIAL_OWNER:
os << " according to assignments in file.";
break;
case INITIAL_LINEAR:
os << " in linear fashion (first n/p to process 0, etc).";
break;
case INITIAL_CYCLIC:
os << " in cyclic (round robin) fashion.";
break;
}
os << endl;
}
if (pio->init_dist_pins >= 0){
os << "\n Distribute pins";
switch (pio->init_dist_pins){
case INITIAL_FILE:
os << " according to assignments in file.";
break;
case INITIAL_LINEAR:
os << " in linear fashion (first n/p to process 0, etc).";
break;
case INITIAL_CYCLIC:
os << " in cyclic (round robin) fashion.";
break;
case INITIAL_ROW:
os << " so each process gets full rows.";
break;
case INITIAL_COL:
os << " so each process gets full columns.";
break;
case INITIAL_ZERO:
os << " all to process zero.";
break;
}
os << endl;
}
os << "##########################################################" << endl;
}
/*****************************************************************************/
/*****************************************************************************/
static void initialize_mesh(MESH_INFO_PTR mesh)
{
/* Initializes mesh variables */
mesh->dd = NULL;
mesh->data_type = MESH;
mesh->num_elems = mesh->num_nodes
= mesh->num_dims
= mesh->num_el_blks
= mesh->num_node_sets
= mesh->num_side_sets
= mesh->necmap
= mesh->elem_array_len
= mesh->gnhedges
= mesh->nhedges
= mesh->vwgt_dim
= mesh->ewgt_dim
= mesh->hewgt_dim
= mesh->blank_count
= mesh->global_blank_count
= 0;
mesh->eb_names = NULL;
mesh->eb_ids = NULL;
mesh->eb_cnts = NULL;
mesh->eb_nnodes = NULL;
mesh->eb_nattrs = NULL;
mesh->ecmap_id = NULL;
mesh->ecmap_cnt = NULL;
mesh->ecmap_elemids = NULL;
mesh->ecmap_sideids = NULL;
mesh->ecmap_neighids = NULL;
mesh->elements = NULL;
mesh->blank = NULL;
mesh->format = ZOLTAN_COMPRESSED_EDGE;
mesh->hgid = NULL;
mesh->hindex = NULL;
mesh->hvertex = NULL;
mesh->hvertex_proc = NULL;
mesh->heWgtId = NULL;
mesh->hewgts = NULL;
}

805
thirdParty/Zoltan/src/driver/dr_maps.c vendored Normal file
View File

@ -0,0 +1,805 @@
/*
* @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
*/
#include "dr_const.h"
#include "dr_externs.h"
#include "dr_maps_const.h"
#include "dr_util_const.h"
#include "dr_err_const.h"
#include "dr_par_util_const.h"
#ifdef __cplusplus
/* if C++, define the rest of this header file as extern C */
extern "C" {
#endif
#define MAP_ALLOC 10
/*
* Routines to build elemental communication maps, given a distributed mesh.
*/
struct map_list_head {
int map_alloc_size;
ZOLTAN_ID_TYPE *glob_id;
int *elem_id;
int *side_id;
ZOLTAN_ID_TYPE *neigh_id;
};
static void compare_maps_with_ddirectory_results(int, MESH_INFO_PTR);
static void sort_and_compare_maps(int, int, MESH_INFO_PTR,
struct map_list_head *, int, int *);
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
unsigned int zdrive_hash(ZOLTAN_ID_TYPE *id, int ngid, unsigned int nprocs)
{
return (id[0] % nprocs);
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
int build_elem_comm_maps(int proc, MESH_INFO_PTR mesh)
{
/*
* Build element communication maps, given a distributed mesh.
* This routine builds initial communication maps for Chaco input
* (for Nemesis, initial communication maps are read from the Nemesis file)
* and rebuilds communication maps after data migration.
*
* One communication map per neighboring processor is built.
* The corresponding maps on neighboring processors
* must be sorted in the same order, so that neighboring processors do not
* have to use ghost elements. For each communication map's pair of
* processors, the lower-numbered processor determines the order of the
* elements in the communication map. The sort key is the elements' global
* IDs on the lower-number processor; the secondary key is the neighboring
* elements global IDs. The secondary key is used when a single element
* must communicate with more than one neighbor.
*/
char *yo = "build_elem_comm_maps";
int i, j;
ELEM_INFO *elem;
ZOLTAN_ID_TYPE iadj_elem;
int iadj_proc;
int indx;
int num_alloc_maps;
int max_adj = 0;
int max_adj_per_map;
int cnt, offset;
int *sindex = NULL;
int tmp;
struct map_list_head *tmp_maps = NULL, *map = NULL;
DEBUG_TRACE_START(proc, yo);
/*
* Free the old maps, if they exist.
*/
if (mesh->ecmap_id != NULL) {
safe_free((void **)(void *) &(mesh->ecmap_id));
safe_free((void **)(void *) &(mesh->ecmap_cnt));
safe_free((void **)(void *) &(mesh->ecmap_elemids));
safe_free((void **)(void *) &(mesh->ecmap_sideids));
safe_free((void **)(void *) &(mesh->ecmap_neighids));
mesh->necmap = 0;
}
/*
* Look for off-processor adjacencies.
* Loop over all elements
*/
num_alloc_maps = MAP_ALLOC;
mesh->ecmap_id = (int *) malloc(num_alloc_maps * sizeof(int));
mesh->ecmap_cnt = (int *) malloc(num_alloc_maps * sizeof(int));
tmp_maps = (struct map_list_head*) malloc(num_alloc_maps
* sizeof(struct map_list_head));
if (mesh->ecmap_id == NULL || mesh->ecmap_cnt == NULL || tmp_maps == NULL) {
Gen_Error(0, "Fatal: insufficient memory");
DEBUG_TRACE_END(proc, yo);
return 0;
}
for (i = 0; i < mesh->num_elems; i++) {
elem = &(mesh->elements[i]);
for (j = 0; j < elem->adj_len; j++) {
/* Skip NULL adjacencies (sides that are not adjacent to another elem). */
if (elem->adj[j] == ZOLTAN_ID_INVALID) continue;
iadj_elem = elem->adj[j];
iadj_proc = elem->adj_proc[j];
if (iadj_proc != proc) {
/*
* Adjacent element is off-processor.
* Add this element to the temporary data structure for
* the appropriate neighboring processor.
*/
if ((indx = in_list2(iadj_proc, mesh->necmap, mesh->ecmap_id)) == -1) {
/*
* Start a new communication map.
*/
if (mesh->necmap >= num_alloc_maps) {
num_alloc_maps += MAP_ALLOC;
mesh->ecmap_id = (int *) realloc(mesh->ecmap_id,
num_alloc_maps * sizeof(int));
mesh->ecmap_cnt = (int *) realloc(mesh->ecmap_cnt,
num_alloc_maps * sizeof(int));
tmp_maps = (struct map_list_head *) realloc(tmp_maps,
num_alloc_maps * sizeof(struct map_list_head));
if (mesh->ecmap_id == NULL || mesh->ecmap_cnt == NULL ||
tmp_maps == NULL) {
Gen_Error(0, "Fatal: insufficient memory");
DEBUG_TRACE_END(proc, yo);
return 0;
}
}
mesh->ecmap_id[mesh->necmap] = iadj_proc;
mesh->ecmap_cnt[mesh->necmap] = 0;
map = &(tmp_maps[mesh->necmap]);
map->glob_id = (ZOLTAN_ID_TYPE *) malloc(MAP_ALLOC * sizeof(ZOLTAN_ID_TYPE));
map->elem_id = (int *) malloc(MAP_ALLOC * sizeof(int));
map->side_id = (int *) malloc(MAP_ALLOC * sizeof(int));
map->neigh_id = (ZOLTAN_ID_TYPE *) malloc(MAP_ALLOC * sizeof(ZOLTAN_ID_TYPE));
if (map->glob_id == NULL || map->elem_id == NULL ||
map->side_id == NULL || map->neigh_id == NULL) {
Gen_Error(0, "Fatal: insufficient memory");
DEBUG_TRACE_END(proc, yo);
return 0;
}
map->map_alloc_size = MAP_ALLOC;
indx = mesh->necmap;
mesh->necmap++;
}
/* Add to map for indx. */
map = &(tmp_maps[indx]);
if (mesh->ecmap_cnt[indx] >= map->map_alloc_size) {
map->map_alloc_size += MAP_ALLOC;
map->glob_id = (ZOLTAN_ID_TYPE *) realloc(map->glob_id,
map->map_alloc_size * sizeof(ZOLTAN_ID_TYPE));
map->elem_id = (int *) realloc(map->elem_id,
map->map_alloc_size * sizeof(int));
map->side_id = (int *) realloc(map->side_id,
map->map_alloc_size * sizeof(int));
map->neigh_id = (ZOLTAN_ID_TYPE *) realloc(map->neigh_id,
map->map_alloc_size * sizeof(ZOLTAN_ID_TYPE));
if (map->glob_id == NULL || map->elem_id == NULL ||
map->side_id == NULL || map->neigh_id == NULL) {
Gen_Error(0, "Fatal: insufficient memory");
DEBUG_TRACE_END(proc, yo);
return 0;
}
}
tmp = mesh->ecmap_cnt[indx];
map->glob_id[tmp] = elem->globalID;
map->elem_id[tmp] = i;
map->side_id[tmp] = j+1; /* side is determined by position in adj array (+1 since not 0-based). */
map->neigh_id[tmp] = iadj_elem;
mesh->ecmap_cnt[indx]++;
max_adj++;
}
}
}
/*
* If no communication maps, don't need to do anything else.
*/
if (mesh->necmap > 0) {
/*
* Allocate data structure for element communication map arrays.
*/
mesh->ecmap_elemids = (int *) malloc(max_adj * sizeof(int));
mesh->ecmap_sideids = (int *) malloc(max_adj * sizeof(int));
mesh->ecmap_neighids = (ZOLTAN_ID_TYPE *) malloc(max_adj * sizeof(ZOLTAN_ID_TYPE));
/*
* Allocate temporary memory for sort index.
*/
max_adj_per_map = 0;
for (i = 0; i < mesh->necmap; i++)
if (mesh->ecmap_cnt[i] > max_adj_per_map)
max_adj_per_map = mesh->ecmap_cnt[i];
sindex = (int *) malloc(max_adj_per_map * sizeof(int));
cnt = 0;
for (i = 0; i < mesh->necmap; i++) {
map = &(tmp_maps[i]);
for (j = 0; j < mesh->ecmap_cnt[i]; j++)
sindex[j] = j;
/*
* Sort the map so that adjacent processors have the same ordering
* for the communication.
* Assume the ordering of the lower-numbered processor in the pair
* of communicating processors.
*/
if (proc < mesh->ecmap_id[i])
quicksort_pointer_inc_id_id(sindex, map->glob_id, map->neigh_id,
0, mesh->ecmap_cnt[i]-1);
else
quicksort_pointer_inc_id_id(sindex, map->neigh_id, map->glob_id,
0, mesh->ecmap_cnt[i]-1);
/*
* Copy sorted data into elem map arrays.
*/
offset = cnt;
for (j = 0; j < mesh->ecmap_cnt[i]; j++) {
mesh->ecmap_elemids[offset] = map->elem_id[sindex[j]];
mesh->ecmap_sideids[offset] = map->side_id[sindex[j]];
mesh->ecmap_neighids[offset] = map->neigh_id[sindex[j]];
offset++;
}
cnt += mesh->ecmap_cnt[i];
}
}
/* Free temporary data structure. */
for (i = 0; i < mesh->necmap; i++) {
safe_free((void **)(void *) &(tmp_maps[i].glob_id));
safe_free((void **)(void *) &(tmp_maps[i].elem_id));
safe_free((void **)(void *) &(tmp_maps[i].side_id));
safe_free((void **)(void *) &(tmp_maps[i].neigh_id));
}
safe_free((void **)(void *) &tmp_maps);
safe_free((void **)(void *) &sindex);
if (Test.DDirectory)
compare_maps_with_ddirectory_results(proc, mesh);
DEBUG_TRACE_END(proc, yo);
return 1;
}
/******************************************************************************/
/******************************************************************************/
static void compare_maps_with_ddirectory_results(
int proc,
MESH_INFO_PTR mesh
)
{
/*
* Routine to demonstrate the use of the Zoltan Distributed Directory
* to build communication maps. This functionality essentially duplicates
* that in build_elem_comm_maps. It provides a test of the DDirectory,
* as the maps generated by the directory should match those generated
* by build_elem_comm_maps.
* This test is probably more complicated than necessary, but perhaps it
* will be adapted to become a communication maps tool within Zoltan.
*/
static const int want_size = 4;
int num_elems = mesh->num_elems;
int max_nelems;
Zoltan_DD_Directory *dd = NULL;
Zoltan_DD_Directory *ddCopy = NULL;
ZOLTAN_ID_PTR gids = NULL;
ZOLTAN_ID_PTR lids = NULL;
ZOLTAN_ID_PTR my_gids = NULL;
ZOLTAN_ID_PTR nbor_gids = NULL;
ZOLTAN_ID_PTR nbor_lids = NULL;
ZOLTAN_ID_PTR i_want = NULL;
ZOLTAN_ID_PTR others_want = NULL;
int *ownerlist = NULL;
int *sindex = NULL;
int num_nbor = 0; /* Number of neighboring elements not on this processor. */
/* This counter counts duplicate entries when an element */
/* is a neighbor of > 1 element on this processor. */
int cnt;
int num_others = 0;
int num_maps = 0;
int map_size = 0;
int max_map_size = 0;
int nbor_proc;
int i, j, k, ierr, error = 0, gerror = 0;
ELEM_INFO_PTR current;
struct map_list_head map;
ZOLTAN_COMM_OBJ *comm, *comm_copy;
if (proc == 0) printf("Testing DDirectory\n");
/* Load array of element globalIDs for elements on this processor. */
/* Count number of neighboring elements not on this processor. */
gids = (ZOLTAN_ID_PTR) malloc(sizeof(ZOLTAN_ID_TYPE) * 2 * num_elems);
if (num_elems > 0 && gids == NULL) {
Gen_Error(0, "Fatal: insufficient memory");
error = 1;
}
lids = gids + num_elems;
for (i = 0; i < num_elems; i++) {
current = &(mesh->elements[i]);
gids[i] = current->globalID;
lids[i] = (ZOLTAN_ID_TYPE)i;
for (j = 0; j < current->adj_len; j++) {
/* Skip NULL adjacencies (sides that are not adjacent to another elem). */
if (current->adj[j] == ZOLTAN_ID_INVALID) continue;
if (current->adj_proc[j] != proc)
num_nbor++;
}
}
/*
* Create DDirectory and register all owned elements.
*/
MPI_Allreduce(&num_elems, &max_nelems, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
ierr = Zoltan_DD_Create(&dd, MPI_COMM_WORLD, 1, 1, 0, max_nelems, 0);
if (ierr) {
Gen_Error(0, "Fatal: Error returned by Zoltan_DD_Create");
error = 1;
}
/*
* Test DD copy functions
*/
if (proc == 0) printf(" Test DD_Copy\n");
ddCopy = Zoltan_DD_Copy(dd);
if (!ddCopy){
Gen_Error(0, "Fatal: Error returned by Zoltan_DD_Copy");
error = 1;
}
if (proc == 0) printf(" Test DD_Copy_To\n");
ierr = Zoltan_DD_Copy_To(&dd, ddCopy);
if (ierr != ZOLTAN_OK){
Gen_Error(0, "Fatal: Error returned by Zoltan_DD_Copy_to");
error = 1;
}
/*
* Test the use of a user provided hash function in one copy.
*/
Zoltan_DD_Set_Hash_Fn(ddCopy, zdrive_hash);
if (proc == 0) printf(" Test Update dd\n");
ierr = Zoltan_DD_Update(dd, gids, lids, NULL, NULL, num_elems);
if (ierr) {
Gen_Error(0, "Fatal: Error returned by Zoltan_DD_Update of dd");
error = 1;
}
if (proc == 0) printf(" Test Update ddCopy\n");
ierr = Zoltan_DD_Update(ddCopy, gids, lids, NULL, NULL, num_elems);
if (ierr) {
Gen_Error(0, "Fatal: Error returned by Zoltan_DD_Update ddCopy");
error = 1;
}
free(gids);
/*
* Use the DDirectory to find owners of off-processor neighboring elements.
* Of course, we have this info in ELEM_INFO, but we do the find to test
* the DDirectory.
*/
nbor_gids = (ZOLTAN_ID_PTR) malloc(sizeof(ZOLTAN_ID_TYPE) * 3 * num_nbor);
if (num_nbor > 0 && nbor_gids == NULL) {
Gen_Error(0, "Fatal: insufficient memory");
error = 1;
}
nbor_lids = nbor_gids + num_nbor;
my_gids = nbor_lids + num_nbor;
ownerlist = (int *) malloc(sizeof(int) * num_nbor);
/*
* Get list of elements whose info is needed.
*/
cnt = 0;
for (i = 0; i < num_elems; i++) {
current = &(mesh->elements[i]);
for (j = 0; j < current->adj_len; j++) {
/* Skip NULL adjacencies (sides that are not adjacent to another elem). */
if (current->adj[j] == ZOLTAN_ID_INVALID) continue;
if (current->adj_proc[j] != proc) {
nbor_gids[cnt] = current->adj[j];
my_gids[cnt] = current->globalID;
cnt++;
}
}
}
/* Sanity check */
if (cnt != num_nbor) {
Gen_Error(0, "Fatal: cnt != num_nbor");
error = 1;
}
if (proc == 0) printf(" Test Find ddCopy\n");
ierr = Zoltan_DD_Find(ddCopy, nbor_gids, nbor_lids,
NULL, NULL, num_nbor, ownerlist);
if (ierr) {
Gen_Error(0, "Fatal: Error returned by Zoltan_DD_Find of ddCopy");
error = 1;
}
if (proc == 0) printf(" Test Find dd\n");
ierr = Zoltan_DD_Find(dd, nbor_gids, nbor_lids,
NULL, NULL, num_nbor, ownerlist);
if (ierr) {
Gen_Error(0, "Fatal: Error returned by Zoltan_DD_Find of dd");
error = 1;
}
if (proc == 0) printf(" Test Destroy\n");
Zoltan_DD_Destroy(&dd);
Zoltan_DD_Destroy(&ddCopy);
/*
* Check for errors
*/
MPI_Allreduce(&error, &gerror, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
if (gerror) {
Gen_Error(0, "Fatal: Error returned by DDirectory Test");
error_report(proc);
free(nbor_gids);
free(ownerlist);
return;
}
/*
* Use the Communication library to invert this information and build
* communication maps.
* We know what to receive and from where; compute what to send and
* to whom.
* Again, this info was computed by build_elem_com_maps, but we are
* testing DDirectory here.
*/
/*
* Build list of off-proc elements (and their owners)
* that this proc wants.
* This list includes duplicate entries when an element
* is a neighbor of > 1 element on this processor.
*/
i_want = (ZOLTAN_ID_PTR) malloc(sizeof(ZOLTAN_ID_TYPE) * want_size * num_nbor);
if (num_nbor > 0 && i_want == NULL) {
Gen_Error(0, "Fatal: insufficient memory");
return;
}
j = 0;
for (i = 0; i < num_nbor; i++) {
i_want[j++] = proc;
i_want[j++] = nbor_gids[i];
i_want[j++] = nbor_lids[i];
i_want[j++] = my_gids[i];
}
ierr = Zoltan_Comm_Create(&comm, num_nbor, ownerlist, MPI_COMM_WORLD, 747,
&num_others);
if (ierr) {
Gen_Error(0, "Fatal: Error returned from Zoltan_Comm_Create");
return;
}
/*
* Test the copy functions
*/
comm_copy = Zoltan_Comm_Copy(comm);
if (!comm_copy){
Gen_Error(0, "Fatal: Error returned from Zoltan_Comm_Copy");
return;
}
ierr = Zoltan_Comm_Copy_To(&comm, comm_copy);
if (ierr){
Gen_Error(0, "Fatal: Error returned from Zoltan_Comm_Copy_To");
return;
}
Zoltan_Comm_Destroy(&comm_copy);
/*
* Do communication to determine which of this proc's data is wanted by
* other procs.
* This info will determine what is put in this proc's communication maps.
*/
others_want = (ZOLTAN_ID_PTR) malloc(sizeof(ZOLTAN_ID_TYPE)*want_size*(num_others+1));
if (others_want == NULL) {
Gen_Error(0, "Fatal: insufficient memory");
return;
}
ierr = Zoltan_Comm_Do(comm, 757, (char *) i_want, want_size * sizeof(ZOLTAN_ID_TYPE),
(char *) others_want);
if (ierr) {
Gen_Error(0, "Fatal: Error returned from Zoltan_Comm_Do");
return;
}
free(i_want);
ierr = Zoltan_Comm_Destroy(&comm);
if (ierr) {
Gen_Error(0, "Fatal: Error returned from Zoltan_Comm_Destroy");
return;
}
/*
* Find number of maps and the size of the largest map.
* The maps should be grouped by neighboring processor
* in others_want.
*/
num_maps = 0;
map_size = max_map_size = 0;
for (i = 0, j = 0; i < num_others; i++, j += want_size) {
nbor_proc = others_want[j];
map_size++;
if (i == (num_others - 1) || nbor_proc != (int) others_want[j+want_size]) {
/* End of map reached */
num_maps++;
if (map_size > max_map_size) max_map_size = map_size;
map_size = 0;
}
}
if (num_maps != mesh->necmap) {
printf("%d DDirectory Test: Different number of maps: "
"%d != %d\n", proc, num_maps, mesh->necmap);
}
/*
* For each map,
* build a map_list_head for the map;
* sort the map_list_head appropriately (as in build_elem_comm_maps);
* compare sorted lists with actually communication maps.
*/
sindex = (int *) malloc(max_map_size * sizeof(int));
if (max_map_size > 0 && sindex == NULL) {
Gen_Error(0, "Fatal: insufficient memory");
return;
}
map.map_alloc_size = max_map_size;
map.elem_id = (int *) malloc(max_map_size * sizeof(int));
map.side_id = (int *) malloc(max_map_size * sizeof(int));
map.glob_id = (ZOLTAN_ID_TYPE *) malloc(max_map_size * sizeof(ZOLTAN_ID_TYPE));
map.neigh_id= (ZOLTAN_ID_TYPE *) malloc(max_map_size * sizeof(ZOLTAN_ID_TYPE));
if (max_map_size > 0 && map.neigh_id == NULL) {
Gen_Error(0, "Fatal: insufficient memory");
return;
}
if (Debug_Driver > 3) {
/* For high debug levels, serialize the following section so that
* output of generated map is serialized (and not junked up).
*/
print_sync_start(proc, 1);
}
map_size = 0;
for (i = 0, j = 0; i < num_others; i++, j += want_size) {
nbor_proc = others_want[j];
map.glob_id[map_size] = others_want[j+1];
map.elem_id[map_size] = others_want[j+2];
current = &(mesh->elements[map.elem_id[map_size]]);
for (k = 0; k < current->adj_len; k++) {
/* Skip NULL adjacencies (sides that are not adjacent to another elem). */
if (current->adj[k] == ZOLTAN_ID_INVALID) continue;
if (current->adj_proc[k] == nbor_proc &&
current->adj[k] == others_want[j+3]) {
map.side_id[map_size] = k + 1;
map.neigh_id[map_size] = current->adj[k];
break;
}
}
map_size++;
if (i == (num_others-1) || nbor_proc != (int) others_want[j+want_size]) {
/*
* End of map has been reached.
* Sort and compare the current map.
*/
sort_and_compare_maps(proc, nbor_proc, mesh, &map, map_size, sindex);
/*
* Reinitialize data structures for new map.
*/
map_size = 0;
}
}
if (Debug_Driver > 3) {
/* For high debug levels, serialize the previous section so that
* output of generated map is serialized (and not junked up).
*/
int nprocs;
MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
print_sync_end(proc, nprocs, 1);
}
free(map.glob_id);
free(map.elem_id);
free(map.side_id);
free(map.neigh_id);
free(sindex);
free(nbor_gids);
free(ownerlist);
free(others_want);
}
static void sort_and_compare_maps(
int proc,
int nbor_proc,
MESH_INFO_PTR mesh,
struct map_list_head *map,
int map_size,
int *sindex
)
{
/*
* Routine to sort a given communication map for a single neighbor processor
* and compare it to the actual communication map for that processor
* (generated by build_elem_comm_maps).
* If the DDirectory were used to build comm maps, this routine could be
* modified to do the assignments to mesh->ecmap_*, rather than do comparisons
* with it.
*/
int i, j;
int cnt = 0;
int indx;
/*
* Sort the given map according to element ids.
* Primary key is determined as in build_elem_comm_maps.
*/
for (i = 0; i < map_size; i++)
sindex[i] = i;
if (proc < nbor_proc)
quicksort_pointer_inc_id_id(sindex, map->glob_id, map->neigh_id,
0, map_size-1);
else
quicksort_pointer_inc_id_id(sindex, map->neigh_id, map->glob_id,
0, map_size-1);
/*
* Compute offset into mesh communication maps for the given nbor proc.
*/
if ((indx = in_list2(nbor_proc, mesh->necmap, mesh->ecmap_id)) == -1) {
printf("%d DDirectory Test: Comm map for nbor proc %d does not exist\n",
proc, nbor_proc);
return;
}
cnt = 0;
for (i = 0; i < indx; i++)
cnt += mesh->ecmap_cnt[i];
/*
* Compare given map to mesh communication map for this nbor proc.
* If the DDirectory code were used to construct maps, assignments
* would be done here (rather than comparisons).
*/
if (map_size != mesh->ecmap_cnt[indx]) {
printf("%d DDirectory Test: Different map size for nbor_proc %d: "
"%d != %d\n", proc, nbor_proc, map_size, mesh->ecmap_cnt[indx]);
return;
}
for (i = 0; i < map_size; i++) {
j = sindex[i];
if (map->elem_id[j] != mesh->ecmap_elemids[i+cnt]) {
printf("%d DDirectory Test: Different element IDs for nbor_proc %d: "
"%d != %d\n", proc, nbor_proc, map->elem_id[j],
mesh->ecmap_elemids[i+cnt]);
}
}
for (i = 0; i < map_size; i++) {
j = sindex[i];
if (map->side_id[j] != mesh->ecmap_sideids[i+cnt]) {
printf("%d DDirectory Test: Different side IDs for nbor_proc %d: "
"%d != %d\n", proc, nbor_proc, map->side_id[j],
mesh->ecmap_sideids[i+cnt]);
}
}
for (i = 0; i < map_size; i++) {
j = sindex[i];
if (map->neigh_id[j] != mesh->ecmap_neighids[i+cnt]) {
printf("%d DDirectory Test: Different neigh IDs for nbor_proc %d: "
ZOLTAN_ID_SPEC " != " ZOLTAN_ID_SPEC "\n", proc, nbor_proc, map->neigh_id[j],
mesh->ecmap_neighids[i+cnt]);
}
}
if (Debug_Driver > 3) {
printf("%d ************* DDirectory Map for %d ***************\n",
proc, nbor_proc);
printf("Local ID\tSide ID\tGlobal ID\tNeigh ID\n");
for (i = 0; i < map_size; i++) {
j = sindex[i];
printf("\t%d\t%d\t" ZOLTAN_ID_SPEC "\t" ZOLTAN_ID_SPEC "\n",
map->elem_id[j], map->side_id[j],
map->glob_id[j], map->neigh_id[j]);
}
}
}
#ifdef __cplusplus
} /* closing bracket for extern "C" */
#endif

Some files were not shown because too many files have changed in this diff Show More