EESSI, somebody else’s stack

EESSI mount with an extend prefix beside it, not inside it

EESSI is somebody else’s tree. Install on top into an owned prefix. Do not write into the mount.

stratum to CernVM-FS to the client to modules

EESSI is a filesystem already built. The client mount is the stack.

EESSI arrives as a mount, not as a local build

Somebody else built the stack. The client mounts it. StackWalker starts here.

Questions

  • What is EESSI, if it is not an install of EasyBuild?

  • Which init script configures Lmod, and which one is irreversible?

  • When does a plan bootstrap GCC instead of using the stack?

What you will be able to do

  1. Initialise EESSI and install on top of it into an operator-owned prefix.

  2. Decide whether your toolchain generation is available before planning anything.

  3. Say what a green build on your own host establishes about the other CPU targets.

A directory exists on many clusters. The same directory exists on many laptops. The directory was not built by anyone at the site. MultiXscale funds a large portion of EESSI’s workforce. The funding is part of the EuroHPC Centre of Excellence (CECAM x EESSI). CASTIEL 2 is the tutorial portal rather than the build farm. The EFP Federated Software Catalogue (CSC.fi with Ghent) is a 2026 catalogue layer above. Compute Canada acts as the design parent of the three-layer split. Boissonneault et al. [2019] Dröge et al. [2023] evaluate why a generic binary does not constitute the stack. GROMACS 2020.4 on Cascade Lake achieves 1.18 ns/day when compiled for SSE 4.1. GROMACS 2020.4 on Cascade Lake achieves 1.86 ns/day when compiled for AVX‑512. The source code is unchanged. The difference is a 57 % gap. The production tree was created after that paper. The bot was created after that paper.

The stack is a filesystem

ls /cvmfs/software.eessi.io/versions/

These are versions of a complete scientific software stack: compilers, MPI and the usual libraries, tuned per microarchitecture. The stack arrives on a filesystem served over HTTP. EESSI is not installed. It is mounted, or the session runs on a machine where it has already been mounted. Select one and initialise it.

source /cvmfs/software.eessi.io/versions/2025.06/init/lmod/bash

init/lmod/bash configures Lmod for the session. init/bash is the irreversible client init; do not source it to “just get Lmod”. A compatibility layer, a module tree, and a collection of toolchains are created without requiring an install step or any maintainer approval. Two warnings must be placed here before any other content. Each consumes actual time. The first warning concerns the ls command. List the versions directory and verify that a version is valid before using it.

ls /cvmfs/software.eessi.io/versions/

A listed version may be an empty placeholder lacking any init/. Speculatively descending into such a placeholder can wedge the filesystem client for all host users. The lookup neither resolves nor raises an error, and readers accumulate in an uninterruptible state beyond any timeout reach. List first. Confirm. Then use. The second concerns the generation question, which determines whether the remainder of this page applies.

Check the generation before planning anything

The compatibility layer is behind the newest EasyBuild toolchain generation. A version of EESSI includes a specific set of top‑level toolchains. An easyconfig names a particular generation. These two facts must agree. If they do not agree, EESSI reports the mismatch. An opt‑in is available.

export EESSI_SITE_TOP_LEVEL_TOOLCHAINS_2025_06='[{"name": "foss", "version": "2026.1"}]'

A setting makes EasyBuild plan the build. Read the plan prior to script execution. When the generation is absent from the compatibility layer, every dependency is skipped. The run then begins by bootstrapping the compiler itself and downloading a couple of hundred megabytes of GCC. Avoid this. Bootstrapping an entire generation into a user prefix duplicates what EESSI’s own build bots do centrally. It also creates a long detour to a stack that cannot be shared. A generation gap means not yet on this EESSI version. A missing generation is a finding about the stack, and the mount itself works.

Installing on top, with EESSI-extend

EESSI supplies a module that configures EasyBuild for stack installation. Build bots use the same module. This path matches the bot’s actions.

source /cvmfs/software.eessi.io/versions/2025.06/init/lmod/bash

export EESSI_USER_INSTALL=$HOME/eessi/2025.06
mkdir -p $EESSI_USER_INSTALL

module load EESSI-extend
eb --show-config
eb <easyconfig>.eb --robot

Build your own without asking anyone. --show-config earns its place again. Run it and read installpath. It returns a path qualified by microarchitecture, for example .../software/linux/x86_64/amd/zen5. Stop and look at that path. It is What “installed” means’s per-architecture tree. The architecture appears in the path instead of being hidden behind a symlink. Same arrangement, made visible. A binary built here is for one microarchitecture and says so. Four prefix variables exist. They differ in who can read the result.

Variable

What it means

EESSI_USER_INSTALL

private to the operator

EESSI_PROJECT_INSTALL

shared with a group

EESSI_SITE_INSTALL

site-wide, on top of EESSI

EESSI_CVMFS_INSTALL

into the distributed repository itself

Set the prefix before loading the module. EESSI-extend reads these at load time. Setting them afterwards changes nothing. EESSI_CVMFS_INSTALL and EESSI_SITE_INSTALL are exclusive of the others. EESSI_USER_INSTALL and EESSI_PROJECT_INSTALL may be set together. Both prefixes appear on MODULEPATH. New installs go to the user prefix.

EB-EESSI-1 — The 2025.06 tree does not carry 2026.1

