[oneapi] fix mkl deps, externally installed, and docs (#22607)
This commit is contained in:
parent
6c16f5c5d5
commit
c8b4414230
@ -38,21 +38,25 @@ Intel no longer releases new versions of Parallel Studio, which can be
|
|||||||
used in Spack via the :ref:<intelpackage>. All of its components can
|
used in Spack via the :ref:<intelpackage>. All of its components can
|
||||||
now be found in oneAPI.
|
now be found in oneAPI.
|
||||||
|
|
||||||
Example
|
Examples
|
||||||
=======
|
========
|
||||||
|
|
||||||
We start with a simple example that will be sufficient for most
|
Building a Package With icx
|
||||||
users. Install the oneAPI compilers::
|
---------------------------
|
||||||
|
|
||||||
|
In this example, we build patchelf with ``icc`` and ``icx``. The
|
||||||
|
compilers are installed with spack.
|
||||||
|
|
||||||
|
Install the oneAPI compilers::
|
||||||
|
|
||||||
spack install intel-oneapi-compilers
|
spack install intel-oneapi-compilers
|
||||||
|
|
||||||
Add the oneAPI compilers to the set of compilers that Spack can use::
|
Add the compilers to your ``compilers.yaml`` so spack can use them::
|
||||||
|
|
||||||
spack compiler add `spack location -i intel-oneapi-compilers`/compiler/latest/linux/bin/intel64
|
spack compiler add `spack location -i intel-oneapi-compilers`/compiler/latest/linux/bin/intel64
|
||||||
spack compiler add `spack location -i intel-oneapi-compilers`/compiler/latest/linux/bin
|
spack compiler add `spack location -i intel-oneapi-compilers`/compiler/latest/linux/bin
|
||||||
|
|
||||||
This adds the compilers to your ``compilers.yaml``. Verify that the
|
Verify that the compilers are available::
|
||||||
compilers are available::
|
|
||||||
|
|
||||||
spack compiler list
|
spack compiler list
|
||||||
|
|
||||||
@ -72,9 +76,11 @@ To build with with ``icx``, do ::
|
|||||||
|
|
||||||
spack install patchelf%oneapi
|
spack install patchelf%oneapi
|
||||||
|
|
||||||
In addition to compilers, oneAPI contains many libraries. The ``hdf5``
|
Using oneAPI MPI to Satisfy a Virtual Dependence
|
||||||
package works with any compatible MPI implementation. To build
|
------------------------------------------------------
|
||||||
``hdf5`` with Intel oneAPI MPI do::
|
|
||||||
|
The ``hdf5`` package works with any compatible MPI implementation. To
|
||||||
|
build ``hdf5`` with Intel oneAPI MPI do::
|
||||||
|
|
||||||
spack install hdf5 +mpi ^intel-oneapi-mpi
|
spack install hdf5 +mpi ^intel-oneapi-mpi
|
||||||
|
|
||||||
@ -95,11 +101,23 @@ To use the compilers, add some information about the installation to
|
|||||||
spack compiler add /opt/intel/oneapi/compiler/latest/linux/bin
|
spack compiler add /opt/intel/oneapi/compiler/latest/linux/bin
|
||||||
|
|
||||||
Adapt the paths above if you did not install the tools in the default
|
Adapt the paths above if you did not install the tools in the default
|
||||||
location. After adding the compilers, using them in Spack will be
|
location. After adding the compilers, using them is the same
|
||||||
exactly the same as if you had installed the
|
as if you had installed the ``intel-oneapi-compilers`` package.
|
||||||
``intel-oneapi-compilers`` package. Another option is to manually add
|
Another option is to manually add the configuration to
|
||||||
the configuration to ``compilers.yaml`` as described in :ref:`Compiler
|
``compilers.yaml`` as described in :ref:`Compiler configuration
|
||||||
configuration <compiler-config>`.
|
<compiler-config>`.
|
||||||
|
|
||||||
|
Libraries
|
||||||
|
---------
|
||||||
|
|
||||||
|
If you want Spack to use MKL that you have installed without Spack in
|
||||||
|
the default location, then add the following to
|
||||||
|
``~/.spack/packages.yaml``, adjusting the version as appropriate::
|
||||||
|
|
||||||
|
intel-oneapi-mkl:
|
||||||
|
externals:
|
||||||
|
- spec: intel-oneapi-mkl@2021.1.1
|
||||||
|
prefix: /opt/intel/oneapi/
|
||||||
|
|
||||||
|
|
||||||
Using oneAPI Tools Installed by Spack
|
Using oneAPI Tools Installed by Spack
|
||||||
|
@ -8,13 +8,13 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from sys import platform
|
from sys import platform
|
||||||
from os.path import basename, dirname, isdir, join
|
from os.path import basename, dirname, isdir
|
||||||
|
|
||||||
from spack.package import Package
|
from spack.package import Package
|
||||||
from spack.util.environment import EnvironmentModifications
|
from spack.util.environment import EnvironmentModifications
|
||||||
from spack.util.executable import Executable
|
from spack.util.executable import Executable
|
||||||
|
|
||||||
from llnl.util.filesystem import find_headers, find_libraries
|
from llnl.util.filesystem import find_headers, find_libraries, join_path
|
||||||
|
|
||||||
|
|
||||||
class IntelOneApiPackage(Package):
|
class IntelOneApiPackage(Package):
|
||||||
@ -33,6 +33,11 @@ def component_dir(self):
|
|||||||
"""Subdirectory for this component in the install prefix."""
|
"""Subdirectory for this component in the install prefix."""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@property
|
||||||
|
def component_path(self):
|
||||||
|
"""Path to component <prefix>/<component>/<version>."""
|
||||||
|
return join_path(self.prefix, self.component_dir, str(self.spec.version))
|
||||||
|
|
||||||
def install(self, spec, prefix, installer_path=None):
|
def install(self, spec, prefix, installer_path=None):
|
||||||
"""Shared install method for all oneapi packages."""
|
"""Shared install method for all oneapi packages."""
|
||||||
|
|
||||||
@ -53,21 +58,20 @@ def install(self, spec, prefix, installer_path=None):
|
|||||||
'--install-dir', prefix)
|
'--install-dir', prefix)
|
||||||
|
|
||||||
# Some installers have a bug and do not return an error code when failing
|
# Some installers have a bug and do not return an error code when failing
|
||||||
if not isdir(join(prefix, self.component_dir)):
|
if not isdir(join_path(prefix, self.component_dir)):
|
||||||
raise RuntimeError('install failed')
|
raise RuntimeError('install failed')
|
||||||
|
|
||||||
def setup_run_environment(self, env):
|
def setup_run_environment(self, env):
|
||||||
|
|
||||||
"""Adds environment variables to the generated module file.
|
"""Adds environment variables to the generated module file.
|
||||||
|
|
||||||
These environment variables come from running:
|
These environment variables come from running:
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ source {prefix}/setvars.sh --force
|
$ source {prefix}/{component}/{version}/env/vars.sh
|
||||||
"""
|
"""
|
||||||
env.extend(EnvironmentModifications.from_sourcing_file(
|
env.extend(EnvironmentModifications.from_sourcing_file(
|
||||||
join(self.prefix, self.component_dir, 'latest/env/vars.sh')))
|
join_path(self.component_path, 'env', 'vars.sh')))
|
||||||
|
|
||||||
|
|
||||||
class IntelOneApiLibraryPackage(IntelOneApiPackage):
|
class IntelOneApiLibraryPackage(IntelOneApiPackage):
|
||||||
@ -75,12 +79,11 @@ class IntelOneApiLibraryPackage(IntelOneApiPackage):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def headers(self):
|
def headers(self):
|
||||||
include_path = '%s/%s/latest/include' % (
|
include_path = join_path(self.component_path, 'include')
|
||||||
self.prefix, self.component_dir)
|
|
||||||
return find_headers('*', include_path, recursive=True)
|
return find_headers('*', include_path, recursive=True)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def libs(self):
|
def libs(self):
|
||||||
lib_path = '%s/%s/latest/lib/intel64' % (self.prefix, self.component_dir)
|
lib_path = join_path(self.component_path, 'lib', 'intel64')
|
||||||
lib_path = lib_path if isdir(lib_path) else dirname(lib_path)
|
lib_path = lib_path if isdir(lib_path) else dirname(lib_path)
|
||||||
return find_libraries('*', root=lib_path, shared=True, recursive=True)
|
return find_libraries('*', root=lib_path, shared=True, recursive=True)
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
|
|
||||||
import glob
|
import glob
|
||||||
import subprocess
|
|
||||||
from os import path
|
from os import path
|
||||||
|
import subprocess
|
||||||
from sys import platform
|
from sys import platform
|
||||||
|
|
||||||
from spack import *
|
from spack import *
|
||||||
@ -36,19 +36,16 @@ class IntelOneapiCompilers(IntelOneApiPackage):
|
|||||||
def component_dir(self):
|
def component_dir(self):
|
||||||
return 'compiler'
|
return 'compiler'
|
||||||
|
|
||||||
def _join_prefix(self, p):
|
|
||||||
return path.join(self.prefix, 'compiler', 'latest', 'linux', p)
|
|
||||||
|
|
||||||
def _ld_library_path(self):
|
def _ld_library_path(self):
|
||||||
dirs = ['lib',
|
dirs = ['lib',
|
||||||
path.join('lib', 'x64'),
|
join_path('lib', 'x64'),
|
||||||
path.join('lib', 'emu'),
|
join_path('lib', 'emu'),
|
||||||
path.join('lib', 'oclfpga', 'host', 'linux64', 'lib'),
|
join_path('lib', 'oclfpga', 'host', 'linux64', 'lib'),
|
||||||
path.join('lib', 'oclfpga', 'linux64', 'lib'),
|
join_path('lib', 'oclfpga', 'linux64', 'lib'),
|
||||||
path.join('compiler', 'lib', 'intel64_lin'),
|
join_path('compiler', 'lib', 'intel64_lin'),
|
||||||
path.join('compiler', 'lib')]
|
join_path('compiler', 'lib')]
|
||||||
for dir in dirs:
|
for dir in dirs:
|
||||||
yield self._join_prefix(dir)
|
yield join_path(self.component_path, 'linux', dir)
|
||||||
|
|
||||||
def install(self, spec, prefix):
|
def install(self, spec, prefix):
|
||||||
# install cpp
|
# install cpp
|
||||||
@ -60,22 +57,23 @@ def install(self, spec, prefix):
|
|||||||
super(IntelOneapiCompilers, self).install(
|
super(IntelOneapiCompilers, self).install(
|
||||||
spec,
|
spec,
|
||||||
prefix,
|
prefix,
|
||||||
installer_path=glob.glob(path.join('fortran-installer', '*'))[0])
|
installer_path=glob.glob(join_path('fortran-installer', '*'))[0])
|
||||||
|
|
||||||
# Some installers have a bug and do not return an error code when failing
|
# Some installers have a bug and do not return an error code when failing
|
||||||
if not path.isfile(path.join(prefix, 'compiler', 'latest', 'linux',
|
if not path.isfile(join_path(self.component_path, 'linux',
|
||||||
'bin', 'intel64', 'ifort')):
|
'bin', 'intel64', 'ifort')):
|
||||||
raise RuntimeError('install failed')
|
raise RuntimeError('install failed')
|
||||||
|
|
||||||
# set rpath so 'spack compiler add' can check version strings
|
# set rpath so 'spack compiler add' can check version strings
|
||||||
# without setting LD_LIBRARY_PATH
|
# without setting LD_LIBRARY_PATH
|
||||||
rpath = ':'.join(self._ld_library_path())
|
rpath = ':'.join(self._ld_library_path())
|
||||||
patch_dirs = [path.join('compiler', 'lib', 'intel64_lin'),
|
patch_dirs = [join_path('compiler', 'lib', 'intel64_lin'),
|
||||||
path.join('compiler', 'lib', 'intel64'),
|
join_path('compiler', 'lib', 'intel64'),
|
||||||
'bin']
|
'bin']
|
||||||
for pd in patch_dirs:
|
for pd in patch_dirs:
|
||||||
patchables = glob.glob(self._join_prefix(path.join(pd, '*')))
|
patchables = glob.glob(join_path(self.component_path, 'linux', pd, '*'))
|
||||||
patchables.append(self._join_prefix(path.join('lib', 'icx-lto.so')))
|
patchables.append(join_path(self.component_path,
|
||||||
|
'linux', 'lib', 'icx-lto.so'))
|
||||||
for file in patchables:
|
for file in patchables:
|
||||||
# Try to patch all files, patchelf will do nothing if
|
# Try to patch all files, patchelf will do nothing if
|
||||||
# file should not be patched
|
# file should not be patched
|
||||||
|
@ -36,6 +36,8 @@ def component_dir(self):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def libs(self):
|
def libs(self):
|
||||||
lib_path = '{0}/{1}/latest/lib/intel64'.format(self.prefix, self.component_dir)
|
lib_path = join_path(self.component_path, 'lib', 'intel64')
|
||||||
mkl_libs = ['libmkl_intel_ilp64', 'libmkl_sequential', 'libmkl_core']
|
mkl_libs = ['libmkl_intel_lp64', 'libmkl_sequential', 'libmkl_core']
|
||||||
return find_libraries(mkl_libs, root=lib_path, shared=True, recursive=False)
|
libs = find_libraries(mkl_libs, root=lib_path, shared=True, recursive=False)
|
||||||
|
libs += find_system_libraries(['libpthread', 'libm', 'libdl'], shared=True)
|
||||||
|
return libs
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
|
|
||||||
|
|
||||||
from os import path
|
|
||||||
import subprocess
|
import subprocess
|
||||||
from sys import platform
|
from sys import platform
|
||||||
|
|
||||||
@ -34,7 +33,7 @@ def component_dir(self):
|
|||||||
return 'mpi'
|
return 'mpi'
|
||||||
|
|
||||||
def setup_dependent_package(self, module, dep_spec):
|
def setup_dependent_package(self, module, dep_spec):
|
||||||
dir = join_path(self.prefix, 'mpi', 'latest', 'bin')
|
dir = join_path(self.component_path, 'bin')
|
||||||
self.spec.mpicc = join_path(dir, 'mpicc')
|
self.spec.mpicc = join_path(dir, 'mpicc')
|
||||||
self.spec.mpicxx = join_path(dir, 'mpicxx')
|
self.spec.mpicxx = join_path(dir, 'mpicxx')
|
||||||
self.spec.mpif77 = join_path(dir, 'mpif77')
|
self.spec.mpif77 = join_path(dir, 'mpif77')
|
||||||
@ -48,7 +47,7 @@ def setup_dependent_build_environment(self, env, dependent_spec):
|
|||||||
env.set('MPICH_FC', spack_fc)
|
env.set('MPICH_FC', spack_fc)
|
||||||
|
|
||||||
# Set compiler wrappers for dependent build stage
|
# Set compiler wrappers for dependent build stage
|
||||||
dir = self._join_prefix('bin')
|
dir = join_path(self.component_path, 'bin')
|
||||||
env.set('MPICC', join_path(dir, 'mpicc'))
|
env.set('MPICC', join_path(dir, 'mpicc'))
|
||||||
env.set('MPICXX', join_path(dir, 'mpicxx'))
|
env.set('MPICXX', join_path(dir, 'mpicxx'))
|
||||||
env.set('MPIF77', join_path(dir, 'mpif77'))
|
env.set('MPIF77', join_path(dir, 'mpif77'))
|
||||||
@ -58,22 +57,19 @@ def setup_dependent_build_environment(self, env, dependent_spec):
|
|||||||
@property
|
@property
|
||||||
def libs(self):
|
def libs(self):
|
||||||
libs = []
|
libs = []
|
||||||
for dir in [path.join('lib', 'release_mt'),
|
for dir in [join_path('lib', 'release_mt'),
|
||||||
'lib',
|
'lib',
|
||||||
path.join('libfabric', 'lib')]:
|
join_path('libfabric', 'lib')]:
|
||||||
lib_path = path.join(self.prefix, 'mpi', 'latest', dir)
|
lib_path = join_path(self.component_path, dir)
|
||||||
ldir = find_libraries('*', root=lib_path, shared=True, recursive=False)
|
ldir = find_libraries('*', root=lib_path, shared=True, recursive=False)
|
||||||
libs += ldir
|
libs += ldir
|
||||||
return libs
|
return libs
|
||||||
|
|
||||||
def _join_prefix(self, path):
|
|
||||||
return join_path(self.prefix, 'mpi', 'latest', path)
|
|
||||||
|
|
||||||
def install(self, spec, prefix):
|
def install(self, spec, prefix):
|
||||||
super(IntelOneapiMpi, self).install(spec, prefix)
|
super(IntelOneapiMpi, self).install(spec, prefix)
|
||||||
|
|
||||||
# need to patch libmpi.so so it can always find libfabric
|
# need to patch libmpi.so so it can always find libfabric
|
||||||
libfabric_rpath = self._join_prefix(path.join('libfabric', 'lib'))
|
libfabric_rpath = join_path(self.component_path, 'libfabric', 'lib')
|
||||||
for lib_version in ['debug', 'release', 'release_mt', 'debug_mt']:
|
for lib_version in ['debug', 'release', 'release_mt', 'debug_mt']:
|
||||||
file = self._join_prefix(path.join('lib', lib_version, 'libmpi.so'))
|
file = join_path(self.component_path, 'lib', lib_version, 'libmpi.so')
|
||||||
subprocess.call(['patchelf', '--set-rpath', libfabric_rpath, file])
|
subprocess.call(['patchelf', '--set-rpath', libfabric_rpath, file])
|
||||||
|
Loading…
Reference in New Issue
Block a user