summaryrefslogtreecommitdiff
path: root/lib/spack/spack/build_systems/intel.py
diff options
context:
space:
mode:
authorTodd Gamblin <tgamblin@llnl.gov>2022-07-30 15:19:18 -0700
committerTodd Gamblin <tgamblin@llnl.gov>2022-07-31 13:29:20 -0700
commitf52f6e99dbf1131886a80112b8c79dfc414afb7c (patch)
tree05cb7d64b2395922f2f24683da49f472075be12c /lib/spack/spack/build_systems/intel.py
parent549ba1ed32372c67fc57271cde3797d58b7dec6e (diff)
downloadspack-f52f6e99dbf1131886a80112b8c79dfc414afb7c.tar.gz
spack-f52f6e99dbf1131886a80112b8c79dfc414afb7c.tar.bz2
spack-f52f6e99dbf1131886a80112b8c79dfc414afb7c.tar.xz
spack-f52f6e99dbf1131886a80112b8c79dfc414afb7c.zip
black: reformat entire repository with black
Diffstat (limited to 'lib/spack/spack/build_systems/intel.py')
-rw-r--r--lib/spack/spack/build_systems/intel.py837
1 files changed, 424 insertions, 413 deletions
diff --git a/lib/spack/spack/build_systems/intel.py b/lib/spack/spack/build_systems/intel.py
index a249afff90..133b5030de 100644
--- a/lib/spack/spack/build_systems/intel.py
+++ b/lib/spack/spack/build_systems/intel.py
@@ -38,25 +38,24 @@ from spack.version import Version, ver
def debug_print(msg, *args):
- '''Prints a message (usu. a variable) and the callers' names for a couple
+ """Prints a message (usu. a variable) and the callers' names for a couple
of stack frames.
- '''
+ """
# https://docs.python.org/2/library/inspect.html#the-interpreter-stack
stack = inspect.stack()
_func_name = 3
- tty.debug("%s.%s:\t%s" % (stack[2][_func_name], stack[1][_func_name], msg),
- *args)
+ tty.debug("%s.%s:\t%s" % (stack[2][_func_name], stack[1][_func_name], msg), *args)
def raise_lib_error(*args):
- '''Bails out with an error message. Shows args after the first as one per
+ """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))
def _expand_fields(s):
- '''[Experimental] Expand arch-related fields in a string, typically a
+ """[Experimental] Expand arch-related fields in a string, typically a
filename.
Supported fields and their typical expansions are::
@@ -66,24 +65,24 @@ def _expand_fields(s):
{libarch} intel64, empty on Mac
{bits} 64
- '''
+ """
# Python-native string formatting requires arg list counts to match the
# replacement field count; optional fields are far easier with regexes.
- _bits = '64'
- _arch = 'intel64' # TBD: ia32
+ _bits = "64"
+ _arch = "intel64" # TBD: ia32
- if 'linux' in sys.platform: # NB: linux2 vs. linux
- s = re.sub('{platform}', 'linux', s)
- s = re.sub('{libarch}', _arch, s)
- elif 'darwin' in sys.platform:
- s = re.sub('{platform}', 'mac', s)
- s = re.sub('{libarch}', '', s) # no arch dirs are used (as of 2018)
+ if "linux" in sys.platform: # NB: linux2 vs. linux
+ s = re.sub("{platform}", "linux", s)
+ s = re.sub("{libarch}", _arch, s)
+ elif "darwin" in sys.platform:
+ s = re.sub("{platform}", "mac", s)
+ s = re.sub("{libarch}", "", s) # no arch dirs are used (as of 2018)
# elif 'win' in sys.platform: # TBD
# s = re.sub('{platform}', 'windows', s)
- s = re.sub('{arch}', _arch, s)
- s = re.sub('{bits}', _bits, s)
+ s = re.sub("{arch}", _arch, s)
+ s = re.sub("{bits}", _bits, s)
return s
@@ -99,12 +98,13 @@ class IntelPackage(PackageBase):
only thing necessary will be to override setup_run_environment
to set the appropriate environment variables.
"""
+
#: Phases of an Intel package
- phases = ['configure', 'install']
+ phases = ["configure", "install"]
#: This attribute is used in UI queries that need to know the build
#: system base class
- build_system_class = 'IntelPackage'
+ build_system_class = "IntelPackage"
#: A dict that maps Spack version specs to release years, needed to infer
#: the installation directory layout for pre-2016 versions in the family of
@@ -117,54 +117,65 @@ class IntelPackage(PackageBase):
# that satisfies self.spec will be used.
version_years = {
# intel-daal is versioned 2016 and later, no divining is needed
- 'intel-ipp@9.0:9': 2016,
- 'intel-mkl@11.3.0:11.3': 2016,
- 'intel-mpi@5.1:5': 2016,
+ "intel-ipp@9.0:9": 2016,
+ "intel-mkl@11.3.0:11.3": 2016,
+ "intel-mpi@5.1:5": 2016,
}
# Below is the list of possible values for setting auto dispatch functions
# for the Intel compilers. Using these allows for the building of fat
# binaries that will detect the CPU SIMD capabilities at run time and
# activate the appropriate extensions.
- auto_dispatch_options = ('COMMON-AVX512', 'MIC-AVX512', 'CORE-AVX512',
- 'CORE-AVX2', 'CORE-AVX-I', 'AVX', 'SSE4.2',
- 'SSE4.1', 'SSSE3', 'SSE3', 'SSE2')
+ auto_dispatch_options = (
+ "COMMON-AVX512",
+ "MIC-AVX512",
+ "CORE-AVX512",
+ "CORE-AVX2",
+ "CORE-AVX-I",
+ "AVX",
+ "SSE4.2",
+ "SSE4.1",
+ "SSSE3",
+ "SSE3",
+ "SSE2",
+ )
@property
def license_required(self):
# The Intel libraries are provided without requiring a license as of
# version 2017.2. Trying to specify one anyway will fail. See:
# https://software.intel.com/en-us/articles/free-ipsxe-tools-and-libraries
- return self._has_compilers or self.version < ver('2017.2')
+ return self._has_compilers or self.version < ver("2017.2")
#: Comment symbol used in the license.lic file
- license_comment = '#'
+ license_comment = "#"
#: Environment variables that Intel searches for a license file
- license_vars = ['INTEL_LICENSE_FILE']
+ license_vars = ["INTEL_LICENSE_FILE"]
#: URL providing information on how to acquire a license key
- license_url = 'https://software.intel.com/en-us/articles/intel-license-manager-faq'
+ license_url = "https://software.intel.com/en-us/articles/intel-license-manager-faq"
#: Location where Intel searches for a license file
@property
def license_files(self):
- dirs = ['Licenses']
+ dirs = ["Licenses"]
if self._has_compilers:
- dirs.append(self.component_bin_dir('compiler'))
+ dirs.append(self.component_bin_dir("compiler"))
for variant, component_suite_dir in {
- '+advisor': 'advisor',
- '+inspector': 'inspector',
- '+itac': 'itac',
- '+vtune': 'vtune_profiler',
+ "+advisor": "advisor",
+ "+inspector": "inspector",
+ "+itac": "itac",
+ "+vtune": "vtune_profiler",
}.items():
if variant in self.spec:
- dirs.append(self.normalize_path(
- 'licenses', component_suite_dir, relative=True))
+ dirs.append(
+ self.normalize_path("licenses", component_suite_dir, relative=True)
+ )
- files = [os.path.join(d, 'license.lic') for d in dirs]
+ files = [os.path.join(d, "license.lic") for d in dirs]
return files
#: Components to install (list of name patterns from pset/mediaconfig.xml)
@@ -173,7 +184,7 @@ class IntelPackage(PackageBase):
def pset_components(self):
# Do not detail single-purpose client packages.
if not self._has_compilers:
- return ['ALL']
+ return ["ALL"]
# tty.warn('DEBUG: installing ALL components')
# return ['ALL']
@@ -183,34 +194,35 @@ class IntelPackage(PackageBase):
# Later releases have overlapping minor parts that differ by "edition".
# NB: The spack package 'intel' is a subset of
# 'intel-parallel-studio@composer' without the lib variants.
- c = ' intel-icc intel-ifort' \
- ' intel-ccomp intel-fcomp intel-comp-' \
- ' intel-compilerproc intel-compilerprof intel-compilerpro-' \
- ' intel-psxe intel-openmp'
+ c = (
+ " intel-icc intel-ifort"
+ " intel-ccomp intel-fcomp intel-comp-"
+ " intel-compilerproc intel-compilerprof intel-compilerpro-"
+ " intel-psxe intel-openmp"
+ )
additions_for = {
- 'cluster': ' intel-icsxe',
- 'professional': ' intel-ips-',
- 'composer': ' intel-compxe',
+ "cluster": " intel-icsxe",
+ "professional": " intel-ips-",
+ "composer": " intel-compxe",
}
if self._edition in additions_for:
c += additions_for[self._edition]
for variant, components_to_add in {
- '+daal': ' intel-daal', # Data Analytics Acceleration Lib
- '+gdb': ' intel-gdb', # Integrated Performance Primitives
- '+ipp': ' intel-ipp intel-crypto-ipp',
- '+mkl': ' intel-mkl', # Math Kernel Library
- '+mpi': ' intel-mpi intel-imb', # MPI runtime, SDK, benchm.
- '+tbb': ' intel-tbb', # Threading Building Blocks
- '+advisor': ' intel-advisor',
- '+clck': ' intel_clck', # Cluster Checker
- '+inspector': ' intel-inspector',
- '+itac': ' intel-itac intel-ta intel-tc'
- ' intel-trace-analyzer intel-trace-collector',
- # Trace Analyzer and Collector
- '+vtune': ' intel-vtune'
- # VTune, ..-profiler since 2020, ..-amplifier before
+ "+daal": " intel-daal", # Data Analytics Acceleration Lib
+ "+gdb": " intel-gdb", # Integrated Performance Primitives
+ "+ipp": " intel-ipp intel-crypto-ipp",
+ "+mkl": " intel-mkl", # Math Kernel Library
+ "+mpi": " intel-mpi intel-imb", # MPI runtime, SDK, benchm.
+ "+tbb": " intel-tbb", # Threading Building Blocks
+ "+advisor": " intel-advisor",
+ "+clck": " intel_clck", # Cluster Checker
+ "+inspector": " intel-inspector",
+ "+itac": " intel-itac intel-ta intel-tc" " intel-trace-analyzer intel-trace-collector",
+ # Trace Analyzer and Collector
+ "+vtune": " intel-vtune"
+ # VTune, ..-profiler since 2020, ..-amplifier before
}.items():
if variant in self.spec:
c += components_to_add
@@ -223,11 +235,11 @@ class IntelPackage(PackageBase):
# ---------------------------------------------------------------------
@property
def _filtered_components(self):
- '''Expands the list of desired component patterns to the exact names
+ """Expands the list of desired component patterns to the exact names
present in the given download.
- '''
+ """
c = self.pset_components
- if 'ALL' in c or 'DEFAULTS' in c: # No filter needed
+ if "ALL" in c or "DEFAULTS" in c: # No filter needed
return c
# mediaconfig.xml is known to contain duplicate components.
@@ -243,8 +255,8 @@ class IntelPackage(PackageBase):
#
# https://software.intel.com/en-us/articles/configuration-file-format
#
- xmltree = ElementTree.parse('pset/mediaconfig.xml')
- for entry in xmltree.getroot().findall('.//Abbr'): # XPath expression
+ xmltree = ElementTree.parse("pset/mediaconfig.xml")
+ for entry in xmltree.getroot().findall(".//Abbr"): # XPath expression
name_present = entry.text
for name_requested in requested:
if name_present.startswith(name_requested):
@@ -254,36 +266,36 @@ class IntelPackage(PackageBase):
@property
def intel64_int_suffix(self):
- '''Provide the suffix for Intel library names to match a client
+ """Provide the suffix for Intel library names to match a client
application's desired int size, conveyed by the active spec variant.
The possible suffixes and their meanings are:
``ilp64`` all of int, long, and pointer are 64 bit,
`` lp64`` only long and pointer are 64 bit; int will be 32bit.
- '''
- if '+ilp64' in self.spec:
- return 'ilp64'
+ """
+ if "+ilp64" in self.spec:
+ return "ilp64"
else:
- return 'lp64'
+ return "lp64"
@property
def _has_compilers(self):
- return self.name in ['intel', 'intel-parallel-studio']
+ return self.name in ["intel", "intel-parallel-studio"]
@property
def _edition(self):
- if self.name == 'intel-parallel-studio':
- return self.version[0] # clearer than .up_to(1), I think.
- elif self.name == 'intel':
- return 'composer'
+ if self.name == "intel-parallel-studio":
+ return self.version[0] # clearer than .up_to(1), I think.
+ elif self.name == "intel":
+ return "composer"
else:
- return ''
+ return ""
@property
def version_yearlike(self):
- '''Return the version in a unified style, suitable for Version class
+ """Return the version in a unified style, suitable for Version class
conditionals.
- '''
+ """
# Input data for this routine: self.version
# Returns: YYYY.Nupdate[.Buildseq]
#
@@ -309,18 +321,18 @@ class IntelPackage(PackageBase):
# (*) YYYY is taken from @property "version_years" (a dict of specs)
#
try:
- if self.name == 'intel':
+ if self.name == "intel":
# Has a "Minor" version element, but it is always set as 0. To
# be useful for comparisons, drop it and get YYYY.Nupdate.
- v_tail = self.version[2:] # coerced just fine via __getitem__
+ v_tail = self.version[2:] # coerced just fine via __getitem__
else:
v_tail = self.version[1:]
except IndexError:
# Hmm - this happens on "spack install intel-mkl@11".
# I thought concretization picks an actual version??
- return self.version # give up
+ return self.version # give up
- if self.name == 'intel-parallel-studio':
+ if self.name == "intel-parallel-studio":
return v_tail
v_year = self.version[0]
@@ -332,7 +344,7 @@ class IntelPackage(PackageBase):
v_year = year
break
- return ver('%s.%s' % (v_year, v_tail))
+ return ver("%s.%s" % (v_year, v_tail))
# ---------------------------------------------------------------------
# Directory handling common to all Intel components
@@ -345,8 +357,8 @@ class IntelPackage(PackageBase):
# Not using class IntelPackage:
# intel-gpu-tools/ intel-mkl-dnn/ intel-tbb/
#
- def normalize_suite_dir(self, suite_dir_name, version_globs=['*.*.*']):
- '''Returns the version-specific and absolute path to the directory of
+ def normalize_suite_dir(self, suite_dir_name, version_globs=["*.*.*"]):
+ """Returns the version-specific and absolute path to the directory of
an Intel product or a suite of product components.
Parameters:
@@ -373,7 +385,7 @@ class IntelPackage(PackageBase):
first) expected to qualify suite_dir_name to its fully
version-specific install directory (as opposed to a
compatibility directory or symlink).
- '''
+ """
# See ./README-intel.rst for background and analysis of dir layouts.
d = self.prefix
@@ -381,7 +393,7 @@ class IntelPackage(PackageBase):
# Distinguish between product installations that were done external to
# Spack (integrated via packages.yaml) and Spack-internal ones. The
# resulting prefixes may differ in directory depth and specificity.
- unversioned_dirname = ''
+ unversioned_dirname = ""
if suite_dir_name and suite_dir_name in d:
# If e.g. MKL was installed outside of Spack, it is likely just one
# product or product component among possibly many other Intel
@@ -391,8 +403,7 @@ class IntelPackage(PackageBase):
# version-specific directory. This is what we want and need, and
# nothing more specific than that, i.e., if needed, convert, e.g.:
# .../compilers_and_libraries*/* -> .../compilers_and_libraries*
- d = re.sub('(%s%s.*?)%s.*' %
- (os.sep, re.escape(suite_dir_name), os.sep), r'\1', d)
+ d = re.sub("(%s%s.*?)%s.*" % (os.sep, re.escape(suite_dir_name), os.sep), r"\1", d)
# The Intel installer scripts try hard to place compatibility links
# named like this in the install dir to convey upgrade benefits to
@@ -448,15 +459,14 @@ class IntelPackage(PackageBase):
if unversioned_dirname:
for g in version_globs:
try_glob = unversioned_dirname + g
- debug_print('trying %s' % try_glob)
+ debug_print("trying %s" % try_glob)
matching_dirs = sorted(glob.glob(try_glob))
# NB: Python glob() returns results in arbitrary order - ugh!
# NB2: sorted() is a shortcut that is NOT number-aware.
if matching_dirs:
- debug_print('found %d:' % len(matching_dirs),
- matching_dirs)
+ debug_print("found %d:" % len(matching_dirs), matching_dirs)
# Take the highest and thus presumably newest match, which
# better be the sole one anyway.
d = matching_dirs[-1]
@@ -469,9 +479,8 @@ class IntelPackage(PackageBase):
debug_print(d)
return Prefix(d)
- def normalize_path(self, component_path, component_suite_dir=None,
- relative=False):
- '''Returns the absolute or relative path to a component or file under a
+ def normalize_path(self, component_path, component_suite_dir=None, relative=False):
+ """Returns the absolute or relative path to a component or file under a
component suite directory.
Intel's product names, scope, and directory layout changed over the
@@ -498,7 +507,7 @@ class IntelPackage(PackageBase):
relative (bool): When True, return path relative to self.prefix,
otherwise, return an absolute path (the default).
- '''
+ """
# Design note: Choosing the default for `component_suite_dir` was a bit
# tricky since there better be a sensible means to specify direct
# parentage under self.prefix (even though you normally shouldn't need
@@ -518,60 +527,59 @@ class IntelPackage(PackageBase):
# are not natively versioned by year.
cs = component_suite_dir
- if cs is None and component_path.startswith('ism'):
- cs = 'parallel_studio_xe'
+ if cs is None and component_path.startswith("ism"):
+ cs = "parallel_studio_xe"
v = self.version_yearlike
# Glob variants to complete component_suite_dir.
# Helper var for older MPI versions - those are reparented, with each
# version in their own version-named dir.
- standalone_glob = '[1-9]*.*.*'
+ standalone_glob = "[1-9]*.*.*"
# Most other components; try most specific glob first.
# flake8 is far too opinionated about lists - ugh.
normalize_kwargs = {
- 'version_globs': [
- '_%s' % self.version,
- '_%s.*' % v.up_to(2), # should be: YYYY.Nupdate
- '_*.*.*', # last resort
+ "version_globs": [
+ "_%s" % self.version,
+ "_%s.*" % v.up_to(2), # should be: YYYY.Nupdate
+ "_*.*.*", # last resort
]
}
for rename_rule in [
# cs given as arg, in years, dir actually used, [version_globs]
- [None, ':2015', 'composer_xe'],
- [None, '2016:', 'compilers_and_libraries'],
- ['advisor', ':2016', 'advisor_xe'],
- ['inspector', ':2016', 'inspector_xe'],
- ['vtune_profiler', ':2017', 'vtune_amplifier_xe'],
- ['vtune', ':2017', 'vtune_amplifier_xe'], # alt.
- ['vtune_profiler', ':2019', 'vtune_amplifier'],
- ['itac', ':', 'itac', [os.sep + standalone_glob]],
+ [None, ":2015", "composer_xe"],
+ [None, "2016:", "compilers_and_libraries"],
+ ["advisor", ":2016", "advisor_xe"],
+ ["inspector", ":2016", "inspector_xe"],
+ ["vtune_profiler", ":2017", "vtune_amplifier_xe"],
+ ["vtune", ":2017", "vtune_amplifier_xe"], # alt.
+ ["vtune_profiler", ":2019", "vtune_amplifier"],
+ ["itac", ":", "itac", [os.sep + standalone_glob]],
]:
if cs == rename_rule[0] and v.satisfies(ver(rename_rule[1])):
cs = rename_rule[2]
if len(rename_rule) > 3:
- normalize_kwargs = {'version_globs': rename_rule[3]}
+ normalize_kwargs = {"version_globs": rename_rule[3]}
break
d = self.normalize_suite_dir(cs, **normalize_kwargs)
# Help find components not located directly under d.
# NB: ancestor() not well suited if version_globs may contain os.sep .
- parent_dir = re.sub(os.sep + re.escape(cs) + '.*', '', d)
+ parent_dir = re.sub(os.sep + re.escape(cs) + ".*", "", d)
reparent_as = {}
- if cs == 'compilers_and_libraries': # must qualify further
- d = os.path.join(d, _expand_fields('{platform}'))
- elif cs == 'composer_xe':
- reparent_as = {'mpi': 'impi'}
+ if cs == "compilers_and_libraries": # must qualify further
+ d = os.path.join(d, _expand_fields("{platform}"))
+ elif cs == "composer_xe":
+ reparent_as = {"mpi": "impi"}
# ignore 'imb' (MPI Benchmarks)
for nominal_p, actual_p in reparent_as.items():
if component_path.startswith(nominal_p):
- dirs = glob.glob(
- os.path.join(parent_dir, actual_p, standalone_glob))
- debug_print('reparent dirs: %s' % dirs)
+ dirs = glob.glob(os.path.join(parent_dir, actual_p, standalone_glob))
+ debug_print("reparent dirs: %s" % dirs)
# Brazenly assume last match is the most recent version;
# convert back to relative of parent_dir, and re-assemble.
rel_dir = dirs[-1].split(parent_dir + os.sep, 1)[-1]
@@ -589,31 +597,31 @@ class IntelPackage(PackageBase):
def component_bin_dir(self, component, **kwargs):
d = self.normalize_path(component, **kwargs)
- if component == 'compiler': # bin dir is always under PARENT
- d = os.path.join(ancestor(d), 'bin', _expand_fields('{libarch}'))
- d = d.rstrip(os.sep) # cosmetics, when {libarch} is empty
+ if component == "compiler": # bin dir is always under PARENT
+ d = os.path.join(ancestor(d), "bin", _expand_fields("{libarch}"))
+ d = d.rstrip(os.sep) # cosmetics, when {libarch} is empty
# NB: Works fine even with relative=True, e.g.:
# composer_xe/compiler -> composer_xe/bin/intel64
- elif component == 'mpi':
- d = os.path.join(d, _expand_fields('{libarch}'), 'bin')
+ elif component == "mpi":
+ d = os.path.join(d, _expand_fields("{libarch}"), "bin")
else:
- d = os.path.join(d, 'bin')
+ d = os.path.join(d, "bin")
debug_print(d)
return d
def component_lib_dir(self, component, **kwargs):
- '''Provide directory suitable for find_libraries() and
+ """Provide directory suitable for find_libraries() and
SPACK_COMPILER_EXTRA_RPATHS.
- '''
+ """
d = self.normalize_path(component, **kwargs)
- if component == 'mpi':
- d = os.path.join(d, _expand_fields('{libarch}'), 'lib')
+ if component == "mpi":
+ d = os.path.join(d, _expand_fields("{libarch}"), "lib")
else:
- d = os.path.join(d, 'lib', _expand_fields('{libarch}'))
- d = d.rstrip(os.sep) # cosmetics, when {libarch} is empty
+ d = os.path.join(d, "lib", _expand_fields("{libarch}"))
+ d = d.rstrip(os.sep) # cosmetics, when {libarch} is empty
- if component == 'tbb': # must qualify further for abi
+ if component == "tbb": # must qualify further for abi
d = os.path.join(d, self._tbb_abi)
debug_print(d)
@@ -622,42 +630,42 @@ class IntelPackage(PackageBase):
def component_include_dir(self, component, **kwargs):
d = self.normalize_path(component, **kwargs)
- if component == 'mpi':
- d = os.path.join(d, _expand_fields('{libarch}'), 'include')
+ if component == "mpi":
+ d = os.path.join(d, _expand_fields("{libarch}"), "include")
else:
- d = os.path.join(d, 'include')
+ d = os.path.join(d, "include")
debug_print(d)
return d
@property
def file_to_source(self):
- '''Full path of file to source for initializing an Intel package.
+ """Full path of file to source for initializing an Intel package.
A client package could override as follows:
` @property`
` def file_to_source(self):`
` return self.normalize_path("apsvars.sh", "vtune_amplifier")`
- '''
+ """
vars_file_info_for = {
# key (usu. spack package name) -> [rel_path, component_suite_dir]
# Extension note: handle additions by Spack name or ad-hoc keys.
- '@early_compiler': ['bin/compilervars', None],
- 'intel-parallel-studio': ['bin/psxevars', 'parallel_studio_xe'],
- 'intel': ['bin/compilervars', None],
- 'intel-daal': ['daal/bin/daalvars', None],
- 'intel-ipp': ['ipp/bin/ippvars', None],
- 'intel-mkl': ['mkl/bin/mklvars', None],
- 'intel-mpi': ['mpi/{libarch}/bin/mpivars', None],
+ "@early_compiler": ["bin/compilervars", None],
+ "intel-parallel-studio": ["bin/psxevars", "parallel_studio_xe"],
+ "intel": ["bin/compilervars", None],
+ "intel-daal": ["daal/bin/daalvars", None],
+ "intel-ipp": ["ipp/bin/ippvars", None],
+ "intel-mkl": ["mkl/bin/mklvars", None],
+ "intel-mpi": ["mpi/{libarch}/bin/mpivars", None],
}
key = self.name
- if self.version_yearlike.satisfies(ver(':2015')):
+ if self.version_yearlike.satisfies(ver(":2015")):
# Same file as 'intel' but 'None' for component_suite_dir will
# resolve differently. Listed as a separate entry to serve as
# example and to avoid pitfalls upon possible refactoring.
- key = '@early_compiler'
+ key = "@early_compiler"
f, component_suite_dir = vars_file_info_for[key]
- f = _expand_fields(f) + '.sh'
+ f = _expand_fields(f) + ".sh"
# TODO?? win32 would have to handle os.sep, '.bat' (unless POSIX??)
f = self.normalize_path(f, component_suite_dir)
@@ -668,50 +676,53 @@ class IntelPackage(PackageBase):
# ---------------------------------------------------------------------
@property
def openmp_libs(self):
- '''Supply LibraryList for linking OpenMP'''
+ """Supply LibraryList for linking OpenMP"""
- if '%intel' in self.spec:
+ if "%intel" in self.spec:
# NB: Hunting down explicit library files may be the Spack way of
# doing things, but be aware that "{icc|ifort} --help openmp"
# steers us towards options instead: -qopenmp-link={dynamic,static}
- omp_libnames = ['libiomp5']
+ omp_libnames = ["libiomp5"]
omp_libs = find_libraries(
omp_libnames,
- root=self.component_lib_dir('compiler'),
- shared=('+shared' in self.spec))
+ root=self.component_lib_dir("compiler"),
+ shared=("+shared" in self.spec),
+ )
# Note about search root here: For MKL, the directory
# "$MKLROOT/../compiler" will be present even for an MKL-only
# product installation (as opposed to one being ghosted via
# packages.yaml), specificially to provide the 'iomp5' libs.
- elif '%gcc' in self.spec:
+ elif "%gcc" in self.spec:
with self.compiler.compiler_environment():
omp_lib_path = Executable(self.compiler.cc)(
- '--print-file-name', 'libgomp.%s' % dso_suffix, output=str)
+ "--print-file-name", "libgomp.%s" % dso_suffix, output=str
+ )
omp_libs = LibraryList(omp_lib_path.strip())
- elif '%clang' in self.spec:
+ elif "%clang" in self.spec:
with self.compiler.compiler_environment():
omp_lib_path = Executable(self.compiler.cc)(
- '--print-file-name', 'libomp.%s' % dso_suffix, output=str)
+ "--print-file-name", "libomp.%s" % dso_suffix, output=str
+ )
omp_libs = LibraryList(omp_lib_path.strip())
if len(omp_libs) < 1:
- raise_lib_error('Cannot locate OpenMP libraries:', omp_libnames)
+ raise_lib_error("Cannot locate OpenMP libraries:", omp_libnames)
debug_print(omp_libs)
return omp_libs
@property
def _gcc_executable(self):
- '''Return GCC executable'''
+ """Return GCC executable"""
# Match the available gcc, as it's done in tbbvars.sh.
- gcc_name = 'gcc'
+ gcc_name = "gcc"
# but first check if -gcc-name is specified in cflags
- for flag in self.spec.compiler_flags['cflags']:
- if flag.startswith('-gcc-name='):
- gcc_name = flag.split('-gcc-name=')[1]
+ for flag in self.spec.compiler_flags["cflags"]:
+ if flag.startswith("-gcc-name="):
+ gcc_name = flag.split("-gcc-name=")[1]
break
debug_print(gcc_name)
return Executable(gcc_name)
@@ -720,24 +731,21 @@ class IntelPackage(PackageBase):
def tbb_headers(self):
# Note: TBB is included as
# #include <tbb/task_scheduler_init.h>
- return HeaderList([
- self.component_include_dir('tbb') + '/dummy.h'])
+ return HeaderList([self.component_include_dir("tbb") + "/dummy.h"])
@property
def tbb_libs(self):
- '''Supply LibraryList for linking TBB'''
+ """Supply LibraryList for linking TBB"""
# TODO: When is 'libtbbmalloc' needed?
- tbb_lib = find_libraries(
- ['libtbb'], root=self.component_lib_dir('tbb'))
+ tbb_lib = find_libraries(["libtbb"], root=self.component_lib_dir("tbb"))
# NB: Like icc with -qopenmp, so does icpc steer us towards using an
# option: "icpc -tbb"
# TODO: clang(?)
- gcc = self._gcc_executable # must be gcc, not self.compiler.cc
+ gcc = self._gcc_executable # must be gcc, not self.compiler.cc
with self.compiler.compiler_environment():
- cxx_lib_path = gcc(
- '--print-file-name', 'libstdc++.%s' % dso_suffix, output=str)
+ cxx_lib_path = gcc("--print-file-name", "libstdc++.%s" % dso_suffix, output=str)
libs = tbb_lib + LibraryList(cxx_lib_path.rstrip())
debug_print(libs)
@@ -745,23 +753,26 @@ class IntelPackage(PackageBase):
@property
def _tbb_abi(self):
- '''Select the ABI needed for linking TBB'''
+ """Select the ABI needed for linking TBB"""
gcc = self._gcc_executable
with self.compiler.compiler_environment():
- matches = re.search(r'(gcc|LLVM).* ([0-9]+\.[0-9]+\.[0-9]+).*',
- gcc('--version', output=str), re.I | re.M)
- abi = ''
- if sys.platform == 'darwin':
+ matches = re.search(
+ r"(gcc|LLVM).* ([0-9]+\.[0-9]+\.[0-9]+).*",
+ gcc("--version", output=str),
+ re.I | re.M,
+ )
+ abi = ""
+ if sys.platform == "darwin":
pass
elif matches:
# TODO: Confirm that this covers clang (needed on Linux only)
gcc_version = Version(matches.groups()[1])
- if gcc_version >= ver('4.7'):
- abi = 'gcc4.7'
- elif gcc_version >= ver('4.4'):
- abi = 'gcc4.4'
+ if gcc_version >= ver("4.7"):
+ abi = "gcc4.7"
+ elif gcc_version >= ver("4.4"):
+ abi = "gcc4.4"
else:
- abi = 'gcc4.1' # unlikely, one hopes.
+ abi = "gcc4.1" # unlikely, one hopes.
# Alrighty then ...
debug_print(abi)
@@ -776,38 +787,41 @@ class IntelPackage(PackageBase):
# For reference, see The Intel Math Kernel Library Link Line Advisor:
# https://software.intel.com/en-us/articles/intel-mkl-link-line-advisor/
- mkl_integer = 'libmkl_intel_' + self.intel64_int_suffix
+ mkl_integer = "libmkl_intel_" + self.intel64_int_suffix
- if self.spec.satisfies('threads=openmp'):
- if '%intel' in self.spec:
- mkl_threading = 'libmkl_intel_thread'
- elif '%gcc' in self.spec or '%clang' in self.spec:
- mkl_threading = 'libmkl_gnu_thread'
+ if self.spec.satisfies("threads=openmp"):
+ if "%intel" in self.spec:
+ mkl_threading = "libmkl_intel_thread"
+ elif "%gcc" in self.spec or "%clang" in self.spec:
+ mkl_threading = "libmkl_gnu_thread"
threading_engine_libs = self.openmp_libs
- elif self.spec.satisfies('threads=tbb'):
- mkl_threading = 'libmkl_tbb_thread'
+ elif self.spec.satisfies("threads=tbb"):
+ mkl_threading = "libmkl_tbb_thread"
threading_engine_libs = self.tbb_libs
- elif self.spec.satisfies('threads=none'):
- mkl_threading = 'libmkl_sequential'
+ elif self.spec.satisfies("threads=none"):
+ mkl_threading = "libmkl_sequential"
threading_engine_libs = LibraryList([])
else:
- raise_lib_error('Cannot determine MKL threading libraries.')
+ raise_lib_error("Cannot determine MKL threading libraries.")
- mkl_libnames = [mkl_integer, mkl_threading, 'libmkl_core']
+ mkl_libnames = [mkl_integer, mkl_threading, "libmkl_core"]
mkl_libs = find_libraries(
- mkl_libnames,
- root=self.component_lib_dir('mkl'),
- shared=('+shared' in self.spec))
+ mkl_libnames, root=self.component_lib_dir("mkl"), shared=("+shared" in self.spec)
+ )
debug_print(mkl_libs)
if len(mkl_libs) < 3:
- raise_lib_error('Cannot locate core MKL libraries:', mkl_libnames,
- 'in:', self.component_lib_dir('mkl'))
+ raise_lib_error(
+ "Cannot locate core MKL libraries:",
+ mkl_libnames,
+ "in:",
+ self.component_lib_dir("mkl"),
+ )
# The Intel MKL link line advisor recommends these system libraries
system_libs = find_system_libraries(
- 'libpthread libm libdl'.split(),
- shared=('+shared' in self.spec))
+ "libpthread libm libdl".split(), shared=("+shared" in self.spec)
+ )
debug_print(system_libs)
return mkl_libs + threading_engine_libs + system_libs
@@ -823,40 +837,40 @@ class IntelPackage(PackageBase):
# we must supply a personality matching the MPI implementation that
# is active for the root package that asked for ScaLapack.
spec_root = self.spec.root
- if sys.platform == 'darwin' and '^mpich' in spec_root:
+ if sys.platform == "darwin" and "^mpich" in spec_root:
# The only supported choice for MKL 2018 on Mac.
- blacs_lib = 'libmkl_blacs_mpich'
- elif '^openmpi' in spec_root:
- blacs_lib = 'libmkl_blacs_openmpi'
- elif '^mpich@1' in spec_root:
+ blacs_lib = "libmkl_blacs_mpich"
+ elif "^openmpi" in spec_root:
+ blacs_lib = "libmkl_blacs_openmpi"
+ elif "^mpich@1" in spec_root:
# Was supported only up to 2015.
- blacs_lib = 'libmkl_blacs'
- elif ('^mpich@2:' in spec_root or
- '^cray-mpich' in spec_root or
- '^mvapich2' in spec_root or
- '^intel-mpi' in spec_root or
- '^intel-oneapi-mpi' in spec_root or
- '^intel-parallel-studio' in spec_root):
- blacs_lib = 'libmkl_blacs_intelmpi'
- elif '^mpt' in spec_root:
- blacs_lib = 'libmkl_blacs_sgimpt'
+ blacs_lib = "libmkl_blacs"
+ elif (
+ "^mpich@2:" in spec_root
+ or "^cray-mpich" in spec_root
+ or "^mvapich2" in spec_root
+ or "^intel-mpi" in spec_root
+ or "^intel-oneapi-mpi" in spec_root
+ or "^intel-parallel-studio" in spec_root
+ ):
+ blacs_lib = "libmkl_blacs_intelmpi"
+ elif "^mpt" in spec_root:
+ blacs_lib = "libmkl_blacs_sgimpt"
else:
- raise_lib_error('Cannot find a BLACS library for the given MPI.')
+ raise_lib_error("Cannot find a BLACS library for the given MPI.")
- int_suff = '_' + self.intel64_int_suffix
+ int_suff = "_" + self.intel64_int_suffix
scalapack_libnames = [
- 'libmkl_scalapack' + int_suff,
+ "libmkl_scalapack" + int_suff,
blacs_lib + int_suff,
]
sca_libs = find_libraries(
- scalapack_libnames,
- root=self.component_lib_dir('mkl'),
- shared=('+shared' in self.spec))
+ scalapack_libnames, root=self.component_lib_dir("mkl"), shared=("+shared" in self.spec)
+ )
debug_print(sca_libs)
if len(sca_libs) < 2:
- raise_lib_error(
- 'Cannot locate ScaLapack/BLACS libraries:', scalapack_libnames)
+ raise_lib_error("Cannot locate ScaLapack/BLACS libraries:", scalapack_libnames)
# NB: ScaLapack is installed as "cluster" components within MKL or
# MKL-encompassing products. But those were *optional* for the ca.
# 2015/2016 product releases, which was easy to overlook, and I have
@@ -871,8 +885,7 @@ class IntelPackage(PackageBase):
# ---------------------------------------------------------------------
@property
def mpi_compiler_wrappers(self):
- '''Return paths to compiler wrappers as a dict of env-like names
- '''
+ """Return paths to compiler wrappers as a dict of env-like names"""
# Intel comes with 2 different flavors of MPI wrappers:
#
# * mpiicc, mpiicpc, and mpiifort are hardcoded to wrap around
@@ -885,30 +898,29 @@ class IntelPackage(PackageBase):
# and friends are set to point to the Intel compilers, but in
# practice, mpicc fails to compile some applications while
# mpiicc works.
- bindir = self.component_bin_dir('mpi')
- if self.compiler.name == 'intel':
+ bindir = self.component_bin_dir("mpi")
+ if self.compiler.name == "intel":
wrapper_vars = {
# eschew Prefix objects -- emphasize the command strings.
- 'MPICC': os.path.join(bindir, 'mpiicc'),
- 'MPICXX': os.path.join(bindir, 'mpiicpc'),
- 'MPIF77': os.path.join(bindir, 'mpiifort'),
- 'MPIF90': os.path.join(bindir, 'mpiifort'),
- 'MPIFC': os.path.join(bindir, 'mpiifort'),
+ "MPICC": os.path.join(bindir, "mpiicc"),
+ "MPICXX": os.path.join(bindir, "mpiicpc"),
+ "MPIF77": os.path.join(bindir, "mpiifort"),
+ "MPIF90": os.path.join(bindir, "mpiifort"),
+ "MPIFC": os.path.join(bindir, "mpiifort"),
}
else:
wrapper_vars = {
- 'MPICC': os.path.join(bindir, 'mpicc'),
- 'MPICXX': os.path.join(bindir, 'mpicxx'),
- 'MPIF77': os.path.join(bindir, 'mpif77'),
- 'MPIF90': os.path.join(bindir, 'mpif90'),
- 'MPIFC': os.path.join(bindir, 'mpif90'),
+ "MPICC": os.path.join(bindir, "mpicc"),
+ "MPICXX": os.path.join(bindir, "mpicxx"),
+ "MPIF77": os.path.join(bindir, "mpif77"),
+ "MPIF90": os.path.join(bindir, "mpif90"),
+ "MPIFC": os.path.join(bindir, "mpif90"),
}
# debug_print("wrapper_vars =", wrapper_vars)
return wrapper_vars
- def mpi_setup_dependent_build_environment(
- self, env, dependent_spec, compilers_of_client={}):
- '''Unified back-end for setup_dependent_build_environment() of
+ def mpi_setup_dependent_build_environment(self, env, dependent_spec, compilers_of_client={}):
+ """Unified back-end for setup_dependent_build_environment() of
Intel packages that provide 'mpi'.
Parameters:
@@ -918,16 +930,16 @@ class IntelPackage(PackageBase):
compilers_of_client (dict): Conveys spack_cc, spack_cxx, etc.,
from the scope of dependent packages; constructed in caller.
- '''
+ """
# See also: setup_dependent_package()
wrapper_vars = {
- 'I_MPI_CC': compilers_of_client['CC'],
- 'I_MPI_CXX': compilers_of_client['CXX'],
- 'I_MPI_F77': compilers_of_client['F77'],
- 'I_MPI_F90': compilers_of_client['F90'],
- 'I_MPI_FC': compilers_of_client['FC'],
+ "I_MPI_CC": compilers_of_client["CC"],
+ "I_MPI_CXX": compilers_of_client["CXX"],
+ "I_MPI_F77": compilers_of_client["F77"],
+ "I_MPI_F90": compilers_of_client["F90"],
+ "I_MPI_FC": compilers_of_client["FC"],
# NB: Normally set by the modulefile, but that is not active here:
- 'I_MPI_ROOT': self.normalize_path('mpi'),
+ "I_MPI_ROOT": self.normalize_path("mpi"),
}
# CAUTION - SIMILAR code in:
@@ -936,27 +948,31 @@ class IntelPackage(PackageBase):
# var/spack/repos/builtin/packages/mvapich2/package.py
#
# On Cray, the regular compiler wrappers *are* the MPI wrappers.
- if 'platform=cray' in self.spec:
+ if "platform=cray" in self.spec:
# TODO: Confirm
- wrapper_vars.update({
- 'MPICC': compilers_of_client['CC'],
- 'MPICXX': compilers_of_client['CXX'],
- 'MPIF77': compilers_of_client['F77'],
- 'MPIF90': compilers_of_client['F90'],
- })
+ wrapper_vars.update(
+ {
+ "MPICC": compilers_of_client["CC"],
+ "MPICXX": compilers_of_client["CXX"],
+ "MPIF77": compilers_of_client["F77"],
+ "MPIF90": compilers_of_client["F90"],
+ }
+ )
else:
compiler_wrapper_commands = self.mpi_compiler_wrappers
- wrapper_vars.update({
- 'MPICC': compiler_wrapper_commands['MPICC'],
- 'MPICXX': compiler_wrapper_commands['MPICXX'],
- 'MPIF77': compiler_wrapper_commands['MPIF77'],
- 'MPIF90': compiler_wrapper_commands['MPIF90'],
- })
+ wrapper_vars.update(
+ {
+ "MPICC": compiler_wrapper_commands["MPICC"],
+ "MPICXX": compiler_wrapper_commands["MPICXX"],
+ "MPIF77": compiler_wrapper_commands["MPIF77"],
+ "MPIF90": compiler_wrapper_commands["MPIF90"],
+ }
+ )
# Ensure that the directory containing the compiler wrappers is in the
# PATH. Spack packages add `prefix.bin` to their dependents' paths,
# but because of the intel directory hierarchy that is insufficient.
- env.prepend_path('PATH', os.path.dirname(wrapper_vars['MPICC']))
+ env.prepend_path("PATH", os.path.dirname(wrapper_vars["MPICC"]))
for key, value in wrapper_vars.items():
env.set(key, value)
@@ -969,17 +985,17 @@ class IntelPackage(PackageBase):
@property
def headers(self):
result = HeaderList([])
- if '+mpi' in self.spec or self.provides('mpi'):
+ if "+mpi" in self.spec or self.provides("mpi"):
result += find_headers(
- ['mpi'],
- root=self.component_include_dir('mpi'),
- recursive=False)
- if '+mkl' in self.spec or self.provides('mkl'):
+ ["mpi"], root=self.component_include_dir("mpi"), recursive=False
+ )
+ if "+mkl" in self.spec or self.provides("mkl"):
result += find_headers(
- ['mkl_cblas', 'mkl_lapacke'],
- root=self.component_include_dir('mkl'),
- recursive=False)
- if '+tbb' in self.spec or self.provides('tbb'):
+ ["mkl_cblas", "mkl_lapacke"],
+ root=self.component_include_dir("mkl"),
+ recursive=False,
+ )
+ if "+tbb" in self.spec or self.provides("tbb"):
result += self.tbb_headers
debug_print(result)
@@ -988,35 +1004,35 @@ class IntelPackage(PackageBase):
@property
def libs(self):
result = LibraryList([])
- if '+tbb' in self.spec or self.provides('tbb'):
+ if "+tbb" in self.spec or self.provides("tbb"):
result = self.tbb_libs + result
- if '+mkl' in self.spec or self.provides('blas'):
+ if "+mkl" in self.spec or self.provides("blas"):
result = self.blas_libs + result
- if '+mkl' in self.spec or self.provides('lapack'):
+ if "+mkl" in self.spec or self.provides("lapack"):
result = self.lapack_libs + result
- if '+mpi' in self.spec or self.provides('mpi'):
+ if "+mpi" in self.spec or self.provides("mpi"):
# If prefix is too general, recursive searches may get files from
# supported but inappropriate sub-architectures like 'mic'.
- libnames = ['libmpifort', 'libmpi']
- if 'cxx' in self.spec.last_query.extra_parameters:
- libnames = ['libmpicxx'] + libnames
- result = find_libraries(
- libnames,
- root=self.component_lib_dir('mpi'),
- shared=True, recursive=True) + result
+ libnames = ["libmpifort", "libmpi"]
+ if "cxx" in self.spec.last_query.extra_parameters:
+ libnames = ["libmpicxx"] + libnames
+ result = (
+ find_libraries(
+ libnames, root=self.component_lib_dir("mpi"), shared=True, recursive=True
+ )
+ + result
+ )
# Intel MPI since 2019 depends on libfabric which is not in the
# lib directory but in a directory of its own which should be
# included in the rpath
- if self.version_yearlike >= ver('2019'):
- d = ancestor(self.component_lib_dir('mpi'))
- if '+external-libfabric' in self.spec:
- result += self.spec['libfabric'].libs
+ if self.version_yearlike >= ver("2019"):
+ d = ancestor(self.component_lib_dir("mpi"))
+ if "+external-libfabric" in self.spec:
+ result += self.spec["libfabric"].libs
else:
- result += find_libraries(['libfabric'],
- os.path.join(d, 'libfabric', 'lib'))
+ result += find_libraries(["libfabric"], os.path.join(d, "libfabric", "lib"))
- if '^mpi' in self.spec.root and ('+mkl' in self.spec or
- self.provides('scalapack')):
+ if "^mpi" in self.spec.root and ("+mkl" in self.spec or self.provides("scalapack")):
result = self.scalapack_libs + result
debug_print(result)
@@ -1037,7 +1053,7 @@ class IntelPackage(PackageBase):
# All Intel packages expect at least the architecture as argument.
# Some accept more args, but those are not (yet?) handled here.
- args = (_expand_fields('{arch}'),)
+ args = (_expand_fields("{arch}"),)
# On Mac, the platform is *also required*, at least as of 2018.
# I am not sure about earlier versions.
@@ -1046,14 +1062,14 @@ class IntelPackage(PackageBase):
env.extend(EnvironmentModifications.from_sourcing_file(f, *args))
- if self.spec.name in ('intel', 'intel-parallel-studio'):
+ if self.spec.name in ("intel", "intel-parallel-studio"):
# this package provides compilers
# TODO: fix check above when compilers are dependencies
- env.set('CC', self.prefix.bin.icc)
- env.set('CXX', self.prefix.bin.icpc)
- env.set('FC', self.prefix.bin.ifort)
- env.set('F77', self.prefix.bin.ifort)
- env.set('F90', self.prefix.bin.ifort)
+ env.set("CC", self.prefix.bin.icc)
+ env.set("CXX", self.prefix.bin.icpc)
+ env.set("FC", self.prefix.bin.ifort)
+ env.set("F77", self.prefix.bin.ifort)
+ env.set("F90", self.prefix.bin.ifort)
def setup_dependent_build_environment(self, env, dependent_spec):
# NB: This function is overwritten by 'mpi' provider packages:
@@ -1067,13 +1083,12 @@ class IntelPackage(PackageBase):
# Handle everything in a callback version.
self._setup_dependent_env_callback(env, dependent_spec)
- def _setup_dependent_env_callback(
- self, env, dependent_spec, compilers_of_client={}):
+ def _setup_dependent_env_callback(self, env, dependent_spec, compilers_of_client={}):
# Expected to be called from a client's
# setup_dependent_build_environment(),
# with args extended to convey the client's compilers as needed.
- if '+mkl' in self.spec or self.provides('mkl'):
+ if "+mkl" in self.spec or self.provides("mkl"):
# Spack's env philosophy demands that we replicate some of the
# settings normally handled by file_to_source ...
#
@@ -1084,49 +1099,48 @@ class IntelPackage(PackageBase):
#
# Use a local dict to facilitate debug_print():
env_mods = {
- 'MKLROOT': self.normalize_path('mkl'),
- 'SPACK_COMPILER_EXTRA_RPATHS': self.component_lib_dir('mkl'),
- 'CMAKE_PREFIX_PATH': self.normalize_path('mkl'),
- 'CMAKE_LIBRARY_PATH': self.component_lib_dir('mkl'),
- 'CMAKE_INCLUDE_PATH': self.component_include_dir('mkl'),
+ "MKLROOT": self.normalize_path("mkl"),
+ "SPACK_COMPILER_EXTRA_RPATHS": self.component_lib_dir("mkl"),
+ "CMAKE_PREFIX_PATH": self.normalize_path("mkl"),
+ "CMAKE_LIBRARY_PATH": self.component_lib_dir("mkl"),
+ "CMAKE_INCLUDE_PATH": self.component_include_dir("mkl"),
}
- env.set('MKLROOT', env_mods['MKLROOT'])
- env.append_path('SPACK_COMPILER_EXTRA_RPATHS',
- env_mods['SPACK_COMPILER_EXTRA_RPATHS'])
- env.append_path('CMAKE_PREFIX_PATH', env_mods['CMAKE_PREFIX_PATH'])
- env.append_path('CMAKE_LIBRARY_PATH',
- env_mods['CMAKE_LIBRARY_PATH'])
- env.append_path('CMAKE_INCLUDE_PATH',
- env_mods['CMAKE_INCLUDE_PATH'])
+ env.set("MKLROOT", env_mods["MKLROOT"])
+ env.append_path("SPACK_COMPILER_EXTRA_RPATHS", env_mods["SPACK_COMPILER_EXTRA_RPATHS"])
+ env.append_path("CMAKE_PREFIX_PATH", env_mods["CMAKE_PREFIX_PATH"])
+ env.append_path("CMAKE_LIBRARY_PATH", env_mods["CMAKE_LIBRARY_PATH"])
+ env.append_path("CMAKE_INCLUDE_PATH", env_mods["CMAKE_INCLUDE_PATH"])
debug_print("adding/modifying build env:", env_mods)
- if '+mpi' in self.spec or self.provides('mpi'):
+ if "+mpi" in self.spec or self.provides("mpi"):
if compilers_of_client:
self.mpi_setup_dependent_build_environment(
- env, dependent_spec, compilers_of_client)
+ env, dependent_spec, compilers_of_client
+ )
# We could forego this nonce function and inline its code here,
# but (a) it sisters mpi_compiler_wrappers() [needed twice]
# which performs dizzyingly similar but necessarily different
# actions, and (b) function code leaves a bit more breathing
# room within the suffocating corset of flake8 line length.
else:
- raise InstallError('compilers_of_client arg required for MPI')
+ raise InstallError("compilers_of_client arg required for MPI")
def setup_dependent_package(self, module, dep_spec):
# https://spack.readthedocs.io/en/latest/spack.html#spack.package_base.PackageBase.setup_dependent_package
# Reminder: "module" refers to Python module.
# Called before the install() method of dependents.
- if '+mpi' in self.spec or self.provides('mpi'):
+ if "+mpi" in self.spec or self.provides("mpi"):
compiler_wrapper_commands = self.mpi_compiler_wrappers
- self.spec.mpicc = compiler_wrapper_commands['MPICC']
- self.spec.mpicxx = compiler_wrapper_commands['MPICXX']
- self.spec.mpif77 = compiler_wrapper_commands['MPIF77']
- self.spec.mpifc = compiler_wrapper_commands['MPIFC']
- debug_print(("spec '%s' received .mpi* properties:" % self.spec),
- compiler_wrapper_commands)
+ self.spec.mpicc = compiler_wrapper_commands["MPICC"]
+ self.spec.mpicxx = compiler_wrapper_commands["MPICXX"]
+ self.spec.mpif77 = compiler_wrapper_commands["MPIF77"]
+ self.spec.mpifc = compiler_wrapper_commands["MPIFC"]
+ debug_print(
+ ("spec '%s' received .mpi* properties:" % self.spec), compiler_wrapper_commands
+ )
# ---------------------------------------------------------------------
# Specifics for installation phase
@@ -1137,19 +1151,20 @@ class IntelPackage(PackageBase):
All Intel software shares the same license, so we store it in a
common 'intel' directory."""
- return os.path.join(self.global_license_dir, 'intel', 'license.lic')
+ return os.path.join(self.global_license_dir, "intel", "license.lic")
@property
def _determine_license_type(self):
- '''Provide appropriate license tokens for the installer (silent.cfg).
- '''
+ """Provide appropriate license tokens for the installer (silent.cfg)."""
# See:
# ./README-intel.rst, section "Details for licensing tokens".
# ./build_systems/README-intel.rst, section "Licenses"
#
# Ideally, we just tell the installer to look around on the system.
# Thankfully, we neither need to care nor emulate where it looks:
- license_type = {'ACTIVATION_TYPE': 'exist_lic', }
+ license_type = {
+ "ACTIVATION_TYPE": "exist_lic",
+ }
# However (and only), if the spack-internal Intel license file has been
# populated beyond its templated explanatory comments, proffer it to
@@ -1160,21 +1175,20 @@ class IntelPackage(PackageBase):
# self.license_files having been populated, so the "if" is usually
# true by the time the present function runs; ../hooks/licensing.py
with open(f) as fh:
- if re.search(r'^[ \t]*[^' + self.license_comment + '\n]',
- fh.read(), re.MULTILINE):
+ if re.search(r"^[ \t]*[^" + self.license_comment + "\n]", fh.read(), re.MULTILINE):
license_type = {
- 'ACTIVATION_TYPE': 'license_file',
- 'ACTIVATION_LICENSE_FILE': f,
+ "ACTIVATION_TYPE": "license_file",
+ "ACTIVATION_LICENSE_FILE": f,
}
debug_print(license_type)
return license_type
def configure(self, spec, prefix):
- '''Generates the silent.cfg file to pass to installer.sh.
+ """Generates the silent.cfg file to pass to installer.sh.
See https://software.intel.com/en-us/articles/configuration-file-format
- '''
+ """
# Both tokens AND values of the configuration file are validated during
# the run of the underlying binary installer. Any unknown token or
@@ -1191,136 +1205,130 @@ class IntelPackage(PackageBase):
# our configuration accordingly. We can do this because the tokens are
# quite long and specific.
- validator_code = open('pset/check.awk', 'r').read()
+ validator_code = open("pset/check.awk", "r").read()
# Let's go a little further and distill the tokens (plus some noise).
- tokenlike_words = set(re.findall(r'[A-Z_]{4,}', validator_code))
+ tokenlike_words = set(re.findall(r"[A-Z_]{4,}", validator_code))
# NB: .cfg files generated with the "--duplicate filename" option have
# the COMPONENTS string begin with a separator - do not worry about it.
- components_joined = ';'.join(self._filtered_components)
- nonrpm_db_dir = os.path.join(prefix, 'nonrpm-db')
+ components_joined = ";".join(self._filtered_components)
+ nonrpm_db_dir = os.path.join(prefix, "nonrpm-db")
config_draft = {
# Basics first - these should be accepted in all products.
- 'ACCEPT_EULA': 'accept',
- 'PSET_MODE': 'install',
- 'CONTINUE_WITH_OPTIONAL_ERROR': 'yes',
- 'CONTINUE_WITH_INSTALLDIR_OVERWRITE': 'yes',
- 'SIGNING_ENABLED': 'no',
-
+ "ACCEPT_EULA": "accept",
+ "PSET_MODE": "install",
+ "CONTINUE_WITH_OPTIONAL_ERROR": "yes",
+ "CONTINUE_WITH_INSTALLDIR_OVERWRITE": "yes",
+ "SIGNING_ENABLED": "no",
# Highly variable package specifics:
- 'PSET_INSTALL_DIR': prefix,
- 'NONRPM_DB_DIR': nonrpm_db_dir,
- 'COMPONENTS': components_joined,
-
+ "PSET_INSTALL_DIR": prefix,
+ "NONRPM_DB_DIR": nonrpm_db_dir,
+ "COMPONENTS": components_joined,
# Conditional tokens; the first is supported post-2015 only.
# Ignore ia32; most recent products don't even provide it.
- 'ARCH_SELECTED': 'INTEL64', # was: 'ALL'
-
+ "ARCH_SELECTED": "INTEL64", # was: 'ALL'
# 'ism' component -- see uninstall_ism(); also varies by release.
- 'PHONEHOME_SEND_USAGE_DATA': 'no',
+ "PHONEHOME_SEND_USAGE_DATA": "no",
# Ah, as of 2018.2, that somewhat loaded term got replaced by one
# in business-speak. We uphold our preference, both out of general
# principles and for technical reasons like overhead and non-routed
# compute nodes.
- 'INTEL_SW_IMPROVEMENT_PROGRAM_CONSENT': 'no',
+ "INTEL_SW_IMPROVEMENT_PROGRAM_CONSENT": "no",
}
# Deal with licensing only if truly needed.
# NB: Token was 'ACTIVATION' pre ~2013, so basically irrelevant here.
- if 'ACTIVATION_TYPE' in tokenlike_words:
+ if "ACTIVATION_TYPE" in tokenlike_words:
config_draft.update(self._determine_license_type)
# Write sorted *by token* so the file looks less like a hash dump.
- f = open('silent.cfg', 'w')
+ f = open("silent.cfg", "w")
for token, value in sorted(config_draft.items()):
if token in tokenlike_words:
- f.write('%s=%s\n' % (token, value))
+ f.write("%s=%s\n" % (token, value))
f.close()
def install(self, spec, prefix):
- '''Runs Intel's install.sh installation script. Afterwards, save the
+ """Runs Intel's install.sh installation script. Afterwards, save the
installer config and logs to <prefix>/.spack
- '''
+ """
# prepare
- tmpdir = tempfile.mkdtemp(prefix='spack-intel-')
+ tmpdir = tempfile.mkdtemp(prefix="spack-intel-")
- install_script = Executable('./install.sh')
- install_script.add_default_env('TMPDIR', tmpdir)
+ install_script = Executable("./install.sh")
+ install_script.add_default_env("TMPDIR", tmpdir)
# Need to set HOME to avoid using ~/intel
- install_script.add_default_env('HOME', prefix)
+ install_script.add_default_env("HOME", prefix)
# perform
- install_script('--silent', 'silent.cfg')
+ install_script("--silent", "silent.cfg")
# preserve config and logs
- dst = os.path.join(self.prefix, '.spack')
- install('silent.cfg', dst)
- for f in glob.glob('%s/intel*log' % tmpdir):
+ dst = os.path.join(self.prefix, ".spack")
+ install("silent.cfg", dst)
+ for f in glob.glob("%s/intel*log" % tmpdir):
install(f, dst)
- @run_after('install')
+ @run_after("install")
def validate_install(self):
# Sometimes the installer exits with an error but doesn't pass a
# non-zero exit code to spack. Check for the existence of a 'bin'
# directory to catch this error condition.
if not os.path.exists(self.prefix.bin):
- raise InstallError('The installer has failed to install anything.')
+ raise InstallError("The installer has failed to install anything.")
- @run_after('install')
+ @run_after("install")
def configure_rpath(self):
- if '+rpath' not in self.spec:
+ if "+rpath" not in self.spec:
return
# https://software.intel.com/en-us/cpp-compiler-18.0-developer-guide-and-reference-using-configuration-files
- compilers_bin_dir = self.component_bin_dir('compiler')
- compilers_lib_dir = self.component_lib_dir('compiler')
+ compilers_bin_dir = self.component_bin_dir("compiler")
+ compilers_lib_dir = self.component_lib_dir("compiler")
- for compiler_name in 'icc icpc ifort'.split():
+ for compiler_name in "icc icpc ifort".split():
f = os.path.join(compilers_bin_dir, compiler_name)
if not os.path.isfile(f):
- raise InstallError(
- 'Cannot find compiler command to configure rpath:\n\t' + f)
+ raise InstallError("Cannot find compiler command to configure rpath:\n\t" + f)
- compiler_cfg = os.path.abspath(f + '.cfg')
- with open(compiler_cfg, 'w') as fh:
- fh.write('-Xlinker -rpath={0}\n'.format(compilers_lib_dir))
+ compiler_cfg = os.path.abspath(f + ".cfg")
+ with open(compiler_cfg, "w") as fh:
+ fh.write("-Xlinker -rpath={0}\n".format(compilers_lib_dir))
- @run_after('install')
+ @run_after("install")
def configure_auto_dispatch(self):
if self._has_compilers:
- if ('auto_dispatch=none' in self.spec):
+ if "auto_dispatch=none" in self.spec:
return
- compilers_bin_dir = self.component_bin_dir('compiler')
+ compilers_bin_dir = self.component_bin_dir("compiler")
- for compiler_name in 'icc icpc ifort'.split():
+ for compiler_name in "icc icpc ifort".split():
f = os.path.join(compilers_bin_dir, compiler_name)
if not os.path.isfile(f):
raise InstallError(
- 'Cannot find compiler command to configure '
- 'auto_dispatch:\n\t' + f)
+ "Cannot find compiler command to configure " "auto_dispatch:\n\t" + f
+ )
ad = []
for x in IntelPackage.auto_dispatch_options:
- if 'auto_dispatch={0}'.format(x) in self.spec:
+ if "auto_dispatch={0}".format(x) in self.spec:
ad.append(x)
- compiler_cfg = os.path.abspath(f + '.cfg')
- with open(compiler_cfg, 'a') as fh:
- fh.write('-ax{0}\n'.format(','.join(ad)))
+ compiler_cfg = os.path.abspath(f + ".cfg")
+ with open(compiler_cfg, "a") as fh:
+ fh.write("-ax{0}\n".format(",".join(ad)))
- @run_after('install')
+ @run_after("install")
def filter_compiler_wrappers(self):
- if (('+mpi' in self.spec or self.provides('mpi')) and
- '~newdtags' in self.spec):
- bin_dir = self.component_bin_dir('mpi')
- for f in 'mpif77 mpif90 mpigcc mpigxx mpiicc mpiicpc ' \
- 'mpiifort'.split():
+ if ("+mpi" in self.spec or self.provides("mpi")) and "~newdtags" in self.spec:
+ bin_dir = self.component_bin_dir("mpi")
+ for f in "mpif77 mpif90 mpigcc mpigxx mpiicc mpiicpc " "mpiifort".split():
f = os.path.join(bin_dir, f)
- filter_file('-Xlinker --enable-new-dtags', ' ', f, string=True)
+ filter_file("-Xlinker --enable-new-dtags", " ", f, string=True)
- @run_after('install')
+ @run_after("install")
def uninstall_ism(self):
# The "Intel(R) Software Improvement Program" [ahem] gets installed,
# apparently regardless of PHONEHOME_SEND_USAGE_DATA.
@@ -1331,12 +1339,11 @@ class IntelPackage(PackageBase):
# "... you can also uninstall the Intel(R) Software Manager
# completely: <installdir>/intel/ism/uninstall.sh"
- f = os.path.join(self.normalize_path('ism'), 'uninstall.sh')
+ f = os.path.join(self.normalize_path("ism"), "uninstall.sh")
if os.path.isfile(f):
- tty.warn('Uninstalling "Intel Software Improvement Program"'
- 'component')
+ tty.warn('Uninstalling "Intel Software Improvement Program"' "component")
uninstall = Executable(f)
- uninstall('--silent')
+ uninstall("--silent")
# TODO? also try
# ~/intel/ism/uninstall --silent
@@ -1346,15 +1353,14 @@ class IntelPackage(PackageBase):
@property
def base_lib_dir(self):
- """Provide the library directory located in the base of Intel installation.
- """
- d = self.normalize_path('')
- d = os.path.join(d, 'lib')
+ """Provide the library directory located in the base of Intel installation."""
+ d = self.normalize_path("")
+ d = os.path.join(d, "lib")
debug_print(d)
return d
- @run_after('install')
+ @run_after("install")
def modify_LLVMgold_rpath(self):
"""Add libimf.so and other required libraries to the RUNPATH of LLVMgold.so.
@@ -1362,8 +1368,9 @@ class IntelPackage(PackageBase):
`ld -plugin LLVMgold.so` is called by the compiler.
"""
if self._has_compilers:
- LLVMgold_libs = find_libraries('LLVMgold', self.base_lib_dir,
- shared=True, recursive=True)
+ LLVMgold_libs = find_libraries(
+ "LLVMgold", self.base_lib_dir, shared=True, recursive=True
+ )
# Ignore ia32 entries as they mostly ignore throughout the rest
# of the file.
# The first entry in rpath preserves the original, the seconds entry
@@ -1371,15 +1378,19 @@ class IntelPackage(PackageBase):
# in compiler releases, then we need to search for libimf.so instead
# of this static path.
for lib in LLVMgold_libs:
- if not self.spec.satisfies('^patchelf'):
+ if not self.spec.satisfies("^patchelf"):
raise spack.error.SpackError(
- 'Attempting to patch RPATH in LLVMgold.so.'
- + '`patchelf` dependency should be set in package.py'
+ "Attempting to patch RPATH in LLVMgold.so."
+ + "`patchelf` dependency should be set in package.py"
)
- patchelf = Executable('patchelf')
- rpath = ':'.join([patchelf('--print-rpath', lib, output=str).strip(),
- '$ORIGIN/../compiler/lib/intel64_lin'])
- patchelf('--set-rpath', rpath, lib)
+ patchelf = Executable("patchelf")
+ rpath = ":".join(
+ [
+ patchelf("--print-rpath", lib, output=str).strip(),
+ "$ORIGIN/../compiler/lib/intel64_lin",
+ ]
+ )
+ patchelf("--set-rpath", rpath, lib)
# Check that self.prefix is there after installation
- run_after('install')(PackageBase.sanity_check_prefix)
+ run_after("install")(PackageBase.sanity_check_prefix)