Episode 3: LAMMPS with EESSI on EuroHPC¶
In our Leonardo Booster tests, EESSI offered newer CPU LAMMPS builds and an older CUDA build. We checked their packages and tried accessing them through a container. This episode shows the setup that worked and the problems we found.
Before you start¶
Prerequisites
A Leonardo Booster account and a Slurm allocation with GPU access.
Familiarity with environment modules and the package checks in Episode 1: Installing LAMMPS on EuroHPC.
A project scratch directory with space for a container image and its cache.
Access to
profile/global,eessi/1.0, andsingularityce/4.3.3on Leonardo.Internet access from a login node to prepare the official EESSI image.
Tested configuration¶
The checks below were performed on Leonardo Booster on 13 October 2026:
Component |
Tested version |
|---|---|
GPU and NVIDIA driver |
A100-SXM-64GB; 535.274.02 |
EESSI CPU target |
|
EESSI accelerator target |
|
EESSI releases inspected |
|
Leonardo access module |
|
Container runtime |
SingularityCE 4.3.3 |
Official EESSI image |
|
EESSI launcher revision |
|
The image supplies an environment for accessing EESSI. Application modules come from the mounted EESSI repository. Using a container does not automatically provide newer LAMMPS modules.
1. Understand the EESSI selection¶
EESSI is the European Environment for Scientific Software Installations. It provides software builds for different CPU and accelerator architectures and forms the basis of the EuroHPC Federation Platform’s Federated Software Catalog.
EESSI selects compatible builds by detecting the hardware on the node where you initialize it. The EuroHPC system name does not select the software. Site configuration determines how the repository is mounted and how host libraries, such as the NVIDIA driver, are exposed.
Keep three choices separate:
Choice |
What it controls |
|---|---|
Access method |
How the EESSI repository becomes available. |
EESSI release |
Which software collection you inspect. |
CPU and accelerator targets |
Which compatible builds are visible. |
An EESSI release name such as 2025.06 is not a LAMMPS version. Read the full
module name and check the executable before choosing an installation.
Create a working directory within your project scratch space:
mkdir -p eessi-lammps-work
cd eessi-lammps-work
export EESSI_LAMMPS_WORKDIR="$PWD"
As you complete the steps, the directory layout will be:
eessi-lammps-work/
├── inventory.sbatch # native EESSI module inspection
├── native-lammps-modules-*.txt # recorded module lists
├── software-layer-scripts/ # official EESSI launcher
├── images/ # downloaded container image
├── cache/ # container download cache
├── tmp/ # image preparation files
├── container-storage/ # launcher state and private container home
├── inspect-container.sh # checks performed inside the container
├── container.sbatch # container job
└── container-lammps-modules-*.txt
2. Access EESSI on Leonardo Booster¶
Check the system-specific instructions¶
The EFP Leonardo instructions
describe compute-node access using a Slurm job name containing _CVMFS_, followed
by EESSI initialization. They also retain a warning about non-interactive and
multi-node usage.
In our tests, the job-name trigger alone did not mount EESSI in either a batch
job or an interactive Booster allocation. The site-provided eessi/1.0 launcher
did mount the repository successfully on allocated compute nodes. The recipe
below uses the site launcher.
Record the available modules¶
Save the following as inventory.sbatch in the project root. Replace the account
placeholder with your allocation account and submit from this directory:
--qos=boost_qos_dbg selects Leonardo Booster’s debug Quality of Service
(QoS) for short tests within the boost_usr_prod partition. It has a maximum
walltime of 30 minutes and higher scheduling priority than the normal QoS;
allocation time still depends on resource availability. For production runs,
remove or replace this directive with a QoS appropriate to your allocation and
adjust the time limit. Check the current
Leonardo scheduling limits.
#!/bin/bash
#SBATCH --job-name=eessi-lammps-inventory
#SBATCH --partition=boost_usr_prod
# Debug QoS for short tests; maximum walltime 30 minutes.
#SBATCH --qos=boost_qos_dbg
#SBATCH --account=EUHPC_XXX_XXX
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=2
#SBATCH --gres=gpu:1
#SBATCH --mem=8G
#SBATCH --time=00:10:00
set -eo pipefail
cd "$SLURM_SUBMIT_DIR"
module load profile/global
module load eessi/1.0
test -d /cvmfs/software.eessi.io/versions
ls /cvmfs/software.eessi.io/versions
for version in 2023.06 2025.06 2026.06; do
module --force purge
if ! module load "EESSI/$version"; then
printf 'EESSI %s is unavailable\n' "$version"
continue
fi
module -t avail 2>&1 | grep -E '^LAMMPS/[0-9]' | sort -u \
> "native-lammps-modules-$version.txt" || true
printf '\nEESSI %s LAMMPS modules:\n' "$version"
cat "native-lammps-modules-$version.txt"
done
cd "$EESSI_LAMMPS_WORKDIR"
sbatch inventory.sbatch
Read the selected CPU and accelerator targets in the Slurm output, then compare the recorded module lists with the table below.
Note
Loading eessi/1.0 both mounts the repository and initializes EESSI. Run it on
an allocated compute node; our login nodes had no EESSI mount.
3. Choose a LAMMPS build¶
The following modules were visible for Ice Lake and A100 (cc80) targets in
both the native environment and the container:
EESSI release |
LAMMPS module |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
No LAMMPS modules found for the selected targets. |
The table records the modules available for Ice Lake and A100 on the test date. Use your job’s output to check the current list.
Check the executable’s capabilities¶
The presence of kokkos in a module name does not establish CUDA support.
Our container checks produced:
Tested LAMMPS build |
KOKKOS backends |
Other checks |
|---|---|---|
|
OpenMP, Serial |
ML-IAP, ML-SNAP, PYTHON; ML-IAP Python import passed. |
|
CUDA, OpenMP |
ML-IAP, ML-SNAP, PYTHON; ML-IAP Python import passed. |
The native CUDA module failed its NVIDIA host-library check. It loaded successfully inside the container when we bound the host EESSI repository, as shown below.
Our checks covered module lists, CUDA driver initialization, lmp -h, and
the lammps.mliap import on one A100. We did not run molecular dynamics or MACE
inference with these EESSI installations.
MACE support¶
These LAMMPS modules include ML-IAP, but their Python environments contained no MACE, PyTorch, CuPy, or cuEquivariance. For a MACE build and copper simulation, follow Episode 2: LAMMPS with MACE on Leonardo Booster, which includes an energy/force comparison with Python MACE.
4. Prepare the official EESSI container¶
Run these downloads on a login node. The compute-node checks will reuse the local image rather than pulling it during an allocation.
Download the launcher and image¶
cd "$EESSI_LAMMPS_WORKDIR"
git clone https://github.com/EESSI/software-layer-scripts.git
git -C software-layer-scripts checkout 6327b3a782f4a17ec54cc2f809624980e33a2f64
module load profile/global
module load singularityce/4.3.3
singularity --version
mkdir -p images cache tmp
export SINGULARITY_CACHEDIR="$PWD/cache"
export SINGULARITY_TMPDIR="$PWD/tmp"
singularity pull images/eessi-debian12.sif \
docker://ghcr.io/eessi/build-node:debian12
sha256sum images/eessi-debian12.sif > images/eessi-debian12.sif.sha256
The image is published by EESSI. The debian12 tag can change, so keep the
launcher revision and the checksum of your downloaded SIF with your records.
Initial download and conversion can take several minutes.
Choose the repository access method¶
The official launcher can mount EESSI inside the container using FUSE. In our independent-mount test, the container started and accessed the GPU, but CVMFS failed to initialize the root catalogue. That test could not list EESSI modules.
The working recipe instead binds the repository mounted by Leonardo’s site
launcher into the container. It therefore still needs a working host EESSI
mount. The launcher uses --repository None to disable its repository mounting,
then receives an explicit read-only bind for the existing repository.
Singularity also reported a squashfuse permission failure in our tests and fell back to extracting the SIF. That fallback allowed the container to run; it was separate from the failed CVMFS catalogue fetch.
5. Inspect EESSI inside the container¶
Save the inspection script¶
Save the following as inspect-container.sh in the project root. The job binds
that directory to /work inside the container:
#!/bin/bash
set -eo pipefail
cd /work
ls /cvmfs/software.eessi.io/versions
nvidia-smi --query-gpu=name,driver_version --format=csv,noheader
/usr/bin/python3 - <<'PY'
import ctypes
cuda = ctypes.CDLL("libcuda.so.1")
assert cuda.cuInit(0) == 0, "CUDA driver initialization failed"
count = ctypes.c_int()
assert cuda.cuDeviceGetCount(ctypes.byref(count)) == 0
assert count.value == 1, "This example expects one visible GPU"
print("CUDA driver check passed; visible GPUs:", count.value)
PY
source /cvmfs/software.eessi.io/versions/2025.06/init/lmod/bash
for version in 2023.06 2025.06 2026.06; do
module --force purge
export EESSI_ACCELERATOR_TARGET_OVERRIDE=accel/nvidia/cc80
if ! module load "EESSI/$version"; then
printf 'EESSI %s is unavailable\n' "$version"
continue
fi
module -t avail 2>&1 | grep -E '^LAMMPS/[0-9]' | sort -u \
> "container-lammps-modules-$version.txt" || true
cat "container-lammps-modules-$version.txt"
done
module --force purge
export EESSI_ACCELERATOR_TARGET_OVERRIDE=accel/nvidia/cc80
module load EESSI/2023.06
module load LAMMPS/2Aug2023_update2-foss-2023a-kokkos-CUDA-12.1.1
timeout 45 mpirun --mca pml ob1 --mca btl self,tcp -np 1 lmp -h \
> container-lammps-help.txt 2>&1
grep -a 'KOKKOS package API' container-lammps-help.txt
sed -n '/Installed packages:/,/List of individual/p' container-lammps-help.txt
python -c 'import lammps.mliap; print("ML-IAP Python import passed")'
The container detected Ice Lake automatically, but EESSI did not automatically
identify the accelerator there. The explicit cc80 override matches the A100
verified by nvidia-smi and the CUDA driver check. It selects the GPU module
collection for that hardware.
We used this mpirun command only for a one-process help check. For simulations,
use a centre-supported MPI setup and test it at the node count you plan to use.
Save the container job¶
Save the following as container.sbatch in the project root. Replace the account
placeholder before submitting:
#!/bin/bash
#SBATCH --job-name=eessi-lammps-container
#SBATCH --partition=boost_usr_prod
# Debug QoS for short tests; maximum walltime 30 minutes.
#SBATCH --qos=boost_qos_dbg
#SBATCH --account=EUHPC_XXX_XXX
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=2
#SBATCH --gres=gpu:1
#SBATCH --mem=16G
#SBATCH --time=00:15:00
set -eo pipefail
cd "$SLURM_SUBMIT_DIR"
module load profile/global
module load singularityce/4.3.3
CONTAINER_RUNTIME_DIR="$(dirname "$(command -v singularity)")"
CONTAINER_RUNTIME_LD_LIBRARY_PATH="${LD_LIBRARY_PATH:-}"
module load eessi/1.0
test -d /cvmfs/software.eessi.io/versions
export PATH="$CONTAINER_RUNTIME_DIR:$PATH"
export LD_LIBRARY_PATH="$CONTAINER_RUNTIME_LD_LIBRARY_PATH"
export SINGULARITY_CACHEDIR="$PWD/cache"
export SINGULARITY_TMPDIR="${TMPDIR:-/tmp}"
export SINGULARITYENV_CUDA_VISIBLE_DEVICES="${CUDA_VISIBLE_DEVICES:-0}"
export EESSI_DO_NOT_MOUNT_CVMFS_CONFIG_CERN_CH=1
mkdir -p container-storage
./software-layer-scripts/eessi_container.sh \
--container "$PWD/images/eessi-debian12.sif" \
--storage "$PWD/container-storage" \
--repository None \
--extra-bind-paths "$PWD:/work,/cvmfs/software.eessi.io:/cvmfs/software.eessi.io:ro" \
--nvidia run --pass-through --cleanenv \
--mode exec /bin/bash /work/inspect-container.sh
Loading the site EESSI environment changes the host module environment. The
script retains the Singularity executable directory and library path selected
before that change. --cleanenv keeps the host software environment from being
inherited wholesale inside the container; the allocated GPU selection is passed
explicitly through SINGULARITYENV_CUDA_VISIBLE_DEVICES.
Submit and compare¶
cd "$EESSI_LAMMPS_WORKDIR"
sbatch container.sbatch
After the job finishes, inspect its output and compare the recorded lists:
for version in 2023.06 2025.06 2026.06; do
diff -u "native-lammps-modules-$version.txt" \
"container-lammps-modules-$version.txt"
done
Our lists matched for all three releases. An empty diff output means the two
lists match. The Slurm output should also show CUDA driver check passed,
KOKKOS package API: CUDA OpenMP, and ML-IAP Python import passed.
Completion checklist¶
EESSI is accessible on the allocated compute node.
The selected release, CPU target, and GPU target are recorded.
The native and container module lists have been inspected and compared.
The container can initialize the CUDA driver on the allocated GPU.
LAMMPS reports the required packages and hardware backend.
The ML-IAP Python interface imports.
Further reading¶
Episode 1: Installing LAMMPS on EuroHPC: LAMMPS installation and package inspection.
Episode 2: LAMMPS with MACE on Leonardo Booster: the Leonardo MACE build and copper example.
CUDA Driver, Toolkit, and Compute Capability Mapping (2026): CUDA compatibility reference.