Skip to content

Commit f298963

Browse files
committed
Improve search for ROCm-LLVM dep and add tests
1 parent 27e599d commit f298963

2 files changed

Lines changed: 94 additions & 21 deletions

File tree

.github/workflows/test-eb-hooks.yml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,48 @@ jobs:
116116
eb --hooks=$PWD/eb_hooks.py "$INCOMPATIBLE_EASYCONFIG" --stop fetch 2>&1 1>/dev/null | grep -q "does not contain a valid list of dictionaries"
117117
echo "Incorrect format for EESSI_SITE_TOP_LEVEL_TOOLCHAINS caught"
118118
119+
check_inject_gpu_property:
120+
runs-on: ubuntu-24.04
121+
strategy:
122+
matrix:
123+
# ROCm-LLVM / rocm-compilers / rompi only exist in the 2025.06 stack
124+
EESSI_VERSION:
125+
- '2025.06'
126+
127+
steps:
128+
- name: Check out software-layer repository
129+
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
130+
131+
- name: Mount EESSI CernVM-FS repository
132+
uses: eessi/github-action-eessi@v3
133+
with:
134+
eessi_stack_version: ${{matrix.EESSI_VERSION}}
135+
use_eessi_module: true
136+
137+
- name: Test that inject_gpu_property tags GPU software correctly
138+
if: ${{ github.event_name == 'pull_request' }}
139+
run: |
140+
module load EESSI-extend/${{matrix.EESSI_VERSION}}-easybuild
141+
142+
# Control: a non-GPU easyconfig must not receive the gpu property
143+
eb --hooks=$PWD/eb_hooks.py --extended-dry-run M4-1.4.19-GCCcore-14.2.0.eb 2>&1 | grep -qF 'add_property("arch","gpu")' && exit 1
144+
echo "Non-GPU easyconfig untouched"
145+
146+
# ROCm-LLVM as a direct dependency (rocm-compilers bundle)
147+
OUT=$(eb --hooks=$PWD/eb_hooks.py --extended-dry-run rocm-compilers-19.0.0-ROCm-6.4.1.eb 2>&1)
148+
echo "$OUT" | grep -qF 'add_property("arch","gpu")'
149+
echo "$OUT" | grep -qF 'setenv("EESSIROCMMINLLVMVERSION","19.0.0-ROCm-6.4.1")'
150+
echo "Direct ROCm-LLVM dependency detected"
151+
152+
# rocm-compilers as the toolchain
153+
OUT=$(eb --hooks=$PWD/eb_hooks.py --extended-dry-run hwloc-ROCm-2.11.2-rocm-compilers-19.0.0-ROCm-6.4.1.eb 2>&1)
154+
echo "$OUT" | grep -qF 'add_property("arch","gpu")'
155+
echo "$OUT" | grep -qF 'setenv("EESSIROCMMINLLVMVERSION","19.0.0-ROCm-6.4.1")'
156+
echo "rocm-compilers toolchain handled"
157+
158+
# rompi as the toolchain (ROCm-LLVM nested inside rocm-compilers bundle)
159+
OUT=$(eb --hooks=$PWD/eb_hooks.py --extended-dry-run OSU-Micro-Benchmarks-7.5-rompi-2025a.eb 2>&1)
160+
echo "$OUT" | grep -qF 'add_property("arch","gpu")'
161+
echo "$OUT" | grep -qF 'setenv("EESSIROCMMINLLVMVERSION","19.0.0-ROCm-6.4.1")'
162+
echo "rompi toolchain handled"
163+

