diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index de3adeb..5cb48af 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 module reset module load EESSI-extend # Loads EasyBuild and we need that for our merge scripts @@ -71,7 +119,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/.github/workflows/prs.yml b/.github/workflows/prs.yml index de52a31..0fc75b3 100644 --- a/.github/workflows/prs.yml +++ b/.github/workflows/prs.yml @@ -31,16 +31,51 @@ 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 + fail=0 + 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 @@ -55,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 diff --git a/scripts/generate_data_files.py b/scripts/generate_data_files.py index 2dd9762..0fe2280 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"}, @@ -174,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) @@ -249,18 +258,19 @@ 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) + 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 = '' set_up_configuration(args="") tmpdir = tempfile.mkdtemp() @@ -390,7 +400,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 d64323a..42422f7 100644 --- a/scripts/process_eessi_software_metadata.py +++ b/scripts/process_eessi_software_metadata.py @@ -15,6 +15,7 @@ "aarch64/neoverse_n1", "aarch64/neoverse_v1", "aarch64/nvidia/grace", + "aarch64/aws/graviton4", "x86_64/generic", "x86_64/amd/zen2", "x86_64/amd/zen3", @@ -33,14 +34,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", @@ -85,7 +102,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 @@ -113,7 +130,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: