From d848559f70ad67842150b51d2792843f3cce4621 Mon Sep 17 00:00:00 2001 From: Massimiliano Culpo Date: Wed, 21 Sep 2016 21:27:59 +0200 Subject: Reworking of `lapack_shared_libs` and similar properties (#1682) * Turned _libs into an iterable Modifications : - added class LibraryList + unit tests - added convenience functions `find_libraries` and `dedupe` - modifed non Intel blas/lapack providers - modified packages using blas_shared_libs and similar functions * atlas : added pthread variant * intel packages : added lapack_libs and blas_libs * find_library_path : removed unused function * PR review : fixed last issues * LibraryList : added test on __add__ return type * LibraryList : added __radd__ fixed unit tests fix : failing unit tests due to missing `self` * cp2k and dependecies : fixed blas-lapack related statements in package.py --- .../repos/builtin/packages/armadillo/package.py | 14 ++++--- .../repos/builtin/packages/arpack-ng/package.py | 34 ++++++--------- var/spack/repos/builtin/packages/atlas/package.py | 36 +++++++++++----- var/spack/repos/builtin/packages/cp2k/package.py | 25 +++++------ var/spack/repos/builtin/packages/dealii/package.py | 5 +-- var/spack/repos/builtin/packages/elk/package.py | 6 +-- var/spack/repos/builtin/packages/gmsh/package.py | 6 +-- var/spack/repos/builtin/packages/hpl/package.py | 2 +- var/spack/repos/builtin/packages/hypre/package.py | 9 ++-- .../packages/intel-parallel-studio/package.py | 44 ++++++++++++-------- var/spack/repos/builtin/packages/mkl/package.py | 48 +++++++++++++--------- var/spack/repos/builtin/packages/mumps/package.py | 8 ++-- .../builtin/packages/netlib-lapack/package.py | 29 +++++++------ .../builtin/packages/netlib-scalapack/package.py | 46 +++++++++++---------- var/spack/repos/builtin/packages/nwchem/package.py | 13 +++--- .../repos/builtin/packages/octopus/package.py | 8 ++-- .../repos/builtin/packages/openblas/package.py | 31 +++++++------- var/spack/repos/builtin/packages/opium/package.py | 10 ++--- var/spack/repos/builtin/packages/pexsi/package.py | 4 +- var/spack/repos/builtin/packages/psi4/package.py | 11 ++--- .../repos/builtin/packages/py-scipy/package.py | 4 +- .../repos/builtin/packages/suite-sparse/package.py | 4 +- .../repos/builtin/packages/sundials/package.py | 10 ++--- .../repos/builtin/packages/superlu-dist/package.py | 5 +-- .../repos/builtin/packages/superlu/package.py | 2 +- .../repos/builtin/packages/trilinos/package.py | 8 ++-- .../repos/builtin/packages/wannier90/package.py | 7 ++-- 27 files changed, 223 insertions(+), 206 deletions(-) (limited to 'var') diff --git a/var/spack/repos/builtin/packages/armadillo/package.py b/var/spack/repos/builtin/packages/armadillo/package.py index 4356f60aca..fdd682f5e5 100644 --- a/var/spack/repos/builtin/packages/armadillo/package.py +++ b/var/spack/repos/builtin/packages/armadillo/package.py @@ -46,18 +46,20 @@ class Armadillo(Package): depends_on('hdf5', when='+hdf5') def install(self, spec, prefix): + arpack = find_libraries(['libarpack'], root=spec[ + 'arpack-ng'].prefix.lib, shared=True) + superlu = find_libraries(['libsuperlu'], root=spec[ + 'superlu'].prefix, shared=False, recurse=True) cmake_args = [ # ARPACK support - '-DARPACK_LIBRARY={0}/libarpack.{1}'.format( - spec['arpack-ng'].prefix.lib, dso_suffix), + '-DARPACK_LIBRARY={0}'.format(arpack.joined()), # BLAS support - '-DBLAS_LIBRARY={0}'.format(spec['blas'].blas_shared_lib), + '-DBLAS_LIBRARY={0}'.format(spec['blas'].blas_libs.joined()), # LAPACK support - '-DLAPACK_LIBRARY={0}'.format(spec['lapack'].lapack_shared_lib), + '-DLAPACK_LIBRARY={0}'.format(spec['lapack'].lapack_libs.joined()), # SuperLU support '-DSuperLU_INCLUDE_DIR={0}'.format(spec['superlu'].prefix.include), - '-DSuperLU_LIBRARY={0}/libsuperlu.a'.format( - spec['superlu'].prefix.lib64), + '-DSuperLU_LIBRARY={0}'.format(superlu.joined()), # HDF5 support '-DDETECT_HDF5={0}'.format('ON' if '+hdf5' in spec else 'OFF') ] diff --git a/var/spack/repos/builtin/packages/arpack-ng/package.py b/var/spack/repos/builtin/packages/arpack-ng/package.py index 0e71125d41..7f92bc1950 100644 --- a/var/spack/repos/builtin/packages/arpack-ng/package.py +++ b/var/spack/repos/builtin/packages/arpack-ng/package.py @@ -88,17 +88,16 @@ class ArpackNg(Package): options.append('-DCMAKE_INSTALL_NAME_DIR:PATH=%s/lib' % prefix) # Make sure we use Spack's blas/lapack: + lapack_libs = spec['lapack'].lapack_libs.joined() + blas_libs = spec['blas'].blas_libs.joined() + options.extend([ '-DLAPACK_FOUND=true', - '-DLAPACK_INCLUDE_DIRS=%s' % spec['lapack'].prefix.include, - '-DLAPACK_LIBRARIES=%s' % ( - spec['lapack'].lapack_shared_lib if '+shared' in spec else - spec['lapack'].lapack_static_lib), + '-DLAPACK_INCLUDE_DIRS={0}'.format(spec['lapack'].prefix.include), + '-DLAPACK_LIBRARIES={0}'.format(lapack_libs), '-DBLAS_FOUND=true', - '-DBLAS_INCLUDE_DIRS=%s' % spec['blas'].prefix.include, - '-DBLAS_LIBRARIES=%s' % ( - spec['blas'].blas_shared_lib if '+shared' in spec else - spec['blas'].blas_static_lib) + '-DBLAS_INCLUDE_DIRS={0}'.format(spec['blas'].prefix.include), + '-DBLAS_LIBRARIES={0}'.format(blas_libs) ]) if '+mpi' in spec: @@ -129,19 +128,12 @@ class ArpackNg(Package): 'F77=%s' % spec['mpi'].mpif77 ]) - if '+shared' in spec: - options.extend([ - '--with-blas=%s' % to_link_flags( - spec['blas'].blas_shared_lib), - '--with-lapack=%s' % to_link_flags( - spec['lapack'].lapack_shared_lib) - ]) - else: - options.extend([ - '--with-blas=%s' % spec['blas'].blas_static_lib, - '--with-lapack=%s' % spec['lapack'].lapack_static_lib, - '--enable-shared=no' - ]) + options.extend([ + '--with-blas={0}'.format(spec['blas'].blas_libs.ld_flags), + '--with-lapack={0}'.format(spec['lapack'].lapack_libs.ld_flags) + ]) + if '+shared' not in spec: + options.append('--enable-shared=no') bootstrap() configure(*options) diff --git a/var/spack/repos/builtin/packages/atlas/package.py b/var/spack/repos/builtin/packages/atlas/package.py index f9d5da6166..e1914aac98 100644 --- a/var/spack/repos/builtin/packages/atlas/package.py +++ b/var/spack/repos/builtin/packages/atlas/package.py @@ -51,6 +51,7 @@ class Atlas(Package): url='http://sourceforge.net/projects/math-atlas/files/Developer%20%28unstable%29/3.11.34/atlas3.11.34.tar.bz2') variant('shared', default=True, description='Builds shared library') + variant('pthread', default=False, description='Use multithreaded libraries') provides('blas') provides('lapack') @@ -107,18 +108,32 @@ class Atlas(Package): make("install") self.install_test() - def setup_dependent_package(self, module, dspec): + @property + def blas_libs(self): # libsatlas.[so,dylib,dll ] contains all serial APIs (serial lapack, # serial BLAS), and all ATLAS symbols needed to support them. Whereas # libtatlas.[so,dylib,dll ] is parallel (multithreaded) version. - name = 'libsatlas.%s' % dso_suffix - libdir = find_library_path(name, - self.prefix.lib64, - self.prefix.lib) - + is_threaded = '+pthread' in self.spec if '+shared' in self.spec: - self.spec.blas_shared_lib = join_path(libdir, name) - self.spec.lapack_shared_lib = self.spec.blas_shared_lib + to_find = ['libtatlas'] if is_threaded else ['libsatlas'] + shared = True + else: + interfaces = [ + 'libptcblas', + 'libptf77blas' + ] if is_threaded else [ + 'libcblas', + 'libf77blas' + ] + to_find = ['liblapack'] + interfaces + ['libatlas'] + shared = False + return find_libraries( + to_find, root=self.prefix, shared=shared, recurse=True + ) + + @property + def lapack_libs(self): + return self.blas_libs def install_test(self): source_file = join_path(os.path.dirname(self.module.__file__), @@ -126,9 +141,8 @@ class Atlas(Package): blessed_file = join_path(os.path.dirname(self.module.__file__), 'test_cblas_dgemm.output') - include_flags = ["-I%s" % join_path(self.spec.prefix, "include")] - link_flags = ["-L%s" % join_path(self.spec.prefix, "lib"), - "-lsatlas"] + include_flags = ["-I%s" % self.spec.prefix.include] + link_flags = self.lapack_libs.ld_flags output = compile_c_and_execute(source_file, include_flags, link_flags) compare_output_file(output, blessed_file) diff --git a/var/spack/repos/builtin/packages/cp2k/package.py b/var/spack/repos/builtin/packages/cp2k/package.py index 785de08d34..15606cd80a 100644 --- a/var/spack/repos/builtin/packages/cp2k/package.py +++ b/var/spack/repos/builtin/packages/cp2k/package.py @@ -95,7 +95,8 @@ class Cp2k(Package): fcflags.extend([ '-I' + spec['fftw'].prefix.include ]) - ldflags = ['-L' + spec['fftw'].prefix.lib] + fftw = find_libraries(['libfftw3'], root=spec['fftw'].prefix.lib) + ldflags = [fftw.search_flags] libs = [] if '+plumed' in self.spec: # Include Plumed.inc in the Makefile @@ -157,9 +158,8 @@ class Cp2k(Package): ), '-I' + join_path(spec['pexsi'].prefix, 'fortran') ]) - ldflags.extend([ - '-L' + spec['scalapack'].prefix.lib - ]) + scalapack = spec['scalapack'].scalapack_libs + ldflags.append(scalapack.search_flags) libs.extend([ join_path(spec['elpa'].prefix.lib, 'libelpa.{0}'.format(dso_suffix)), @@ -176,20 +176,15 @@ class Cp2k(Package): 'libmetis.{0}'.format(dso_suffix) ), ]) - libs.extend(spec['scalapack'].scalapack_shared_libs) + libs.extend(scalapack) libs.extend(self.spec['mpi'].mpicxx_shared_libs) libs.extend(self.compiler.stdcxx_libs) # LAPACK / BLAS - ldflags.extend([ - '-L' + spec['lapack'].prefix.lib, - '-L' + spec['blas'].prefix.lib - ]) - libs.extend([ - join_path(spec['fftw'].prefix.lib, - 'libfftw3.{0}'.format(dso_suffix)), - spec['lapack'].lapack_shared_lib, - spec['blas'].blas_shared_lib - ]) + lapack = spec['lapack'].lapack_libs + blas = spec['blas'].blas_libs + + ldflags.append((lapack + blas).search_flags) + libs.extend([str(x) for x in (fftw, lapack, blas)]) # Write compiler flags to file mkf.write('CPPFLAGS = {0}\n'.format(' '.join(cppflags))) diff --git a/var/spack/repos/builtin/packages/dealii/package.py b/var/spack/repos/builtin/packages/dealii/package.py index 9e8c639128..89732f98b8 100644 --- a/var/spack/repos/builtin/packages/dealii/package.py +++ b/var/spack/repos/builtin/packages/dealii/package.py @@ -123,6 +123,7 @@ class Dealii(Package): options.remove(word) dsuf = 'dylib' if sys.platform == 'darwin' else 'so' + lapack_blas = spec['lapack'].lapack_libs + spec['blas'].blas_libs options.extend([ '-DCMAKE_BUILD_TYPE=DebugRelease', '-DDEAL_II_COMPONENT_EXAMPLES=ON', @@ -135,9 +136,7 @@ class Dealii(Package): '-DLAPACK_FOUND=true', '-DLAPACK_INCLUDE_DIRS=%s;%s' % ( spec['lapack'].prefix.include, spec['blas'].prefix.include), - '-DLAPACK_LIBRARIES=%s;%s' % ( - spec['lapack'].lapack_shared_lib, - spec['blas'].blas_shared_lib), + '-DLAPACK_LIBRARIES=%s' % lapack_blas.joined(';'), '-DMUPARSER_DIR=%s' % spec['muparser'].prefix, '-DUMFPACK_DIR=%s' % spec['suite-sparse'].prefix, '-DTBB_DIR=%s' % spec['tbb'].prefix, diff --git a/var/spack/repos/builtin/packages/elk/package.py b/var/spack/repos/builtin/packages/elk/package.py index b089e585dd..acaf863935 100644 --- a/var/spack/repos/builtin/packages/elk/package.py +++ b/var/spack/repos/builtin/packages/elk/package.py @@ -87,12 +87,12 @@ class Elk(Package): # BLAS/LAPACK support # Note: BLAS/LAPACK must be compiled with OpenMP support # if the +openmp variant is chosen - blas = 'blas.a' + blas = 'blas.a' lapack = 'lapack.a' if '+blas' in spec: - blas = spec['blas'].blas_shared_lib + blas = spec['blas'].blas_libs.joined() if '+lapack' in spec: - lapack = spec['lapack'].lapack_shared_lib + lapack = spec['lapack'].lapack_libs.joined() # lapack must come before blas config['LIB_LPK'] = ' '.join([lapack, blas]) diff --git a/var/spack/repos/builtin/packages/gmsh/package.py b/var/spack/repos/builtin/packages/gmsh/package.py index 1d375f2186..dd142866e5 100644 --- a/var/spack/repos/builtin/packages/gmsh/package.py +++ b/var/spack/repos/builtin/packages/gmsh/package.py @@ -87,9 +87,9 @@ class Gmsh(Package): options.append('-DENABLE_OS_SPECIFIC_INSTALL=OFF') # Make sure GMSH picks up correct BlasLapack by providing linker flags - options.append('-DBLAS_LAPACK_LIBRARIES=%s %s' % - (to_link_flags(spec['lapack'].lapack_shared_lib), - to_link_flags(spec['blas'].blas_shared_lib))) + blas_lapack = spec['lapack'].lapack_libs + spec['blas'].blas_libs + options.append( + '-DBLAS_LAPACK_LIBRARIES={0}'.format(blas_lapack.ld_flags)) # Gmsh does not have an option to compile against external metis. # Its own Metis, however, fails to build diff --git a/var/spack/repos/builtin/packages/hpl/package.py b/var/spack/repos/builtin/packages/hpl/package.py index efd5c8bb1d..fa0013de17 100644 --- a/var/spack/repos/builtin/packages/hpl/package.py +++ b/var/spack/repos/builtin/packages/hpl/package.py @@ -78,7 +78,7 @@ class Hpl(Package): 'MPlib = -L{0}'.format(spec['mpi'].prefix.lib), # Linear Algebra library (BLAS or VSIPL) 'LAinc = {0}'.format(spec['blas'].prefix.include), - 'LAlib = {0}'.format(spec['blas'].blas_shared_lib), + 'LAlib = {0}'.format(spec['blas'].blas_libs.joined()), # F77 / C interface 'F2CDEFS = -DAdd_ -DF77_INTEGER=int -DStringSunStyle', # HPL includes / libraries / specifics diff --git a/var/spack/repos/builtin/packages/hypre/package.py b/var/spack/repos/builtin/packages/hypre/package.py index fdc236dcf4..96ed8411dd 100644 --- a/var/spack/repos/builtin/packages/hypre/package.py +++ b/var/spack/repos/builtin/packages/hypre/package.py @@ -60,13 +60,14 @@ class Hypre(Package): # to command the linker to include whole static libs' content into the # shared lib # Note: --with-(lapack|blas)_libs= needs space separated list of names + lapack = spec['lapack'].lapack_libs + blas = spec['blas'].blas_libs + configure_args = [ '--prefix=%s' % prefix, - '--with-lapack-libs=%s' % to_lib_name( - spec['lapack'].lapack_shared_lib), + '--with-lapack-libs=%s' % lapack.names, '--with-lapack-lib-dirs=%s' % spec['lapack'].prefix.lib, - '--with-blas-libs=%s' % to_lib_name( - spec['blas'].blas_shared_lib), + '--with-blas-libs=%s' % blas.names, '--with-blas-lib-dirs=%s' % spec['blas'].prefix.lib ] diff --git a/var/spack/repos/builtin/packages/intel-parallel-studio/package.py b/var/spack/repos/builtin/packages/intel-parallel-studio/package.py index 65db3351a1..74bdba455f 100644 --- a/var/spack/repos/builtin/packages/intel-parallel-studio/package.py +++ b/var/spack/repos/builtin/packages/intel-parallel-studio/package.py @@ -45,6 +45,10 @@ class IntelParallelStudio(IntelInstaller): variant('tools', default=True, description="Install the Intel Advisor, " "VTune Amplifier, and Inspector tools") + variant('shared', default=True, description='Builds shared library') + variant('ilp64', default=False, description='64 bit integers') + variant('openmp', default=False, description='OpenMP multithreading layer') + provides('mpi', when='@cluster:+mpi') provides('mkl', when='+mkl') provides('daal', when='+daal') @@ -55,6 +59,28 @@ class IntelParallelStudio(IntelInstaller): provides('lapack', when='+mkl') # TODO: MKL also provides implementation of Scalapack. + @property + def blas_libs(self): + shared = True if '+shared' in self.spec else False + suffix = dso_suffix if '+shared' in self.spec else 'a' + mkl_integer = ['libmkl_intel_ilp64'] if '+ilp64' in self.spec else ['libmkl_intel_lp64'] # NOQA: ignore=E501 + mkl_threading = ['libmkl_intel_thread'] if '+openmp' in self.spec else ['libmkl_sequential'] # NOQA: ignore=E501 + mkl_libs = find_libraries( + mkl_integer + ['libmkl_core'] + mkl_threading, + root=join_path(self.prefix.lib, 'intel64'), + shared=shared + ) + system_libs = [ + 'libpthread.{0}'.format(suffix), + 'libm.{0}'.format(suffix), + 'libdl.{0}'.format(suffix) + ] + return mkl_libs + system_libs + + @property + def lapack_libs(self): + return self.blas_libs + def check_variants(self, spec): error_message = '\t{variant} can not be turned off if "+all" is set' @@ -171,24 +197,6 @@ class IntelParallelStudio(IntelInstaller): os.symlink(os.path.join(self.prefix.man, "common", "man1"), os.path.join(self.prefix.man, "man1")) - def setup_dependent_package(self, module, dspec): - # For now use Single Dynamic Library: - # To set the threading layer at run time, use the - # mkl_set_threading_layer function or set MKL_THREADING_LAYER - # variable to one of the following values: INTEL, SEQUENTIAL, PGI. - # To set interface layer at run time, use the mkl_set_interface_layer - # function or set the MKL_INTERFACE_LAYER variable to LP64 or ILP64. - - # Otherwise one would need to specify several libraries - # (e.g. mkl_intel_lp64;mkl_sequential;mkl_core), which reflect - # different interface and threading layers. - - name = 'libmkl_rt.%s' % dso_suffix - libdir = find_library_path(name, self.prefix.lib64, self.prefix.lib) - - self.spec.blas_shared_lib = join_path(libdir, name) - self.spec.lapack_shared_lib = self.spec.blas_shared_lib - def setup_environment(self, spack_env, run_env): # TODO: Determine variables needed for the professional edition. diff --git a/var/spack/repos/builtin/packages/mkl/package.py b/var/spack/repos/builtin/packages/mkl/package.py index 71a233ff3e..a7353d57c4 100644 --- a/var/spack/repos/builtin/packages/mkl/package.py +++ b/var/spack/repos/builtin/packages/mkl/package.py @@ -24,13 +24,40 @@ class Mkl(IntelInstaller): version('11.3.3.210', 'f72546df27f5ebb0941b5d21fd804e34', url="file://%s/l_mkl_11.3.3.210.tgz" % os.getcwd()) + variant('shared', default=True, description='Builds shared library') + variant('ilp64', default=False, description='64 bit integers') + variant('openmp', default=False, description='OpenMP multithreading layer') + # virtual dependency provides('blas') provides('lapack') # TODO: MKL also provides implementation of Scalapack. - def install(self, spec, prefix): + @property + def blas_libs(self): + shared = True if '+shared' in self.spec else False + suffix = dso_suffix if '+shared' in self.spec else 'a' + mkl_integer = ['libmkl_intel_ilp64'] if '+ilp64' in self.spec else ['libmkl_intel_lp64'] # NOQA: ignore=E501 + mkl_threading = ['libmkl_sequential'] + if '+openmp' in spec: + mkl_threading = ['libmkl_intel_thread'] if '%intel' in self.spec else ['libmkl_gnu_thread'] # NOQA: ignore=E501 + mkl_libs = find_libraries( + mkl_integer + ['libmkl_core'] + mkl_threading, + root=join_path(self.prefix.lib, 'intel64'), + shared=shared + ) + system_libs = [ + 'libpthread.{0}'.format(suffix), + 'libm.{0}'.format(suffix), + 'libdl.{0}'.format(suffix) + ] + return mkl_libs + system_libs + + @property + def lapack_libs(self): + return self.blas_libs + def install(self, spec, prefix): self.intel_prefix = os.path.join(prefix, "pkg") IntelInstaller.install(self, spec, prefix) @@ -45,25 +72,6 @@ class Mkl(IntelInstaller): os.symlink(os.path.join(mkl_lib_dir, f), os.path.join(self.prefix, "lib", f)) - def setup_dependent_package(self, module, dspec): - # For now use Single Dynamic Library: - # To set the threading layer at run time, use the - # mkl_set_threading_layer function or set MKL_THREADING_LAYER - # variable to one of the following values: INTEL, SEQUENTIAL, PGI. - # To set interface layer at run time, use the mkl_set_interface_layer - # function or set the MKL_INTERFACE_LAYER variable to LP64 or ILP64. - - # Otherwise one would need to specify several libraries - # (e.g. mkl_intel_lp64;mkl_sequential;mkl_core), which reflect - # different interface and threading layers. - - name = 'libmkl_rt.%s' % dso_suffix - libdir = find_library_path(name, self.prefix.lib64, self.prefix.lib) - - # Now set blas/lapack libs: - self.spec.blas_shared_lib = join_path(libdir, name) - self.spec.lapack_shared_lib = self.spec.blas_shared_lib - def setup_dependent_environment(self, spack_env, run_env, dependent_spec): # set up MKLROOT for everyone using MKL package spack_env.set('MKLROOT', self.prefix) diff --git a/var/spack/repos/builtin/packages/mumps/package.py b/var/spack/repos/builtin/packages/mumps/package.py index 32bc42a9c3..3466f091a0 100644 --- a/var/spack/repos/builtin/packages/mumps/package.py +++ b/var/spack/repos/builtin/packages/mumps/package.py @@ -75,9 +75,8 @@ class Mumps(Package): raise RuntimeError( 'You cannot use the variants parmetis or ptscotch without mpi') - makefile_conf = ["LIBBLAS = %s" % to_link_flags( - self.spec['blas'].blas_shared_lib) - ] + blas = self.spec['blas'].blas_libs + makefile_conf = ["LIBBLAS = %s" % blas.ld_flags] orderings = ['-Dpord'] @@ -136,11 +135,12 @@ class Mumps(Package): 'OPTC = %s -O ' % fpic]) if '+mpi' in self.spec: + scalapack = self.spec['scalapack'].scalapack_libs makefile_conf.extend( ["CC = %s" % join_path(self.spec['mpi'].prefix.bin, 'mpicc'), "FC = %s" % join_path(self.spec['mpi'].prefix.bin, 'mpif90'), "FL = %s" % join_path(self.spec['mpi'].prefix.bin, 'mpif90'), - "SCALAP = %s" % self.spec['scalapack'].fc_link, + "SCALAP = %s" % scalapack.ld_flags, "MUMPS_TYPE = par"]) else: makefile_conf.extend( diff --git a/var/spack/repos/builtin/packages/netlib-lapack/package.py b/var/spack/repos/builtin/packages/netlib-lapack/package.py index 93d64fb466..b73fe850d7 100644 --- a/var/spack/repos/builtin/packages/netlib-lapack/package.py +++ b/var/spack/repos/builtin/packages/netlib-lapack/package.py @@ -67,6 +67,20 @@ class NetlibLapack(Package): '${CMAKE_CURRENT_SOURCE_DIR}/cmake/', 'CBLAS/CMakeLists.txt', string=True) + @property + def blas_libs(self): + shared = True if '+shared' in self.spec else False + return find_libraries( + ['libblas'], root=self.prefix, shared=shared, recurse=True + ) + + @property + def lapack_libs(self): + shared = True if '+shared' in self.spec else False + return find_libraries( + ['liblapack'], root=self.prefix, shared=shared, recurse=True + ) + def install_one(self, spec, prefix, shared): cmake_args = [ '-DBUILD_SHARED_LIBS:BOOL=%s' % ('ON' if shared else 'OFF'), @@ -100,18 +114,3 @@ class NetlibLapack(Package): # Build shared libraries if requested. if '+shared' in spec: self.install_one(spec, prefix, True) - - def setup_dependent_package(self, module, dspec): - # This is WIP for a prototype interface for virtual packages. - # We can update this as more builds start depending on BLAS/LAPACK. - libdir = find_library_path( - 'libblas.a', self.prefix.lib64, self.prefix.lib) - - self.spec.blas_static_lib = join_path(libdir, 'libblas.a') - self.spec.lapack_static_lib = join_path(libdir, 'liblapack.a') - - if '+shared' in self.spec: - self.spec.blas_shared_lib = join_path( - libdir, 'libblas.%s' % dso_suffix) - self.spec.lapack_shared_lib = join_path( - libdir, 'liblapack.%s' % dso_suffix) diff --git a/var/spack/repos/builtin/packages/netlib-scalapack/package.py b/var/spack/repos/builtin/packages/netlib-scalapack/package.py index 13e932e176..fe9f1a3023 100644 --- a/var/spack/repos/builtin/packages/netlib-scalapack/package.py +++ b/var/spack/repos/builtin/packages/netlib-scalapack/package.py @@ -28,10 +28,11 @@ import sys class NetlibScalapack(Package): """ScaLAPACK is a library of high-performance linear algebra routines for - parallel distributed memory machines""" + parallel distributed memory machines + """ homepage = "http://www.netlib.org/scalapack/" - url = "http://www.netlib.org/scalapack/scalapack-2.0.2.tgz" + url = "http://www.netlib.org/scalapack/scalapack-2.0.2.tgz" version('2.0.2', '2f75e600a2ba155ed9ce974a1c4b536f') version('2.0.1', '17b8cde589ea0423afe1ec43e7499161') @@ -39,10 +40,16 @@ class NetlibScalapack(Package): # versions before 2.0.0 are not using cmake and requires blacs as # a separated package - variant('shared', default=True, - description='Build the shared library version') - variant('fpic', default=False, - description="Build with -fpic compiler option") + variant( + 'shared', + default=True, + description='Build the shared library version' + ) + variant( + 'fpic', + default=False, + description='Build with -fpic compiler option' + ) provides('scalapack') @@ -51,6 +58,13 @@ class NetlibScalapack(Package): depends_on('blas') depends_on('cmake', when='@2.0.0:', type='build') + @property + def scalapack_libs(self): + shared = True if '+shared' in self.spec else False + return find_libraries( + ['libscalapack'], root=self.prefix, shared=shared, recurse=True + ) + def install(self, spec, prefix): options = [ "-DBUILD_SHARED_LIBS:BOOL=%s" % ('ON' if '+shared' in spec else @@ -60,14 +74,13 @@ class NetlibScalapack(Package): ] # Make sure we use Spack's Lapack: + blas = spec['blas'].blas_libs + lapack = spec['lapack'].lapack_libs options.extend([ '-DLAPACK_FOUND=true', - '-DLAPACK_LIBRARIES=%s' % ( - spec['lapack'].lapack_shared_lib if '+shared' in spec else - spec['lapack'].lapack_static_lib), - '-DBLAS_LIBRARIES=%s' % ( - spec['blas'].blas_shared_lib if '+shared' in spec else - spec['blas'].blas_static_lib) + '-DLAPACK_INCLUDE_DIRS=%s' % spec['lapack'].prefix.include, + '-DLAPACK_LIBRARIES=%s' % (lapack.joined()), + '-DBLAS_LIBRARIES=%s' % (blas.joined()) ]) if '+fpic' in spec: @@ -86,12 +99,3 @@ class NetlibScalapack(Package): # The shared libraries are not installed correctly on Darwin: if (sys.platform == 'darwin') and ('+shared' in spec): fix_darwin_install_name(prefix.lib) - - def setup_dependent_package(self, module, dependent_spec): - spec = self.spec - lib_suffix = dso_suffix if '+shared' in spec else 'a' - - spec.fc_link = '-L%s -lscalapack' % spec.prefix.lib - spec.cc_link = spec.fc_link - spec.libraries = [join_path(spec.prefix.lib, - 'libscalapack.%s' % lib_suffix)] diff --git a/var/spack/repos/builtin/packages/nwchem/package.py b/var/spack/repos/builtin/packages/nwchem/package.py index 13c710a35a..b15c1c02fd 100644 --- a/var/spack/repos/builtin/packages/nwchem/package.py +++ b/var/spack/repos/builtin/packages/nwchem/package.py @@ -66,6 +66,9 @@ class Nwchem(Package): patch('Gcc6_macs_optfix.patch', when='@6.6', level=0) def install(self, spec, prefix): + scalapack = spec['scalapack'].scalapack_libs + lapack = spec['lapack'].lapack_libs + blas = spec['blas'].blas_libs # see http://www.nwchem-sw.org/index.php/Compiling_NWChem args = [] args.extend([ @@ -79,13 +82,11 @@ class Nwchem(Package): 'USE_PYTHONCONFIG=y', 'PYTHONVERSION=%s' % spec['python'].version.up_to(2), 'PYTHONHOME=%s' % spec['python'].prefix, - 'BLASOPT=%s %s' % ( - to_link_flags(spec['lapack'].lapack_shared_lib), - to_link_flags(spec['blas'].blas_shared_lib)), - 'BLAS_LIB=%s' % to_link_flags(spec['blas'].blas_shared_lib), - 'LAPACK_LIB=%s' % to_link_flags(spec['lapack'].lapack_shared_lib), + 'BLASOPT=%s' % ((lapack + blas).ld_flags), + 'BLAS_LIB=%s' % blas.ld_flags, + 'LAPACK_LIB=%s' % lapack.ld_flags, 'USE_SCALAPACK=y', - 'SCALAPACK=%s' % spec['scalapack'].fc_link, + 'SCALAPACK=%s' % scalapack.ld_flags, 'NWCHEM_MODULES=all python', 'NWCHEM_LONG_PATHS=Y' # by default NWCHEM_TOP is 64 char max ]) diff --git a/var/spack/repos/builtin/packages/octopus/package.py b/var/spack/repos/builtin/packages/octopus/package.py index ff4a106940..adb760f06d 100644 --- a/var/spack/repos/builtin/packages/octopus/package.py +++ b/var/spack/repos/builtin/packages/octopus/package.py @@ -46,13 +46,13 @@ class Octopus(Package): # FEAST, Libfm, PFFT, ISF, PNFFT def install(self, spec, prefix): + lapack = spec['lapack'].lapack_libs + blas = spec['blas'].blas_libs args = [] args.extend([ '--prefix=%s' % prefix, - '--with-blas=%s' % to_link_flags( - spec['blas'].blas_shared_lib), - '--with-lapack=%s' % to_link_flags( - spec['lapack'].lapack_shared_lib), + '--with-blas=%s' % blas.ld_flags, + '--with-lapack=%s' % lapack.ld_flags, '--with-gsl-prefix=%s' % spec['gsl'].prefix, '--with-libxc-prefix=%s' % spec['libxc'].prefix, 'CC=%s' % spec['mpi'].mpicc, diff --git a/var/spack/repos/builtin/packages/openblas/package.py b/var/spack/repos/builtin/packages/openblas/package.py index 23c7b02daf..89c35fb991 100644 --- a/var/spack/repos/builtin/packages/openblas/package.py +++ b/var/spack/repos/builtin/packages/openblas/package.py @@ -30,7 +30,7 @@ import os class Openblas(Package): """OpenBLAS: An optimized BLAS library""" homepage = "http://www.openblas.net" - url = "http://github.com/xianyi/OpenBLAS/archive/v0.2.15.tar.gz" + url = "http://github.com/xianyi/OpenBLAS/archive/v0.2.15.tar.gz" version('0.2.19', '28c998054fd377279741c6f0b9ea7941') version('0.2.18', '805e7f660877d588ea7e3792cda2ee65') @@ -51,6 +51,17 @@ class Openblas(Package): patch('make.patch') + @property + def blas_libs(self): + shared = True if '+shared' in self.spec else False + return find_libraries( + ['libopenblas'], root=self.prefix, shared=shared, recurse=True + ) + + @property + def lapack_libs(self): + return self.blas_libs + def install(self, spec, prefix): # As of 06/2016 there is no mechanism to specify that packages which # depends on Blas/Lapack need C or/and Fortran symbols. For now @@ -100,6 +111,9 @@ class Openblas(Package): # no quotes around prefix (spack doesn't use a shell) make('install', "PREFIX=%s" % prefix, *make_defs) + # TODO : the links below are mainly there because client + # TODO : packages are wrongly written. Check if they can be removed + # Blas virtual package should provide blas.a and libblas.a with working_dir(prefix.lib): symlink('libopenblas.a', 'blas.a') @@ -120,21 +134,6 @@ class Openblas(Package): # test. self.check_install(spec) - def setup_dependent_package(self, module, dspec): - # This is WIP for a prototype interface for virtual packages. - # We can update this as more builds start depending on BLAS/LAPACK. - libdir = find_library_path('libopenblas.a', - self.prefix.lib64, - self.prefix.lib) - - self.spec.blas_static_lib = join_path(libdir, 'libopenblas.a') - self.spec.lapack_static_lib = self.spec.blas_static_lib - - if '+shared' in self.spec: - self.spec.blas_shared_lib = join_path(libdir, 'libopenblas.%s' % - dso_suffix) - self.spec.lapack_shared_lib = self.spec.blas_shared_lib - def check_install(self, spec): source_file = join_path(os.path.dirname(self.module.__file__), 'test_cblas_dgemm.c') diff --git a/var/spack/repos/builtin/packages/opium/package.py b/var/spack/repos/builtin/packages/opium/package.py index 2c81d92cc0..521f917230 100644 --- a/var/spack/repos/builtin/packages/opium/package.py +++ b/var/spack/repos/builtin/packages/opium/package.py @@ -29,7 +29,7 @@ class Opium(Package): """DFT pseudopotential generation project""" homepage = "https://opium.sourceforge.net/index.html" - url = "https://downloads.sourceforge.net/project/opium/opium/opium-v3.8/opium-v3.8-src.tgz" + url = "https://downloads.sourceforge.net/project/opium/opium/opium-v3.8/opium-v3.8-src.tgz" version('3.8', 'f710c0f869e70352b4a510c31e13bf9f') @@ -37,12 +37,8 @@ class Opium(Package): depends_on('lapack') def install(self, spec, prefix): - options = [ - 'LDFLAGS=%s %s' % ( - to_link_flags(spec['lapack'].lapack_shared_lib), - to_link_flags(spec['blas'].blas_shared_lib) - ) - ] + libs = spec['lapack'].lapack_libs + spec['blas'].blas_libs + options = ['LDFLAGS=%s' % libs.ld_flags] configure(*options) with working_dir("src", create=False): diff --git a/var/spack/repos/builtin/packages/pexsi/package.py b/var/spack/repos/builtin/packages/pexsi/package.py index e74ad6df01..9fc71d4c52 100644 --- a/var/spack/repos/builtin/packages/pexsi/package.py +++ b/var/spack/repos/builtin/packages/pexsi/package.py @@ -67,8 +67,8 @@ class Pexsi(Package): '@PARMETIS_PREFIX': self.spec['parmetis'].prefix, '@LAPACK_PREFIX': self.spec['lapack'].prefix, '@BLAS_PREFIX': self.spec['blas'].prefix, - '@LAPACK_LIBS': self.spec['lapack'].lapack_shared_lib, - '@BLAS_LIBS': self.spec['lapack'].blas_shared_lib, + '@LAPACK_LIBS': self.spec['lapack'].lapack_libs.joined(), + '@BLAS_LIBS': self.spec['lapack'].blas_libs.joined(), '@STDCXX_LIB': ' '.join(self.compiler.stdcxx_libs) } diff --git a/var/spack/repos/builtin/packages/psi4/package.py b/var/spack/repos/builtin/packages/psi4/package.py index 6296d0cee6..566aa50f44 100644 --- a/var/spack/repos/builtin/packages/psi4/package.py +++ b/var/spack/repos/builtin/packages/psi4/package.py @@ -32,7 +32,7 @@ class Psi4(Package): a variety of molecular properties.""" homepage = "http://www.psicode.org/" - url = "https://github.com/psi4/psi4/archive/0.5.tar.gz" + url = "https://github.com/psi4/psi4/archive/0.5.tar.gz" version('0.5', '53041b8a9be3958384171d0d22f9fdd0') @@ -62,9 +62,10 @@ class Psi4(Package): def install(self, spec, prefix): cmake_args = [ '-DBLAS_TYPE={0}'.format(spec['blas'].name.upper()), - '-DBLAS_LIBRARIES={0}'.format(spec['blas'].blas_shared_lib), + '-DBLAS_LIBRARIES={0}'.format(spec['blas'].blas_libs.joined()), '-DLAPACK_TYPE={0}'.format(spec['lapack'].name.upper()), - '-DLAPACK_LIBRARIES={0}'.format(spec['lapack'].lapack_shared_lib), + '-DLAPACK_LIBRARIES={0}'.format( + spec['lapack'].lapack_libs.joined()), '-DBOOST_INCLUDEDIR={0}'.format(spec['boost'].prefix.include), '-DBOOST_LIBRARYDIR={0}'.format(spec['boost'].prefix.lib), '-DENABLE_CHEMPS2=OFF' @@ -90,9 +91,9 @@ class Psi4(Package): kwargs = {'ignore_absent': True, 'backup': False, 'string': True} - cc_files = ['bin/psi4-config'] + cc_files = ['bin/psi4-config'] cxx_files = ['bin/psi4-config', 'include/psi4/psiconfig.h'] - template = 'share/psi4/plugin/Makefile.template' + template = 'share/psi4/plugin/Makefile.template' for filename in cc_files: filter_file(os.environ['CC'], self.compiler.cc, diff --git a/var/spack/repos/builtin/packages/py-scipy/package.py b/var/spack/repos/builtin/packages/py-scipy/package.py index 83a69c5682..68b2cb13e0 100644 --- a/var/spack/repos/builtin/packages/py-scipy/package.py +++ b/var/spack/repos/builtin/packages/py-scipy/package.py @@ -47,7 +47,7 @@ class PyScipy(Package): env['ATLAS'] = join_path( spec['atlas'].prefix.lib, 'libatlas.' + dso_suffix) else: - env['BLAS'] = spec['blas'].blas_shared_lib - env['LAPACK'] = spec['lapack'].lapack_shared_lib + env['BLAS'] = spec['blas'].blas_libs.joined() + env['LAPACK'] = spec['lapack'].lapack_libs.joined() python('setup.py', 'install', '--prefix=%s' % prefix) diff --git a/var/spack/repos/builtin/packages/suite-sparse/package.py b/var/spack/repos/builtin/packages/suite-sparse/package.py index a71bfd8bd4..22f069885d 100644 --- a/var/spack/repos/builtin/packages/suite-sparse/package.py +++ b/var/spack/repos/builtin/packages/suite-sparse/package.py @@ -80,8 +80,8 @@ class SuiteSparse(Package): # Make sure Spack's Blas/Lapack is used. Otherwise System's # Blas/Lapack might be picked up. - blas = to_link_flags(spec['blas'].blas_shared_lib) - lapack = to_link_flags(spec['lapack'].lapack_shared_lib) + blas = spec['blas'].blas_libs.ld_flags + lapack = spec['lapack'].lapack_libs.ld_flags if '@4.5.1' in spec: # adding -lstdc++ is clearly an ugly way to do this, but it follows # with the TCOV path of SparseSuite 4.5.1's Suitesparse_config.mk diff --git a/var/spack/repos/builtin/packages/sundials/package.py b/var/spack/repos/builtin/packages/sundials/package.py index 7582954ab1..6ee247b7ea 100644 --- a/var/spack/repos/builtin/packages/sundials/package.py +++ b/var/spack/repos/builtin/packages/sundials/package.py @@ -31,7 +31,7 @@ class Sundials(Package): Solvers)""" homepage = "http://computation.llnl.gov/casc/sundials/" - url = "http://computation.llnl.gov/projects/sundials-suite-nonlinear-differential-algebraic-equation-solvers/download/sundials-2.6.2.tar.gz" + url = "http://computation.llnl.gov/projects/sundials-suite-nonlinear-differential-algebraic-equation-solvers/download/sundials-2.6.2.tar.gz" version('2.6.2', '3deeb0ede9f514184c6bd83ecab77d95') @@ -79,9 +79,9 @@ class Sundials(Package): if '+lapack' in spec: cmake_args.extend([ '-DLAPACK_ENABLE=ON', - '-DLAPACK_LIBRARIES={0};{1}'.format( - spec['lapack'].lapack_shared_lib, - spec['blas'].blas_shared_lib + '-DLAPACK_LIBRARIES={0}'.format( + (spec['lapack'].lapack_libs + + spec['blas'].blas_libs).joined(';') ) ]) else: @@ -113,7 +113,7 @@ class Sundials(Package): elif '+pthread' in spec: cmake_args.append('-DSUPERLUMT_THREAD_TYPE=Pthread') else: - msg = 'You must choose either +openmp or +pthread when ' + msg = 'You must choose either +openmp or +pthread when ' msg += 'building with SuperLU_MT' raise RuntimeError(msg) else: diff --git a/var/spack/repos/builtin/packages/superlu-dist/package.py b/var/spack/repos/builtin/packages/superlu-dist/package.py index 85b7f689d0..a29b74bf08 100644 --- a/var/spack/repos/builtin/packages/superlu-dist/package.py +++ b/var/spack/repos/builtin/packages/superlu-dist/package.py @@ -46,15 +46,14 @@ class SuperluDist(Package): depends_on('metis@5:') def install(self, spec, prefix): + lapack_blas = spec['lapack'].lapack_libs + spec['blas'].blas_libs makefile_inc = [] makefile_inc.extend([ 'PLAT = _mac_x', 'DSuperLUroot = %s' % self.stage.source_path, 'DSUPERLULIB = $(DSuperLUroot)/lib/libsuperlu_dist.a', 'BLASDEF = -DUSE_VENDOR_BLAS', - 'BLASLIB = %s %s' % - (to_link_flags(spec['lapack'].lapack_shared_lib), - to_link_flags(spec['blas'].blas_shared_lib)), + 'BLASLIB = %s' % lapack_blas.ld_flags, 'METISLIB = -L%s -lmetis' % spec['metis'].prefix.lib, 'PARMETISLIB = -L%s -lparmetis' % spec['parmetis'].prefix.lib, 'FLIBS =', diff --git a/var/spack/repos/builtin/packages/superlu/package.py b/var/spack/repos/builtin/packages/superlu/package.py index c634c1d1ba..d9cff650b6 100644 --- a/var/spack/repos/builtin/packages/superlu/package.py +++ b/var/spack/repos/builtin/packages/superlu/package.py @@ -42,7 +42,7 @@ class Superlu(Package): '-DCMAKE_POSITION_INDEPENDENT_CODE=ON', # BLAS support '-Denable_blaslib=OFF', - '-DBLAS_blas_LIBRARY={0}'.format(spec['blas'].blas_shared_lib) + '-DBLAS_blas_LIBRARY={0}'.format(spec['blas'].blas_libs.joined()) ] cmake_args.extend(std_cmake_args) diff --git a/var/spack/repos/builtin/packages/trilinos/package.py b/var/spack/repos/builtin/packages/trilinos/package.py index 3a88f67340..716d8f8eb6 100644 --- a/var/spack/repos/builtin/packages/trilinos/package.py +++ b/var/spack/repos/builtin/packages/trilinos/package.py @@ -132,6 +132,8 @@ class Trilinos(Package): mpi_bin = spec['mpi'].prefix.bin # Note: -DXYZ_LIBRARY_NAMES= needs semicolon separated list of names + blas = spec['blas'].blas_libs + lapack = spec['lapack'].lapack_libs options.extend([ '-DTrilinos_ENABLE_ALL_PACKAGES:BOOL=ON', '-DTrilinos_ENABLE_ALL_OPTIONAL_PACKAGES:BOOL=ON', @@ -145,12 +147,10 @@ class Trilinos(Package): '-DTPL_ENABLE_MPI:BOOL=ON', '-DMPI_BASE_DIR:PATH=%s' % spec['mpi'].prefix, '-DTPL_ENABLE_BLAS=ON', - '-DBLAS_LIBRARY_NAMES=%s' % to_lib_name( - spec['blas'].blas_shared_lib), + '-DBLAS_LIBRARY_NAMES=%s' % ';'.join(blas.names), '-DBLAS_LIBRARY_DIRS=%s' % spec['blas'].prefix.lib, '-DTPL_ENABLE_LAPACK=ON', - '-DLAPACK_LIBRARY_NAMES=%s' % to_lib_name( - spec['lapack'].lapack_shared_lib), + '-DLAPACK_LIBRARY_NAMES=%s' % ';'.join(lapack.names), '-DLAPACK_LIBRARY_DIRS=%s' % spec['lapack'].prefix.lib, '-DTrilinos_ENABLE_EXPLICIT_INSTANTIATION:BOOL=ON', '-DTrilinos_ENABLE_CXX11:BOOL=ON', diff --git a/var/spack/repos/builtin/packages/wannier90/package.py b/var/spack/repos/builtin/packages/wannier90/package.py index 189e568cdc..119d2cf769 100644 --- a/var/spack/repos/builtin/packages/wannier90/package.py +++ b/var/spack/repos/builtin/packages/wannier90/package.py @@ -47,13 +47,12 @@ class Wannier90(Package): def install(self, spec, prefix): + lapack = self.spec['lapack'].lapack_libs + blas = self.spec['blas'].blas_libs substitutions = { '@F90': spack_fc, '@MPIF90': self.spec['mpi'].mpifc, - '@LIBS': ' '.join([ - self.spec['lapack'].lapack_shared_lib, - self.spec['lapack'].blas_shared_lib - ]) + '@LIBS': (lapack + blas).joined() } ####### # TODO : this part is replicated in PEXSI -- cgit v1.2.3-70-g09d2