Compare commits

...

6 Commits

Author SHA1 Message Date
Harmen Stoppels
01423a9bea ROCmPackage: depend on hip-lang 2025-04-09 10:02:54 +02:00
Harmen Stoppels
0ac63a3799 add hip compiler property 2025-04-09 10:02:54 +02:00
Harmen Stoppels
2519ad20da compiler-wrapper: add hip support 2025-04-09 10:02:54 +02:00
Harmen Stoppels
adfb6ee6aa depends_on llvm-amdgpu -> requires %llvm-amdpu 2025-04-09 10:00:38 +02:00
Harmen Stoppels
d17c118a78 add hip-lang as a language virtual 2025-04-09 10:00:35 +02:00
Harmen Stoppels
1a57df46f6 compiler-wrapper: respect -x and --language
To compile hip code, the clang++ is invoked with -x hip, so we should
derive the language from the -x flag.
2025-04-09 10:00:35 +02:00
12 changed files with 118 additions and 40 deletions

View File

@ -33,6 +33,7 @@ packages:
glu: [mesa-glu, openglu]
golang: [go, gcc]
go-or-gccgo-bootstrap: [go-bootstrap, gcc]
hip-lang: [llvm-amdgpu]
iconv: [libiconv]
ipp: [intel-oneapi-ipp]
java: [openjdk, jdk]

View File

@ -199,10 +199,21 @@ def cxx(self) -> Optional[str]:
return self.spec.extra_attributes["compilers"].get("cxx", None)
return self._cxx_path()
@property
def hip(self) -> Optional[str]:
assert self.spec.concrete, "cannot retrieve HIP compiler, spec is not concrete"
if self.spec.external:
return self.spec.extra_attributes["compilers"].get("hip", None)
return self._hip_path()
def _cxx_path(self) -> Optional[str]:
"""Returns the path to the C++ compiler, if the package was installed by Spack"""
return None
def _hip_path(self) -> Optional[str]:
"""Returns the path to the HIP compiler, if the package was installed by Spack"""
return self._cxx_path()
@property
def fortran(self):
assert self.spec.concrete, "cannot retrieve Fortran compiler, spec is not concrete"

View File

@ -77,7 +77,7 @@
import os
import spack.variant
from spack.directives import conflicts, depends_on, variant
from spack.directives import conflicts, depends_on, requires, variant
from spack.package_base import PackageBase
from spack.util.environment import EnvironmentModifications
@ -140,9 +140,7 @@ class ROCmPackage(PackageBase):
when="+rocm",
)
depends_on("llvm-amdgpu", type="build", when="+rocm")
depends_on("hsa-rocr-dev", when="+rocm")
depends_on("hip +rocm", when="+rocm")
depends_on("hip-lang", type="build", when="+rocm")
# need amd gpu type for rocm builds
conflicts("amdgpu_target=none", when="+rocm")
@ -183,14 +181,14 @@ def asan_on(self, env: EnvironmentModifications):
# Add compiler minimum versions based on the first release where the
# processor is included in llvm/lib/Support/TargetParser.cpp
depends_on("llvm-amdgpu@5.2.0:", when="amdgpu_target=gfx940")
depends_on("llvm-amdgpu@5.7.0:", when="amdgpu_target=gfx941")
depends_on("llvm-amdgpu@5.7.0:", when="amdgpu_target=gfx942")
depends_on("llvm-amdgpu@5.2.0:", when="amdgpu_target=gfx1036")
depends_on("llvm-amdgpu@5.3.0:", when="amdgpu_target=gfx1100")
depends_on("llvm-amdgpu@5.3.0:", when="amdgpu_target=gfx1101")
depends_on("llvm-amdgpu@5.3.0:", when="amdgpu_target=gfx1102")
depends_on("llvm-amdgpu@5.3.0:", when="amdgpu_target=gfx1103")
requires("%[virtuals=hip-lang] llvm-amdgpu@5.2.0:", when="amdgpu_target=gfx940")
requires("%[virtuals=hip-lang] llvm-amdgpu@5.7.0:", when="amdgpu_target=gfx941")
requires("%[virtuals=hip-lang] llvm-amdgpu@5.7.0:", when="amdgpu_target=gfx942")
requires("%[virtuals=hip-lang] llvm-amdgpu@5.2.0:", when="amdgpu_target=gfx1036")
requires("%[virtuals=hip-lang] llvm-amdgpu@5.3.0:", when="amdgpu_target=gfx1100")
requires("%[virtuals=hip-lang] llvm-amdgpu@5.3.0:", when="amdgpu_target=gfx1101")
requires("%[virtuals=hip-lang] llvm-amdgpu@5.3.0:", when="amdgpu_target=gfx1102")
requires("%[virtuals=hip-lang] llvm-amdgpu@5.3.0:", when="amdgpu_target=gfx1103")
# Compiler conflicts

View File

@ -1421,6 +1421,7 @@ compiler(Compiler) :- compiler_supports_target(Compiler, _, _).
language("c").
language("cxx").
language("fortran").
language("hip-lang").
language_runtime("fortran-rt").
error(10, "Only external, or concrete, compilers are allowed for the {0} language", Language)

