#!/bin/bash # Copyright(C) 1999-2020, 2023 National Technology & Engineering Solutions # of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with # NTESS, the U.S. Government retains certain rights in this software. # # See packages/seacas/LICENSE for details ######################################################################## function usage { if [ $OLDGETOPT -eq 1 ] ; then usage_old else usage_new fi } function usage_new { cat < [-n ] [--root ] [--subdir ] [--spread_suffix ] [--multikl] [--spectral] [--inertial] [--linear] [--rcb] [--rcb_ignore_z] [--rib] [--hsfc] [--random] [--scattered] [--weight ] [...others...] meshfile.ext Decomposition methods: [0..3] = speed ranking 0=fastest (See chaco and/or zoltan documentation for more details) --multikl: [3] Multilevel KL. Gives high quality partitions. Slow, high memory use. --spectral: [2] use eigenvectors of a matrix constructed from the graph to partition the graph. --hsfc [?] Hilbert Space-Filling Curve (uses Zoltan) --rib: [?] (default) Recursive Inertial Bisection (uses Zoltan) --rcb: [?] Recursive Coordinate Bisection (uses Zoltan) --rcb_ignore_z: [?] Recursive Coordinate Bisection (uses Zoltan), ignoring the z dimension coordinates --inertial: [1] vertices divided into sets of equal mass by planes orthogonal to the principle axis. Good, fast, medium memory --linear: [0] vertices in order first n/p to proc 0, next to proc 1. (fast and sometimes good). --random: [0] vertices are assigned randomly to sets in a way that preserves balance. --scattered: [0] vertices are handed out in order with the next vertex going to whichever set is smallest. --brick [-] special decomposition method; not useful for general use. --zpinch [-] special decomposition method; not useful for general use. NOTE: The decomposition options can also be specified as "-l type" For example "--multikl" is the same as "-l multikl" Other options: --help Print this message (-h) --launch Prefix nem_slice call with this command to run it. The cmd argument must be quoted if it contains options for cmd. --nolaunch Prevent decomp from searching for launch script. --noop Only echo the nem_slice and nem_spread commands. --nodal Nodal Decomposition (-N) --elemental Elemental Decomposition (default, -E) --input Optional nem_slice input file (-i) --weight Specification of weighting options (-w) --viz_mesh Output mesh showing processor distribution of elements. (-V) --spheres_linear Decompose sphere elements using linear method (matches old behavior) (-s) --processors <#p> Specify number of processors (-p, -j) --root Root directory to begin the path to on the separate disks (-R) --subdir Continuation of the path on the separate disks to the files (-S) --spread_suffix Suffix for parallel files (default: meshfile suffix) (-X) --64 Force creation of 64-bit integer decomposed files (-6) -n Specify additional nem_slice options Documentation: https://sandialabs.github.io/seacas-docs/sphinx/html/index.html#decomp" help-email: sierra-help@sandia.gov DECOMP_USAGE_EOF exit 1 } function usage_old { cat < [-n ] [-R ] [-S ] [-X ] [-l multikl] [-l spectral] [-l inertial] [-l linear] [-l rcb] [-l rcb_ignore_z] [-l rib] [-l hsfc] [-l random] [-l scattered] [...others...] meshfile.ext Decomposition methods: [0..3] = speed ranking 0=fastest (See chaco and/or zoltan documentation for more details) -l multikl: [3] Multilevel KL. Gives high quality partitions. Slow, high memory use. -l spectral: [2] use eigenvectors of a matrix constructed from the graph to partition the graph. -l hsfc [?] Hilbert Space-Filling Curve (uses Zoltan) -l rib: [?] (default) Recursive Inertial Bisection (uses Zoltan) -l rcb: [?] Recursive Coordinate Bisection (uses Zoltan) -l rcb_ignore_z: [?] Recursive Coordinate Bisection (uses Zoltan) ignoring the z dimension coordinates -l inertial: [1] vertices divided into sets of equal mass by planes orthogonal to the principle axis. Good, fast, medium memory -l linear: [0] vertices in order first n/p to proc 0, next to proc 1. (fast and sometimes good). -l random: [0] vertices are assigned randomly to sets in a way that preserves balance. -l scattered: [0] vertices are handed out in order with the next vertex going to whichever set is smallest. -l brick [-] special decomposition method; not useful for general use. -l zpinch [-] special decomposition method; not useful for general use. Other options: -N Nodal Decomposition -E Elemental Decomposition (default) -n options Specify nem_slice options -h Print this message -i Optional nem_slice input file -s Decompose sphere elements using linear method (matches old behavior) -p #p Specify number of processors (or -j) -R root_dir Root directory to begin the path to on the separate disks -S sub_dir Continuation of the path on the separate disks to the files -X suffix Suffix for parallel files (default: meshfile suffix) -V Output mesh showing processor distribution of elements -6 Force creation of 64-bit integer decomposed files Documentation: https://sandialabs.github.io/seacas-docs/sphinx/html/index.html#decomp" help-email: sierra-help@sandia.gov DECOMP_USAGE_EOF exit 1 } function old_getopt { echo ${txtred} cat < $pexsh echo "LB file = $nemesis" >> $pexsh echo "Parallel Results File Base Name = $basename" >> $pexsh echo "File Extension for Spread Files = .$suffix_spread" >> $pexsh echo "Number of Processors = $numproc " >> $pexsh if [ "$debug_level" != "0" ] then echo "Debug = $debug_level" >> $pexsh fi echo "------------------------------------------------------------" >> $pexsh echo " Parallel I/O section" >> $pexsh echo "------------------------------------------------------------" >> $pexsh echo "Parallel Disk Info= number=1, offset=1, zeros, nosubdirectory">> $pexsh echo "Parallel file location = root=$rootdir, subdir=$subdir" >> $pexsh echo ${txtblu} echo "Executing:" echo " $NEM_SPREAD $use64 $pexsh" echo ${txtrst} ${NOOP:+echo }$NEM_SPREAD $use64 $pexsh } ######################################################################## # initialize variables # Text color variables if [[ $TERM == *"xterm"* ]] || [[ $TERM == "screen" ]]; then txtund=$(tput sgr 0 1) # Underline txtbld=$(tput bold) # Bold txtred=$(tput setaf 1) # Red txtgrn=$(tput setaf 2) # Green txtylw=$(tput setaf 3) # Yellow txtblu=$(tput setaf 4) # Blue txtpur=$(tput setaf 5) # Purple txtcyn=$(tput setaf 6) # Cyan txtwht=$(tput setaf 7) # White txtrst=$(tput sgr0) # Text reset else export TERM=dumb txtund="" txtbld="" txtred="" txtgrn="" txtylw="" txtblu="" txtpur="" txtcyn="" txtwht="" txtrst="" fi basename='' processors='' debug_level='0' decomp_type="-e" decomp_method="-l rib" nem_slice_flag="-c" weighting='' rootdir="$(pwd)/" subdir="." suffix_spread='' spheres="-S" do_viz="" curdir=$(pwd) use64="" ACCESSBIN=$(dirname "$0") ACCESSBIN=$(cd "${ACCESSBIN}" && pwd) NEM_SLICE=${ACCESSBIN}/nem_slice NEM_SPREAD=${ACCESSBIN}/nem_spread NOOP= ######################################################################## # Test that the getopt being used will handle the long options... TEST=$(getopt -T) if [ $? != 4 ] ; then old_getopt OLDGETOPT=1 else OLDGETOPT=0 fi if [ $# -eq 0 ] ; then usage fi ######################################################################## # decomp options: if [ $OLDGETOPT -eq 1 ] ; then TEMP=$(getopt Hh6ENn:i:o:p:j:r:R:S:X:sl:vVd: "$@") else TEMP=$(getopt -o Hh6ENn:i:o:p:j:r:R:S:X:sl:vVd:w: -a \ --long input: \ --long launch: \ --long nolaunch \ --long noop \ --long help \ --long nem_slice_flag \ --long 64 \ --long processors: \ --long rootdir: \ --long subdir: \ --long spread_suffix: \ --long spheres_linear \ --long viz_mesh \ --long verbose \ --long debug: \ --long nodal \ --long elemental \ --long multikl \ --long rcb \ --long rcb_ignore_z \ --long rib \ --long hsfc \ --long spectral \ --long inertial \ --long linear \ --long random \ --long scattered \ --long brick \ --long zpinch \ --long weight: \ -n 'decomp' -- "$@") fi if [ $? != 0 ] ; then usage ; exit 1 ; fi # Note the quotes around `$TEMP': they are essential! eval set -- "$TEMP" while true ; do case "$1" in (-h|--help) usage ; shift ;; (-H|--help) usage_new ; shift ;; (-v|--verbose) set -x ; shift ;; (-V|--viz_mesh) do_viz="-y" ; shift ;; (-d|--debug) debug_level="$2" ; shift 2 ;; (-n|--nem_slice_flag) nem_slice_flag="$2" ; shift 2 ;; (-N|--nodal) decomp_type="-n" ; shift ;; (-E|--elemental) decomp_type="-e" ; shift ;; (-i|--input) input=$2 ; shift 2 ;; (-w|--weight) weighting="-w $2" ; shift 2 ;; (-p|-j|--processors) processors=$2 ; shift 2 ;; (-R|--rootdir) rootdir=$2 ; shift 2 ;; (-S|--subdir) subdir=$2 ; shift 2 ;; (-X|--spread_suffix) suffix_spread=$2 ; shift 2 ;; (-s|--spheres_linear) spheres="" ; shift ;; (-6|--64) use64="-64" ; shift ;; (--noop) NOOP="--noop" ; shift ;; (--launch) LAUNCH="$2" ; shift 2 ;; (--nolaunch) LAUNCH="nolaunch" ; shift ;; (-l) decomp_method="-l $2" ; shift 2 ;; # Decomposition Method options... (--multikl) decomp_method="-l multikl" ; shift ;; (--rcb) decomp_method="-l rcb" ; shift ;; (--rcb_ignore_z) decomp_method="-l rcb,ignore_z" ; shift ;; (--rib) decomp_method="-l rib" ; shift ;; (--hsfc) decomp_method="-l hsfc" ; shift ;; (--spectral) decomp_method="-l spectral" ; shift ;; (--inertial) decomp_method="-l inertial" ; shift ;; (--linear) decomp_method="-l linear" ; shift ;; (--random) decomp_method="-l random" ; shift ;; (--scattered) decomp_method="-l scattered" ; shift ;; (--brick) decomp_method="-l brick" ; shift ;; (--zpinch) decomp_method="-l zpinch" ; shift ;; (--) shift ; break ;; (*) echo "${txtred}ERROR: unrecognized option $1${txtrst}" ; shift ;; esac done # Figure out how to run nem_slice where we are. if [ "${LAUNCH:-}" == "nolaunch" ] then # Ensure launch is NOT used --nolaunch was passed. LAUNCH= else # If a specific launch script was passed and runs on the node we are on, use it. # If not, if Sierra launch command is in path and runs on the node we are on # we will try to use that. # If not we will run nem_slice directly (ie, w/o launch). if [ -z "${LAUNCH:-}" ] then LAUNCH=$(command -v launch) fi if [ -n "${LAUNCH}" ] then if [ $(basename $LAUNCH) == launch ] then # If 'launch' was found or passed, # Always run nem_slice with -n 1 LAUNCH="$LAUNCH -n 1" fi # If the launch script doesn't work to run something simple, don't use it. $LAUNCH >/dev/null 2>&1 true || LAUNCH= if [ -z "$PBS_JOBID" -a -z "$LSB_JOBID" -a -z "$SLURM_JOB_ID" ] then # Unset these if we we are NOT in an allocation. unset OMPI_MCA_btl_openib_ib_retry_count unset OMPI_MCA_btl_openib_ib_timeout export OMPI_MCA_mtl=^psm export OMPI_MCA_pml=^cm export OMPI_MCA_btl=tcp,vader,self if [ -n "${SIERRA_LIBRARY_PATH}" ] then export DYLD_LIBRARY_PATH=$SIERRA_LIBRARY_PATH fi fi fi fi ######################################################################## if [ $# -eq 0 ] ; then echo ${txtred} echo "ERROR:******************************************************************" echo "ERROR:" echo "ERROR: No 'meshfile' specified." echo "ERROR:" echo "ERROR:******************************************************************" echo ${txtrst} usage else if [ -e "$1" ] then file=$1 suffix_mesh=${file##*.} if test -z "$suffix_spread" then suffix_spread=$suffix_mesh fi basename=${file%.*} else echo ${txtred} echo "ERROR:******************************************************************" echo "ERROR:" echo "ERROR: $1 does not exist." echo "ERROR:" echo "ERROR:******************************************************************" echo ${txtrst} usage fi fi if [ -n "$input" ] then if [ ! -e "$input" ] then echo ${txtred} echo "ERROR:******************************************************************" echo "ERROR:" echo "ERROR: Input file $input does not exist." echo "ERROR:" echo "ERROR:******************************************************************" echo ${txtrst} usage fi fi if test -z "$processors" then echo echo ${txtred} echo "ERROR:***************************************************" echo "ERROR:" echo "ERROR: Must specify number of processors --processors (-p -j) option" echo "ERROR:" echo "ERROR:***************************************************" echo ${txtrst} echo usage fi if [ $processors -eq 1 ] then echo ${txtgrn} echo "INFO: No decomposition needed for --processors = 1" echo ${txtrst} echo exit 0 fi ######################################################################## execute_loadbalance "$basename" "$processors" "$decomp_method" "$nem_slice_flag" "$NEM_SLICE" "$input" "$LAUNCH" "$decomp_type" "$weighting" if [ $? -ne 0 ] then echo ${txtred} echo "ERROR:******************************************************************" echo "ERROR:" echo "ERROR During nem_slice execution. Check error output above and rerun" echo "ERROR:" echo "ERROR:******************************************************************" echo ${txtrst} exit 1 else echo "${txtgrn}...nem_slice successful execution${txtrst}" fi ######################################################################## execute_spread "$basename" "$rootdir" "$subdir" "$processors" "$NEM_SPREAD" if [ $? -ne 0 ] then echo ${txtred} echo "ERROR:******************************************************************" echo "ERROR:" echo "ERROR During nem_spread execution. Check error output above and rerun" echo "ERROR:" echo "ERROR:******************************************************************" echo ${txtrst} exit 1 else echo "${txtgrn}...nem_spread successful execution${txtrst}" fi echo "${txtgrn}DECOMP Successful Execution${txtrst}"