diff --git a/lib/spack/external/__init__.py b/lib/spack/external/__init__.py index 2d96eb3c96..26ac1f63d0 100644 --- a/lib/spack/external/__init__.py +++ b/lib/spack/external/__init__.py @@ -18,7 +18,7 @@ * Homepage: https://pypi.python.org/pypi/archspec * Usage: Labeling, comparison and detection of microarchitectures -* Version: 0.2.3 (commit 7b8fe60b69e2861e7dac104bc1c183decfcd3daf) +* Version: 0.2.4 (commit 48b92512b9ce203ded0ebd1ac41b42593e931f7c) astunparse ---------------- diff --git a/lib/spack/external/archspec/__init__.py b/lib/spack/external/archspec/__init__.py index 7568bbd0e9..2930ad719e 100644 --- a/lib/spack/external/archspec/__init__.py +++ b/lib/spack/external/archspec/__init__.py @@ -1,3 +1,3 @@ """Init file to avoid namespace packages""" -__version__ = "0.2.3" +__version__ = "0.2.4" diff --git a/lib/spack/external/archspec/cpu/__init__.py b/lib/spack/external/archspec/cpu/__init__.py index 5fa60d2874..6fbb43b785 100644 --- a/lib/spack/external/archspec/cpu/__init__.py +++ b/lib/spack/external/archspec/cpu/__init__.py @@ -5,9 +5,10 @@ """The "cpu" package permits to query and compare different CPU microarchitectures. """ -from .detect import host +from .detect import brand_string, host from .microarchitecture import ( TARGETS, + InvalidCompilerVersion, Microarchitecture, UnsupportedMicroarchitecture, generic_microarchitecture, @@ -15,10 +16,12 @@ ) __all__ = [ + "brand_string", + "host", + "TARGETS", + "InvalidCompilerVersion", "Microarchitecture", "UnsupportedMicroarchitecture", - "TARGETS", "generic_microarchitecture", - "host", "version_components", ] diff --git a/lib/spack/external/archspec/cpu/detect.py b/lib/spack/external/archspec/cpu/detect.py index 179b7a947b..d99295d907 100644 --- a/lib/spack/external/archspec/cpu/detect.py +++ b/lib/spack/external/archspec/cpu/detect.py @@ -155,6 +155,31 @@ def _is_bit_set(self, register: int, bit: int) -> bool: mask = 1 << bit return register & mask > 0 + def brand_string(self) -> Optional[str]: + """Returns the brand string, if available.""" + if self.highest_extension_support < 0x80000004: + return None + + r1 = self.cpuid.registers_for(eax=0x80000002, ecx=0) + r2 = self.cpuid.registers_for(eax=0x80000003, ecx=0) + r3 = self.cpuid.registers_for(eax=0x80000004, ecx=0) + result = struct.pack( + "IIIIIIIIIIII", + r1.eax, + r1.ebx, + r1.ecx, + r1.edx, + r2.eax, + r2.ebx, + r2.ecx, + r2.edx, + r3.eax, + r3.ebx, + r3.ecx, + r3.edx, + ).decode("utf-8") + return result.strip("\x00") + @detection(operating_system="Windows") def cpuid_info(): @@ -174,8 +199,8 @@ def _check_output(args, env): WINDOWS_MAPPING = { - "AMD64": "x86_64", - "ARM64": "aarch64", + "AMD64": X86_64, + "ARM64": AARCH64, } @@ -409,3 +434,16 @@ def compatibility_check_for_riscv64(info, target): return (target == arch_root or arch_root in target.ancestors) and ( target.name == info.name or target.vendor == "generic" ) + + +def brand_string() -> Optional[str]: + """Returns the brand string of the host, if detected, or None.""" + if platform.system() == "Darwin": + return _check_output( + ["sysctl", "-n", "machdep.cpu.brand_string"], env=_ensure_bin_usrbin_in_path() + ).strip() + + if host().family == X86_64: + return CpuidInfoCollector().brand_string() + + return None diff --git a/lib/spack/external/archspec/cpu/microarchitecture.py b/lib/spack/external/archspec/cpu/microarchitecture.py index a6526aa926..7a251b905e 100644 --- a/lib/spack/external/archspec/cpu/microarchitecture.py +++ b/lib/spack/external/archspec/cpu/microarchitecture.py @@ -208,6 +208,8 @@ def optimization_flags(self, compiler, version): """Returns a string containing the optimization flags that needs to be used to produce code optimized for this micro-architecture. + The version is expected to be a string of dot separated digits. + If there is no information on the compiler passed as argument the function returns an empty string. If it is known that the compiler version we want to use does not support this architecture the function @@ -216,6 +218,11 @@ def optimization_flags(self, compiler, version): Args: compiler (str): name of the compiler to be used version (str): version of the compiler to be used + + Raises: + UnsupportedMicroarchitecture: if the requested compiler does not support + this micro-architecture. + ValueError: if the version doesn't match the expected format """ # If we don't have information on compiler at all return an empty string if compiler not in self.family.compilers: @@ -232,6 +239,14 @@ def optimization_flags(self, compiler, version): msg = msg.format(compiler, best_target, best_target.family) raise UnsupportedMicroarchitecture(msg) + # Check that the version matches the expected format + if not re.match(r"^(?:\d+\.)*\d+$", version): + msg = ( + "invalid format for the compiler version argument. " + "Only dot separated digits are allowed." + ) + raise InvalidCompilerVersion(msg) + # If we have information on this compiler we need to check the # version being used compiler_info = self.compilers[compiler] @@ -292,7 +307,7 @@ def generic_microarchitecture(name): Args: name (str): name of the micro-architecture """ - return Microarchitecture(name, parents=[], vendor="generic", features=[], compilers={}) + return Microarchitecture(name, parents=[], vendor="generic", features=set(), compilers={}) def version_components(version): @@ -367,7 +382,15 @@ def fill_target_from_dict(name, data, targets): TARGETS = LazyDictionary(_known_microarchitectures) -class UnsupportedMicroarchitecture(ValueError): +class ArchspecError(Exception): + """Base class for errors within archspec""" + + +class UnsupportedMicroarchitecture(ArchspecError, ValueError): """Raised if a compiler version does not support optimization for a given micro-architecture. """ + + +class InvalidCompilerVersion(ArchspecError, ValueError): + """Raised when an invalid format is used for compiler versions in archspec.""" diff --git a/lib/spack/external/archspec/json/cpu/microarchitectures.json b/lib/spack/external/archspec/json/cpu/microarchitectures.json index 1e77caba4a..1e8a8caa35 100644 --- a/lib/spack/external/archspec/json/cpu/microarchitectures.json +++ b/lib/spack/external/archspec/json/cpu/microarchitectures.json @@ -2937,8 +2937,6 @@ "ilrcpc", "flagm", "ssbs", - "paca", - "pacg", "dcpodp", "svei8mm", "svebf16", @@ -3066,8 +3064,6 @@ "flagm", "ssbs", "sb", - "paca", - "pacg", "dcpodp", "sve2", "sveaes", @@ -3081,8 +3077,7 @@ "svebf16", "i8mm", "bf16", - "dgh", - "bti" + "dgh" ], "compilers" : { "gcc": [ diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py index 362efc289a..e3dd3ca6df 100644 --- a/lib/spack/spack/solver/asp.py +++ b/lib/spack/spack/solver/asp.py @@ -2072,7 +2072,7 @@ def _supported_targets(self, compiler_name, compiler_version, targets): try: with warnings.catch_warnings(): warnings.simplefilter("ignore") - target.optimization_flags(compiler_name, compiler_version) + target.optimization_flags(compiler_name, str(compiler_version)) supported.append(target) except archspec.cpu.UnsupportedMicroarchitecture: continue diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py index cc4bec8e3c..009d9b6a36 100644 --- a/lib/spack/spack/test/concretize.py +++ b/lib/spack/spack/test/concretize.py @@ -1244,10 +1244,11 @@ def test_variant_not_default(self): @pytest.mark.regression("20055") @pytest.mark.only_clingo("Use case not supported by the original concretizer") - def test_custom_compiler_version(self, mutable_config, compiler_factory): + def test_custom_compiler_version(self, mutable_config, compiler_factory, monkeypatch): mutable_config.set( "compilers", [compiler_factory(spec="gcc@10foo", operating_system="redhat6")] ) + monkeypatch.setattr(spack.compiler.Compiler, "real_version", "10.2.1") s = Spec("a %gcc@10foo os=redhat6").concretized() assert "%gcc@10foo" in s