summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGreg Becker <becker33@llnl.gov>2022-11-07 21:50:16 -0800
committerGitHub <noreply@github.com>2022-11-07 21:50:16 -0800
commitc9561c5a0e962a7c17eb961d21bfd4f7728e656b (patch)
treecb58d0eb0c5430e8f7db88f07cd0e5ac4cabe156 /lib
parentf099a68e65f3db5f33cb73b9ab9b798b37f4e4cf (diff)
downloadspack-c9561c5a0e962a7c17eb961d21bfd4f7728e656b.tar.gz
spack-c9561c5a0e962a7c17eb961d21bfd4f7728e656b.tar.bz2
spack-c9561c5a0e962a7c17eb961d21bfd4f7728e656b.tar.xz
spack-c9561c5a0e962a7c17eb961d21bfd4f7728e656b.zip
intel oneapi classic bootstrapping (#31285)
The `intel` compiler at versions > 20 is provided by the `intel-oneapi-compilers-classic` package (a thin wrapper around the `intel-oneapi-compilers` package), and the `oneapi` compiler is provided by the `intel-oneapi-compilers` package. Prior to this work, neither of these compilers could be bootstrapped by Spack as part of an install with `install_missing_compilers: True`. Changes made to make these two packages bootstrappable: 1. The `intel-oneapi-compilers-classic` package includes a bin directory and symlinks to the compiler executables, not just logical pointers in Spack. 2. Spack can look for bootstrapped compilers in directories other than `$prefix/bin`, defined on a per-package basis 3. `intel-oneapi-compilers` specifies a non-default search directory for the compiler executables. 4. The `spack.compilers` module now can make more advanced associations between packages and compilers, not just simple name translations 5. Spack support for lmod hierarchies accounts for differences between package names and the associated compiler names for `intel-oneapi-compilers/oneapi`, `intel-oneapi-compilers-classic/intel@20:`, `llvm+clang/clang`, and `llvm-amdgpu/rocmcc`. - [x] full end-to-end testing - [x] add unit tests
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/compilers/__init__.py16
-rw-r--r--lib/spack/spack/installer.py18
-rw-r--r--lib/spack/spack/modules/lmod.py20
-rw-r--r--lib/spack/spack/test/installer.py11
-rw-r--r--lib/spack/spack/test/modules/lmod.py9
5 files changed, 48 insertions, 26 deletions
diff --git a/lib/spack/spack/compilers/__init__.py b/lib/spack/spack/compilers/__init__.py
index 05ffaf9f6c..e54f8dc96c 100644
--- a/lib/spack/spack/compilers/__init__.py
+++ b/lib/spack/spack/compilers/__init__.py
@@ -49,12 +49,26 @@ _compiler_to_pkg = {
"clang": "llvm+clang",
"oneapi": "intel-oneapi-compilers",
"rocmcc": "llvm-amdgpu",
+ "intel@2020:": "intel-oneapi-compilers-classic",
+}
+
+# TODO: generating this from the previous dict causes docs errors
+package_name_to_compiler_name = {
+ "llvm": "clang",
+ "intel-oneapi-compilers": "oneapi",
+ "llvm-amdgpu": "rocmcc",
+ "intel-oneapi-compilers-classic": "intel",
}
def pkg_spec_for_compiler(cspec):
"""Return the spec of the package that provides the compiler."""
- spec_str = "%s@%s" % (_compiler_to_pkg.get(cspec.name, cspec.name), cspec.versions)
+ for spec, package in _compiler_to_pkg.items():
+ if cspec.satisfies(spec):
+ spec_str = "%s@%s" % (package, cspec.versions)
+ break
+ else:
+ spec_str = str(cspec)
return spack.spec.Spec(spec_str)
diff --git a/lib/spack/spack/installer.py b/lib/spack/spack/installer.py
index 62770d0349..a0f505a922 100644
--- a/lib/spack/spack/installer.py
+++ b/lib/spack/spack/installer.py
@@ -1241,6 +1241,12 @@ class PackageInstaller(object):
fail_fast = request.install_args.get("fail_fast")
self.fail_fast = self.fail_fast or fail_fast
+ def _add_compiler_package_to_config(self, pkg):
+ compiler_search_prefix = getattr(pkg, "compiler_search_prefix", pkg.spec.prefix)
+ spack.compilers.add_compilers_to_config(
+ spack.compilers.find_compilers([compiler_search_prefix])
+ )
+
def _install_task(self, task):
"""
Perform the installation of the requested spec and/or dependency
@@ -1266,9 +1272,7 @@ class PackageInstaller(object):
if use_cache and _install_from_cache(pkg, cache_only, explicit, unsigned):
self._update_installed(task)
if task.compiler:
- spack.compilers.add_compilers_to_config(
- spack.compilers.find_compilers([pkg.spec.prefix])
- )
+ self._add_compiler_package_to_config(pkg)
return
pkg.run_tests = tests is True or tests and pkg.name in tests
@@ -1296,9 +1300,7 @@ class PackageInstaller(object):
# If a compiler, ensure it is added to the configuration
if task.compiler:
- spack.compilers.add_compilers_to_config(
- spack.compilers.find_compilers([pkg.spec.prefix])
- )
+ self._add_compiler_package_to_config(pkg)
except spack.build_environment.StopPhase as e:
# A StopPhase exception means that do_install was asked to
# stop early from clients, and is not an error at this point
@@ -1717,9 +1719,7 @@ class PackageInstaller(object):
# It's an already installed compiler, add it to the config
if task.compiler:
- spack.compilers.add_compilers_to_config(
- spack.compilers.find_compilers([pkg.spec.prefix])
- )
+ self._add_compiler_package_to_config(pkg)
else:
# At this point we've failed to get a write or a read
diff --git a/lib/spack/spack/modules/lmod.py b/lib/spack/spack/modules/lmod.py
index bb288336ea..3378e53354 100644
--- a/lib/spack/spack/modules/lmod.py
+++ b/lib/spack/spack/modules/lmod.py
@@ -184,22 +184,10 @@ class LmodConfiguration(BaseConfiguration):
# If it is in the list of supported compilers family -> compiler
if self.spec.name in spack.compilers.supported_compilers():
provides["compiler"] = spack.spec.CompilerSpec(str(self.spec))
- # Special case for llvm
- if self.spec.name == "llvm":
- provides["compiler"] = spack.spec.CompilerSpec(str(self.spec))
- provides["compiler"].name = "clang"
- # Special case for llvm-amdgpu
- if self.spec.name == "llvm-amdgpu":
- provides["compiler"] = spack.spec.CompilerSpec(str(self.spec))
- provides["compiler"].name = "rocmcc"
- # Special case for oneapi
- if self.spec.name == "intel-oneapi-compilers":
- provides["compiler"] = spack.spec.CompilerSpec(str(self.spec))
- provides["compiler"].name = "oneapi"
- # Special case for oneapi classic
- if self.spec.name == "intel-oneapi-compilers-classic":
- provides["compiler"] = spack.spec.CompilerSpec(str(self.spec))
- provides["compiler"].name = "intel"
+ elif self.spec.name in spack.compilers.package_name_to_compiler_name:
+ # If it is the package for a supported compiler, but of a different name
+ cname = spack.compilers.package_name_to_compiler_name[self.spec.name]
+ provides["compiler"] = spack.spec.CompilerSpec("%s@%s" % (cname, self.spec.version))
# All the other tokens in the hierarchy must be virtual dependencies
for x in self.hierarchy_tokens:
diff --git a/lib/spack/spack/test/installer.py b/lib/spack/spack/test/installer.py
index 8a713ca704..4c85f4ba26 100644
--- a/lib/spack/spack/test/installer.py
+++ b/lib/spack/spack/test/installer.py
@@ -487,6 +487,17 @@ def test_update_tasks_for_compiler_packages_as_compiler(mock_packages, config, m
assert installer.build_pq[0][1].compiler
+def test_bootstrapping_compilers_with_different_names_from_spec(
+ install_mockery, mutable_config, mock_fetch
+):
+ with spack.config.override("config:install_missing_compilers", True):
+ with spack.concretize.disable_compiler_existence_check():
+ spec = spack.spec.Spec("trivial-install-test-package%oneapi@22.2.0").concretized()
+ spec.package.do_install()
+
+ assert spack.spec.CompilerSpec("oneapi@22.2.0") in spack.compilers.all_compiler_specs()
+
+
def test_dump_packages_deps_ok(install_mockery, tmpdir, mock_packages):
"""Test happy path for dump_packages with dependencies."""
diff --git a/lib/spack/spack/test/modules/lmod.py b/lib/spack/spack/test/modules/lmod.py
index 5d0d04032e..c0d228c2fe 100644
--- a/lib/spack/spack/test/modules/lmod.py
+++ b/lib/spack/spack/test/modules/lmod.py
@@ -81,6 +81,15 @@ class TestLmod(object):
else:
assert repetitions == 1
+ def test_compilers_provided_different_name(self, factory, module_configuration):
+ module_configuration("complex_hierarchy")
+ module, spec = factory("intel-oneapi-compilers%clang@3.3")
+
+ provides = module.conf.provides
+
+ assert "compiler" in provides
+ assert provides["compiler"] == spack.spec.CompilerSpec("oneapi@3.0")
+
def test_simple_case(self, modulefile_content, module_configuration):
"""Tests the generation of a simple TCL module file."""