Reworking of lapack_shared_libs and similar properties (#1682)

* Turned <provider>_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
This commit is contained in:
Massimiliano Culpo 2016-09-21 21:27:59 +02:00 committed by Todd Gamblin
parent 6b6f868f2a
commit d848559f70
33 changed files with 526 additions and 244 deletions

View File

@ -2090,12 +2090,11 @@ Blas and Lapack libraries
Different packages provide implementation of ``Blas`` and ``Lapack`` routines. Different packages provide implementation of ``Blas`` and ``Lapack`` routines.
The names of the resulting static and/or shared libraries differ from package The names of the resulting static and/or shared libraries differ from package
to package. In order to make the ``install()`` method indifferent to the to package. In order to make the ``install()`` method independent of the
choice of ``Blas`` implementation, each package which provides it choice of ``Blas`` implementation, each package which provides it
sets up ``self.spec.blas_shared_lib`` and ``self.spec.blas_static_lib`` to sets up ``self.spec.blas_libs`` to point to the correct ``Blas`` libraries.
point to the shared and static ``Blas`` libraries, respectively. The same The same applies to packages which provide ``Lapack``. Package developers are advised to
applies to packages which provide ``Lapack``. Package developers are advised to use these variables, for example ``spec['blas'].blas_libs.joined()`` instead of
use these variables, for example ``spec['blas'].blas_shared_lib`` instead of
hard-coding ``join_path(spec['blas'].prefix.lib, 'libopenblas.so')``. hard-coding ``join_path(spec['blas'].prefix.lib, 'libopenblas.so')``.
^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^

View File

@ -22,18 +22,22 @@
# License along with this program; if not, write to the Free Software # License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
############################################################################## ##############################################################################
import os import collections
import errno
import fileinput
import getpass
import glob import glob
import numbers
import os
import re import re
import shutil import shutil
import stat import stat
import errno
import getpass
from contextlib import contextmanager
import subprocess import subprocess
import fileinput import sys
from contextlib import contextmanager
import llnl.util.tty as tty import llnl.util.tty as tty
from llnl.util.lang import dedupe
__all__ = ['set_install_permissions', 'install', 'install_tree', __all__ = ['set_install_permissions', 'install', 'install_tree',
'traverse_tree', 'traverse_tree',
@ -42,8 +46,8 @@
'filter_file', 'filter_file',
'FileFilter', 'change_sed_delimiter', 'is_exe', 'force_symlink', 'FileFilter', 'change_sed_delimiter', 'is_exe', 'force_symlink',
'set_executable', 'copy_mode', 'unset_executable_mode', 'set_executable', 'copy_mode', 'unset_executable_mode',
'remove_dead_links', 'remove_linked_tree', 'find_library_path', 'remove_dead_links', 'remove_linked_tree',
'fix_darwin_install_name', 'to_link_flags', 'to_lib_name'] 'fix_darwin_install_name', 'find_libraries', 'LibraryList']
def filter_file(regex, repl, *filenames, **kwargs): def filter_file(regex, repl, *filenames, **kwargs):
@ -440,35 +444,162 @@ def fix_darwin_install_name(path):
stdout=subprocess.PIPE).communicate()[0] stdout=subprocess.PIPE).communicate()[0]
break break
# Utilities for libraries
def to_lib_name(library):
"""Transforms a path to the library /path/to/lib<name>.xyz into <name> class LibraryList(collections.Sequence):
"""Sequence of absolute paths to libraries
Provides a few convenience methods to manipulate library paths and get
commonly used compiler flags or names
""" """
# Assume libXYZ.suffix
return os.path.basename(library)[3:].split(".")[0]
def __init__(self, libraries):
self.libraries = list(libraries)
def to_link_flags(library): @property
"""Transforms a path to a <library> into linking flags -L<dir> -l<name>. def directories(self):
"""Stable de-duplication of the directories where the libraries
reside
Return: >>> l = LibraryList(['/dir1/liba.a', '/dir2/libb.a', '/dir1/libc.a'])
A string of linking flags. >>> assert l.directories == ['/dir1', '/dir2']
""" """
dir = os.path.dirname(library) return list(dedupe(
name = to_lib_name(library) os.path.dirname(x) for x in self.libraries if os.path.dirname(x)
res = '-L%s -l%s' % (dir, name) ))
return res
@property
def basenames(self):
"""Stable de-duplication of the base-names in the list
def find_library_path(libname, *paths): >>> l = LibraryList(['/dir1/liba.a', '/dir2/libb.a', '/dir3/liba.a'])
"""Searches for a file called <libname> in each path. >>> assert l.basenames == ['liba.a', 'libb.a']
Return:
directory where the library was found, if found. None otherwise.
""" """
for path in paths: return list(dedupe(os.path.basename(x) for x in self.libraries))
library = join_path(path, libname)
if os.path.exists(library): @property
return path def names(self):
"""Stable de-duplication of library names in the list
>>> l = LibraryList(['/dir1/liba.a', '/dir2/libb.a', '/dir3/liba.so'])
>>> assert l.names == ['a', 'b']
"""
return list(dedupe(x.split('.')[0][3:] for x in self.basenames))
@property
def search_flags(self):
"""Search flags for the libraries
>>> l = LibraryList(['/dir1/liba.a', '/dir2/libb.a', '/dir1/liba.so'])
>>> assert l.search_flags == '-L/dir1 -L/dir2'
"""
return ' '.join(['-L' + x for x in self.directories])
@property
def link_flags(self):
"""Link flags for the libraries
>>> l = LibraryList(['/dir1/liba.a', '/dir2/libb.a', '/dir1/liba.so'])
>>> assert l.search_flags == '-la -lb'
"""
return ' '.join(['-l' + name for name in self.names])
@property
def ld_flags(self):
"""Search flags + link flags
>>> l = LibraryList(['/dir1/liba.a', '/dir2/libb.a', '/dir1/liba.so'])
>>> assert l.search_flags == '-L/dir1 -L/dir2 -la -lb'
"""
return self.search_flags + ' ' + self.link_flags
def __getitem__(self, item):
cls = type(self)
if isinstance(item, numbers.Integral):
return self.libraries[item]
return cls(self.libraries[item])
def __add__(self, other):
return LibraryList(dedupe(self.libraries + list(other)))
def __radd__(self, other):
return self.__add__(other)
def __eq__(self, other):
return self.libraries == other.libraries
def __len__(self):
return len(self.libraries)
def joined(self, separator=' '):
return separator.join(self.libraries)
def __repr__(self):
return self.__class__.__name__ + '(' + repr(self.libraries) + ')'
def __str__(self):
return self.joined()
def find_libraries(args, root, shared=True, recurse=False):
"""Returns an iterable object containing a list of full paths to
libraries if found.
Args:
args: iterable object containing a list of library names to \
search for (e.g. 'libhdf5')
root: root folder where to start searching
shared: if True searches for shared libraries, otherwise for static
recurse: if False search only root folder, if True descends top-down \
from the root
Returns:
list of full paths to the libraries that have been found
"""
if not isinstance(args, collections.Sequence) or isinstance(args, str):
message = '{0} expects a sequence of strings as first argument'
message += ' [got {1} instead]'
raise TypeError(message.format(find_libraries.__name__, type(args)))
# Construct the right suffix for the library
if shared is True:
suffix = 'dylib' if sys.platform == 'darwin' else 'so'
else:
suffix = 'a'
# List of libraries we are searching with suffixes
libraries = ['{0}.{1}'.format(lib, suffix) for lib in args]
# Search method
if recurse is False:
search_method = _find_libraries_non_recursive
else:
search_method = _find_libraries_recursive
return search_method(libraries, root)
def _find_libraries_recursive(libraries, root):
library_dict = collections.defaultdict(list)
for path, _, files in os.walk(root):
for lib in libraries:
if lib in files:
library_dict[lib].append(
join_path(path, lib)
)
answer = []
for lib in libraries:
answer.extend(library_dict[lib])
return LibraryList(answer)
def _find_libraries_non_recursive(libraries, root):
def lib_or_none(lib):
library = join_path(root, lib)
if not os.path.exists(library):
return None return None
return library
return LibraryList(
[lib_or_none(lib) for lib in libraries if lib_or_none(lib) is not None]
)

