Skip to content
Merged
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
dbe9e70
LLVM: Fix failure for multiple offload targets
Thyre Mar 23, 2025
4a4fc7b
LLVM: Fix sanity check typo for AMDGPU
Thyre Mar 30, 2025
9ccfe55
LLVM: Pass device architectures as CMake runtime arg
Thyre Mar 31, 2025
e28bec1
LLVM: Add new AMGGPU targets
Thyre Mar 31, 2025
62a6d76
LLVM: Escape device architecture quotation
Thyre Mar 31, 2025
084aec6
LLVM: Escape arch-string once again
Thyre Mar 31, 2025
7ed6c5f
LLVM: Move LIBOMPTARGET_PLUGINS_TO_BUILD to runtime CMake arguments
Thyre Mar 31, 2025
70f9e81
LLVM: Escape LIBOMPTARGET_PLUGINS_TO_BUILD
Thyre Mar 31, 2025
9308202
LLVM: Restrict LIBOMPTARGET_DEVICE_ARCHITECTURES to LLVM 19-20
Thyre Mar 31, 2025
f1ef40d
LLVM: Handle switch to generic .bc files in sanity check
Thyre Mar 31, 2025
ed4a465
LLVM: Drop AMDGPU_GFX_SUPPORT
Thyre Mar 31, 2025
30880dd
LLVM: Fixup adding LIBOMPTARGET_DEVICE_ARCHITECTURES
Thyre Mar 31, 2025
bc51796
LLVM: Also check NVPTX and AMDGPU for all targets
Thyre Mar 31, 2025
526176d
LLVM: Fix sanity_check for renamed llvm-offload-device-info
Thyre Mar 31, 2025
2c2482b
LLVM: Improve all check for build_targets in sanity_check
Thyre Mar 31, 2025
4e8574a
LLVM: Revert escaped quotations
Thyre Mar 31, 2025
120005e
LLVM: Ignore failing nvptx64 tests without ptxas in PATH
Thyre Apr 1, 2025
404b4fd
LLVM: Switch to internal which
Thyre Apr 1, 2025
1aa1e05
LLVM: Make sure test_suite_ignore_patterns is a list before appending
Thyre Apr 2, 2025
64f8dc3
LLVM: Ignore failed AMDGPU tests
Thyre Apr 2, 2025
f685d67
LLVM: Ignore AMDGPU tests without ROCr-Runtime dependency
Thyre Apr 7, 2025
c157dd8
LLVM: Clarify ROCR-Runtime check
Thyre Apr 9, 2025
98ff120
LLVM: Use pipe to split runtime arguments
Thyre Apr 23, 2025
a173a53
LLVM: Write CMake arguments after updating runtime args in multi-step…
Thyre Apr 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 53 additions & 23 deletions easybuild/easyblocks/l/llvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
from easybuild.toolchains.compiler.clang import Clang
from easybuild.tools import LooseVersion
from easybuild.tools.build_log import EasyBuildError, print_msg, print_warning
from easybuild.tools.config import ERROR, SEARCH_PATH_LIB_DIRS, build_option
from easybuild.tools.config import ERROR, IGNORE, SEARCH_PATH_LIB_DIRS, build_option
from easybuild.tools.environment import setvar
from easybuild.tools.filetools import apply_regex_substitutions, change_dir, copy_dir, copy_file
from easybuild.tools.filetools import mkdir, remove_file, symlink, which, write_file
Expand Down Expand Up @@ -74,12 +74,6 @@
X86_64: ['X86'],
}

AMDGPU_GFX_SUPPORT = [
'gfx700', 'gfx701', 'gfx801', 'gfx803', 'gfx900', 'gfx902', 'gfx906', 'gfx908', 'gfx90a', 'gfx90c',
'gfx940', 'gfx941', 'gfx942', 'gfx1010', 'gfx1030', 'gfx1031', 'gfx1032', 'gfx1033', 'gfx1034',
'gfx1035', 'gfx1036', 'gfx1100', 'gfx1101', 'gfx1102', 'gfx1103', 'gfx1150', 'gfx1151'
]