eb_hooks.py

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@
1111
import easybuild.tools.environment as env
1212
from easybuild.easyblocks.generic.configuremake import obtain_config_guess
1313
from easybuild.framework.easyconfig.constants import EASYCONFIG_CONSTANTS
14-
from easybuild.framework.easyconfig.easyconfig import get_toolchain_hierarchy
14+
from easybuild.framework.easyconfig.easyconfig import (
15+
get_toolchain_hierarchy,
16+
process_easyconfig,
17+
robot_find_easyconfig,
18+
)
1519
from easybuild.tools import config
1620
from easybuild.tools.build_log import EasyBuildError, print_msg, print_warning
1721
from easybuild.tools.config import build_option, install_path, update_build_option
@@ -1934,45 +1938,69 @@ def replace_binary_non_distributable_files_with_symlinks(log, install_dir, pkg_n
19341938
symlink(host_inj_path, full_path)
19351939

19361940

1941+
def find_rocm_llvm_dependency(ec):
1942+
"""
1943+
Return the ROCm-LLVM dependency for this easyconfig, or None. ROCm-LLVM can
1944+
be a direct dependency, a direct toolchain component (rocm-compilers as the
1945+
toolchain), or one level deeper inside the rocm-compilers bundle when the
1946+
toolchain is rompi/rfbf/rfoss.
1947+
"""
1948+
for dep in ec.asdict()['dependencies']:
1949+
if dep['name'] == 'ROCm-LLVM':
1950+
return dep
1951+
1952+
if is_system_toolchain(ec.toolchain.name):
1953+
return None
1954+
1955+
tcdeps = ec.toolchain.tcdeps or []
1956+
for dep in tcdeps:
1957+
if dep['name'] == 'ROCm-LLVM':
1958+
return dep
1959+
for dep in tcdeps:
1960+
if dep['name'] == 'rocm-compilers':
1961+
rocm_compilers_ec = robot_find_easyconfig(dep['name'], dep['version'] + dep['versionsuffix'])
1962+
if rocm_compilers_ec:
1963+
rocm_compilers_deps = process_easyconfig(rocm_compilers_ec)[0]['ec'].dependencies(runtime_only=True)
1964+
for subdep in rocm_compilers_deps:
1965+
if subdep['name'] == 'ROCm-LLVM':
1966+
return subdep
1967+
1968+
return None
1969+
1970+
19371971
def inject_gpu_property(ec):
19381972
"""
19391973
Add 'gpu' property and EESSI<PACKAGE>VERSION envvars via modluafooter
19401974
easyconfig parameter, and drop dependencies to build dependencies
19411975
"""
19421976
ec_dict = ec.asdict()
1943-
# Check if CUDA, cuDNN, you-name-it is in the dependencies, if so
1944-
# - drop dependency to build dependency
1945-
# - add 'gpu' Lmod property
1946-
# - add envvar with package version
1947-
pkg_names = ( "CUDA", "cuDNN", "ROCm-LLVM" )
1948-
# skip dropping step for ROCm-LLVM as it is redistributable
1949-
drop_to_builddep = ( "CUDA", "cuDNN" )
19501977
pkg_versions = { }
19511978
add_gpu_property = ''
19521979

1953-
# If none of the gpu packages are in the easyconfig, do not process further
1954-
dep_names = {dep[0] for dep in ec_dict['dependencies']}
1955-
if not any(pkg in dep_names for pkg in pkg_names):
1956-
return ec
1957-
1958-
# Check if pkg_name is in the dependencies, if so drop dependency to build
1980+
# Check if pkg_name is related to CUDA, if so drop dependency to build
19591981
# dependency and set variable for later adding the 'gpu' Lmod property
19601982
# to '.remove' dependencies from ec_dict['dependencies'] we make a copy,
19611983
# iterate over the copy and can then savely use '.remove' on the original
1962-
for pkg_name in pkg_names:
1984+
# ec_dict['dependencies'].
1985+
for pkg_name in ('CUDA', 'cuDNN'):
19631986
for dep in ec_dict['dependencies'][:]:
19641987
if dep[0] != pkg_name:
19651988
continue
19661989

19671990
add_gpu_property = 'add_property("arch","gpu")'
19681991
pkg_versions[pkg_name] = dep[1]
19691992

1970-
if pkg_name in drop_to_builddep:
1971-
ec.log.info("Dropping dependency on %s to build dependency" % pkg_name)
1972-
ec_dict['dependencies'].remove(dep)
1973-
# Avoid adding a duplicate
1974-
if dep not in ec_dict['builddependencies']:
1975-
ec_dict['builddependencies'].append(dep)
1993+
ec.log.info("Dropping dependency on %s to build dependency" % pkg_name)
1994+
ec_dict['dependencies'].remove(dep)
1995+
if dep not in ec_dict['builddependencies']:
1996+
ec_dict['builddependencies'].append(dep)
1997+
1998+
# ROCm-LLVM is handled separately: it is redistributable (kept as a runtime dep)
1999+
# and may be pulled in via a ROCm toolchain rather than as a direct dependency.
2000+
rocm_llvm_dep = find_rocm_llvm_dependency(ec)
2001+
if rocm_llvm_dep is not None:
2002+
add_gpu_property = 'add_property("arch","gpu")'
2003+
pkg_versions['ROCm-LLVM'] = rocm_llvm_dep['version'] + (rocm_llvm_dep['versionsuffix'] or '')
19762004

19772005
if add_gpu_property:
19782006
ec.log.info("Injecting gpu as Lmod arch property and envvars for dependencies with their version")

0 commit comments

Comments
 (0)