View File

@ -374,6 +374,22 @@ def __iter__(self):
return wrapper() return wrapper()
def dedupe(sequence):
"""Yields a stable de-duplication of an hashable sequence
Args:
sequence: hashable sequence to be de-duplicated
Returns:
stable de-duplication of the sequence
"""
seen = set()
for x in sequence:
if x not in seen:
yield x
seen.add(x)
class RequiredAttributeError(ValueError): class RequiredAttributeError(ValueError):
def __init__(self, message): def __init__(self, message):

View File

@ -527,6 +527,13 @@ def __init__(self, spec_like, *dep_like, **kwargs):
# XXX(deptype): default deptypes # XXX(deptype): default deptypes
self._add_dependency(spec, ('build', 'link')) self._add_dependency(spec, ('build', 'link'))
def __getattr__(self, item):
"""Delegate to self.package if the attribute is not in the spec"""
# This line is to avoid infinite recursion in case package is
# not present among self attributes
package = super(Spec, self).__getattribute__('package')
return getattr(package, item)
def get_dependency(self, name): def get_dependency(self, name):
dep = self._dependencies.get(name) dep = self._dependencies.get(name)
if dep is not None: if dep is not None:

View File

@ -53,6 +53,7 @@
'git_fetch', 'git_fetch',
'hg_fetch', 'hg_fetch',
'install', 'install',
'library_list',
'link_tree', 'link_tree',
'lock', 'lock',
'make_executable', 'make_executable',

View File

@ -0,0 +1,111 @@
##############################################################################
# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
# Produced at the Lawrence Livermore National Laboratory.
#
# This file is part of Spack.
# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
# LLNL-CODE-647188
#
# For details, see https://github.com/llnl/spack
# Please also see the LICENSE file for our notice and the LGPL.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License (as
# published by the Free Software Foundation) version 2.1, February 1999.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
# conditions of the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
import unittest
from llnl.util.filesystem import LibraryList
class LibraryListTest(unittest.TestCase):
def setUp(self):
l = [
'/dir1/liblapack.a',
'/dir2/libfoo.dylib',
'/dir1/libblas.a',
'/dir3/libbar.so',
'libbaz.so'
]
self.liblist = LibraryList(l)
def test_repr(self):
x = eval(repr(self.liblist))
self.assertEqual(self.liblist, x)
def test_joined_and_str(self):
s1 = self.liblist.joined()
self.assertEqual(
s1,
'/dir1/liblapack.a /dir2/libfoo.dylib /dir1/libblas.a /dir3/libbar.so libbaz.so' # NOQA: ignore=E501
)
s2 = str(self.liblist)
self.assertEqual(s1, s2)
s3 = self.liblist.joined(';')
self.assertEqual(
s3,
'/dir1/liblapack.a;/dir2/libfoo.dylib;/dir1/libblas.a;/dir3/libbar.so;libbaz.so' # NOQA: ignore=E501
)
def test_flags(self):
search_flags = self.liblist.search_flags
self.assertTrue('-L/dir1' in search_flags)
self.assertTrue('-L/dir2' in search_flags)
self.assertTrue('-L/dir3' in search_flags)
self.assertTrue(isinstance(search_flags, str))
link_flags = self.liblist.link_flags
self.assertEqual(
link_flags,
'-llapack -lfoo -lblas -lbar -lbaz'
)
ld_flags = self.liblist.ld_flags
self.assertEqual(ld_flags, search_flags + ' ' + link_flags)
def test_paths_manipulation(self):
names = self.liblist.names
self.assertEqual(names, ['lapack', 'foo', 'blas', 'bar', 'baz'])
directories = self.liblist.directories
self.assertEqual(directories, ['/dir1', '/dir2', '/dir3'])
def test_get_item(self):
a = self.liblist[0]
self.assertEqual(a, '/dir1/liblapack.a')
b = self.liblist[:]
self.assertEqual(type(b), type(self.liblist))
self.assertEqual(self.liblist, b)
self.assertTrue(self.liblist is not b)
def test_add(self):
pylist = [
'/dir1/liblapack.a', # removed from the final list
'/dir2/libbaz.so',
'/dir4/libnew.a'
]
another = LibraryList(pylist)
l = self.liblist + another
self.assertEqual(len(l), 7)
# Invariant : l == l + l
self.assertEqual(l, l + l)
# Always produce an instance of LibraryList
self.assertEqual(
type(self.liblist),
type(self.liblist + pylist)
)
self.assertEqual(
type(pylist + self.liblist),
type(self.liblist)
)