You have set one prefix variable, loaded EESSI-extend on the 2025.06 tree, and run a plan for an easyconfig on foss-2026.1. The run opens by fetching a couple of hundred megabytes of GCC. The 2025.06 layer does not carry that generation.

  1. What has happened?

  2. You could let it run. Give two reasons not to.

  3. What is the honest thing to report, and to whom?

Solution

The compatibility layer for EESSI 2025.06 does not carry foss-2026.1. (It does carry foss-2025b; that pin would not have produced this plan.) Nothing above the compiler exists to be reused, so the plan is to build the generation itself, starting with the compiler.

Two reasons not to. It duplicates work the EESSI build bots do centrally for every supported CPU target, where yours would cover one. And what you end up with is a whole generation inside a user prefix that nobody else can use and that you now maintain.

The honest report is a generation gap: this recipe needs foss-2026.1, this EESSI version’s layer stops short of it, so the ceiling here is a build on an ordinary target rather than an EESSI-verified one. That goes to whoever asked for the software, and the software-layer entry is module load EESSI/2026.06 (or source of that version’s init), not a wait until 2026.06 is the default and not a local rebuild of foss-2026.1 on 2025.06. 2026.06 is already listed under /cvmfs/software.eessi.io/versions/.

When the filesystem client is the problem

Symptoms manifest in a specific way. A host client may report healthy yet be unusable. The probe reports fine and the server answers a plain HTTP request within milliseconds. Every directory listing into a nested path then blocks forever and poisons the shell that ran it. Two solutions exist, ordered by preference. If the account has polkit rights on the host, which an ordinary user often does, restarting the mount clears the stuck readers. The operation should be performed from a terminal that did not run the hanging command. If the account lacks polkit rights, a container can be used. The container mounts the distributed filesystem itself, requires only unprivileged user namespaces, and is independent of the host client state.

git clone --depth 1 https://github.com/EESSI/software-layer-scripts.git
export APPTAINER_CACHEDIR=$PWD/storage/apptainer-cache
./software-layer-scripts/eessi_container.sh \
 --mode exec --access ro --storage $PWD/storage \
 --extra-bind-paths "$PWD/ecs:/ecs:ro" \
 -- /bin/bash /ecs/run-extend.sh

Each of four details costs an attempt. The script lives in software-layer-scripts. It was moved. software-layer no longer carries it. --mode run warns. --mode run behaves as exec. Pass exec. The script that is run must be inside a bound path. A script that resolves outside the bind mount fails as though the file were absent. Set APPTAINER_CACHEDIR. With the older SINGULARITY_ name also set, the older one wins. The newer name is dropped with no message. Diagnosing the host client further rarely pays. On one host, root-catalog fetches succeeded. Nested traversal stalled on that host. A second server disabled timeouts. A second server wiped the cache. Neither change affected the outcome. A container on the same host and network traversed everything instantly.

Building by hand on top of it

Building without EasyBuild may be required. Load the buildenv module of the toolchain instead of improvising.

module load buildenv/default-foss-2025b
module load <dependency modules>
make
readelf -d <binary>
ldd <binary>

buildenv configures $CC and $CFLAGS in the same way as EasyBuild. Wrappers that inject RPATH are installed. The two commands after make constitute the third check of What “installed” means, executed manually. The binary records a runtime path. Nothing resolves outside the stack.

Contributing back

Installing in a local prefix assists the operator. Moving it into EESSI proper requires a separate task. The order is important. These six steps constitute the postcard. An easystack is the list the bot will build is the YAML. The bot is three processes and a comment is the comment that starts the build and the ingest that creates a module. A site stack next to EESSI, not inside it is the site tree that never goes into software.eessi.io. Place the easyconfig into EasyBuild, or open a pull request for it. Build it in the EESSI build environment using EESSI-extend. Add an entry to the easystack file for that EESSI version and toolchain generation. Open a pull request against the software layer, targeting main. A builder posts one bot: build for:arch=... per supported CPU target. When green, bot:deploy uploads the tarballs. A Stratum-0 ingest publishes them. Two conditions apply before work starts. The easyconfig must come first. A software-layer entry references an easyconfig instead of restating one. Deployment waits for the EasyBuild pull request to be merged, even though both can be open simultaneously. A green build on the host does not constitute the claim. The bot builds x86-64 from generic up through Zen and Sapphire Rapids, and builds aarch64 from generic through Neoverse and Grace. Software that works only on the local microarchitecture is not ready, regardless of local green status. That matches the distinction of What “installed” means, with a larger set of trees.

The three that bite

The rest of this page outlines procedures. The three steps require real time. The steps must be performed in the given order. List before descending. A version directory may act as an unpopulated placeholder. Speculative listing into such a directory wedges the filesystem client for every user on the host. Confirm that an init/ exists before proceeding. Check the generation before planning. The compatibility layer lags behind the newest toolchain generation. Report a gap as a finding. Do not use it to bootstrap a compiler. One prefix variable, set before the module load. The EESSI-extend reads it at load time. A second or late variable causes a failure that appears as the module ignoring the request. After that, keep two aspects in view. The installpath returns a microarchitecture‑qualified path. The path corresponds to What “installed” means’s per‑architecture tree with the architecture visible in the path. The all‑CPU‑target claim belongs to the bot. It does not belong to the host.

What to remember

  • EESSI is a stack to mount rather than to install.

  • List /cvmfs/software.eessi.io/versions before descending: an empty placeholder can wedge the client.

  • init/lmod/bash configures Lmod. init/bash is the irreversible client init.