Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 24 additions & 25 deletions devbuild.sh
Original file line number Diff line number Diff line change
Expand Up @@ -95,21 +95,7 @@ Settings:
EOF_SETTINGS
}

# env. variables saved into singularity container environment file ufs-srw.env
env_vars () {

cat >"${SRW_ENV}" <<EOF_ENV
PATH=${SRW_DIR}/${BIN_DIR}:${PATH}
LD_LIBRARY_PATH=${LD_LIBRARY_PATH}
HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH:-}
HDF5_USE_FILE_LOCKING=FALSE
ESMFMKFILE=${ESMFMKFILE:-}
CRTM_FIX=${CRTM_FIX:-}

EOF_ENV
}

# Singularity gnu containers: make a wrapper script template for the UFS SRW binaries
# Singularity gnu containers: make a wrapper script template for the UFS SRW binaries
srw_binary_wrapper() {
local img=""
local bind_add=""
Expand Down Expand Up @@ -152,10 +138,12 @@ arg="\$@"

EOF_WRAP

# Add compiler-specific variables
# Add compiler-specific variables and pick the runtime modules that
# provide (in place of a baked ufs-srw.env file) PATH, LD_LIBRARY_PATH,
# ESMFMKFILE, CRTM_FIX, etc. inside the container.
if [[ ${COMPILER} == intel ]]; then
cat >>"${SRW_WRAP}" <<EOF_WRAP
export ${container}ENV_FI_PROVIDER_PATH=${FI_PROVIDER_PATH}
export ${container}ENV_FI_PROVIDER_PATH=${FI_PROVIDER_PATH}
EOF_WRAP
elif [[ ${COMPILER} == gnu ]]; then
cat >>"${SRW_WRAP}" <<EOF_WRAP
Expand All @@ -175,13 +163,26 @@ export ${container}ENV_OMPI_MCA_mca_base_component_show_load_errors=0
EOF_WRAP
fi

# Complete writing into a wrapper file
# Complete writing into a wrapper file. Rather than passing a baked
# environment file to the container (--env-file), load the containerized
# Lmod modules for this compiler at run time, inside the container, and
# then hand off to the actual binary (cmd) and its arguments (arg).
cat >>"${SRW_WRAP}" <<EOF_WRAP

CONTAINERBIN=\$(which ${containerbin})

"\${CONTAINERBIN}" exec --env-file ${SRW_ENV} \
${bind_add:-} \$img \$cmd \$arg
# cmd and arg are passed as positional parameters to the inner bash (after
# the "bash" placeholder for \$0), not interpolated into the script text,
# so their contents are never re-parsed as shell syntax -- "\$@" below just
# reassembles them as literal argv, the same as a direct unquoted call.
"\${CONTAINERBIN}" exec ${bind_add:-} \$img bash -c '
source /usr/share/lmod/lmod/init/bash
module use /opt/modulefiles
module use ${SRW_DIR}/modulefiles
module load ${MODULE_FILE}
export PATH=${SRW_DIR}/${BIN_DIR}:\$PATH
exec "\$@"
' bash \$cmd \$arg
EOF_WRAP

chmod +x "${SRW_WRAP}"
Expand Down Expand Up @@ -569,10 +570,8 @@ else
export LDFLAGS+=" -L$MPI_ROOT/lib "
fi
if [[ "${PLATFORM}" == "container" ]]; then
export SRW_ENV="${SRW_DIR}/ufs-srw.env"
export SRW_WRAP="${SRW_DIR}/srw.sh"
env_vars
srw_binary_wrapper
srw_binary_wrapper
fi
fi
module list
Expand Down Expand Up @@ -612,8 +611,8 @@ if [[ "${PLATFORM}" = "container" && "${CLEAN}" == "false" && "${BUILD}" == "fal
if [ "{BIN_DIR}" == "exec" ]; then
printf 'PLATFORM=container: a directory name for binaries is "${BIN_DIR}"\n '
printf ' needs to differ from "exec". Specify --bin-dir=bin when rerunning the devbuild.sh\n '
printf ' or link the executables to a wrapper script manually, and adjust the search\n '
printf ' path in $SRW_ENV file \n' >&2
printf ' or link the executables to a wrapper script manually, and adjust the module\n '
printf ' list in the srw_binary_wrapper function in devbuild.sh \n' >&2
else
[[ -d "${SRW_DIR}/exec" ]] && rm -rf "${SRW_DIR}/exec"
mkdir ${SRW_DIR}/exec
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -838,18 +838,20 @@ When all the conda environments and binaries are successfully built, exit from t

exit

Use Wrapper Scripts and Runtime Environment Files
Use the Wrapper Script
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In addition to binaries and conda installs, successful build produces:

* ``srw.sh`` — wrapper to launch tasks within the container
* ``ufs-srw.env`` — runtime environment settings and environment variables

Each binary in the ``bin`` directory is symlinked to this single wrapper script. At run time, ``srw.sh`` starts the container and, before handing off to the actual binary, loads the same Lmod modulefile that was used to build the code (e.g., ``build_container_gnu`` or ``build_container_intel``) from inside the container.

Verify the following configuration in the ``srw.sh``:

* ``img`` variable points to the correct ``.sif`` GNU container image file, absolute path
* ``-B`` binds all host directories, required for access inside the container at runtime, including staged data locations
* the ``module load`` line inside the ``bash -c`` block loads the correct build modulefile for the compiler used (``build_container_gnu`` or ``build_container_intel``)

Prepare the Workflow Module File
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Table of Variables in ``config_defaults.yaml``
EXTRN_MDL_SOURCE_BASEDIR_ICS, EXTRN_MDL_FILES_ICS
* - task_get_extrn_lbcs
- EXTRN_MDL_NAME_LBCS, LBC_SPEC_INTVL_HRS, EXTRN_MDL_LBCS_OFFSET_HRS, FV3GFS_FILE_FMT_LBCS, EXTRN_MDL_SYSBASEDIR_LBCS,
USE_USER_STAGED_EXTRN_FILES,EXTRN_MDL_SOURCE_BASEDIR_LBCS, EXTRN_MDL_FILES_LBCS
EXTRN_MDL_LBCS_MAX_FCST_HRS, EXTRN_MDL_LBCS_BRIDGE_INTVL_HRS, USE_USER_STAGED_EXTRN_FILES, EXTRN_MDL_SOURCE_BASEDIR_LBCS, EXTRN_MDL_FILES_LBCS
* - task_make_ics
- KMP_AFFINITY_MAKE_ICS, OMP_NUM_THREADS_MAKE_ICS, OMP_STACKSIZE_MAKE_ICS, USE_FVCOM, FVCOM_WCSTART, FVCOM_DIR, FVCOM_FILE, VCOORD_FILE
* - task_make_lbcs
Expand Down
10 changes: 8 additions & 2 deletions doc/UsersGuide/CustomizingTheWorkflow/ConfigWorkflow.rst
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ If non-default parameters are selected for the variables in this section, they s
``CYCLETHROTTLE``: (Default: 200)
The number of active forecast cycles that can be run simultaneously via Rocoto.

``BUILD_MOD_FN``: (Default: ``'build_{{ user.MACHINE|lower() }}_{{ workflow.COMPILER }}'``)
Name of an alternative build modulefile to use if running on an unsupported platform. It is set automatically for supported machines.
``BUILD_MOD_FN``: (Default: ``'{{ "build_" ~ user.MACHINE|lower() ~ "_" ~ workflow.COMPILER if user.MACHINE != "CONTAINER" else "wflow_container" }}'``)
Name of an alternative build modulefile to use if running on an unsupported platform. It is set automatically for supported machines. For all machines, this defaults to ``build_<machine>_<compiler>``, except when ``MACHINE: CONTAINER``, in which case ``wflow_container`` is used instead, so it no longer needs to be set explicitly for container runs.

``WFLOW_MOD_FN``: (Default: ``'wflow_{{ user.MACHINE|lower() }}'``)
Name of an alternative workflow modulefile to use if running on an unsupported platform. It is set automatically for supported machines.
Expand Down Expand Up @@ -915,6 +915,12 @@ For each workflow task, certain parameter values must be passed to the job sched
``FV3GFS_FILE_FMT_LBCS``: (Default: "nemsio")
If using the FV3GFS model as the source of the :term:`LBCs` (i.e., if ``EXTRN_MDL_NAME_LBCS: "FV3GFS"``), this variable specifies the format of the model files to use when generating the LBCs. Valid values: ``"nemsio"`` | ``"grib2"`` | ``"netcdf"``

``EXTRN_MDL_LBCS_MAX_FCST_HRS``: (Default: "")
The maximum forecast hour available from a single cycle of the model specified in ``EXTRN_MDL_NAME_LBCS`` (e.g., 48 for HRRR). Leave unset (the default) if a single cycle already covers the full ``FCST_LEN_HRS``, which is the case for most models/configurations. If set and less than ``FCST_LEN_HRS``, the ``get_extrn_lbcs`` task will automatically bridge to subsequent cycles of the same model (see ``EXTRN_MDL_LBCS_BRIDGE_INTVL_HRS`` below) to obtain LBCs for forecast hours beyond what the base cycle can provide.

``EXTRN_MDL_LBCS_BRIDGE_INTVL_HRS``: (Default: 24)
Only used when ``EXTRN_MDL_LBCS_MAX_FCST_HRS`` is set and less than ``FCST_LEN_HRS``. The number of hours between checks for a fresher (later) cycle of ``EXTRN_MDL_NAME_LBCS`` to bridge to (e.g., 6 to check for a new cycle every 6 hours). Before each ``EXTRN_MDL_LBCS_BRIDGE_INTVL_HRS``-sized chunk of forecast hours is retrieved, the workflow checks whether a fresher on-schedule cycle is available and switches to it if so, always preferring the freshest available guidance. If the fresher cycle is not yet available (e.g., in real-time operation), the chunk falls back to extending whichever cycle is currently in use, up to that cycle's own ``EXTRN_MDL_LBCS_MAX_FCST_HRS``. This check repeats every interval for the remainder of the run.

File and Directory Parameters
--------------------------------

Expand Down
2 changes: 1 addition & 1 deletion modulefiles/wflow_container.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ a singularity/apptainer container]===])

load("conda")
load("rocoto")
load("singularity")
--load("singularity")
Comment thread
natalie-perlin marked this conversation as resolved.

if mode() == "load" then
execute{cmd="conda activate srw_app", modeA={"load"}}
Expand Down
Loading
Loading