View File

@ -46,18 +46,20 @@ class Armadillo(Package):
depends_on('hdf5', when='+hdf5') depends_on('hdf5', when='+hdf5')
def install(self, spec, prefix): 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 = [ cmake_args = [
# ARPACK support # ARPACK support
'-DARPACK_LIBRARY={0}/libarpack.{1}'.format( '-DARPACK_LIBRARY={0}'.format(arpack.joined()),
spec['arpack-ng'].prefix.lib, dso_suffix),
# BLAS support # BLAS support
'-DBLAS_LIBRARY={0}'.format(spec['blas'].blas_shared_lib), '-DBLAS_LIBRARY={0}'.format(spec['blas'].blas_libs.joined()),
# LAPACK support # LAPACK support
'-DLAPACK_LIBRARY={0}'.format(spec['lapack'].lapack_shared_lib), '-DLAPACK_LIBRARY={0}'.format(spec['lapack'].lapack_libs.joined()),
# SuperLU support # SuperLU support
'-DSuperLU_INCLUDE_DIR={0}'.format(spec['superlu'].prefix.include), '-DSuperLU_INCLUDE_DIR={0}'.format(spec['superlu'].prefix.include),
'-DSuperLU_LIBRARY={0}/libsuperlu.a'.format( '-DSuperLU_LIBRARY={0}'.format(superlu.joined()),
spec['superlu'].prefix.lib64),
# HDF5 support # HDF5 support
'-DDETECT_HDF5={0}'.format('ON' if '+hdf5' in spec else 'OFF') '-DDETECT_HDF5={0}'.format('ON' if '+hdf5' in spec else 'OFF')
] ]

View File

@ -88,17 +88,16 @@ def install(self, spec, prefix):
options.append('-DCMAKE_INSTALL_NAME_DIR:PATH=%s/lib' % prefix) options.append('-DCMAKE_INSTALL_NAME_DIR:PATH=%s/lib' % prefix)
# Make sure we use Spack's blas/lapack: # Make sure we use Spack's blas/lapack:
lapack_libs = spec['lapack'].lapack_libs.joined()
blas_libs = spec['blas'].blas_libs.joined()
options.extend([ options.extend([
'-DLAPACK_FOUND=true', '-DLAPACK_FOUND=true',
'-DLAPACK_INCLUDE_DIRS=%s' % spec['lapack'].prefix.include, '-DLAPACK_INCLUDE_DIRS={0}'.format(spec['lapack'].prefix.include),
'-DLAPACK_LIBRARIES=%s' % ( '-DLAPACK_LIBRARIES={0}'.format(lapack_libs),
spec['lapack'].lapack_shared_lib if '+shared' in spec else
spec['lapack'].lapack_static_lib),
'-DBLAS_FOUND=true', '-DBLAS_FOUND=true',
'-DBLAS_INCLUDE_DIRS=%s' % spec['blas'].prefix.include, '-DBLAS_INCLUDE_DIRS={0}'.format(spec['blas'].prefix.include),
'-DBLAS_LIBRARIES=%s' % ( '-DBLAS_LIBRARIES={0}'.format(blas_libs)
spec['blas'].blas_shared_lib if '+shared' in spec else
spec['blas'].blas_static_lib)
]) ])
if '+mpi' in spec: if '+mpi' in spec:
@ -129,19 +128,12 @@ def install(self, spec, prefix):
'F77=%s' % spec['mpi'].mpif77 'F77=%s' % spec['mpi'].mpif77
]) ])
if '+shared' in spec:
options.extend([ options.extend([
'--with-blas=%s' % to_link_flags( '--with-blas={0}'.format(spec['blas'].blas_libs.ld_flags),
spec['blas'].blas_shared_lib), '--with-lapack={0}'.format(spec['lapack'].lapack_libs.ld_flags)
'--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'
]) ])
if '+shared' not in spec:
options.append('--enable-shared=no')
bootstrap() bootstrap()
configure(*options) configure(*options)

View File

