From 0ee15358fcf348e85fdeaf134fe71df6dcf15b72 Mon Sep 17 00:00:00 2001 From: Alan O'Cais Date: Tue, 1 Sep 2026 17:23:43 +0200 Subject: [PATCH 1/4] Add support for ROCm, new toolchains, and 2026.06 --- .github/workflows/docs.yml | 49 +++++++++++++++++++++- scripts/generate_data_files.py | 31 ++++++++------ scripts/process_eessi_software_metadata.py | 25 ++++++++++- 3 files changed, 89 insertions(+), 16 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 91201ea..52f3160 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -36,6 +36,31 @@ jobs: export EESSI_ARCHDETECT_OPTIONS_OVERRIDE="x86_64/intel/icelake" # Set GPU overrides for the stack to query (we have no GPU, so also override the GPU check) export EESSI_OVERRIDE_GPU_CHECK=1 + + ## CPU only ## + # First do 2023.06 for EB 4 + ( module load EESSI/2023.06 && module load EasyBuild/4 && module load EESSI-extend && python scripts/generate_data_files.py --eessi-version=2023.06 ) & + pid1=$! + # then 2023.06 for EB 5 + ( module load EESSI/2023.06 && module load EasyBuild/5 && module load EESSI-extend && python scripts/generate_data_files.py --eessi-version=2023.06 ) & + pid2=$! + # then 2025.06 for EB 5 (does not have EB4) + ( module load EESSI/2025.06 && module load EasyBuild/5 && module load EESSI-extend && python scripts/generate_data_files.py --eessi-version=2025.06 ) & + pid3=$! + # then 2026.06 for EB 5 (does not have EB4) + ( module load EESSI/2026.06 && module load EasyBuild/5 && module load EESSI-extend && python scripts/generate_data_files.py --eessi-version=2026.06 ) & + pid4=$! + fail=0 # initialise + wait $pid1 || fail=1 + wait $pid2 || fail=2 + wait $pid3 || fail=3 + wait $pid4 || fail=4 + if [ $fail -ne 0 ]; then + echo "One or more jobs failed for CPU only (at least job $fail)" + exit 1 + fi + + ## NVIDIA GPU ## # First do 2023.06 for EB 4 export EESSI_ACCELERATOR_TARGET_OVERRIDE="accel/nvidia/cc80" # Stick to 8.0 for EB4 as options for 9.0 set by EESSI-extend are not understood there ( module load EESSI/2023.06 && module load EasyBuild/4 && module load EESSI-extend && python scripts/generate_data_files.py --eessi-version=2023.06 ) & @@ -48,14 +73,37 @@ jobs: export EESSI_ACCELERATOR_TARGET_OVERRIDE="accel/nvidia/cc90" ( module load EESSI/2025.06 && module load EasyBuild/5 && module load EESSI-extend && python scripts/generate_data_files.py --eessi-version=2025.06 ) & pid3=$! + # then 2026.06 for EB 5 (does not have EB4) + export EESSI_ACCELERATOR_TARGET_OVERRIDE="accel/nvidia/cc90" + ( module load EESSI/2026.06 && module load EasyBuild/5 && module load EESSI-extend && python scripts/generate_data_files.py --eessi-version=2026.06 ) & + pid4=$! fail=0 # initialise wait $pid1 || fail=1 wait $pid2 || fail=2 wait $pid3 || fail=3 + wait $pid4 || fail=4 + if [ $fail -ne 0 ]; then + echo "One or more jobs failed for NVIDIA GPU (at least job $fail)" + exit 1 + fi + + ## AMD GPU (2025.06+) ## + # 2025.06 for EB 5 (does not have EB4) + export EESSI_ACCELERATOR_TARGET_OVERRIDE="accel/amd/gfx1200" + ( module load EESSI/2025.06 && module load EasyBuild/5 && module load EESSI-extend && python scripts/generate_data_files.py --eessi-version=2025.06 ) & + pid1=$! + # then 2026.06 for EB 5 (does not have EB4) + export EESSI_ACCELERATOR_TARGET_OVERRIDE="accel/amd/gfx1200" + ( module load EESSI/2026.06 && module load EasyBuild/5 && module load EESSI-extend && python scripts/generate_data_files.py --eessi-version=2026.06 ) & + pid2=$! + fail=0 # initialise + wait $pid1 || fail=1 + wait $pid2 || fail=2 if [ $fail -ne 0 ]; then echo "One or more jobs failed (at least job $fail)" exit 1 fi + # Merge all these results together python scripts/merge_data_files.py out.yaml eessi*.yaml mv out.yaml docs/data/eessi_software_metadata.yaml @@ -68,7 +116,6 @@ jobs: export EESSI_VERSION_OVERRIDE="2025.06-001" export EESSI_ARCHDETECT_OPTIONS_OVERRIDE="riscv64/generic" export EESSI_SOFTWARE_SUBDIR_OVERRIDE="riscv64/generic" - export EESSI_ACCELERATOR_TARGET_OVERRIDE="does/not/exist" export EESSI_CPU_FAMILY_OVERRIDE="x86_64" module load EESSI/2025.06 module load EasyBuild/5 diff --git a/scripts/generate_data_files.py b/scripts/generate_data_files.py index 2dd9762..f186ce1 100644 --- a/scripts/generate_data_files.py +++ b/scripts/generate_data_files.py @@ -19,7 +19,7 @@ from contextlib import contextmanager SUPPORTED_REPOSITORIES = { - 'software.eessi.io': ["2025.06", "2023.06"], + 'software.eessi.io': ["2026.06", "2025.06", "2023.06"], 'dev.eessi.io/riscv': ["2025.06-001"], } @@ -32,7 +32,13 @@ # Give order to my toolchains so I can easily figure out what "latest" means EESSI_SUPPORTED_TOP_LEVEL_TOOLCHAINS = OrderedDict( { + "2026.06": [ + {"name": "lfoss", "version": "2026.1"}, + {"name": "foss", "version": "2026.1"}, + ], "2025.06": [ + {"name": "rompi", "version": "2025a"}, + {"name": "lfoss", "version": "2025b"}, {"name": "foss", "version": "2025b"}, {"name": "foss", "version": "2025a"}, {"name": "foss", "version": "2024a"}, @@ -249,18 +255,17 @@ def merge_dicts(d1, d2): print("You must have selected a CPU architecture via EESSI_ARCHDETECT_OPTIONS_OVERRIDE environment variable") exit() base_path = f"/cvmfs/{repository}/versions/{eessi_version}/software/linux/{eessi_reference_architecture}" - cpu_easyconfig_files_dict = collect_eb_files(os.path.join(base_path, "software")) - # We also gather all the acclerator installations for NVIDIA-enabled packages - # We're not typically running this script on a node with a GPU so an override must have been set - eessi_reference_nvidia_architecture = os.getenv("EESSI_ACCELERATOR_TARGET_OVERRIDE", False) - if not eessi_reference_nvidia_architecture: - print("You must have selected a GPU architecture via EESSI_ACCELERATOR_TARGET_OVERRIDE") - exit() - accel_base_path = os.path.join(base_path, eessi_reference_nvidia_architecture) - accel_easyconfig_files_dict = collect_eb_files(os.path.join(accel_base_path, "software")) - # Merge the easyconfig files - easyconfig_files_dict = merge_dicts(cpu_easyconfig_files_dict, accel_easyconfig_files_dict) + # If the accelerator override is set, we want to gather all the acclerator installations for accelerator-enabled + # packages. We're not typically running this script on a node with a GPU so an override must have been set. + eessi_reference_accel_architecture = os.getenv("EESSI_ACCELERATOR_TARGET_OVERRIDE", False) + if eessi_reference_accel_architecture: + accel_base_path = os.path.join(base_path, eessi_reference_accel_architecture) + output_stub = '-' + eessi_reference_accel_architecture.replace('/', '_') + easyconfig_files_dict = collect_eb_files(os.path.join(accel_base_path, "software")) + else: + easyconfig_files_dict = collect_eb_files(os.path.join(base_path, "software")) + output_stub = '' set_up_configuration(args="") tmpdir = tempfile.mkdtemp() @@ -390,7 +395,7 @@ def merge_dicts(d1, d2): # Store the result with open( - f"eessi_software_{eessi_version}-eb{str(EASYBUILD_VERSION.version[0])}.yaml", + f"eessi_software_{eessi_version}-eb{str(EASYBUILD_VERSION.version[0])}{output_stub}.yaml", "w", ) as f: yaml.dump(eessi_software, f) diff --git a/scripts/process_eessi_software_metadata.py b/scripts/process_eessi_software_metadata.py index a413188..ab7002b 100644 --- a/scripts/process_eessi_software_metadata.py +++ b/scripts/process_eessi_software_metadata.py @@ -13,6 +13,7 @@ "aarch64/neoverse_n1", "aarch64/neoverse_v1", "aarch64/nvidia/grace", + "aarch64/aws/graviton4", "x86_64/generic", "x86_64/amd/zen2", "x86_64/amd/zen3", @@ -31,14 +32,30 @@ NVIDIA_ARCHITECTURES = [ "accel/nvidia/cc70", + "accel/nvidia/cc75", "accel/nvidia/cc80", "accel/nvidia/cc90", "accel/nvidia/cc100", "accel/nvidia/cc120", ] +ROCM_ARCHITECTURES = [ + "accel/amd/gfx1030", + "accel/amd/gfx1100", + "accel/amd/gfx1101", + "accel/amd/gfx1200", + "accel/amd/gfx1201", + "accel/amd/gfx908", + "accel/amd/gfx90a", + "accel/amd/gfx942", +] + TOOLCHAIN_FAMILIES = [ + "2026.1_lfoss", + "2026.1_foss", + "2025b_lfoss", "2025b_foss", + "2025a_rompi", "2025a_foss", "2024a_foss", "2023b_foss", @@ -83,7 +100,7 @@ def get_software_information_by_filename(file_metadata, original_path=None, tool # needs to be a dict as we can filter on associated cpu arch base_version_dict["gpu_arch"] = {} detected_accel_arch = None - for accel_arch in NVIDIA_ARCHITECTURES: + for accel_arch in NVIDIA_ARCHITECTURES + ROCM_ARCHITECTURES: if f"/{accel_arch}/" in original_path: detected_accel_arch = accel_arch break @@ -111,7 +128,11 @@ def get_software_information_by_filename(file_metadata, original_path=None, tool # If we have an accelerator module let's check which architectures are supported if detected_accel_arch: base_version_dict["gpu_arch"][arch] = [] - for accel_arch in NVIDIA_ARCHITECTURES: + if accel_arch in ROCM_ARCHITECTURES: + accel_architectures = ROCM_ARCHITECTURES + else: + accel_architectures = NVIDIA_ARCHITECTURES + for accel_arch in accel_architectures: accel_substituted_modulefile = substituted_modulefile.replace(detected_accel_arch, accel_arch) found = subprocess.run(["grep", "-q", accel_substituted_modulefile, substituted_spider_cache]).returncode == 0 if found: From def3e39eb9ca8c81b6087fec2f74f7e16b01413e Mon Sep 17 00:00:00 2001 From: Alan O'Cais Date: Wed, 2 Sep 2026 18:28:26 +0200 Subject: [PATCH 2/4] Mention which path is being searched --- scripts/generate_data_files.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/generate_data_files.py b/scripts/generate_data_files.py index f186ce1..85a8f1f 100644 --- a/scripts/generate_data_files.py +++ b/scripts/generate_data_files.py @@ -261,9 +261,11 @@ def merge_dicts(d1, d2): eessi_reference_accel_architecture = os.getenv("EESSI_ACCELERATOR_TARGET_OVERRIDE", False) if eessi_reference_accel_architecture: accel_base_path = os.path.join(base_path, eessi_reference_accel_architecture) + print(f"Searching for all accelerator easyconfigs under {accel_base_path}") output_stub = '-' + eessi_reference_accel_architecture.replace('/', '_') easyconfig_files_dict = collect_eb_files(os.path.join(accel_base_path, "software")) else: + print(f"Searching for all easyconfigs under {base_path}") easyconfig_files_dict = collect_eb_files(os.path.join(base_path, "software")) output_stub = '' From 925abaeec93fe2ebc039776b0a54f0ccd69f2310 Mon Sep 17 00:00:00 2001 From: Alan O'Cais Date: Wed, 2 Sep 2026 18:46:36 +0200 Subject: [PATCH 3/4] Make CI a bit more challenging --- .github/workflows/prs.yml | 42 ++++++++++++++++++++++++++++++---- scripts/generate_data_files.py | 3 +++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/.github/workflows/prs.yml b/.github/workflows/prs.yml index de52a31..147713b 100644 --- a/.github/workflows/prs.yml +++ b/.github/workflows/prs.yml @@ -31,16 +31,50 @@ jobs: export EESSI_DEBUG_INIT=1 # Set CPU override for the stack to query export EESSI_ARCHDETECT_OPTIONS_OVERRIDE="x86_64/intel/icelake" - # Set GPU overrides for the stack to query (we have no GPU, so also override the GPU check) - export EESSI_ACCELERATOR_TARGET_OVERRIDE="accel/nvidia/cc90" - export EESSI_OVERRIDE_GPU_CHECK=1 module load EESSI/2023.06 module load EasyBuild/5 module load EESSI-extend python scripts/generate_data_files.py --eessi-version=2023.06 ) & + pid1=$! + # then 2025.06 for EB 5 with AMD accelerators (does not have EB4) + ( + module --force purge + export EESSI_DEBUG_INIT=1 + # Set CPU override for the stack to query + export EESSI_ARCHDETECT_OPTIONS_OVERRIDE="x86_64/intel/icelake" + # Set GPU overrides for the stack to query (we have no GPU, so also override the GPU check) + export EESSI_ACCELERATOR_TARGET_OVERRIDE="accel/amd/gfx1200" + export EESSI_OVERRIDE_GPU_CHECK=1 + module load EESSI/2025.06 + module load EasyBuild/5 + module load EESSI-extend + python scripts/generate_data_files.py --eessi-version=2025.06 + ) & + pid2=$! + # then 2025.06 for EB 5 with NVIDIA accelerators (does not have EB4) + ( + module --force purge + export EESSI_DEBUG_INIT=1 + # Set CPU override for the stack to query + export EESSI_ARCHDETECT_OPTIONS_OVERRIDE="x86_64/intel/icelake" + # Set GPU overrides for the stack to query (we have no GPU, so also override the GPU check) + export EESSI_ACCELERATOR_TARGET_OVERRIDE="accel/nvidia/cc80" + export EESSI_OVERRIDE_GPU_CHECK=1 + module load EESSI/2025.06 + module load EasyBuild/5 + module load EESSI-extend + python scripts/generate_data_files.py --eessi-version=2025.06 + ) & + pid3=$! # Merge all these results together - wait + wait $pid1 || fail=1 + wait $pid2 || fail=2 + wait $pid3 || fail=3 + if [ $fail -ne 0 ]; then + echo "One or more jobs failed (at least job $fail)" + exit 1 + fi module reset module load EESSI-extend # Loads EasyBuild and we need that for our merge scripts python scripts/merge_data_files.py out.yaml eessi*.yaml diff --git a/scripts/generate_data_files.py b/scripts/generate_data_files.py index 85a8f1f..0fe2280 100644 --- a/scripts/generate_data_files.py +++ b/scripts/generate_data_files.py @@ -180,6 +180,9 @@ def collect_eb_files(base_path): # Find all .eb files recursively eb_files = glob.glob(os.path.join(base_path, "*/*/easybuild/*.eb")) + if not eb_files: + raise FileNotFoundError(f"No .eb files found under {base_path}, that's probably an error") + for eb_file in eb_files: folder = os.path.dirname(eb_file) From 472aa2d1e8a9e8247256c53feb3949d463c7e43d Mon Sep 17 00:00:00 2001 From: Alan O'Cais Date: Wed, 2 Sep 2026 18:57:55 +0200 Subject: [PATCH 4/4] Fix a couple of bugs --- .github/workflows/prs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prs.yml b/.github/workflows/prs.yml index 147713b..0fc75b3 100644 --- a/.github/workflows/prs.yml +++ b/.github/workflows/prs.yml @@ -68,6 +68,7 @@ jobs: ) & pid3=$! # Merge all these results together + fail=0 wait $pid1 || fail=1 wait $pid2 || fail=2 wait $pid3 || fail=3 @@ -89,7 +90,6 @@ jobs: export EESSI_VERSION_OVERRIDE="2025.06-001" export EESSI_ARCHDETECT_OPTIONS_OVERRIDE="riscv64/generic" export EESSI_SOFTWARE_SUBDIR_OVERRIDE="riscv64/generic" - export EESSI_ACCELERATOR_TARGET_OVERRIDE="does/not/exist" export EESSI_CPU_FAMILY_OVERRIDE="x86_64" module load EESSI/2025.06 module load EasyBuild/5