A versionsuffix is part of the name¶
What you will be able to do
Say what a
versionsuffixdoes, and what it does not.Tell a derived suffix from a hand-written one, and say why the format cannot report which is which.
Say what a module named for a version does and does not guarantee about the tree under it.
Here is a module name from a real cluster:
NVHPC/25.11-CUDA-12.9.1
Enter the recipe and the default naming scheme builds that string.
Edit versionsuffix and the name moves; the dependency list does not.
Version 25.11 of the NVIDIA HPC SDK (NVHPC) is mentioned, followed by a reference to CUDA 12.9.1.
The latter part constitutes a versionsuffix.
This is the most easily misread parameter in EasyBuild, as it resembles a constraint yet is a label.
The suffix and the dependency are two different lines¶
The easyconfig behind that module states both of these:
Reading those two statements together leads to a mistaken interpretation of each statement’s function.
The dependency binds the exact pin from A pin is for one generation, one module, with no range.
The versionsuffix reports, and it reports into the module’s own name.
%(cudaver)s is the templating from An easyconfig is Python, resolved from the CUDA dependency, so the two are related by derivation.
They are not related by enforcement.
EasyBuild derives the suffix from the dependency once, at parse time, and writes the result into a filename.
Nothing checks afterwards that the name still describes the tree.
The third line also shows that nvidia-compilers takes versionsuffix as its own third positional attribute, which is A pin is for one generation’s ('name', 'version', 'versionsuffix', 'toolchain') tuple.
A suffix travels as data from one easyconfig into another’s dependency list.
Placing it in the fourth slot causes EasyBuild to treat it as a toolchain.
From below, a suffix is not a suffix¶
Examine the identical toolchain as employed by a package that uses it.
The toolchain’s version reads 25.11-CUDA-12.9.1.
It is not 25.11 with a suffix beside it; it is a single string with the suffix already folded in.
That is what the consumer sees, and A toolchain is a hierarchy’s hierarchy is keyed on exactly that string.
So a versionsuffix is structural for whoever declares it and opaque to whoever depends on it.
NVHPC-25.11-CUDA-12.9.1 and NVHPC-25.11-CUDA-12.8.0 are two unrelated toolchains as far as the hierarchy walk is concerned, in the same way that foss-2025a and foss-2024a are.
EB-Suffix-1 — Are these the same toolchain
Four module names:
NVHPC/25.11-CUDA-12.9.1
NVHPC/25.11-CUDA-12.8.0
NVHPC/25.11
VASP6/6.5.1-NVHPC-25.11-CUDA-12.9.1-ACC
A package declares
toolchain = {'name': 'NVHPC', 'version': '25.11-CUDA-12.9.1'}. Which of the first three satisfies it?To the hierarchy walk of A toolchain is a hierarchy, how many distinct toolchains do the first three names represent?
In the fourth name, which part is derived from a dependency and which is a label somebody typed?
Solution
Only the first. The toolchain’s version is the whole string
25.11-CUDA-12.9.1, suffix folded in, and a version match is exact.
Three. The suffix is not a modifier the walk looks through; it is part of
the key. 25.11-CUDA-12.9.1 and 25.11-CUDA-12.8.0 are as unrelated to
each other as foss-2025a and foss-2024a, and 25.11 on its own is a
third thing again.
In the fourth, -CUDA-12.9.1 belongs to the toolchain and was derived
from its CUDA dependency through %(cudaver)s. -ACC is VASP6’s own
versionsuffix and names a build variant: the OpenACC target rather than
the CPU one. Nothing derives it, and nothing in the format marks the
difference between the two.
What happens when the name stops being true¶
A label without enforcement can become stale, and this staleness is where the parameter incurs real time cost.
The 25.11 tarball is a cuda_multi build.
It includes both CUDA 12.9 and CUDA 13.0 in a single archive, placed in versioned directories alongside unversioned entries.
math_libs/include and math_libs/lib64 are links, as are comm_libs/nccl and comm_libs/nvshmem.
The targets of those four links are what a compiler and a linker locate.
The SDK’s installer determines the link destinations, and it does not consistently follow the version resolved by EasyBuild.
A single installation of that tarball on 2026-01-27 covered four architectures:
Architecture |
|
|---|---|
AMD-ZEN2 |
12.9 |
AMD-ZEN4 |
12.9 |
AMD-ZEN4-H100 |
13.0 |
INTEL-AVX512 |
13.0 |
Two of the four architectures do not follow any predictable pattern, and INTEL-AVX512 lacks a GPU.
EBNVHPCCUDAVER reported 12.9 for all four. That the easyblock resolved the version correctly while the installer ignored it on two of the four architectures in that batch.
No aspect of this contradicts the module’s name.
The name remained -CUDA-12.9.1, the dependency remained pinned to CUDA 12.9.1, and both matched the specification.
On two of the four architectures the underlying tree contained CUDA 13.0.
The consequence is specific.
Any component linking cuSPARSE via that toolchain extracts libcusparse.so.12 from the 13.0 tree, which requires libnvJitLink.so.13.
That library exists only within the 13.0 redistributable, and nothing adds it to the runtime path.
The binary links, installs, and then fails to start.
The check that found it, and the way it nearly did not¶
EasyBuild includes a check that examines this situation.
The check inspects installed binaries against their recorded runtime library search path (RPATH) and reports each library it cannot resolve.
libnvJitLink.so.13 was reported.
The build specified skipsteps = ['sanitycheck'] in its easyconfig, based on the reasoning that the check produced a failure the package could not fix.
Both components of that reasoning were true, yet the conclusion remained incorrect.
The check identified a defect in the toolchain module, disabling it did not enable the binary to start.
The responsibility for discovery was shifted to the user.
The check also carries a reputation issue that deserves clarification.
In a GPU package the check appears to fail on libcuda.so.1, which resides with the driver and exists only on GPU nodes.
This is not the case: EasyBuild exempts that library by default, together with libcuda.so, libnvidia-ml.so and libnvidia-ml.so.1.
Any other reported library constitutes a genuine finding.
The one-line version¶
A versionsuffix forms part of a module’s name, and a name does not constitute a mechanism.
The dependency performs the binding; the suffix reports it once during parse time, and no further checks occur.
Thus, the test shows that a module named for one version may behave as if it carries another.
Disregard the name and examine the tree.
The sanity check is based on appearance, which justifies retaining it even when it reports another’s problem.
Next: the definition of “installed” and the two factors that determine it.