Fix HPL build, convert to MakefilePackage (#3777)

* Fix HPL build, convert to MakefilePackage

* Flake8 fix

* Fix: spec -> self.spec

* Properly query for system libraries

* Update Intel-MKL as well

* Recurse in system libs, fix MKL path, fixes lapack_libs
This commit is contained in:
Adam J. Stewart 2017-04-21 12:11:29 -05:00 committed by GitHub
parent 41efada340
commit 5250e8ee89
4 changed files with 118 additions and 41 deletions

View File

@ -47,6 +47,7 @@
'copy_mode', 'copy_mode',
'filter_file', 'filter_file',
'find_libraries', 'find_libraries',
'find_system_libraries',
'fix_darwin_install_name', 'fix_darwin_install_name',
'force_remove', 'force_remove',
'force_symlink', 'force_symlink',
@ -583,6 +584,54 @@ def __str__(self):
return self.joined() return self.joined()
def find_system_libraries(args, shared=True):
"""Searches the usual system library locations for the libraries
specified in args.
Search order is as follows:
1. /lib64
2. /lib
3. /usr/lib64
4. /usr/lib
5. /usr/local/lib64
6. /usr/local/lib
:param args: Library name(s) to search for
:type args: str or collections.Sequence
:param bool shared: if True searches for shared libraries,
:returns: The libraries that have been found
:rtype: LibraryList
"""
if isinstance(args, str):
args = [args]
elif not isinstance(args, collections.Sequence):
message = '{0} expects a string or sequence of strings as the '
message += 'first argument [got {1} instead]'
message = message.format(find_system_libraries.__name__, type(args))
raise TypeError(message)
libraries_found = []
search_locations = [
'/lib64',
'/lib',
'/usr/lib64',
'/usr/lib',
'/usr/local/lib64',
'/usr/local/lib',
]
for library in args:
for root in search_locations:
result = find_libraries(library, root, shared, recurse=True)
if result:
libraries_found += result
break
return libraries_found
def find_libraries(args, root, shared=True, recurse=False): def find_libraries(args, root, shared=True, recurse=False):
"""Returns an iterable object containing a list of full paths to """Returns an iterable object containing a list of full paths to
libraries if found. libraries if found.

View File

@ -27,7 +27,7 @@
import platform import platform
class Hpl(Package): class Hpl(MakefilePackage):
"""HPL is a software package that solves a (random) dense linear system """HPL is a software package that solves a (random) dense linear system
in double precision (64 bits) arithmetic on distributed-memory computers. in double precision (64 bits) arithmetic on distributed-memory computers.
It can thus be regarded as a portable as well as freely available It can thus be regarded as a portable as well as freely available
@ -45,7 +45,11 @@ class Hpl(Package):
parallel = False parallel = False
def configure(self, spec, arch): arch = '{0}-{1}'.format(platform.system(), platform.processor())
build_targets = ['arch={0}'.format(arch)]
def edit(self, spec, prefix):
# List of configuration options # List of configuration options
# Order is important # Order is important
config = [] config = []
@ -66,7 +70,7 @@ def configure(self, spec, arch):
'RM = /bin/rm -f', 'RM = /bin/rm -f',
'TOUCH = touch', 'TOUCH = touch',
# Platform identifier # Platform identifier
'ARCH = {0}'.format(arch), 'ARCH = {0}'.format(self.arch),
# HPL Directory Structure / HPL library # HPL Directory Structure / HPL library
'TOPdir = {0}'.format(os.getcwd()), 'TOPdir = {0}'.format(os.getcwd()),
'INCdir = $(TOPdir)/include', 'INCdir = $(TOPdir)/include',
@ -74,7 +78,7 @@ def configure(self, spec, arch):
'LIBdir = $(TOPdir)/lib/$(ARCH)', 'LIBdir = $(TOPdir)/lib/$(ARCH)',
'HPLlib = $(LIBdir)/libhpl.a', 'HPLlib = $(LIBdir)/libhpl.a',
# Message Passing library (MPI) # Message Passing library (MPI)
'MPinc = -I{0}'.format(spec['mpi'].prefix.include), 'MPinc = {0}'.format(spec['mpi'].prefix.include),
'MPlib = -L{0}'.format(spec['mpi'].prefix.lib), 'MPlib = -L{0}'.format(spec['mpi'].prefix.lib),
# Linear Algebra library (BLAS or VSIPL) # Linear Algebra library (BLAS or VSIPL)
'LAinc = {0}'.format(spec['blas'].prefix.include), 'LAinc = {0}'.format(spec['blas'].prefix.include),
@ -99,21 +103,13 @@ def configure(self, spec, arch):
]) ])
# Write configuration options to include file # Write configuration options to include file
with open('Make.{0}'.format(arch), 'w') as makefile: with open('Make.{0}'.format(self.arch), 'w') as makefile:
for var in config: for var in config:
makefile.write('{0}\n'.format(var)) makefile.write('{0}\n'.format(var))
def install(self, spec, prefix): def install(self, spec, prefix):
# Arch used for file naming purposes only
arch = '{0}-{1}'.format(platform.system(), platform.processor())
# Generate Makefile include
self.configure(spec, arch)
make('arch={0}'.format(arch))
# Manual installation # Manual installation
install_tree(join_path('bin', arch), prefix.bin) install_tree(join_path('bin', self.arch), prefix.bin)
install_tree(join_path('lib', arch), prefix.lib) install_tree(join_path('lib', self.arch), prefix.lib)
install_tree(join_path('include', arch), prefix.include) install_tree(join_path('include', self.arch), prefix.include)
install_tree('man', prefix.man) install_tree('man', prefix.man)

