Merge pull request #1023 from epfl-scitas/packages/mumps

Corrected the shared libraries and tests in mumps package
This commit is contained in:
Todd Gamblin 2016-06-20 10:48:12 -07:00 committed by GitHub
commit 9b299cb2bb
2 changed files with 211 additions and 70 deletions

View file

@ -0,0 +1,119 @@
diff -Naur MUMPS_5.0.1/libseq/Makefile MUMPS_5.0.1.new/libseq/Makefile
--- MUMPS_5.0.1/libseq/Makefile 2015-07-23 19:08:32.000000000 +0200
+++ MUMPS_5.0.1.new/libseq/Makefile 2016-06-07 10:41:16.585179151 +0200
@@ -8,11 +8,15 @@
include ../Makefile.inc
-libmpiseq: libmpiseq$(PLAT)$(LIBEXT)
+libmpiseq: libmpiseq$(PLAT)$(LIBEXT) libmpiseq$(PLAT)$(SHLIBEXT)
libmpiseq$(PLAT)$(LIBEXT): mpi.o mpic.o elapse.o
$(AR)$@ mpi.o mpic.o elapse.o
$(RANLIB) $@
+
+libmpiseq$(PLAT)$(SHLIBEXT): mpi.o mpic.o elapse.o
+ $(FC) $(LDFLAGS) $^ -o libmpiseq$(PLAT)$(SHLIBEXT)
+
.f.o:
$(FC) $(OPTF) -c $*.f $(OUTF)$*.o
.c.o:
diff -Naur MUMPS_5.0.1/Makefile MUMPS_5.0.1.new/Makefile
--- MUMPS_5.0.1/Makefile 2015-07-23 19:08:29.000000000 +0200
+++ MUMPS_5.0.1.new/Makefile 2016-06-07 10:50:21.863281217 +0200
@@ -51,7 +51,7 @@
dexamples: d
(cd examples ; $(MAKE) d)
-requiredobj: Makefile.inc $(LIBSEQNEEDED) $(libdir)/libpord$(PLAT)$(LIBEXT)
+requiredobj: Makefile.inc $(LIBSEQNEEDED) $(libdir)/libpord$(PLAT)$(LIBEXT) $(libdir)/libpord$(PLAT)$(SHLIBEXT)
# dummy MPI library (sequential version)
@@ -62,16 +62,25 @@
$(libdir)/libpord$(PLAT)$(LIBEXT):
if [ "$(LPORDDIR)" != "" ] ; then \
cd $(LPORDDIR); \
- $(MAKE) CC="$(CC)" CFLAGS="$(OPTC)" AR="$(AR)" RANLIB="$(RANLIB)" OUTC="$(OUTC)" LIBEXT=$(LIBEXT); \
+ $(MAKE) CC="$(CC)" CFLAGS="$(OPTC)" AR="$(AR)" RANLIB="$(RANLIB)" LDFLAGS="$(LDFLAGS)" OUTC="$(OUTC)" LIBEXT=$(LIBEXT) PLAT=$(PLAT) SHLIBEXT=$(SHLIBEXT); \
fi;
if [ "$(LPORDDIR)" != "" ] ; then \
cp $(LPORDDIR)/libpord$(LIBEXT) $@; \
fi;
+$(libdir)/libpord$(PLAT)$(SHLIBEXT):
+ if [ "$(LPORDDIR)" != "" ] ; then \
+ cd $(LPORDDIR); \
+ $(MAKE) CC="$(CC)" CFLAGS="$(OPTC)" AR="$(AR)" RANLIB="$(RANLIB)" LDFLAGS="$(LDFLAGS)" OUTC="$(OUTC)" LIBEXT=$(LIBEXT) PLAT=$(PLAT) SHLIBEXT=$(SHLIBEXT) libpord$(PLAT)$(SHLIBEXT); \
+ fi;
+ if [ "$(LPORDDIR)" != "" ] ; then \
+ cp $(LPORDDIR)/libpord$(PLAT)$(SHLIBEXT) $@; \
+ fi;
+
clean:
(cd src; $(MAKE) clean)
(cd examples; $(MAKE) clean)
- (cd $(libdir); $(RM) *$(PLAT)$(LIBEXT))
+ (cd $(libdir); $(RM) *$(PLAT)$(LIBEXT) *$(PLAT)$(SHLIBEXT))
(cd libseq; $(MAKE) clean)
if [ "$(LPORDDIR)" != "" ] ; then \
cd $(LPORDDIR); $(MAKE) realclean; \
diff -Naur MUMPS_5.0.1/PORD/lib/Makefile MUMPS_5.0.1.new/PORD/lib/Makefile
--- MUMPS_5.0.1/PORD/lib/Makefile 2015-07-23 19:08:29.000000000 +0200
+++ MUMPS_5.0.1.new/PORD/lib/Makefile 2016-06-07 10:49:48.889000958 +0200
@@ -13,7 +13,7 @@
OBJS = graph.o gbipart.o gbisect.o ddcreate.o ddbisect.o nestdiss.o \
multisector.o gelim.o bucket.o tree.o \
- symbfac.o interface.o sort.o minpriority.o
+ symbfac.o interface.o sort.o minpriority.o
# Note: numfac.c read.c mapping.c triangular.c matrix.c kernel.c
# were not direcly used by MUMPS and have been removed from the
@@ -24,12 +24,15 @@
.c.o:
$(CC) $(COPTIONS) -c $*.c $(OUTC)$*.o
-libpord$(LIBEXT):$(OBJS)
+libpord$(PLAT)$(LIBEXT):$(OBJS)
$(AR)$@ $(OBJS)
$(RANLIB) $@
+libpord$(PLAT)$(SHLIBEXT): $(OBJS)
+ $(CC) $(LDFLAGS) $(OBJS) -o libpord$(PLAT)$(SHLIBEXT)
+
clean:
rm -f *.o
realclean:
- rm -f *.o libpord.a
+ rm -f *.o libpord$(PLAT)$(SHLIBEXT) libpord$(PLAT)$(LIBEXT)
diff -Naur MUMPS_5.0.1/src/Makefile MUMPS_5.0.1.new/src/Makefile
--- MUMPS_5.0.1/src/Makefile 2015-07-23 19:08:29.000000000 +0200
+++ MUMPS_5.0.1.new/src/Makefile 2016-06-07 10:40:52.534703722 +0200
@@ -24,7 +24,10 @@
include $(topdir)/Makefile.inc
mumps_lib: $(libdir)/libmumps_common$(PLAT)$(LIBEXT) \
- $(libdir)/lib$(ARITH)mumps$(PLAT)$(LIBEXT)
+ $(libdir)/libmumps_common$(PLAT)$(SHLIBEXT) \
+ $(libdir)/lib$(ARITH)mumps$(PLAT)$(LIBEXT) \
+ $(libdir)/lib$(ARITH)mumps$(PLAT)$(SHLIBEXT)
+
OBJS_COMMON_MOD = \
ana_omp_m.o\
@@ -162,6 +165,13 @@
$(AR)$@ $?
$(RANLIB) $@
+$(libdir)/libmumps_common$(PLAT)$(SHLIBEXT): $(OBJS_COMMON_MOD) $(OBJS_COMMON_OTHER)
+ $(FC) $(LDFLAGS) $^ -L$(libdir) $(LORDERINGS) $(LIBS) $(LIBBLAS) $(LIBOTHERS) -o $(libdir)/libmumps_common$(PLAT)$(SHLIBEXT)
+
+
+$(libdir)/lib$(ARITH)mumps$(PLAT)$(SHLIBEXT): $(OBJS_MOD) $(OBJS_OTHER)
+ $(FC) $(LDFLAGS) $^ -L$(libdir) -lmumps_common$(PLAT) $(LORDERINGS) $(LIBS) $(LIBBLAS) $(LIBOTHERS) -o $(libdir)/lib$(ARITH)mumps$(PLAT)$(SHLIBEXT)
+
# Dependencies between modules:
$(ARITH)mumps_load.o: $(ARITH)mumps_comm_buffer.o \
$(ARITH)mumps_struc_def.o \

