Update Package : Zoltan (#1793)

* Refactored and reorganized the 'zoltan' install script.

* Fixed a few bugs with the '+mpi' and '+fortan' variants of 'zoltan'.

* Reintroduced and improved the '+shared' variant for the 'zoltan' package.

* Improved compatibility with different MPI providers for 'zoltan'.
This commit is contained in:
Joseph Ciurej 2016-09-20 02:46:13 -07:00 committed by Todd Gamblin
parent c9fe2cd469
commit e73a7c80bf

View File

@ -22,10 +22,11 @@
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
from spack import *
import re
import os
import glob
from spack import *
class Zoltan(Package):
@ -47,23 +48,28 @@ class Zoltan(Package):
version('3.6', '9cce794f7241ecd8dbea36c3d7a880f9')
version('3.3', '5eb8f00bda634b25ceefa0122bd18d65')
variant('debug', default=False,
description='Builds a debug version of the library')
variant('shared', default=True,
description='Builds a shared version of the library')
variant('debug', default=False, description='Builds a debug version of the library.')
variant('shared', default=True, description='Builds a shared version of the library.')
variant('fortran', default=True, description='Enable Fortran support')
variant('mpi', default=False, description='Enable MPI support')
variant('fortran', default=True, description='Enable Fortran support.')
variant('mpi', default=True, description='Enable MPI support.')
depends_on('mpi', when='+mpi')
def install(self, spec, prefix):
config_args = [
'--enable-f90interface'
if '+fortan' in spec else '--disable-f90interface',
def url_for_version(self, version):
return '%s/zoltan_distrib_v%s.tar.gz' % (Zoltan.base_url, version)
'--enable-mpi'
if '+mpi' in spec else '--disable-mpi',
def install(self, spec, prefix):
# FIXME: The older Zoltan versions fail to compile the F90 MPI wrappers
# because of some complicated generic type problem.
if spec.satisfies('@:3.6+fortran+mpi'):
raise RuntimeError(('Cannot build Zoltan v{0} with +fortran and '
'+mpi; please disable one of these features '
'or upgrade versions.').format(self.version))
config_args = [
self.get_config_flag('f90interface', 'fortran'),
self.get_config_flag('mpi', 'mpi'),
]
config_cflags = [
'-O0' if '+debug' in spec else '-O3',
@ -71,49 +77,70 @@ def install(self, spec, prefix):
]
if '+shared' in spec:
config_args.append('--with-ar=$(CXX) -shared $(LDFLAGS) -o')
config_args.append('RANLIB=echo')
config_args.append('--with-ar=$(CXX) -shared $(LDFLAGS) -o')
config_cflags.append('-fPIC')
if spec.satisfies('%gcc'):
config_args.append('--with-libs={0}'.format('-lgfortran'))
if '+mpi' in spec:
config_args.append('CC=%s/mpicc' % spec['mpi'].prefix.bin)
config_args.append('CXX=%s/mpicxx' % spec['mpi'].prefix.bin)
config_args.append('--with-mpi=%s' % spec['mpi'].prefix)
config_args.append('--with-mpi-compilers=%s' %
spec['mpi'].prefix.bin)
config_args.append('CC={0}'.format(spec['mpi'].mpicc))
config_args.append('CXX={0}'.format(spec['mpi'].mpicxx))
config_args.append('FC={0}'.format(spec['mpi'].mpifc))
mpi_libs = ' -l'.join(self.get_mpi_libs())
config_args.append('--with-mpi={0}'.format(spec['mpi'].prefix))
config_args.append('--with-mpi-libs=-l{0}'.format(mpi_libs))
# NOTE: Early versions of Zoltan come packaged with a few embedded
# library packages (e.g. ParMETIS, Scotch), which messes with Spack's
# ability to descend directly into the package's source directory.
source_directory = self.stage.source_path
if spec.satisfies('@:3.6'):
cd('Zoltan_v%s' % self.version)
zoltan_directory = 'Zoltan_v{0}'.format(self.version)
source_directory = join_path(source_directory, zoltan_directory)
mkdirp('build')
cd('build')
build_directory = join_path(source_directory, 'build')
with working_dir(build_directory, create=True):
config = Executable(join_path(source_directory, 'configure'))
config(
'--prefix={0}'.format(prefix),
'--with-cflags={0}'.format(' '.join(config_cflags)),
'--with-cxxflags={0}'.format(' '.join(config_cflags)),
'--with-fcflags={0}'.format(' '.join(config_cflags)),
*config_args
)
config_zoltan = Executable('../configure')
config_zoltan(
'--prefix=%s' % pwd(),
'--with-cflags=%s' % ' '.join(config_cflags),
'--with-cxxflags=%s' % ' '.join(config_cflags),
*config_args)
make()
make('install')
# NOTE: Earlier versions of Zoltan cannot be built in parallel
# because they contain nested Makefile dependency bugs.
make(parallel=not spec.satisfies('@:3.6+fortran'))
make('install')
# NOTE: Unfortunately, Zoltan doesn't provide any configuration
# options for the extension of the output library files, so this
# script must change these extensions as a post-processing step.
if '+shared' in spec:
for libpath in glob.glob('lib/*.a'):
libdir, libname = (os.path.dirname(libpath),
os.path.basename(libpath))
move(libpath, os.path.join(
libdir, re.sub(r'\.a$', '.so', libname)))
for lib_path in glob.glob(join_path(prefix, 'lib', '*.a')):
lib_static_name = os.path.basename(lib_path)
lib_shared_name = re.sub(r'\.a$', '.{0}'.format(dso_suffix),
lib_static_name)
move(lib_path, join_path(prefix, 'lib', lib_shared_name))
mkdirp(prefix)
move('include', prefix)
move('lib', prefix)
def get_config_flag(self, flag_name, flag_variant):
flag_pre = 'en' if '+{0}'.format(flag_variant) in self.spec else 'dis'
return '--{0}able-{1}'.format(flag_pre, flag_name)
def url_for_version(self, version):
return '%s/zoltan_distrib_v%s.tar.gz' % (Zoltan.base_url, version)
# NOTE: Zoltan assumes that it's linking against an MPI library that can
# be found with '-lmpi,' which isn't the case for many MPI packages. This
# function finds the names of the actual libraries for Zoltan's MPI dep.
def get_mpi_libs(self):
mpi_libs = set()
for lib_path in glob.glob(join_path(self.spec['mpi'].prefix.lib, '*')):
mpi_lib_match = re.match(
r'^(lib)((\w*)mpi(\w*))\.((a)|({0}))$'.format(dso_suffix),
os.path.basename(lib_path))
if mpi_lib_match:
mpi_libs.add(mpi_lib_match.group(2))
return list(mpi_libs)