View File

@ -54,28 +54,44 @@ class IntelMkl(IntelInstaller):
@property @property
def blas_libs(self): def blas_libs(self):
shared = True if '+shared' in self.spec else False spec = self.spec
suffix = dso_suffix if '+shared' in self.spec else 'a' prefix = self.prefix
mkl_integer = ['libmkl_intel_ilp64'] if '+ilp64' in self.spec else ['libmkl_intel_lp64'] # NOQA: ignore=E501 shared = '+shared' in spec
if '+ilp64' in spec:
mkl_integer = ['libmkl_intel_ilp64']
else:
mkl_integer = ['libmkl_intel_lp64']
mkl_threading = ['libmkl_sequential'] mkl_threading = ['libmkl_sequential']
if '+openmp' in self.spec:
mkl_threading = ['libmkl_intel_thread', 'libiomp5'] if '%intel' in self.spec else ['libmkl_gnu_thread'] # NOQA: ignore=E501 if '+openmp' in spec:
if '%intel' in spec:
mkl_threading = ['libmkl_intel_thread', 'libiomp5']
else:
mkl_threading = ['libmkl_gnu_thread']
# TODO: TBB threading: ['libmkl_tbb_thread', 'libtbb', 'libstdc++'] # TODO: TBB threading: ['libmkl_tbb_thread', 'libtbb', 'libstdc++']
mkl_root = join_path(prefix.lib, 'intel64')
mkl_libs = find_libraries( mkl_libs = find_libraries(
mkl_integer + ['libmkl_core'] + mkl_threading, mkl_integer + ['libmkl_core'] + mkl_threading,
root=join_path(self.prefix.lib, 'intel64'), root=mkl_root,
shared=shared shared=shared
) )
system_libs = [
'libpthread.{0}'.format(suffix), # Intel MKL link line advisor recommends these system libraries
'libm.{0}'.format(suffix), system_libs = find_system_libraries(
'libdl.{0}'.format(suffix) ['libpthread', 'libm', 'libdl'],
] shared=shared
)
return mkl_libs + system_libs return mkl_libs + system_libs
@property @property
def lapack_libs(self): def lapack_libs(self):
return self.libs return self.blas_libs
@property @property
def scalapack_libs(self): def scalapack_libs(self):

View File

@ -96,7 +96,7 @@ class IntelParallelStudio(IntelInstaller):
variant('ilp64', default=False, description='64 bit integers') variant('ilp64', default=False, description='64 bit integers')
variant('openmp', default=False, description='OpenMP multithreading layer') variant('openmp', default=False, description='OpenMP multithreading layer')
provides('mpi', when='@cluster:+mpi') provides('mpi', when='@cluster.0:cluster.9999+mpi')
provides('mkl', when='+mkl') provides('mkl', when='+mkl')
provides('daal', when='+daal') provides('daal', when='+daal')
provides('ipp', when='+ipp') provides('ipp', when='+ipp')
@ -108,28 +108,44 @@ class IntelParallelStudio(IntelInstaller):
@property @property
def blas_libs(self): def blas_libs(self):
shared = True if '+shared' in self.spec else False spec = self.spec
suffix = dso_suffix if '+shared' in self.spec else 'a' prefix = self.prefix
mkl_integer = ['libmkl_intel_ilp64'] if '+ilp64' in self.spec else ['libmkl_intel_lp64'] # NOQA: ignore=E501 shared = '+shared' in spec
if '+ilp64' in spec:
mkl_integer = ['libmkl_intel_ilp64']
else:
mkl_integer = ['libmkl_intel_lp64']
mkl_threading = ['libmkl_sequential'] mkl_threading = ['libmkl_sequential']
if '+openmp' in self.spec:
mkl_threading = ['libmkl_intel_thread', 'libiomp5'] if '%intel' in self.spec else ['libmkl_gnu_thread'] # NOQA: ignore=E501 if '+openmp' in spec:
if '%intel' in spec:
mkl_threading = ['libmkl_intel_thread', 'libiomp5']
else:
mkl_threading = ['libmkl_gnu_thread']
# TODO: TBB threading: ['libmkl_tbb_thread', 'libtbb', 'libstdc++'] # TODO: TBB threading: ['libmkl_tbb_thread', 'libtbb', 'libstdc++']
mkl_root = join_path(prefix, 'mkl', 'lib', 'intel64')
mkl_libs = find_libraries( mkl_libs = find_libraries(
mkl_integer + ['libmkl_core'] + mkl_threading, mkl_integer + ['libmkl_core'] + mkl_threading,
root=join_path(self.prefix, 'mkl', 'lib', 'intel64'), root=mkl_root,
shared=shared shared=shared
) )
system_libs = [
'libpthread.{0}'.format(suffix), # Intel MKL link line advisor recommends these system libraries
'libm.{0}'.format(suffix), system_libs = find_system_libraries(
'libdl.{0}'.format(suffix) ['libpthread', 'libm', 'libdl'],
] shared=shared
)
return mkl_libs + system_libs return mkl_libs + system_libs
@property @property
def lapack_libs(self): def lapack_libs(self):
return self.libs return self.blas_libs
@property @property
def scalapack_libs(self): def scalapack_libs(self):