View file

@ -23,7 +23,10 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
############################################################################## ##############################################################################
from spack import * from spack import *
import os, sys, glob import os
import sys
import subprocess
class Mumps(Package): class Mumps(Package):
"""MUMPS: a MUltifrontal Massively Parallel sparse direct Solver""" """MUMPS: a MUltifrontal Massively Parallel sparse direct Solver"""
@ -44,7 +47,6 @@ class Mumps(Package):
variant('idx64', default=False, description='Use int64_t/integer*8 as default index type') variant('idx64', default=False, description='Use int64_t/integer*8 as default index type')
variant('shared', default=True, description='Build shared libraries') variant('shared', default=True, description='Build shared libraries')
depends_on('scotch + esmumps', when='~ptscotch+scotch') depends_on('scotch + esmumps', when='~ptscotch+scotch')
depends_on('scotch + esmumps + mpi', when='+ptscotch') depends_on('scotch + esmumps + mpi', when='+ptscotch')
depends_on('metis@5:', when='+metis') depends_on('metis@5:', when='+metis')
@ -54,49 +56,64 @@ class Mumps(Package):
depends_on('scalapack', when='+mpi') depends_on('scalapack', when='+mpi')
depends_on('mpi', when='+mpi') depends_on('mpi', when='+mpi')
patch('mumps-shared.patch', when='+shared')
# this function is not a patch function because in case scalapack # this function is not a patch function because in case scalapack
# is needed it uses self.spec['scalapack'].fc_link set by the # is needed it uses self.spec['scalapack'].fc_link set by the
# setup_dependent_environment in scalapck. This happen after patch # setup_dependent_environment in scalapck. This happen after patch
# end before install # end before install
# def patch(self): # def patch(self):
def write_makefile_inc(self): def write_makefile_inc(self):
if ('+parmetis' in self.spec or '+ptscotch' in self.spec) and '+mpi' not in self.spec: if (('+parmetis' in self.spec or
raise RuntimeError('You cannot use the variants parmetis or ptscotch without mpi') '+ptscotch' in self.spec)) and '+mpi' not in self.spec:
raise RuntimeError('You cannot use the variants parmetis or ptscotch without mpi') # NOQA: E501
makefile_conf = ["LIBBLAS = -L%s -lblas" % self.spec['blas'].prefix.lib] makefile_conf = [
"LIBBLAS = -L%s -lblas" % self.spec['blas'].prefix.lib
]
orderings = ['-Dpord'] orderings = ['-Dpord']
if '+ptscotch' in self.spec or '+scotch' in self.spec: if '+ptscotch' in self.spec or '+scotch' in self.spec:
join_lib = ' -l%s' % ('pt' if '+ptscotch' in self.spec else '') join_lib = ' -l%s' % ('pt' if '+ptscotch' in self.spec else '')
makefile_conf.extend( makefile_conf.extend([
["ISCOTCH = -I%s" % self.spec['scotch'].prefix.include, "ISCOTCH = -I%s" % self.spec['scotch'].prefix.include,
"LSCOTCH = -L%s %s%s" % (self.spec['scotch'].prefix.lib, "LSCOTCH = -L%s %s%s" % (self.spec['scotch'].prefix.lib,
join_lib, join_lib,
join_lib.join(['esmumps', 'scotch', 'scotcherr']))]) join_lib.join(['esmumps',
'scotch',
'scotcherr']))
])
orderings.append('-Dscotch') orderings.append('-Dscotch')
if '+ptscotch' in self.spec: if '+ptscotch' in self.spec:
orderings.append('-Dptscotch') orderings.append('-Dptscotch')
if '+parmetis' in self.spec and '+metis' in self.spec: if '+parmetis' in self.spec and '+metis' in self.spec:
libname = 'parmetis' if '+parmetis' in self.spec else 'metis' makefile_conf.extend([
makefile_conf.extend( "IMETIS = -I%s" % self.spec['parmetis'].prefix.include,
["IMETIS = -I%s" % self.spec['parmetis'].prefix.include, "LMETIS = -L%s -l%s -L%s -l%s" % (
"LMETIS = -L%s -l%s -L%s -l%s" % (self.spec['parmetis'].prefix.lib, 'parmetis',self.spec['metis'].prefix.lib, 'metis')]) self.spec['parmetis'].prefix.lib, 'parmetis',
self.spec['metis'].prefix.lib, 'metis')
])
orderings.append('-Dparmetis') orderings.append('-Dparmetis')
elif '+metis' in self.spec: elif '+metis' in self.spec:
makefile_conf.extend( makefile_conf.extend([
["IMETIS = -I%s" % self.spec['metis'].prefix.include, "IMETIS = -I%s" % self.spec['metis'].prefix.include,
"LMETIS = -L%s -l%s" % (self.spec['metis'].prefix.lib, 'metis')]) "LMETIS = -L%s -l%s" % (self.spec['metis'].prefix.lib,
'metis')
])
orderings.append('-Dmetis') orderings.append('-Dmetis')
makefile_conf.append("ORDERINGSF = %s" % (' '.join(orderings))) makefile_conf.append("ORDERINGSF = %s" % (' '.join(orderings)))
# when building shared libs need -fPIC, otherwise # when building shared libs need -fPIC, otherwise /usr/bin/ld:
# /usr/bin/ld: graph.o: relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC # graph.o: relocation R_X86_64_32 against `.rodata.str1.1' can
# not be used when making a shared object; recompile with
# -fPIC
fpic = '-fPIC' if '+shared' in self.spec else '' fpic = '-fPIC' if '+shared' in self.spec else ''
# TODO: test this part, it needs a full blas, scalapack and # TODO: test this part, it needs a full blas, scalapack and
# partitionning environment with 64bit integers # partitionning environment with 64bit integers
if '+idx64' in self.spec: if '+idx64' in self.spec:
@ -104,7 +121,7 @@ def write_makefile_inc(self):
# the fortran compilation flags most probably are # the fortran compilation flags most probably are
# working only for intel and gnu compilers this is # working only for intel and gnu compilers this is
# perhaps something the compiler should provide # perhaps something the compiler should provide
['OPTF = %s -O -DALLOW_NON_INIT %s' % (fpic,'-fdefault-integer-8' if self.compiler.name == "gcc" else '-i8'), ['OPTF = %s -O -DALLOW_NON_INIT %s' % (fpic, '-fdefault-integer-8' if self.compiler.name == "gcc" else '-i8'), # NOQA: E501
'OPTL = %s -O ' % fpic, 'OPTL = %s -O ' % fpic,
'OPTC = %s -O -DINTSIZE64' % fpic]) 'OPTC = %s -O -DINTSIZE64' % fpic])
else: else:
@ -113,48 +130,46 @@ def write_makefile_inc(self):
'OPTL = %s -O ' % fpic, 'OPTL = %s -O ' % fpic,
'OPTC = %s -O ' % fpic]) 'OPTC = %s -O ' % fpic])
if '+mpi' in self.spec: if '+mpi' in self.spec:
makefile_conf.extend( makefile_conf.extend(
["CC = %s" % join_path(self.spec['mpi'].prefix.bin, 'mpicc'), ["CC = %s" % self.spec['mpi'].mpicc,
"FC = %s" % join_path(self.spec['mpi'].prefix.bin, 'mpif90'), "FC = %s" % self.spec['mpi'].mpifc,
"FL = %s" % join_path(self.spec['mpi'].prefix.bin, 'mpif90'),
"SCALAP = %s" % self.spec['scalapack'].fc_link, "SCALAP = %s" % self.spec['scalapack'].fc_link,
"MUMPS_TYPE = par"]) "MUMPS_TYPE = par"])
else: else:
makefile_conf.extend( makefile_conf.extend(
["CC = cc", ["CC = cc",
"FC = fc", "FC = fc",
"FL = fc",
"MUMPS_TYPE = seq"]) "MUMPS_TYPE = seq"])
# TODO: change the value to the correct one according to the # TODO: change the value to the correct one according to the
# compiler possible values are -DAdd_, -DAdd__ and/or -DUPPER # compiler possible values are -DAdd_, -DAdd__ and/or -DUPPER
makefile_conf.append("CDEFS = -DAdd_") makefile_conf.extend([
'CDEFS = -DAdd_',
'FL = $(FC)',
])
if '+shared' in self.spec: if '+shared' in self.spec:
makefile_conf.append('SHLIBEXT = .%s' % dso_suffix)
if sys.platform == 'darwin': if sys.platform == 'darwin':
# Building dylibs with mpif90 causes segfaults on 10.8 and 10.10. Use gfortran. (Homebrew) makefile_conf.append(
makefile_conf.extend([ 'LDFLAGS = -dynamiclib -Wl,-install_name -Wl,{0}/$(notdir $@) {1}{0} -undefined dynamic_lookup'.format(prefix.lib, self.compiler.fc_rpath_arg) # NOQA: E501
'LIBEXT=.dylib', )
'AR=%s -dynamiclib -Wl,-install_name -Wl,%s/$(notdir $@) -undefined dynamic_lookup -o ' % (os.environ['FC'],prefix.lib),
'RANLIB=echo'
])
else:
makefile_conf.extend([
'LIBEXT=.so',
'AR=$(FL) -shared -Wl,-soname -Wl,%s/$(notdir $@) -o' % prefix.lib,
'RANLIB=echo'
])
else: else:
makefile_conf.append(
'LDFLAGS = -shared {0}{1}'.format(
self.compiler.fc_rpath_arg,
prefix.lib)
)
makefile_conf.extend([ makefile_conf.extend([
'LIBEXT = .a', 'LIBEXT = .a',
'AR = ar vr', 'AR = ar vr ',
'RANLIB = ranlib' 'RANLIB = ranlib'
]) ])
makefile_inc_template = \
makefile_inc_template = join_path(os.path.dirname(self.module.__file__), join_path(os.path.dirname(self.module.__file__),
'Makefile.inc') 'Makefile.inc')
with open(makefile_inc_template, "r") as fh: with open(makefile_inc_template, "r") as fh:
makefile_conf.extend(fh.read().split('\n')) makefile_conf.extend(fh.read().split('\n'))
@ -164,46 +179,53 @@ def write_makefile_inc(self):
makefile_inc = '\n'.join(makefile_conf) makefile_inc = '\n'.join(makefile_conf)
fh.write(makefile_inc) fh.write(makefile_inc)
def install(self, spec, prefix): def install(self, spec, prefix):
make_libs = [] make_libs = []
# the choice to compile ?examples is to have kind of a sanity # the choice to compile ?examples is to have kind of a sanity
# check on the libraries generated. # check on the libraries generated.
if '+float' in spec: if '+float' in spec:
make_libs.append('sexamples') make_libs.append('s')
if '+complex' in spec: if '+complex' in spec:
make_libs.append('cexamples') make_libs.append('c')
if '+double' in spec: if '+double' in spec:
make_libs.append('dexamples') make_libs.append('d')
if '+complex' in spec: if '+complex' in spec:
make_libs.append('zexamples') make_libs.append('z')
self.write_makefile_inc() self.write_makefile_inc()
# Build fails in parallel make('mumps_lib', parallel=False)
make(*make_libs, parallel=False) make(*make_libs)
install_tree('lib', prefix.lib) install_tree('lib', prefix.lib)
install_tree('include', prefix.include) install_tree('include', prefix.include)
if '~mpi' in spec: if '~mpi' in spec:
lib_dsuffix = '.dylib' if sys.platform == 'darwin' else '.so' install('libseq/libmpiseq.a', prefix.lib)
lib_suffix = lib_dsuffix if '+shared' in spec else '.a' if '+shared' in spec:
install('libseq/libmpiseq%s' % lib_suffix, prefix.lib) install('libseq/libmpiseq.{0}'.format(dso_suffix), prefix.lib)
for f in glob.glob(join_path('libseq','*.h')): install('libseq/mpi.h', prefix.include)
install(f, prefix.include) install('libseq/mpif.h', prefix.include)
# FIXME: extend the tests to mpirun -np 2 (or alike) when
# build with MPI
# FIXME: use something like numdiff to compare blessed output
# with the current
# TODO: test the installed mumps and not the one in stage
if '~mpi' in spec:
for t in make_libs:
make('{0}examples'.format(t))
# FIXME: extend the tests to mpirun -np 2 (or alike) when build with MPI
# FIXME: use something like numdiff to compare blessed output with the current
with working_dir('examples'): with working_dir('examples'):
if '+float' in spec: for t in make_libs:
os.system('./ssimpletest < input_simpletest_real') input_file = 'input_simpletest_{0}'.format(
if '+complex' in spec: 'real' if t in ['s', 'd'] else 'cmplx')
os.system('./csimpletest < input_simpletest_real') with open(input_file) as input:
if '+double' in spec: test = './{0}simpletest'.format(t)
os.system('./dsimpletest < input_simpletest_real') ret = subprocess.call(test,
if '+complex' in spec: stdin=input)
os.system('./zsimpletest < input_simpletest_cmplx') if ret is not 0:
raise RuntimeError(
'The test {0} did not pass'.format(test))