Add support for clang with OpenMP and other minor changes to oneapi build system (#42717)

* Add support for clang in oneapi packages with OpenMP

* Add fallback search for libomp in OneApi package with OpenMP threading

* Add requires for the compiler when using threads=openmp in intel-oneapi-mkl

* Cosmetic changes to messages in oneapi.py

* Update error message in oneapi.py

Co-authored-by: Robert Cohn <rscohn2@gmail.com>

* Update another error message in oneapi.py

Co-authored-by: Robert Cohn <rscohn2@gmail.com>

* Inline helper error function in oneapi.py

* Update one more error message in oneapi.py

* Wrap long line in oneapi.py

---------

Co-authored-by: Robert Cohn <rscohn2@gmail.com>
This commit is contained in:
Mikael Simberg 2024-02-16 17:39:31 +01:00 committed by GitHub
parent 5c3df6e8ca
commit c56cf8c0d2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 28 additions and 10 deletions

View File

@ -22,13 +22,6 @@
from .generic import Package from .generic import Package
def raise_lib_error(*args):
"""Bails out with an error message. Shows args after the first as one per
line, tab-indented, useful for long paths to line up and stand out.
"""
raise InstallError("\n\t".join(str(i) for i in args))
class IntelOneApiPackage(Package): class IntelOneApiPackage(Package):
"""Base class for Intel oneAPI packages.""" """Base class for Intel oneAPI packages."""
@ -206,20 +199,35 @@ def openmp_libs(self):
libname = "libiomp5" libname = "libiomp5"
elif self.spec.satisfies("%gcc"): elif self.spec.satisfies("%gcc"):
libname = "libgomp" libname = "libgomp"
elif self.spec.satisfies("%clang"):
libname = "libomp"
else: else:
raise_lib_error("MKL OMP requires one of %gcc, %oneapi,or %intel") raise InstallError(
"OneAPI package with OpenMP threading requires one of %clang, %gcc, %oneapi, "
"or %intel"
)
# query the compiler for the library path # query the compiler for the library path
with self.compiler.compiler_environment(): with self.compiler.compiler_environment():
omp_lib_path = Executable(self.compiler.cc)( omp_lib_path = Executable(self.compiler.cc)(
"--print-file-name", f"{libname}.{dso_suffix}", output=str "--print-file-name", f"{libname}.{dso_suffix}", output=str
).strip() ).strip()
# Newer versions of clang do not give the full path to libomp. If that's
# the case, look in a path relative to the compiler where libomp is
# typically found. If it's not found there, error out.
if not os.path.exists(omp_lib_path) and self.spec.satisfies("%clang"):
compiler_root = os.path.dirname(os.path.dirname(os.path.realpath(self.compiler.cc)))
omp_lib_path_compiler = os.path.join(compiler_root, "lib", f"{libname}.{dso_suffix}")
if os.path.exists(omp_lib_path_compiler):
omp_lib_path = omp_lib_path_compiler
# if the compiler cannot find the file, it returns the input path # if the compiler cannot find the file, it returns the input path
if not os.path.exists(omp_lib_path): if not os.path.exists(omp_lib_path):
raise_lib_error(f"Cannot locate OpenMP library: {omp_lib_path}") raise InstallError(f"OneAPI package cannot locate OpenMP library: {omp_lib_path}")
omp_libs = LibraryList(omp_lib_path) omp_libs = LibraryList(omp_lib_path)
tty.info(f"mkl requires openmp library: {omp_libs}") tty.info(f"OneAPI package requires OpenMP library: {omp_libs}")
return omp_libs return omp_libs
# find_headers uses heuristics to determine the include directory # find_headers uses heuristics to determine the include directory

View File

@ -125,6 +125,16 @@ class IntelOneapiMkl(IntelOneApiLibraryPackage):
multi=False, multi=False,
) )
requires(
"%clang",
"%gcc",
"%intel",
"%oneapi",
policy="one_of",
when="threads=openmp",
msg="MKL with OpenMP threading requires GCC, clang, or Intel compilers",
)
depends_on("tbb") depends_on("tbb")
# cluster libraries need mpi # cluster libraries need mpi
depends_on("mpi", when="+cluster") depends_on("mpi", when="+cluster")