Distributed CWL WRF Workflow #
This tutorial runs the WRF part of the existing WRF/EMEP Linear Workflow across multiple compute nodes. The
workflow is written in CWL, while its REAL and WRF tools use mpirun to
distribute model processes over Karolina nodes allocated by the scheduler.
Important
This tutorial does not run WRF inside a container. It loads WRF and MPI
from EESSI on Karolina and runs CWL with --no-container. This ensures
that WRF uses the MPI environment provided by Karolina when it starts
processes on multiple nodes. Do not use the container image linked from
WorkflowHub for this tutorial.
How Distribution Works#
The selected CWL workflow has two main model steps:
step3_realprepares the WRF boundary and initial-condition files.step4_wrfstarts the weather model after REAL succeeds.
The upstream CWL tool definitions use baseCommand: mpirun and pass the
realcores or wrfcores input with -np. CWL controls the dependency
between REAL and WRF. MPI distributes each model step over the allocated
nodes. LEXIS Platform submits the job and stages the final output dataset.
This workflow is distributed within one HPC system. It does not span two independent clusters.
Note
Before starting, log in to the LEXIS Platform and select a project with access to
Karolina’s qcpu partition. Karolina’s compute nodes must also have
outbound internet access because the job installs cwltool from PyPI at
the start of each execution. No SSH access to Karolina is required. For
help with prerequisites, see How-to Guide.
The example workflow is marked work-in-progress in WorkflowHub. Test it on a development or experimental allocation before using a production allocation.
Download the Workflow and Example Data#
On your computer, clone the source repository linked from WorkflowHub:
git clone https://github.com/UoMResearchIT/wrf_emep_cwl_linear_workflow.git
cd wrf_emep_cwl_linear_workflow
Download wrf_emep_UK_example_inputs.tar.gz from the example-data record. Extract it as specified by the
workflow authors:
mkdir -p input_files
tar -xzf wrf_emep_UK_example_inputs.tar.gz \
-C input_files --strip-components=1
This tutorial runs only workflows/wrf_workflow.cwl. It does not run the
ERA5 download, WPS or EMEP sections of the complete workflow.
Prepare a Self-Contained CWL File#
The workflow imports its individual tool definitions from the upstream
atmos-tools-library repository. Resolve those imports before uploading the
input dataset so the compute job does not download CWL files at runtime.
Create a local CWL environment and pack the workflow:
python3 -m venv cwl-pack-venv
source cwl-pack-venv/bin/activate
python -m pip install cwltool==3.2.20260413085819
cwltool --validate workflows/wrf_workflow.cwl
cwltool --pack workflows/wrf_workflow.cwl \
> workflows/wrf_workflow_packed.cwl
deactivate
--pack preserves the existing WorkflowHub workflow while placing its
referenced CWL definitions in one file. It does not add any specific CWL
syntax.
Check the WRF settings file:
generate_rundir: true
realcores: 2
wrfcores: 256
namelist_real:
class: File
path: '../input_files/namelists/namelist.input.wrf'
namelist_wrf:
class: File
path: '../input_files/namelists/namelist.input.wrf'
metdir:
class: Directory
path: '../input_files/wrf_met_input'
Karolina CPU nodes have 128 cores. Therefore, wrfcores: 256 demonstrates
distribution across two nodes. Keep realcores small because REAL only
prepares the initial and boundary-condition files.
The upstream documentation requires WRF filenames without colons when using
Singularity. This tutorial runs the host application, but keeping
nocolons = .true. in the WRF namelist also makes output dataset handling
more portable.
Prepare the Input Dataset#
Create an archive containing only the packed workflow, its settings and the example data. Run this command from the repository root:
zip -r wrf-cwl-input.zip \
workflows/wrf_workflow_packed.cwl \
example_workflow_configurations/wrf_real_cwl_settings.yaml \
input_files
First open Data Management/Datasets and upload
wrf-cwl-input.zip. Enable unpacking and name the dataset
WRF CWL Input. After unpacking, workflows,
example_workflow_configurations and input_files must be at the dataset
root. See Data Management for the complete upload procedure.
Prepare the Jobscript#
Create the following jobscript. LEXIS Platform supplies the scheduler directives, so
do not add #SBATCH lines:
#!/usr/bin/env bash
set -euo pipefail
EXECUTION_DIR="$PWD"
INPUT_DIR="${EXECUTION_DIR}/input"
VENV_DIR="${EXECUTION_DIR}/cwl-runner-venv"
WORK_DIR="${EXECUTION_DIR}/cwl-work"
OUTPUT_DIR="${EXECUTION_DIR}/output"
module purge
source /cvmfs/software.eessi.io/versions/2025.06/init/bash
module load Python/3.12.3-GCCcore-13.3.0
module load WRF/4.6.1-foss-2024a-dmpar
python -m venv "${VENV_DIR}"
source "${VENV_DIR}/bin/activate"
python -m pip install \
--disable-pip-version-check \
cwltool==3.2.20260413085819
command -v real.exe
command -v wrf.exe
command -v mpirun
command -v cwltool
mkdir -p "${OUTPUT_DIR}"
mkdir -p "${WORK_DIR}/tmp"
mkdir -p "${WORK_DIR}/out"
echo "MPI hosts visible to this allocation:"
mpirun hostname | sort -u
cd "${INPUT_DIR}"
cwltool \
--no-container \
--relax-path-checks \
--debug \
--tmpdir-prefix "${WORK_DIR}/tmp/" \
--tmp-outdir-prefix "${WORK_DIR}/out/" \
--outdir "${OUTPUT_DIR}" \
workflows/wrf_workflow_packed.cwl \
example_workflow_configurations/wrf_real_cwl_settings.yaml
echo "WRF rank log count:"
find "${OUTPUT_DIR}" -name 'rsl.out.*' | wc -l
grep -R "SUCCESS EM_REAL INIT" "${OUTPUT_DIR}"/rsl.out.*
grep -R "SUCCESS COMPLETE WRF" "${OUTPUT_DIR}"/rsl.out.*
--no-container makes the CWL tools use the provider’s WRF and MPI
installation. --relax-path-checks is required because standard WRF
filenames can contain characters that CWL normally rejects. The two temporary
directory options keep CWL’s WRF working files in the execution directory,
which is visible to every node in the allocation.
The job creates a new virtual environment and downloads the pinned cwltool
version during every execution. This keeps the workflow self-contained and
removes the need for a cluster login, but it requires outbound internet access
from the compute node. The other allocated cores remain idle during this short
installation step.
Tip
For repeated executions, users with SSH access may create the virtual
environment once under /scratch/project/PROJECT_ID after loading the
same EESSI Python module. Replace the python -m venv and pip install
commands with a source command pointing to that environment. A
persistent environment avoids repeated downloads but ties the jobscript to
that Karolina project directory. Do not copy a virtual environment created
on another computer.
Upload the Jobscript#
Now open Data Management/Job Scripts and click
Create Jobscript. Name it Distributed WRF CWL, select your project and
the target system, paste the script, then complete the metadata and review
steps. See Job Scripts section for the full upload procedure.
Create the HPC Jobscript Workflow#
Open Workflows, select HPC Jobscript, expand Distributed WRF CWL and
create a workflow from the uploaded version.
Name it
Distributed WRF CWL Workflow.Select Karolina, its
qcpupartition and your project’s Karolina computation resource.Enable input staging and select
WRF CWL Input.**LEXIS Platform** makes the unpacked dataset available to the job underinput.Enable output staging. Use
Distributed WRF Outputas the title andoutputas the source path.In advanced settings, set Max cores to
256. Karolina’sqcpunodes have 128 cores, so this requests two nodes for the WRF step.Start with a walltime of
43200seconds (12 hours), as stated by the WorkflowHub example. Shorten it after measuring a successful test run.Review the summary and create the workflow.
Warning
wrfcores controls mpirun -np inside CWL, while Max cores controls
the scheduler allocation. Keep them equal. Requesting more MPI processes
than allocated cores can overload a node or cause the job to fail.
Run and Monitor the Workflow#
Open the workflow details and create an execution named
WRF distributed run 1. Review the selected cluster, partition, resource,
walltime and core count, then create the execution.
In the Progress view, open the job task and select View HPC Job Logs.
The initial MPI hosts visible to this allocation section should list more
than one hostname. The CWL debug log should then show REAL completing before
WRF starts. WRF creates one rsl.out.* and rsl.error.* pair per MPI
rank, and the jobscript prints the final WRF rank log count. Hostnames are
the authoritative confirmation of node placement; the file count confirms
ranks but not which nodes hosted them.
Check the Results#
After a successful execution, open Distributed WRF Output. It should
contain the WRF output files and rank logs collected by the CWL workflow,
including names matching:
wrfout_d*
rsl.out.*
rsl.error.*