diff --git a/.ci/env/derecho.sh b/.ci/env/derecho.sh new file mode 100755 index 0000000000..2feea5c9ee --- /dev/null +++ b/.ci/env/derecho.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +echo "Setting up derecho environment" +workingDirectory=$PWD +. /etc/profile.d/z00_modules.sh +echo "Loading modules : $*" +cmd="module purge" +echo $cmd && eval "${cmd}" + +# We should be handed in the modules to load +while [ $# -gt 0 ]; do + cmd="module load $1" + echo $cmd && eval "${cmd}" + shift +done + +# Go back to working directory if for unknown reason HPC config changing your directory on you +if [ "$workingDirectory" != "$PWD" ]; then + echo "derecho module loading changed working directory" + echo " Moving back to $workingDirectory" + cd $workingDirectory +fi diff --git a/.ci/env/helpers.sh b/.ci/env/helpers.sh new file mode 100644 index 0000000000..2ddd560893 --- /dev/null +++ b/.ci/env/helpers.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +# Useful string manipulation functions, leaving in for posterity +# https://stackoverflow.com/a/8811800 +# contains(string, substring) +# +# Returns 0 if the specified string contains the specified substring, +# otherwise returns 1. +contains() +{ + string="$1" + substring="$2" + + if [ "${string#*"$substring"}" != "$string" ]; then + echo 0 # $substring is in $string + else + echo 1 # $substring is not in $string + fi +} + +setenvStr() +{ + # Changing IFS produces the most consistent results + tmpIFS=$IFS + IFS="," + string="$1" + for s in $string; do + if [ ! -z $s ]; then + eval "echo export \"$s\"" + eval "export \"$s\"" + fi + done + IFS=$tmpIFS +} + +banner() +{ + lengthBanner=$1 + shift + # https://www.shellscript.sh/examples/banner/ + printf "#%${lengthBanner}s#\n" | tr " " "=" + printf "# %-$(( ${lengthBanner} - 2 ))s #\n" "`date`" + printf "# %-$(( ${lengthBanner} - 2 ))s #\n" " " + printf "# %-$(( ${lengthBanner} - 2 ))s #\n" "$*" + printf "#%${lengthBanner}s#\n" | tr " " "=" +} diff --git a/.ci/env/hostenv.sh b/.ci/env/hostenv.sh new file mode 100644 index 0000000000..208d1e57f3 --- /dev/null +++ b/.ci/env/hostenv.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +# Allow selection of hostname, and if none is provided use the current machine +# While this may seem unintuitive at first, it provides the flexibility of using +# "named" configurations without being explicitly tied to fqdn +hostname=$AS_HOST +if [ -z "$hostname" ]; then + hostname=$( python3 -c "import socket; print( socket.getfqdn() )" ) +fi + +if [ $( contains ${hostname} hsn.de.hpc ) -eq 0 ]; then + # Derecho HPC SuSE PBS + . .ci/env/derecho.sh +else + echo "No known environment for '${hostname}', using current" +fi diff --git a/.ci/hpc-workflows b/.ci/hpc-workflows new file mode 160000 index 0000000000..97ca807b0e --- /dev/null +++ b/.ci/hpc-workflows @@ -0,0 +1 @@ +Subproject commit 97ca807b0e1b7d67a35ab10e938b29774242e48e diff --git a/.ci/mpas_compilation.jsonc b/.ci/mpas_compilation.jsonc new file mode 100644 index 0000000000..31e393e261 --- /dev/null +++ b/.ci/mpas_compilation.jsonc @@ -0,0 +1,48 @@ +// MPAS Compilation tests +{ + "submit_options" : + { + // Default values + "timelimit" : "00:15:00", + "working_directory" : "..", + "arguments" : + { + "base_env_numprocs" : [ "-e", "NUM_PROCS=4" ], + + ".*make.*::args_build_core" : [ "-c", "atmosphere" ], + ".*debug.*::args_build_debug" : [ "-d" ], + ".*make.*::args_build_options" : [ "-b", "-j $NUM_PROCS" ], + ".*make.*gnu.*::args_target" : [ "-t", "gnu" ] + }, + // Derecho-specifics + "hsn.de.hpc" : + { + "submission" : "PBS", + "queue" : "main", + "hpc_arguments" : + { + "node_select" : { "-l " : { "select" : 1, "ncpus" : 16 } }, + "priority" : { "-l " : { "job_priority" : "economy" } } + }, + "arguments" : + { + // We want NUM_PROCS to match ncpus + "base_env_numprocs" : [ "-e", "NUM_PROCS=16" ], + "very_last_modules" : [ "cray-mpich", "parallel-netcdf" ], + ".*gnu.*::test_modules" : [ "gcc/12.2.0" ] + } + } + }, + // Specific GNU compilation test + "make-gnu" : + { + "steps" : + { + // Eventually include debug and other compile modes + "optimized" : + { + "command" : ".ci/tests/build.sh" + } + } + } +} diff --git a/.ci/tests/build.sh b/.ci/tests/build.sh new file mode 100755 index 0000000000..3431007f52 --- /dev/null +++ b/.ci/tests/build.sh @@ -0,0 +1,90 @@ +#!/bin/sh +help() +{ + echo "./build.sh as_host workingdir [options] [-- ]" + echo " as_host First argument must be the host configuration to use for environment loading" + echo " workingdir Second argument must be the working dir to immediate cd to" + echo " -b Additional make arguments passed in" + echo " -c Core to build" + echo " -t Target configuration (gnu, intel, etc)" + echo " -d Debug build" + echo " -e environment variables in comma-delimited list, e.g. var=1,foo,bar=0" + echo " -- Directly pass options to hostenv.sh, equivalent to hostenv.sh " + echo " -h Print this message" + echo "" + echo "If you wish to use an env var in your arg such as '-b core=\$CORE -e CORE=atmosphere', you must" + echo "you will need to do '-b \\\$CORE -e CORE=atmosphere' to delay shell expansion" +} + +echo "Input arguments:" +echo "$*" + +AS_HOST=$1 +shift +if [ $AS_HOST = "-h" ]; then + help + exit 0 +fi + +workingDirectory=$1 +shift + +cd $workingDirectory + +# Get some helper functions, AS_HOST must be set by this point to work +. .ci/env/helpers.sh + +while getopts b:c:t:de:h opt; do + case $opt in + b) + buildCommand="$OPTARG" + ;; + c) + core="$OPTARG" + ;; + t) + target="$OPTARG" + ;; + d) + debug="DEBUG=true" + ;; + e) + envVars="$envVars,$OPTARG" + ;; + h) help; exit 0 ;; + *) help; exit 1 ;; + :) help; exit 1 ;; + \?) help; exit 1 ;; + esac +done + +shift "$((OPTIND - 1))" + +# Everything else goes to our env setup, POSIX does not specify how to pass in +# arguments to sourced script, but all args are already shifted. This is left for +# posterity to "show" what is happening and the assumption of the remaining args +. .ci/env/hostenv.sh $* + +# Now evaluate env vars in case it pulls from hostenv.sh +if [ ! -z "$envVars" ]; then + setenvStr "$envVars" +fi + +# Re-evaluate input values for delayed expansion +eval "core=\"$core\"" +eval "target=\"$target\"" +eval "buildCommand=\"$buildCommand\"" + +make clean CORE=$core + +echo "Compiling with options $target core=$core $debug $buildCommand" +echo "make $target CORE=$core $debug $buildCommand" +make $target CORE=$core $debug $buildCommand +result=$? + +if [ $result -ne 0 ]; then + echo "Failed to compile" + exit 1 +fi + +echo "TEST $(basename $0) PASS" diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..c96aa594e8 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule ".ci/hpc-workflows"] + path = .ci/hpc-workflows + url = https://github.com/islas/hpc-workflows/