remove_gcc_dependency_opts = {
'CLANG_DEFAULT_CXX_STDLIB': 'libc++',
'CLANG_DEFAULT_RTLIB': 'compiler-rt',
Expand Down Expand Up @@ -203,8 +197,7 @@ class EB_LLVM(CMakeMake):
def extra_options():
extra_vars = CMakeMake.extra_options()
extra_vars.update({
'amd_gfx_list': [None, "List of AMDGPU targets to build for. Possible values: " +
', '.join(AMDGPU_GFX_SUPPORT), CUSTOM],
'amd_gfx_list': [None, "List of AMDGPU targets to build for.", CUSTOM],
'assertions': [False, "Enable assertions. Helps to catch bugs in Clang.", CUSTOM],
'bootstrap': [True, "Build LLVM-Clang using itself", CUSTOM],
'build_bolt': [False, "Build the LLVM bolt binary optimizer", CUSTOM],
Expand Down Expand Up @@ -365,11 +358,13 @@ def __init__(self, *args, **kwargs):
cuda_cc_list = build_option('cuda_compute_capabilities') or self.cfg['cuda_compute_capabilities'] or []
amd_gfx_list = self.cfg['amd_gfx_list'] or []

# List of (lower-case) dependencies
self.deps = [dep['name'].lower() for dep in self.cfg.dependencies()]

# Build targets
build_targets = self.cfg['build_targets'] or []
if not build_targets:
self.log.debug("No build targets specified, using default detection")
deps = [dep['name'].lower() for dep in self.cfg.dependencies()]
arch = get_cpu_architecture()
if arch not in DEFAULT_TARGETS_MAP:
raise EasyBuildError("No default build targets defined for CPU architecture %s.", arch)
Expand All @@ -378,19 +373,22 @@ def __init__(self, *args, **kwargs):
# If CUDA is included as a dep, add NVPTX as a target
# There are (old) toolchains with CUDA as part of the toolchain
cuda_toolchain = hasattr(self.toolchain, 'COMPILER_CUDA_FAMILY')
if 'cuda' in deps or cuda_toolchain or cuda_cc_list:
if 'cuda' in self.deps or cuda_toolchain or cuda_cc_list:
if LooseVersion(self.version) < LooseVersion('18'):
self.log.info(f"Not auto-enabling {BUILD_TARGET_NVPTX} offload target, only done for LLVM >= 18")
else:
build_targets.append(BUILD_TARGET_NVPTX)
self.offload_targets += ['cuda'] # Used for LLVM >= 19
self.log.debug(f"{BUILD_TARGET_NVPTX} enabled by CUDA dependency/cuda_compute_capabilities")

# For AMDGPU support we need ROCR-Runtime and
# ROCT-Thunk-Interface, however, since ROCT is a dependency of
# ROCR we only check for the ROCR-Runtime here
# For AMDGPU support during runtime we need ROCR-Runtime and ROCT-Thunk-Interface. While split into
# separate packages pre ROCm 6.2, it is now combined into ROCR-Runtime. As ROCR-Thunk-Interface was a
# dependency for ROCR-Runtime before, checking for ROCR-Runtime as a dependency is sufficient.
# Generally, ROCR-Runtime is not a hard dependency for LLVM. If not found, LLVM can still build
# an offload-capable compiler runtime, and will try to dlopen the required libraries at runtime.
# Therefore, also allow the build without ROCR-Runtime, with only the desired architecture list being set.
# https://openmp.llvm.org/SupportAndFAQ.html#q-how-to-build-an-openmp-amdgpu-offload-capable-compiler
if 'rocr-runtime' in deps or amd_gfx_list:
if 'rocr-runtime' in self.deps or amd_gfx_list:
if LooseVersion(self.version) < LooseVersion('18'):
self.log.info(f"Not auto-enabling {BUILD_TARGET_AMDGPU} offload target, only done for LLVM >= 18")
else:
Expand Down Expand Up @@ -467,7 +465,7 @@ def _configure_final_build(self):

if 'openmp' in self.final_projects:
if LooseVersion(self.version) >= LooseVersion('19') and self.cfg['build_openmp_offload']:
self._cmakeopts['LIBOMPTARGET_PLUGINS_TO_BUILD'] = ';'.join(self.offload_targets)
self.runtimes_cmake_args['LIBOMPTARGET_PLUGINS_TO_BUILD'] = '%s' % '|'.join(self.offload_targets)
self._cmakeopts['OPENMP_ENABLE_LIBOMPTARGET'] = 'ON'
self._cmakeopts['LIBOMP_INSTALL_ALIASES'] = 'OFF'
if not self.cfg['build_openmp_tools']:
Expand Down Expand Up @@ -635,12 +633,12 @@ def configure_step(self):
if not get_software_root('CUDA'):
setvar('CUDA_NVCC_EXECUTABLE', 'IGNORE')

if 'openmp' in self.final_projects:
if 'openmp' in self.final_projects and LooseVersion('19') <= LooseVersion(self.version) < LooseVersion('20'):
gpu_archs = []
gpu_archs += ['sm_%s' % cc for cc in self.cuda_cc]
gpu_archs += self.amd_gfx
if gpu_archs:
general_opts['LIBOMPTARGET_DEVICE_ARCHITECTURES'] = '"%s"' % ';'.join(gpu_archs)
self.runtimes_cmake_args['LIBOMPTARGET_DEVICE_ARCHITECTURES'] = '%s' % '|'.join(gpu_archs)

self._configure_general_build()
self.add_cmake_opts()
Expand Down Expand Up @@ -674,6 +672,9 @@ def configure_step3(self):
self._cmakeopts = {}
self._configure_general_build()
self._configure_final_build()
# Update runtime CMake arguments, as they might have
# changed when configuring the final build arguments
self._add_cmake_runtime_args()
if self.full_llvm:
self._cmakeopts.update(remove_gcc_dependency_opts)

Expand Down Expand Up @@ -932,6 +933,25 @@ def test_step(self):
if LooseVersion(self.version) >= LooseVersion('19'):
self._set_gcc_prefix()
self._create_compiler_config_file(self.cfg_compilers, self.gcc_prefix, self.final_dir)
# For nvptx64 tests, find out if 'ptxas' exists in $PATH. If not, ignore all nvptx64 test failures
pxtas_path = which('ptxas', on_error=IGNORE)
if not pxtas_path:
self.cfg['test_suite_ignore_patterns'] = \
(self.cfg['test_suite_ignore_patterns'] or []) + \
["nvptx64-nvidia-cuda", "nvptx64-nvidia-cuda-LTO"]
# If the AMDGPU target is built, tests will be run if libhsa-runtime64.so is found.
# However, this can cause issues if the system libraries are used, due to other loaded modules.
# Therefore, ignore failing tests if ROCr-Runtime is not in the dependencies and
# warn about this in the logs.
if ((BUILD_TARGET_AMDGPU in self.cfg['build_targets'] or
'all' in self.cfg['build_targets']) and
'rocr-runtime' not in self.deps):
self.cfg['test_suite_ignore_patterns'] = \
(self.cfg['test_suite_ignore_patterns'] or []) + \
['amdgcn-amd-amdhsa']
self.log.warning("ROCr-Runtime not in dependencies, "
"ignoring failing tests for AMDGPU target.")

max_failed = self.cfg['test_suite_max_failed']
num_failed = self._para_test_step(parallel=1)
if num_failed is None:
Expand Down Expand Up @@ -1174,22 +1194,32 @@ def sanity_check_step(self, custom_paths=None, custom_commands=None, extension=F
omp_lib_files += ['libomptarget.so']
if LooseVersion(self.version) < LooseVersion('19'):
omp_lib_files += ['libomptarget.rtl.%s.so' % arch]
if 'NVPTX' in self.cfg['build_targets']:
if BUILD_TARGET_NVPTX in self.cfg['build_targets'] or 'all' in self.cfg['build_targets']:
if LooseVersion(self.version) < LooseVersion('19'):
omp_lib_files += ['libomptarget.rtl.cuda.so']
omp_lib_files += ['libomptarget-nvptx-sm_%s.bc' % cc for cc in self.cuda_cc]
if 'AMDGPU' in self.cfg['build_targets']:
if LooseVersion(self.version) < LooseVersion('20'):
omp_lib_files += ['libomptarget-nvptx-sm_%s.bc' % cc for cc in self.cuda_cc]
else:
omp_lib_files += ['libomptarget-nvptx.bc']
if BUILD_TARGET_AMDGPU in self.cfg['build_targets'] or 'all' in self.cfg['build_targets']:
if LooseVersion(self.version) < LooseVersion('19'):
omp_lib_files += ['libomptarget.rtl.amdgpu.so']
omp_lib_files += ['llibomptarget-amdgpu-%s.bc' % gfx for gfx in self.amd_gfx]
if LooseVersion(self.version) < LooseVersion('20'):
omp_lib_files += ['libomptarget-amdgpu-%s.bc' % gfx for gfx in self.amd_gfx]
else:
omp_lib_files += ['libomptarget-amdgpu.bc']

if LooseVersion(self.version) < LooseVersion('19'):
# Before LLVM 19, omp related libraries are installed under 'ROOT/lib''
check_lib_files += omp_lib_files
else:
# Starting from LLVM 19, omp related libraries are installed the runtime library directory
check_librt_files += omp_lib_files
check_bin_files += ['llvm-omp-kernel-replay', 'llvm-omp-device-info']
check_bin_files += ['llvm-omp-kernel-replay']
if LooseVersion(self.version) < LooseVersion('20'):
check_bin_files += ['llvm-omp-device-info']
else:
check_bin_files += ['llvm-offload-device-info']

if self.cfg['build_openmp_tools']:
check_files += [os.path.join('lib', 'clang', resdir_version, 'include', 'ompt.h')]
Expand Down