View File

@ -216,16 +216,13 @@ def check_args_contents(cc, args, must_contain, must_not_contain):
assert a not in cc_modified_args
def check_env_var(executable, var, expected):
"""Check environment variables updated by the passed compiler wrapper
This assumes that cc will print debug output when it's environment
contains SPACK_TEST_COMMAND=dump-env-<variable-to-debug>
"""
executable = Executable(str(executable))
with set_env(SPACK_TEST_COMMAND="dump-env-" + var):
output = executable(*test_args, output=str).strip()
assert executable.path + ": " + var + ": " + expected == output
def check_wrapper_var(exe, *args, var, expected):
"""Check variables set by the compiler wrapper. This works by setting SPACK_TEST_COMMAND to
dump-var-<variable-to-debug>, which will print the variable and exit."""
executable = Executable(str(exe))
with set_env(SPACK_TEST_COMMAND=f"dump-var-{var}"):
output = executable(*args, output=str).strip()
assert f"{executable.path}: {var}: {expected}" == output
def dump_mode(cc, args):
@ -749,11 +746,22 @@ def test_system_path_cleanup(wrapper_environment, wrapper_dir):
"""
cc = wrapper_dir / "cc"
system_path = "/bin:/usr/bin:/usr/local/bin"
with set_env(SPACK_COMPILER_WRAPPER_PATH=str(wrapper_dir), SPACK_CC="true"):
with set_env(SPACK_COMPILER_WRAPPER_PATH=str(wrapper_dir)):
with set_env(PATH=str(wrapper_dir) + ":" + system_path):
check_env_var(cc, "PATH", system_path)
check_wrapper_var(cc, *test_args, var="PATH", expected=system_path)
with set_env(PATH=str(wrapper_dir) + "/:" + system_path):
check_env_var(cc, "PATH", system_path)
check_wrapper_var(cc, *test_args, var="PATH", expected=system_path)
def test_language_from_flags(wrapper_environment, wrapper_dir):
"""Tes that the compiler language mode is determined by -x/--language flags if present"""
cc = wrapper_dir / "cc"
for flag_value, lang in [("c", "CC"), ("c++", "CXX"), ("f77", "F77"), ("f95", "FC")]:
check_wrapper_var(cc, "-c", "file", "-x", flag_value, var="comp", expected=lang)
check_wrapper_var(cc, "-c", "file", f"-x{flag_value}", var="comp", expected=lang)
check_wrapper_var(cc, "-c", "file", f"--language={flag_value}", var="comp", expected=lang)
check_wrapper_var(cc, "-c", "file", "--language", flag_value, var="comp", expected=lang)
def test_ld_deps_partial(wrapper_environment, wrapper_dir):

View File

@ -68,6 +68,7 @@ def url_for_version(self, version):
depends_on("zlib-api", type="link")
depends_on("z3", type="link")
depends_on("ncurses", type="link")
requires("%[virtuals=c,cxx] llvm-amdgpu")
for ver in [
"5.3.0",
@ -94,12 +95,9 @@ def url_for_version(self, version):
"6.3.3",
"master",
]:
# llvm libs are linked statically, so this *could* be a build dep
depends_on(f"llvm-amdgpu@{ver}", when=f"@{ver}")
# aomp may not build rocm-device-libs as part of llvm-amdgpu, so make
# that a conditional dependency
depends_on(f"rocm-device-libs@{ver}", when=f"@{ver} ^llvm-amdgpu ~rocm-device-libs")
# in reality this should be a link type dep, but libLLVM is linked statically,
# and just requiring llvm-amdgpu as a compiler suffices for now.
requires(f"%llvm-amdgpu@{ver}", when=f"@{ver}")
depends_on(f"rocm-cmake@{ver}", when=f"@{ver}", type="build")
for ver in [

View File

@ -178,9 +178,10 @@ execute() {
unset IFS
exit
;;
dump-env-*)
var=${SPACK_TEST_COMMAND#dump-env-}
dump-var-*)
var=${SPACK_TEST_COMMAND#dump-var-}
eval "printf '%s\n' \"\$0: \$var: \$$var\""
exit
;;
*)
die "Unknown test command: '$SPACK_TEST_COMMAND'"
@ -296,9 +297,36 @@ fi
# Note. SPACK_ALWAYS_XFLAGS are applied for all compiler invocations,
# including version checks (SPACK_XFLAGS variants are not applied
# for version checks).
command="${0##*/}"
command_from_argv0="${0##*/}"
command="$command_from_argv0"
comp="CC"
vcheck_flags=""
_command_from_flags() {
while [ $# -ne 0 ]; do
arg="$1"
shift
case "$arg" in
-x|--language)
_lang="$1"
shift ;;
-x*)
_lang="${arg#-x}" ;;
--language=*)
_lang="${arg#--language=}" ;;
*) continue ;;
esac
done
case "$_lang" in
c) command=cc ;;
c++|f77|f95|hip) command="$_lang" ;;
*) command="$command_from_argv0" ;; # drop unknown languages
esac
}
_command_from_flags "$@"
case "$command" in
cpp)
mode=cpp
@ -337,6 +365,14 @@ case "$command" in
debug_flags="-g"
vcheck_flags="${SPACK_ALWAYS_FFLAGS}"
;;
hip)
command="$SPACK_HIPCXX"
language="HIP"
comp="HIPCXX"
lang_flags=HIP
debug_flags="-g"
vcheck_flags="${SPACK_ALWAYS_HIPCXXFLAGS}"
;;
ld|ld.gold|ld.lld)
mode=ld
if [ -z "$SPACK_CC_RPATH_ARG" ]; then

View File

@ -43,7 +43,7 @@ class CompilerWrapper(Package):
if sys.platform != "win32":
version(
"1.0",
sha256="c65a9d2b2d4eef67ab5cb0684d706bb9f005bb2be94f53d82683d7055bdb837c",
sha256="01db837305c8e181f142da3341c8438e0a7b4e03f0361df19d5784ab68b3c1f2",
expand=False,
)
else:
@ -156,6 +156,9 @@ def setup_dependent_build_environment(self, env, dependent_spec):
_var_list.append(("fortran", "fortran", "F77", "SPACK_F77"))
_var_list.append(("fortran", "fortran", "FC", "SPACK_FC"))
if dependent_spec.has_virtual_dependency("hip-lang"):
_var_list.append(("hip-lang", "hip", "HIPCXX", "SPACK_HIPCXX"))
# The package is not used as a compiler, so skip this setup
if not _var_list:
return

View File

@ -69,6 +69,8 @@ class Hip(CMakePackage):
depends_on("libedit", type="build")
depends_on("perl@5.10:", type=("build", "run"))
requires("%[virtuals=c,cxx] llvm-amdgpu")
test_requires_compiler = True
with when("+rocm"):
@ -123,8 +125,8 @@ class Hip(CMakePackage):
"6.3.3",
]:
depends_on(f"hsa-rocr-dev@{ver}", when=f"@{ver}")
requires(f"%llvm-amdgpu@{ver}", when=f"@{ver}")
depends_on(f"comgr@{ver}", when=f"@{ver}")
depends_on(f"llvm-amdgpu@{ver} +rocm-device-libs", when=f"@{ver}")
depends_on(f"rocminfo@{ver}", when=f"@{ver}")
depends_on(f"roctracer-dev-api@{ver}", when=f"@{ver}")

View File

@ -57,6 +57,8 @@ class HipifyClang(CMakePackage):
depends_on("cxx", type="build")
depends_on("cmake@3.5:", type="build")
requires("%[virtuals=c,cxx] llvm-amdgpu")
for ver in [
"5.3.0",
"5.3.3",
@ -82,7 +84,7 @@ class HipifyClang(CMakePackage):
"6.3.3",
"master",
]:
depends_on(f"llvm-amdgpu@{ver}", when=f"@{ver}")
requires(f"%llvm-amdgpu@{ver}", when=f"@{ver}")
for ver in [
"5.5.0",

View File

@ -64,6 +64,7 @@ class HsaRocrDev(CMakePackage):
depends_on("numactl")
depends_on("pkgconfig")
depends_on("libdrm", when="@6.3:")
requires("%[virtuals=c,cxx] llvm-amdgpu")
for ver in [
"5.3.0",
@ -112,9 +113,7 @@ class HsaRocrDev(CMakePackage):
"6.3.3",
"master",
]:
depends_on(f"llvm-amdgpu@{ver}", when=f"@{ver}")
# allow standalone rocm-device-libs (useful for aomp)
depends_on(f"rocm-device-libs@{ver}", when=f"@{ver} ^llvm-amdgpu ~rocm-device-libs")
requires(f"%llvm-amdgpu@{ver}", when=f"@{ver}")
for ver in [
"5.5.0",

View File

@ -23,6 +23,7 @@ class LlvmAmdgpu(CMakePackage, LlvmDetection, CompilerPackage):
"c": "rocmcc/amdclang",
"cxx": "rocmcc/amdclang++",
"fortran": "rocmcc/amdflang",
"hip-lang": "rocmcc/amdclang++",
}
stdcxx_libs = ("-lstdc++",)
@ -59,6 +60,7 @@ class LlvmAmdgpu(CMakePackage, LlvmDetection, CompilerPackage):
version("5.3.0", sha256="4e3fcddb5b8ea8dcaa4417e0e31a9c2bbdc9e7d4ac3401635a636df32905c93e")
provides("c", "cxx")
provides("hip-lang")
provides("fortran")
variant(
@ -372,3 +374,20 @@ def _cxx_path(self):
def _fortran_path(self):
return os.path.join(self.spec.prefix.bin, "amdflang")
@classmethod
def runtime_constraints(cls, *, spec, pkg):
"""Callback function to inject runtime-related rules into the solver.
Rule-injection is obtained through method calls of the ``pkg`` argument.
Args:
spec: spec that will inject runtime dependencies
pkg: object used to forward information to the solver
"""
pkg("*").depends_on(
"hip +rocm",
when="%[virtuals=hip-lang] llvm-amdgpu",
type="link",
description="If any package uses %llvm-amdgpu for hip-lang, it depends on hip",
)