Skip to content

Commit 01641a5

Browse files
natalie-perlinNatalie Perlin
andauthored
[develop] Updated option to use PLATFORM=container instead of singularity (#1373)
* Updated option for PLATFORM=container for GNU and Intel compilers, to build and run SRW. Both GNU- and Intel-based compilers have Rockylinux9 and include spack-stack-libraries v1.9.2 for the current UFS WM and SRW App. * Both containers are staged on NOAA RDHPCs Tier-1 platforms in common locations. * GNU-based singularity/apptainer containers could be built on a community platform from a DockerHub repository image, and include GCC-13.3.1 compiler suite and OpenMPI 4.1.6. * Intel container that could be downloaded from a DockerHub repository does not include compilers or MPI. A workaround to build a combined container with all the libraries and compilers is suggested (in the Documentation) --------- Co-authored-by: Natalie Perlin <Natalie.Perlin@noaa.gov>
1 parent ee10788 commit 01641a5

23 files changed

Lines changed: 727 additions & 317 deletions

devbuild.sh

Lines changed: 96 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#!/usr/bin/env bash
2-
32
# usage instructions
43
usage () {
54
cat << EOF_USAGE
@@ -19,6 +18,8 @@ OPTIONS
1918
ATM (default) Atmosphere only
2019
ATMAQ Online-CMAQ (air quality)
2120
ATMF UFS_FIRE (coupled Community Fire Behavior Model)
21+
-v, --verbose
22+
build with verbose output
2223
--ccpp="CCPP_SUITE1,CCPP_SUITE2..."
2324
CCPP suites (CCPP_SUITES) to include in build; delimited with ','
2425
--enable-options="OPTION1,OPTION2,..."
@@ -52,8 +53,6 @@ OPTIONS
5253
number of build jobs; defaults to 4
5354
--use-sub-modules
5455
Use sub-component modules instead of top-level level SRW modules
55-
-v, --verbose
56-
build with verbose output
5756
5857
TARGETS
5958
default = builds the default list of components for the specified application
@@ -98,53 +97,94 @@ EOF_SETTINGS
9897

9998
# env. variables saved into singularity container environment file ufs-srw.env
10099
env_vars () {
101-
local vars_file="$1"
102100

103-
cat >"${vars_file}" <<EOF_ENV
101+
cat >"${SRW_ENV}" <<EOF_ENV
104102
PATH=${SRW_DIR}/${BIN_DIR}:${PATH}
105103
LD_LIBRARY_PATH=${LD_LIBRARY_PATH}
106-
CPATH=${CPATH}
104+
HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH:-}
105+
HDF5_USE_FILE_LOCKING=FALSE
106+
ESMFMKFILE=${ESMFMKFILE:-}
107+
CRTM_FIX=${CRTM_FIX:-}
108+
107109
EOF_ENV
108110
}
109111

110112
# Singularity gnu containers: make a wrapper script template for the UFS SRW binaries
111113
srw_binary_wrapper() {
112-
local wrapper="$1"
113-
local bind_dir=${BIND_DIR:-/home}
114-
if [[ -n "${BIND_ADD:-}" ]]; then
115-
local bind_add="-B ${BIND_ADD}"
114+
local img=""
115+
local bind_add=""
116+
local container=""
117+
if [[ -n "${APPTAINER_CONTAINER:-}" ]]; then
118+
container=APPTAINER
119+
img="${APPTAINER_CONTAINER}"
120+
bind_dirs=${APPTAINER_BIND:-}
121+
elif [[ -n "${SINGULARITY_CONTAINER:-}" ]]; then
122+
container=SINGULARITY
123+
img="${SINGULARITY_CONTAINER}"
124+
bind_dirs=${SINGULARITY_BIND:-}
125+
else
126+
printf "ERROR: PLATFORM = container is defined\n" >&2
127+
printf " but no expected container environment variables found \n" >&2
128+
exit 65
116129
fi
117-
local srw_env=${SRW_ENV:-}
118-
local img_sif=${IMG:-/full/path/to/container/image.sif}
119-
cat >"${wrapper}" <<EOF_WRAP
130+
printf "container = $container \n" >&2
131+
local containerbin=${container,,}
132+
if [[ -n "${bind_dirs:-}" ]]; then
133+
IFS=',' read -r -a add_dirs <<< "${bind_dirs}"
134+
for add_dir in "${add_dirs[@]}"; do
135+
bind_add="${bind_add} -B $add_dir"
136+
done
137+
else
138+
bind_add="-B $(echo "${SRW_DIR}" | cut -d'/' -f1-2)" # local filesystem to bind-mount into the container
139+
fi
140+
141+
# write a wrapper file
142+
cat >"${SRW_WRAP}" <<EOF_WRAP
120143
#!/bin/bash
121144
set -x
122145
123-
export SINGULARITYENV_FI_PROVIDER=tcp
124-
export SINGULARITY_SHELL=/bin/bash
146+
export ${container}ENV_FI_PROVIDER=tcp
147+
export ${container}_SHELL=/bin/bash
125148
126-
img=${img_sif}
149+
img=${img}
127150
cmd=\$(basename "\$0")
128151
arg="\$@"
129152
130-
export SINGULARITYENV_PMIX_MCA_gds=hash
131-
export SINGULARITYENV_OMPI_MCA_btl="^openib"
153+
EOF_WRAP
154+
155+
# Add compiler-specific variables
156+
if [[ ${COMPILER} == intel ]]; then
157+
cat >>"${SRW_WRAP}" <<EOF_WRAP
158+
export ${container}ENV_FI_PROVIDER_PATH=${FI_PROVIDER_PATH}
159+
EOF_WRAP
160+
elif [[ ${COMPILER} == gnu ]]; then
161+
cat >>"${SRW_WRAP}" <<EOF_WRAP
162+
export ${container}ENV_PMIX_MCA_gds=hash
163+
export ${container}ENV_PMIX_MCA_psec=native
164+
export ${container}ENV_OMPI_MCA_btl="^openib"
132165
133166
if ip link show eth0 &>/dev/null; then
134-
export SINGULARITYENV_OMPI_MCA_btl_tcp_if_include=eth0
167+
export ${container}ENV_OMPI_MCA_btl_tcp_if_include=eth0
168+
export ${container}ENV_OMPI_MCA_oob_tcp_if_include=eth0
169+
fi
170+
171+
export ${container}ENV_OMPI_MCA_pml=ob1
172+
export ${container}ENV_OMPI_MCA_btl_vader_single_copy_mechanism=none
173+
export ${container}ENV_OMPI_MCA_btl_sm_single_copy_mechanism=none
174+
export ${container}ENV_OMPI_MCA_mca_base_component_show_load_errors=0
175+
EOF_WRAP
135176
fi
136177

137-
export SINGULARITYENV_OMPI_MCA_pml=ob1
138-
export SINGULARITYENV_OMPI_MCA_btl_vader_single_copy_mechanism=none
139-
export SINGULARITYENV_OMPI_MCA_mca_base_component_show_load_errors=0
178+
# Complete writing into a wrapper file
179+
cat >>"${SRW_WRAP}" <<EOF_WRAP
140180
141-
SINGULARITY=\$(which singularity)
181+
CONTAINERBIN=\$(which ${containerbin})
142182
143-
"\${SINGULARITY}" exec --env-file ${srw_env} \
144-
-B ${bind_dir} ${bind_add:-} \${img} \$cmd \$arg
183+
"\${CONTAINERBIN}" exec --env-file ${SRW_ENV} \
184+
${bind_add:-} \$img \$cmd \$arg
145185
EOF_WRAP
146186

147-
chmod +x "${wrapper}"
187+
chmod +x "${SRW_WRAP}"
148188
}
149189

150190
# print usage error and exit
@@ -258,6 +298,7 @@ if [ -z $PLATFORM ] ; then
258298
fi
259299
# set PLATFORM (MACHINE)
260300
MACHINE="${PLATFORM}"
301+
261302
printf "PLATFORM(MACHINE)=${PLATFORM}\n" >&2
262303

263304

@@ -286,7 +327,7 @@ if [ "${BUILD_CONDA}" = "on" ] ; then
286327
conda activate
287328
if ! conda env list | grep -q "^srw_app\s" ; then
288329
time mamba env create -n srw_app --file environment.yml
289-
if [ "${PLATFORM}" = "singularity" ] ; then
330+
if [ "${PLATFORM}" == "container" ] ; then
290331
conda activate srw_app
291332
conda install -y -c conda-forge netcdf4
292333
conda deactivate
@@ -311,7 +352,6 @@ fi
311352

312353
# Conda environment should have linux utilities to perform these tasks on macos.
313354
SRW_DIR=$(cd "$(dirname "$(readlink -f -n "${BASH_SOURCE[0]}" )" )" && pwd -P)
314-
MACHINE_SETUP=${SRW_DIR}/src/UFS_UTILS/sorc/machine-setup.sh
315355
BUILD_DIR="${BUILD_DIR:-${SRW_DIR}/build}"
316356
INSTALL_DIR=${INSTALL_DIR:-$SRW_DIR}
317357
CONDA_BUILD_DIR="$(readlink -f "${CONDA_BUILD_DIR}")"
@@ -346,7 +386,7 @@ if [ -z "${COMPILER}" ] ; then
346386
orion|hercules) COMPILER=intel ;;
347387
wcoss2) COMPILER=intel ;;
348388
derecho) COMPILER=intel ;;
349-
macos|singularity) COMPILER=gnu ;;
389+
macos|singularity|apptainer) COMPILER=gnu ;;
350390
odin|noaacloud) COMPILER=intel ;;
351391
*)
352392
COMPILER=intel
@@ -399,7 +439,7 @@ else
399439
while true; do
400440
if [[ $(ps -o stat= -p ${LCL_PID}) != *"+"* ]] ; then
401441
printf "ERROR: Build directory already exists\n" >&2
402-
printf " BUILD_DIR=${BUILD_DIR}\n\n" >&2
442+
printf " BUILD_DIR=${BUILD_DIR}\n" >&2
403443
usage >&2
404444
exit 64
405445
fi
@@ -419,7 +459,6 @@ else
419459
done
420460
fi
421461
fi
422-
423462
# cmake settings
424463
CMAKE_SETTINGS="\
425464
-DBUILD_MACHINE=${MACHINE}\
@@ -463,7 +502,7 @@ printf "... Load MODULE_FILE and create BUILD directory ...\n"
463502
if [ $USE_SUB_MODULES = true ]; then
464503
#helper to try and load module
465504
function load_module() {
466-
505+
467506
set +e
468507
#try most specialized modulefile first
469508
MODF="$1${PLATFORM}.${COMPILER}"
@@ -529,12 +568,11 @@ else
529568
if [[ "${PLATFORM}" == "macos" ]]; then
530569
export LDFLAGS+=" -L$MPI_ROOT/lib "
531570
fi
532-
if [[ "${PLATFORM}" == "singularity" && "${COMPILER}" == "gnu" ]]; then
571+
if [[ "${PLATFORM}" == "container" ]]; then
533572
export SRW_ENV="${SRW_DIR}/ufs-srw.env"
534573
export SRW_WRAP="${SRW_DIR}/srw.sh"
535-
export BIND_DIR="$(echo "$SRW_DIR" | cut -d'/' -f1-2)"
536-
env_vars ${SRW_ENV}
537-
srw_binary_wrapper ${SRW_WRAP}
574+
env_vars
575+
srw_binary_wrapper
538576
fi
539577
fi
540578
module list
@@ -569,6 +607,28 @@ else
569607
fi
570608
fi
571609

610+
if [[ "${PLATFORM}" = "container" && "${CLEAN}" == "false" && "${BUILD}" == "false" ]]; then
611+
printf "Final step for PLATFORM=${PLATFORM} is to link executables to a wrapper script\n" >&2
612+
if [ "{BIN_DIR}" == "exec" ]; then
613+
printf 'PLATFORM=container: a directory name for binaries is "${BIN_DIR}"\n '
614+
printf ' needs to differ from "exec". Specify --bin-dir=bin when rerunning the devbuild.sh\n '
615+
printf ' or link the executables to a wrapper script manually, and adjust the search\n '
616+
printf ' path in $SRW_ENV file \n' >&2
617+
else
618+
[[ -d "${SRW_DIR}/exec" ]] && rm -rf "${SRW_DIR}/exec"
619+
mkdir ${SRW_DIR}/exec
620+
cd ${SRW_DIR}/${BIN_DIR}
621+
for file in *; do
622+
echo $file
623+
if [[ "$file" != "build_settings.yaml" ]]; then
624+
ln -s ${SRW_WRAP} ${SRW_DIR}/exec/$file
625+
else
626+
cp -v $file ${SRW_DIR}/exec/.
627+
fi
628+
done
629+
fi
630+
fi
631+
572632
# Copy config/python directories from component to main directory (EE2 compliance)
573633
if [ "${BUILD_UFS_UTILS}" = "on" ]; then
574634
if [ -d "${SRW_DIR}/parm/ufs_utils_parm" ]; then

devclean.sh

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ OPTIONS
2020
-c, --conda
2121
Remove "conda" directory and conda_loc file in SRW main directory
2222
--container
23-
For cleaning builds within the SRW containers, will remove the "container-bin"
24-
directory rather than "exec". Has no effect if \`-b\` is not specified.
23+
For cleaning builds within the SRW containers, will remove the "bin"
24+
directory in addition to "exec". Has no effect if \`-b\` is not specified.
2525
-f, --force
2626
Remove directories as requested, without asking for user confirmation of their deletion.
2727
-s, --sub-modules
@@ -100,11 +100,10 @@ if [ ${REMOVE_BUILD} == true ]; then
100100
"${SRW_DIR}/include" \
101101
"${SRW_DIR}/lib" \
102102
"${SRW_DIR}/lib64" \
103+
"${SRW_DIR}/exec" \
103104
)
104105
if [ ${CONTAINER} == true ]; then
105-
removal_list+=("${SRW_DIR}/container-bin")
106-
else
107-
removal_list+=("${SRW_DIR}/exec")
106+
removal_list+=("${SRW_DIR}/bin")
108107
fi
109108
fi
110109

0 commit comments

Comments
 (0)