@ -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') 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('shared', default=True, description='Builds shared library')
variant('pthread', default=False, description='Use multithreaded libraries')
provides('blas') provides('blas')
provides('lapack') provides('lapack')
@ -107,18 +108,32 @@ def install(self, spec, prefix):
make("install") make("install")
self.install_test() 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, # libsatlas.[so,dylib,dll ] contains all serial APIs (serial lapack,
# serial BLAS), and all ATLAS symbols needed to support them. Whereas # serial BLAS), and all ATLAS symbols needed to support them. Whereas
# libtatlas.[so,dylib,dll ] is parallel (multithreaded) version. # libtatlas.[so,dylib,dll ] is parallel (multithreaded) version.
name = 'libsatlas.%s' % dso_suffix is_threaded = '+pthread' in self.spec
libdir = find_library_path(name,
self.prefix.lib64,
self.prefix.lib)
if '+shared' in self.spec: if '+shared' in self.spec:
self.spec.blas_shared_lib = join_path(libdir, name) to_find = ['libtatlas'] if is_threaded else ['libsatlas']
self.spec.lapack_shared_lib = self.spec.blas_shared_lib 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): def install_test(self):
source_file = join_path(os.path.dirname(self.module.__file__), source_file = join_path(os.path.dirname(self.module.__file__),
@ -126,9 +141,8 @@ def install_test(self):
blessed_file = join_path(os.path.dirname(self.module.__file__), blessed_file = join_path(os.path.dirname(self.module.__file__),
'test_cblas_dgemm.output') 'test_cblas_dgemm.output')
include_flags = ["-I%s" % join_path(self.spec.prefix, "include")] include_flags = ["-I%s" % self.spec.prefix.include]
link_flags = ["-L%s" % join_path(self.spec.prefix, "lib"), link_flags = self.lapack_libs.ld_flags
"-lsatlas"]
output = compile_c_and_execute(source_file, include_flags, link_flags) output = compile_c_and_execute(source_file, include_flags, link_flags)
compare_output_file(output, blessed_file) compare_output_file(output, blessed_file)

View File

@ -95,7 +95,8 @@ def install(self, spec, prefix):
fcflags.extend([ fcflags.extend([
'-I' + spec['fftw'].prefix.include '-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 = [] libs = []
if '+plumed' in self.spec: if '+plumed' in self.spec:
# Include Plumed.inc in the Makefile # Include Plumed.inc in the Makefile
@ -157,9 +158,8 @@ def install(self, spec, prefix):
), ),
'-I' + join_path(spec['pexsi'].prefix, 'fortran') '-I' + join_path(spec['pexsi'].prefix, 'fortran')
]) ])
ldflags.extend([ scalapack = spec['scalapack'].scalapack_libs
'-L' + spec['scalapack'].prefix.lib ldflags.append(scalapack.search_flags)
])
libs.extend([ libs.extend([
join_path(spec['elpa'].prefix.lib, join_path(spec['elpa'].prefix.lib,
'libelpa.{0}'.format(dso_suffix)), 'libelpa.{0}'.format(dso_suffix)),
@ -176,20 +176,15 @@ def install(self, spec, prefix):
'libmetis.{0}'.format(dso_suffix) '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.spec['mpi'].mpicxx_shared_libs)
libs.extend(self.compiler.stdcxx_libs) libs.extend(self.compiler.stdcxx_libs)
# LAPACK / BLAS # LAPACK / BLAS
ldflags.extend([ lapack = spec['lapack'].lapack_libs
'-L' + spec['lapack'].prefix.lib, blas = spec['blas'].blas_libs
'-L' + spec['blas'].prefix.lib
]) ldflags.append((lapack + blas).search_flags)
libs.extend([ libs.extend([str(x) for x in (fftw, lapack, blas)])
join_path(spec['fftw'].prefix.lib,
'libfftw3.{0}'.format(dso_suffix)),
spec['lapack'].lapack_shared_lib,
spec['blas'].blas_shared_lib
])
# Write compiler flags to file # Write compiler flags to file
mkf.write('CPPFLAGS = {0}\n'.format(' '.join(cppflags))) mkf.write('CPPFLAGS = {0}\n'.format(' '.join(cppflags)))

View File

@ -123,6 +123,7 @@ def install(self, spec, prefix):
options.remove(word) options.remove(word)
dsuf = 'dylib' if sys.platform == 'darwin' else 'so' dsuf = 'dylib' if sys.platform == 'darwin' else 'so'
lapack_blas = spec['lapack'].lapack_libs + spec['blas'].blas_libs
options.extend([ options.extend([
'-DCMAKE_BUILD_TYPE=DebugRelease', '-DCMAKE_BUILD_TYPE=DebugRelease',
'-DDEAL_II_COMPONENT_EXAMPLES=ON', '-DDEAL_II_COMPONENT_EXAMPLES=ON',
@ -135,9 +136,7 @@ def install(self, spec, prefix):
'-DLAPACK_FOUND=true', '-DLAPACK_FOUND=true',
'-DLAPACK_INCLUDE_DIRS=%s;%s' % ( '-DLAPACK_INCLUDE_DIRS=%s;%s' % (
spec['lapack'].prefix.include, spec['blas'].prefix.include), spec['lapack'].prefix.include, spec['blas'].prefix.include),
'-DLAPACK_LIBRARIES=%s;%s' % ( '-DLAPACK_LIBRARIES=%s' % lapack_blas.joined(';'),
spec['lapack'].lapack_shared_lib,
spec['blas'].blas_shared_lib),
'-DMUPARSER_DIR=%s' % spec['muparser'].prefix, '-DMUPARSER_DIR=%s' % spec['muparser'].prefix,
'-DUMFPACK_DIR=%s' % spec['suite-sparse'].prefix, '-DUMFPACK_DIR=%s' % spec['suite-sparse'].prefix,
'-DTBB_DIR=%s' % spec['tbb'].prefix, '-DTBB_DIR=%s' % spec['tbb'].prefix,

View File

@ -90,9 +90,9 @@ def configure(self, spec):
blas = 'blas.a' blas = 'blas.a'
lapack = 'lapack.a' lapack = 'lapack.a'
if '+blas' in spec: if '+blas' in spec:
blas = spec['blas'].blas_shared_lib blas = spec['blas'].blas_libs.joined()
if '+lapack' in spec: if '+lapack' in spec:
lapack = spec['lapack'].lapack_shared_lib lapack = spec['lapack'].lapack_libs.joined()
# lapack must come before blas # lapack must come before blas
config['LIB_LPK'] = ' '.join([lapack, blas]) config['LIB_LPK'] = ' '.join([lapack, blas])

View File

@ -87,9 +87,9 @@ def install(self, spec, prefix):
options.append('-DENABLE_OS_SPECIFIC_INSTALL=OFF') options.append('-DENABLE_OS_SPECIFIC_INSTALL=OFF')
# Make sure GMSH picks up correct BlasLapack by providing linker flags # Make sure GMSH picks up correct BlasLapack by providing linker flags
options.append('-DBLAS_LAPACK_LIBRARIES=%s %s' % blas_lapack = spec['lapack'].lapack_libs + spec['blas'].blas_libs
(to_link_flags(spec['lapack'].lapack_shared_lib), options.append(
to_link_flags(spec['blas'].blas_shared_lib))) '-DBLAS_LAPACK_LIBRARIES={0}'.format(blas_lapack.ld_flags))
# Gmsh does not have an option to compile against external metis. # Gmsh does not have an option to compile against external metis.
# Its own Metis, however, fails to build # Its own Metis, however, fails to build

View File

@ -78,7 +78,7 @@ def configure(self, spec, arch):
'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),
'LAlib = {0}'.format(spec['blas'].blas_shared_lib), 'LAlib = {0}'.format(spec['blas'].blas_libs.joined()),
# F77 / C interface # F77 / C interface
'F2CDEFS = -DAdd_ -DF77_INTEGER=int -DStringSunStyle', 'F2CDEFS = -DAdd_ -DF77_INTEGER=int -DStringSunStyle',
# HPL includes / libraries / specifics # HPL includes / libraries / specifics

View File

@ -60,13 +60,14 @@ def install(self, spec, prefix):
# to command the linker to include whole static libs' content into the # to command the linker to include whole static libs' content into the
# shared lib # shared lib
# Note: --with-(lapack|blas)_libs= needs space separated list of names # Note: --with-(lapack|blas)_libs= needs space separated list of names
lapack = spec['lapack'].lapack_libs
blas = spec['blas'].blas_libs
configure_args = [ configure_args = [
'--prefix=%s' % prefix, '--prefix=%s' % prefix,
'--with-lapack-libs=%s' % to_lib_name( '--with-lapack-libs=%s' % lapack.names,
spec['lapack'].lapack_shared_lib),
'--with-lapack-lib-dirs=%s' % spec['lapack'].prefix.lib, '--with-lapack-lib-dirs=%s' % spec['lapack'].prefix.lib,
'--with-blas-libs=%s' % to_lib_name( '--with-blas-libs=%s' % blas.names,
spec['blas'].blas_shared_lib),
'--with-blas-lib-dirs=%s' % spec['blas'].prefix.lib '--with-blas-lib-dirs=%s' % spec['blas'].prefix.lib
] ]

View File

@ -45,6 +45,10 @@ class IntelParallelStudio(IntelInstaller):
variant('tools', default=True, description="Install the Intel Advisor, " variant('tools', default=True, description="Install the Intel Advisor, "
"VTune Amplifier, and Inspector tools") "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('mpi', when='@cluster:+mpi')
provides('mkl', when='+mkl') provides('mkl', when='+mkl')
provides('daal', when='+daal') provides('daal', when='+daal')
@ -55,6 +59,28 @@ class IntelParallelStudio(IntelInstaller):
provides('lapack', when='+mkl') provides('lapack', when='+mkl')
# TODO: MKL also provides implementation of Scalapack. # 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): def check_variants(self, spec):
error_message = '\t{variant} can not be turned off if "+all" is set' error_message = '\t{variant} can not be turned off if "+all" is set'
@ -171,24 +197,6 @@ def install(self, spec, prefix):
os.symlink(os.path.join(self.prefix.man, "common", "man1"), os.symlink(os.path.join(self.prefix.man, "common", "man1"),
os.path.join(self.prefix.man, "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): def setup_environment(self, spack_env, run_env):
# TODO: Determine variables needed for the professional edition. # TODO: Determine variables needed for the professional edition.

View File

@ -24,13 +24,40 @@ class Mkl(IntelInstaller):
version('11.3.3.210', 'f72546df27f5ebb0941b5d21fd804e34', version('11.3.3.210', 'f72546df27f5ebb0941b5d21fd804e34',
url="file://%s/l_mkl_11.3.3.210.tgz" % os.getcwd()) 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 # virtual dependency
provides('blas') provides('blas')
provides('lapack') provides('lapack')
# TODO: MKL also provides implementation of Scalapack. # 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") self.intel_prefix = os.path.join(prefix, "pkg")
IntelInstaller.install(self, spec, prefix) IntelInstaller.install(self, spec, prefix)
@ -45,25 +72,6 @@ def install(self, spec, prefix):
os.symlink(os.path.join(mkl_lib_dir, f), os.symlink(os.path.join(mkl_lib_dir, f),
os.path.join(self.prefix, "lib", 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): def setup_dependent_environment(self, spack_env, run_env, dependent_spec):
# set up MKLROOT for everyone using MKL package # set up MKLROOT for everyone using MKL package
spack_env.set('MKLROOT', self.prefix) spack_env.set('MKLROOT', self.prefix)

View File

@ -75,9 +75,8 @@ def write_makefile_inc(self):
raise RuntimeError( raise RuntimeError(
'You cannot use the variants parmetis or ptscotch without mpi') 'You cannot use the variants parmetis or ptscotch without mpi')
makefile_conf = ["LIBBLAS = %s" % to_link_flags( blas = self.spec['blas'].blas_libs
self.spec['blas'].blas_shared_lib) makefile_conf = ["LIBBLAS = %s" % blas.ld_flags]
]
orderings = ['-Dpord'] orderings = ['-Dpord']
@ -136,11 +135,12 @@ def write_makefile_inc(self):
'OPTC = %s -O ' % fpic]) 'OPTC = %s -O ' % fpic])
if '+mpi' in self.spec: if '+mpi' in self.spec:
scalapack = self.spec['scalapack'].scalapack_libs
makefile_conf.extend( makefile_conf.extend(
["CC = %s" % join_path(self.spec['mpi'].prefix.bin, 'mpicc'), ["CC = %s" % join_path(self.spec['mpi'].prefix.bin, 'mpicc'),
"FC = %s" % join_path(self.spec['mpi'].prefix.bin, 'mpif90'), "FC = %s" % join_path(self.spec['mpi'].prefix.bin, 'mpif90'),
"FL = %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"]) "MUMPS_TYPE = par"])
else: else:
makefile_conf.extend( makefile_conf.extend(

View File

@ -67,6 +67,20 @@ def patch(self):
'${CMAKE_CURRENT_SOURCE_DIR}/cmake/', '${CMAKE_CURRENT_SOURCE_DIR}/cmake/',
'CBLAS/CMakeLists.txt', string=True) '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): def install_one(self, spec, prefix, shared):
cmake_args = [ cmake_args = [
'-DBUILD_SHARED_LIBS:BOOL=%s' % ('ON' if shared else 'OFF'), '-DBUILD_SHARED_LIBS:BOOL=%s' % ('ON' if shared else 'OFF'),
@ -100,18 +114,3 @@ def install(self, spec, prefix):
# Build shared libraries if requested. # Build shared libraries if requested.
if '+shared' in spec: if '+shared' in spec:
self.install_one(spec, prefix, True) 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)

View File

@ -28,7 +28,8 @@
class NetlibScalapack(Package): class NetlibScalapack(Package):
"""ScaLAPACK is a library of high-performance linear algebra routines for """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/" 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"
@ -39,10 +40,16 @@ class NetlibScalapack(Package):
# versions before 2.0.0 are not using cmake and requires blacs as # versions before 2.0.0 are not using cmake and requires blacs as
# a separated package # a separated package
variant('shared', default=True, variant(
description='Build the shared library version') 'shared',
variant('fpic', default=False, default=True,
description="Build with -fpic compiler option") description='Build the shared library version'
)
variant(
'fpic',
default=False,
description='Build with -fpic compiler option'
)
provides('scalapack') provides('scalapack')
@ -51,6 +58,13 @@ class NetlibScalapack(Package):
depends_on('blas') depends_on('blas')
depends_on('cmake', when='@2.0.0:', type='build') 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): def install(self, spec, prefix):
options = [ options = [
"-DBUILD_SHARED_LIBS:BOOL=%s" % ('ON' if '+shared' in spec else "-DBUILD_SHARED_LIBS:BOOL=%s" % ('ON' if '+shared' in spec else
@ -60,14 +74,13 @@ def install(self, spec, prefix):
] ]
# Make sure we use Spack's Lapack: # Make sure we use Spack's Lapack:
blas = spec['blas'].blas_libs
lapack = spec['lapack'].lapack_libs
options.extend([ options.extend([
'-DLAPACK_FOUND=true', '-DLAPACK_FOUND=true',
'-DLAPACK_LIBRARIES=%s' % ( '-DLAPACK_INCLUDE_DIRS=%s' % spec['lapack'].prefix.include,
spec['lapack'].lapack_shared_lib if '+shared' in spec else '-DLAPACK_LIBRARIES=%s' % (lapack.joined()),
spec['lapack'].lapack_static_lib), '-DBLAS_LIBRARIES=%s' % (blas.joined())
'-DBLAS_LIBRARIES=%s' % (
spec['blas'].blas_shared_lib if '+shared' in spec else
spec['blas'].blas_static_lib)
]) ])
if '+fpic' in spec: if '+fpic' in spec:
@ -86,12 +99,3 @@ def install(self, spec, prefix):
# The shared libraries are not installed correctly on Darwin: # The shared libraries are not installed correctly on Darwin:
if (sys.platform == 'darwin') and ('+shared' in spec): if (sys.platform == 'darwin') and ('+shared' in spec):
fix_darwin_install_name(prefix.lib) 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)]

View File

@ -66,6 +66,9 @@ class Nwchem(Package):
patch('Gcc6_macs_optfix.patch', when='@6.6', level=0) patch('Gcc6_macs_optfix.patch', when='@6.6', level=0)
def install(self, spec, prefix): 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 # see http://www.nwchem-sw.org/index.php/Compiling_NWChem
args = [] args = []
args.extend([ args.extend([
@ -79,13 +82,11 @@ def install(self, spec, prefix):
'USE_PYTHONCONFIG=y', 'USE_PYTHONCONFIG=y',
'PYTHONVERSION=%s' % spec['python'].version.up_to(2), 'PYTHONVERSION=%s' % spec['python'].version.up_to(2),
'PYTHONHOME=%s' % spec['python'].prefix, 'PYTHONHOME=%s' % spec['python'].prefix,
'BLASOPT=%s %s' % ( 'BLASOPT=%s' % ((lapack + blas).ld_flags),
to_link_flags(spec['lapack'].lapack_shared_lib), 'BLAS_LIB=%s' % blas.ld_flags,
to_link_flags(spec['blas'].blas_shared_lib)), 'LAPACK_LIB=%s' % lapack.ld_flags,
'BLAS_LIB=%s' % to_link_flags(spec['blas'].blas_shared_lib),
'LAPACK_LIB=%s' % to_link_flags(spec['lapack'].lapack_shared_lib),
'USE_SCALAPACK=y', 'USE_SCALAPACK=y',
'SCALAPACK=%s' % spec['scalapack'].fc_link, 'SCALAPACK=%s' % scalapack.ld_flags,
'NWCHEM_MODULES=all python', 'NWCHEM_MODULES=all python',
'NWCHEM_LONG_PATHS=Y' # by default NWCHEM_TOP is 64 char max 'NWCHEM_LONG_PATHS=Y' # by default NWCHEM_TOP is 64 char max
]) ])

View File

@ -46,13 +46,13 @@ class Octopus(Package):
# FEAST, Libfm, PFFT, ISF, PNFFT # FEAST, Libfm, PFFT, ISF, PNFFT
def install(self, spec, prefix): def install(self, spec, prefix):
lapack = spec['lapack'].lapack_libs
blas = spec['blas'].blas_libs
args = [] args = []
args.extend([ args.extend([
'--prefix=%s' % prefix, '--prefix=%s' % prefix,
'--with-blas=%s' % to_link_flags( '--with-blas=%s' % blas.ld_flags,
spec['blas'].blas_shared_lib), '--with-lapack=%s' % lapack.ld_flags,
'--with-lapack=%s' % to_link_flags(
spec['lapack'].lapack_shared_lib),
'--with-gsl-prefix=%s' % spec['gsl'].prefix, '--with-gsl-prefix=%s' % spec['gsl'].prefix,
'--with-libxc-prefix=%s' % spec['libxc'].prefix, '--with-libxc-prefix=%s' % spec['libxc'].prefix,
'CC=%s' % spec['mpi'].mpicc, 'CC=%s' % spec['mpi'].mpicc,

View File

@ -51,6 +51,17 @@ class Openblas(Package):
patch('make.patch') 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): def install(self, spec, prefix):
# As of 06/2016 there is no mechanism to specify that packages which # 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 # depends on Blas/Lapack need C or/and Fortran symbols. For now
@ -100,6 +111,9 @@ def install(self, spec, prefix):
# no quotes around prefix (spack doesn't use a shell) # no quotes around prefix (spack doesn't use a shell)
make('install', "PREFIX=%s" % prefix, *make_defs) 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 # Blas virtual package should provide blas.a and libblas.a
with working_dir(prefix.lib): with working_dir(prefix.lib):
symlink('libopenblas.a', 'blas.a') symlink('libopenblas.a', 'blas.a')
@ -120,21 +134,6 @@ def install(self, spec, prefix):
# test. # test.
self.check_install(spec) 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): def check_install(self, spec):
source_file = join_path(os.path.dirname(self.module.__file__), source_file = join_path(os.path.dirname(self.module.__file__),
'test_cblas_dgemm.c') 'test_cblas_dgemm.c')

View File

@ -37,12 +37,8 @@ class Opium(Package):
depends_on('lapack') depends_on('lapack')
def install(self, spec, prefix): def install(self, spec, prefix):
options = [ libs = spec['lapack'].lapack_libs + spec['blas'].blas_libs
'LDFLAGS=%s %s' % ( options = ['LDFLAGS=%s' % libs.ld_flags]
to_link_flags(spec['lapack'].lapack_shared_lib),
to_link_flags(spec['blas'].blas_shared_lib)
)
]
configure(*options) configure(*options)
with working_dir("src", create=False): with working_dir("src", create=False):

View File

@ -67,8 +67,8 @@ def install(self, spec, prefix):
'@PARMETIS_PREFIX': self.spec['parmetis'].prefix, '@PARMETIS_PREFIX': self.spec['parmetis'].prefix,
'@LAPACK_PREFIX': self.spec['lapack'].prefix, '@LAPACK_PREFIX': self.spec['lapack'].prefix,
'@BLAS_PREFIX': self.spec['blas'].prefix, '@BLAS_PREFIX': self.spec['blas'].prefix,
'@LAPACK_LIBS': self.spec['lapack'].lapack_shared_lib, '@LAPACK_LIBS': self.spec['lapack'].lapack_libs.joined(),
'@BLAS_LIBS': self.spec['lapack'].blas_shared_lib, '@BLAS_LIBS': self.spec['lapack'].blas_libs.joined(),
'@STDCXX_LIB': ' '.join(self.compiler.stdcxx_libs) '@STDCXX_LIB': ' '.join(self.compiler.stdcxx_libs)
} }

View File

@ -62,9 +62,10 @@ class Psi4(Package):
def install(self, spec, prefix): def install(self, spec, prefix):
cmake_args = [ cmake_args = [
'-DBLAS_TYPE={0}'.format(spec['blas'].name.upper()), '-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_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_INCLUDEDIR={0}'.format(spec['boost'].prefix.include),
'-DBOOST_LIBRARYDIR={0}'.format(spec['boost'].prefix.lib), '-DBOOST_LIBRARYDIR={0}'.format(spec['boost'].prefix.lib),
'-DENABLE_CHEMPS2=OFF' '-DENABLE_CHEMPS2=OFF'

View File

@ -47,7 +47,7 @@ def install(self, spec, prefix):
env['ATLAS'] = join_path( env['ATLAS'] = join_path(
spec['atlas'].prefix.lib, 'libatlas.' + dso_suffix) spec['atlas'].prefix.lib, 'libatlas.' + dso_suffix)
else: else:
env['BLAS'] = spec['blas'].blas_shared_lib env['BLAS'] = spec['blas'].blas_libs.joined()
env['LAPACK'] = spec['lapack'].lapack_shared_lib env['LAPACK'] = spec['lapack'].lapack_libs.joined()
python('setup.py', 'install', '--prefix=%s' % prefix) python('setup.py', 'install', '--prefix=%s' % prefix)

View File

@ -80,8 +80,8 @@ def install(self, spec, prefix):
# Make sure Spack's Blas/Lapack is used. Otherwise System's # Make sure Spack's Blas/Lapack is used. Otherwise System's
# Blas/Lapack might be picked up. # Blas/Lapack might be picked up.
blas = to_link_flags(spec['blas'].blas_shared_lib) blas = spec['blas'].blas_libs.ld_flags
lapack = to_link_flags(spec['lapack'].lapack_shared_lib) lapack = spec['lapack'].lapack_libs.ld_flags
if '@4.5.1' in spec: if '@4.5.1' in spec:
# adding -lstdc++ is clearly an ugly way to do this, but it follows # 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 # with the TCOV path of SparseSuite 4.5.1's Suitesparse_config.mk

View File

@ -79,9 +79,9 @@ def install(self, spec, prefix):
if '+lapack' in spec: if '+lapack' in spec:
cmake_args.extend([ cmake_args.extend([
'-DLAPACK_ENABLE=ON', '-DLAPACK_ENABLE=ON',
'-DLAPACK_LIBRARIES={0};{1}'.format( '-DLAPACK_LIBRARIES={0}'.format(
spec['lapack'].lapack_shared_lib, (spec['lapack'].lapack_libs +
spec['blas'].blas_shared_lib spec['blas'].blas_libs).joined(';')
) )
]) ])
else: else:

View File

@ -46,15 +46,14 @@ class SuperluDist(Package):
depends_on('metis@5:') depends_on('metis@5:')
def install(self, spec, prefix): def install(self, spec, prefix):
lapack_blas = spec['lapack'].lapack_libs + spec['blas'].blas_libs
makefile_inc = [] makefile_inc = []
makefile_inc.extend([ makefile_inc.extend([
'PLAT = _mac_x', 'PLAT = _mac_x',
'DSuperLUroot = %s' % self.stage.source_path, 'DSuperLUroot = %s' % self.stage.source_path,
'DSUPERLULIB = $(DSuperLUroot)/lib/libsuperlu_dist.a', 'DSUPERLULIB = $(DSuperLUroot)/lib/libsuperlu_dist.a',
'BLASDEF = -DUSE_VENDOR_BLAS', 'BLASDEF = -DUSE_VENDOR_BLAS',
'BLASLIB = %s %s' % 'BLASLIB = %s' % lapack_blas.ld_flags,
(to_link_flags(spec['lapack'].lapack_shared_lib),
to_link_flags(spec['blas'].blas_shared_lib)),
'METISLIB = -L%s -lmetis' % spec['metis'].prefix.lib, 'METISLIB = -L%s -lmetis' % spec['metis'].prefix.lib,
'PARMETISLIB = -L%s -lparmetis' % spec['parmetis'].prefix.lib, 'PARMETISLIB = -L%s -lparmetis' % spec['parmetis'].prefix.lib,
'FLIBS =', 'FLIBS =',

View File

@ -42,7 +42,7 @@ def install(self, spec, prefix):
'-DCMAKE_POSITION_INDEPENDENT_CODE=ON', '-DCMAKE_POSITION_INDEPENDENT_CODE=ON',
# BLAS support # BLAS support
'-Denable_blaslib=OFF', '-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) cmake_args.extend(std_cmake_args)

View File

@ -132,6 +132,8 @@ def install(self, spec, prefix):
mpi_bin = spec['mpi'].prefix.bin mpi_bin = spec['mpi'].prefix.bin
# Note: -DXYZ_LIBRARY_NAMES= needs semicolon separated list of names # Note: -DXYZ_LIBRARY_NAMES= needs semicolon separated list of names
blas = spec['blas'].blas_libs
lapack = spec['lapack'].lapack_libs
options.extend([ options.extend([
'-DTrilinos_ENABLE_ALL_PACKAGES:BOOL=ON', '-DTrilinos_ENABLE_ALL_PACKAGES:BOOL=ON',
'-DTrilinos_ENABLE_ALL_OPTIONAL_PACKAGES:BOOL=ON', '-DTrilinos_ENABLE_ALL_OPTIONAL_PACKAGES:BOOL=ON',
@ -145,12 +147,10 @@ def install(self, spec, prefix):
'-DTPL_ENABLE_MPI:BOOL=ON', '-DTPL_ENABLE_MPI:BOOL=ON',
'-DMPI_BASE_DIR:PATH=%s' % spec['mpi'].prefix, '-DMPI_BASE_DIR:PATH=%s' % spec['mpi'].prefix,
'-DTPL_ENABLE_BLAS=ON', '-DTPL_ENABLE_BLAS=ON',
'-DBLAS_LIBRARY_NAMES=%s' % to_lib_name( '-DBLAS_LIBRARY_NAMES=%s' % ';'.join(blas.names),
spec['blas'].blas_shared_lib),
'-DBLAS_LIBRARY_DIRS=%s' % spec['blas'].prefix.lib, '-DBLAS_LIBRARY_DIRS=%s' % spec['blas'].prefix.lib,
'-DTPL_ENABLE_LAPACK=ON', '-DTPL_ENABLE_LAPACK=ON',
'-DLAPACK_LIBRARY_NAMES=%s' % to_lib_name( '-DLAPACK_LIBRARY_NAMES=%s' % ';'.join(lapack.names),
spec['lapack'].lapack_shared_lib),
'-DLAPACK_LIBRARY_DIRS=%s' % spec['lapack'].prefix.lib, '-DLAPACK_LIBRARY_DIRS=%s' % spec['lapack'].prefix.lib,
'-DTrilinos_ENABLE_EXPLICIT_INSTANTIATION:BOOL=ON', '-DTrilinos_ENABLE_EXPLICIT_INSTANTIATION:BOOL=ON',
'-DTrilinos_ENABLE_CXX11:BOOL=ON', '-DTrilinos_ENABLE_CXX11:BOOL=ON',

View File

@ -47,13 +47,12 @@ class Wannier90(Package):
def install(self, spec, prefix): def install(self, spec, prefix):
lapack = self.spec['lapack'].lapack_libs
blas = self.spec['blas'].blas_libs
substitutions = { substitutions = {
'@F90': spack_fc, '@F90': spack_fc,
'@MPIF90': self.spec['mpi'].mpifc, '@MPIF90': self.spec['mpi'].mpifc,
'@LIBS': ' '.join([ '@LIBS': (lapack + blas).joined()
self.spec['lapack'].lapack_shared_lib,
self.spec['lapack'].blas_shared_lib
])
} }
####### #######
# TODO : this part is replicated in PEXSI # TODO : this part is replicated in PEXSI