in lib/ramble/spack/build_systems/intel.py [0:0]
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
years. This function provides a unified interface to their directory
names.
Parameters:
component_path (str): a component name like 'mkl', or 'mpi', or a
deeper relative path.
component_suite_dir (str): _Unversioned_ name of the expected
parent directory of component_path. When absent or `None`, an
appropriate default will be used. A present but empty string
`""` requests that `component_path` refer to `self.prefix`
directly.
Typical values: `compilers_and_libraries`, `composer_xe`,
`parallel_studio_xe`.
Also supported: `advisor`, `inspector`, `vtune`. The actual
directory name for these suites varies by release year. The
name will be corrected as needed for use in the return value.
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
# a function for that). I chose "" to allow that case be represented,
# and 'None' or the absence of the kwarg to represent the most relevant
# case for the time of writing.
#
# In the 2015 releases (the earliest in Spack as of 2018), there were
# nominally two separate products that provided the compilers:
# "Composer" as lower tier, and "Parallel Studio" as upper tier. In
# Spack, we justifiably retcon both as "intel-parallel-studio@composer"
# and "...@cluster", respectively. Both of these use the older
# "composer_xe" dir layout, as do their virtual package personas.
#
# All other "intel-foo" packages in Spack as of 2018-04 use the
# "compilers_and_libraries" layout, including the 2016 releases that
# are not natively versioned by year.
cs = component_suite_dir
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]*.*.*'
# 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
]
}
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]],
]:
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]}
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)
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'}
# 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)
# 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]
component_path = component_path.replace(nominal_p, rel_dir, 1)
d = parent_dir
d = os.path.join(d, component_path)
if relative:
d = os.path.relpath(os.path.realpath(d), parent_dir)
debug_print(d)
return d