diff --git a/eessi_software_subdir.py b/eessi_software_subdir.py index 93e0af1ab3..af9df722d9 100755 --- a/eessi_software_subdir.py +++ b/eessi_software_subdir.py @@ -4,7 +4,7 @@ # import os import argparse -import archspec.cpu +from archspec.cpu.detect import compatible_microarchitectures, raw_info_dictionary software_subdir = os.getenv('EESSI_SOFTWARE_SUBDIR_OVERRIDE') if software_subdir is None: @@ -14,7 +14,26 @@ default=False, help='Use generic for CPU name.') args = parser.parse_args() - host_cpu = archspec.cpu.host() + # we can't directly use archspec.cpu.host(), because we may get back a virtual microarchitecture like x86_64_v3... + def sorting_fn(item): + """Helper function to sort compatible microarchitectures.""" + return len(item.ancestors), len(item.features) + + raw_cpu_info = raw_info_dictionary() + compat_targets = compatible_microarchitectures(raw_cpu_info) + + # filter out generic targets + non_generic_compat_targets = [t for t in compat_targets if t.vendor != "generic"] + + # Filter the candidates to be descendant of the best generic candidate + best_generic = max([t for t in compat_targets if t.vendor == "generic"], key=sorting_fn) + best_compat_targets = [t for t in non_generic_compat_targets if t > best_generic] + + if best_compat_targets: + host_cpu = max(best_compat_targets, key=sorting_fn) + else: + host_cpu = max(non_generic_compat_targets, key=sorting_fn) + vendors = { 'GenuineIntel': 'intel', 'AuthenticAMD': 'amd', diff --git a/init/eessi_software_subdir_for_host.py b/init/eessi_software_subdir_for_host.py index 83bddf61eb..b09b4711e4 100755 --- a/init/eessi_software_subdir_for_host.py +++ b/init/eessi_software_subdir_for_host.py @@ -7,6 +7,7 @@ import platform import sys import archspec.cpu +from archspec.cpu.detect import compatible_microarchitectures, raw_info_dictionary VENDOR_MAP = { 'GenuineIntel': 'intel', @@ -33,7 +34,26 @@ def det_host_triple(): Determine host triple: (, , ). may be None if there's no match in VENDOR_MAP. """ - host_cpu = archspec.cpu.host() + # we can't directly use archspec.cpu.host(), because we may get back a virtual microarchitecture like x86_64_v3... + def sorting_fn(item): + """Helper function to sort compatible microarchitectures.""" + return len(item.ancestors), len(item.features) + + raw_cpu_info = raw_info_dictionary() + compat_targets = compatible_microarchitectures(raw_cpu_info) + + # filter out generic targets + non_generic_compat_targets = [t for t in compat_targets if t.vendor != "generic"] + + # Filter the candidates to be descendant of the best generic candidate + best_generic = max([t for t in compat_targets if t.vendor == "generic"], key=sorting_fn) + best_compat_targets = [t for t in non_generic_compat_targets if t > best_generic] + + if best_compat_targets: + host_cpu = max(best_compat_targets, key=sorting_fn) + else: + host_cpu = max(non_generic_compat_targets, key=sorting_fn) + host_vendor = VENDOR_MAP.get(host_cpu.vendor) host_cpu_family = host_cpu.family.name host_cpu_name = host_cpu.name