xref: /petsc/config/BuildSystem/config/packages/MUMPS.py (revision 419beca1004e80ebaf01ed86ca4fa04d30fb35e8)
1import config.package
2
3class Configure(config.package.Package):
4  def __init__(self, framework):
5    config.package.Package.__init__(self, framework)
6    self.gitcommit        = 'MUMPS_5.0.1-p1.tar.gz'
7    self.download         = ['git://https://bitbucket.org/petsc/pkg-mumps.git',
8                             'http://ftp.mcs.anl.gov/pub/petsc/externalpackages/MUMPS_5.0.1-p1.tar.gz']
9    self.liblist          = [['libcmumps.a','libdmumps.a','libsmumps.a','libzmumps.a','libmumps_common.a','libpord.a'],
10                            ['libcmumps.a','libdmumps.a','libsmumps.a','libzmumps.a','libmumps_common.a','libpord.a','libpthread.a'],
11                            ['libcmumps.a','libdmumps.a','libsmumps.a','libzmumps.a','libmumps_common.a','libpord.a','libmpiseq.a'],
12                            ['libcmumps.a','libdmumps.a','libsmumps.a','libzmumps.a','libmumps_common.a','libpord.a','libpthread.a','libmpiseq.a']]
13    self.functions        = ['dmumps_c']
14    self.includes         = ['dmumps_c.h']
15    #
16    # Mumps does NOT work with 64 bit integers without a huge number of hacks we ain't making
17    self.requires32bitint = 1;  # 1 means that the package will not work with 64 bit integers
18    self.downloadonWindows= 1
19    self.hastests         = 1
20    self.hastestsdatafiles= 1
21    return
22
23  def setupHelp(self, help):
24    import nargs
25    config.package.Package.setupHelp(self, help)
26    help.addArgument('MUMPS', '-with-mumps-serial', nargs.ArgBool(None, 0, 'Use serial build of MUMPS'))
27    return
28
29  def setupDependencies(self, framework):
30    config.package.Package.setupDependencies(self, framework)
31    self.blasLapack   = framework.require('config.packages.BlasLapack',self)
32    self.mpi          = framework.require('config.packages.MPI',self)
33    self.metis        = framework.require('config.packages.metis',self)
34    self.parmetis     = framework.require('config.packages.parmetis',self)
35    self.ptscotch     = framework.require('config.packages.PTScotch',self)
36    self.scalapack    = framework.require('config.packages.scalapack',self)
37    if self.argDB['with-mumps-serial']:
38      self.deps       = [self.blasLapack]
39      self.odeps      = [self.metis]
40    else:
41      self.deps       = [self.scalapack,self.mpi,self.blasLapack]
42      self.odeps      = [self.metis,self.parmetis,self.ptscotch]
43    return
44
45  def consistencyChecks(self):
46    config.package.Package.consistencyChecks(self)
47    if self.argDB['with-'+self.package] or self.argDB['download-'+self.package]:
48      if self.mpi.usingMPIUni and not self.argDB['with-mumps-serial']:
49        raise RuntimeError('Since you are building without MPI you must use --with-mumps-serial to install the correct MUMPS.')
50    if self.argDB['with-mumps-serial']:
51      if not self.mpi.usingMPIUni:
52        raise RuntimeError('Serial MUMPS version is only compatible with MPIUni\nReconfigure using --with-mpi=0')
53      elif self.mpi.usingMPIUniFortranBinding:
54        raise RuntimeError('Serial MUMPS version is incompatible with the MPIUni Fortran bindings\nReconfigure using --with-mpiuni-fortran-binding=0')
55    return
56
57  def Install(self):
58    import os
59
60    if not hasattr(self.compilers, 'FC'):
61      raise RuntimeError('Cannot install '+self.name+' without Fortran, make sure you do NOT have --with-fc=0')
62    if not self.compilers.FortranDefineCompilerOption:
63      raise RuntimeError('Fortran compiler cannot handle preprocessing directives from command line.')
64    g = open(os.path.join(self.packageDir,'Makefile.inc'),'w')
65    g.write('LPORDDIR   = $(topdir)/PORD/lib/\n')
66    g.write('IPORD      = -I$(topdir)/PORD/include/\n')
67    g.write('LPORD      = -L$(LPORDDIR) -lpord\n')
68    g.write('PLAT       = \n')
69    orderingsc = '-Dpord'
70    orderingsf = self.compilers.FortranDefineCompilerOption+'pord'
71    # Disable threads on BGL
72    if self.libraries.isBGL():
73      orderingsc += ' -DWITHOUT_PTHREAD'
74    if self.metis.found:
75      g.write('IMETIS = '+self.headers.toString(self.metis.include)+'\n')
76      g.write('LMETIS = '+self.libraries.toString(self.metis.lib)+'\n')
77      orderingsc += ' -Dmetis'
78      orderingsf += ' '+self.compilers.FortranDefineCompilerOption+'metis'
79    if self.parmetis.found:
80      g.write('IPARMETIS = '+self.headers.toString(self.parmetis.include)+'\n')
81      g.write('LPARMETIS = '+self.libraries.toString(self.parmetis.lib)+'\n')
82      orderingsc += ' -Dparmetis'
83      orderingsf += ' '+self.compilers.FortranDefineCompilerOption+'parmetis'
84    if self.ptscotch.found:
85      g.write('ISCOTCH = '+self.headers.toString(self.ptscotch.include)+'\n')
86      g.write('LSCOTCH = '+self.libraries.toString(self.ptscotch.lib)+'\n')
87      orderingsc += ' -Dscotch  -Dptscotch'
88      orderingsf += ' '+self.compilers.FortranDefineCompilerOption+'scotch '+self.compilers.FortranDefineCompilerOption+'ptscotch'
89
90    g.write('ORDERINGSC = '+orderingsc+'\n')
91    g.write('ORDERINGSF = '+orderingsf+'\n')
92    g.write('LORDERINGS  = $(LPARMETIS) $(LMETIS) $(LPORD) $(LSCOTCH)\n')
93    g.write('IORDERINGSC = $(IPARMETIS) $(IMETIS) $(IPORD) $(ISCOTCH)\n')
94    g.write('IORDERINGSF = $(ISCOTCH)\n')
95
96    g.write('RM = /bin/rm -f\n')
97    self.setCompilers.pushLanguage('C')
98    g.write('CC = '+self.setCompilers.getCompiler()+'\n')
99    g.write('OPTC    = ' + self.removeWarningFlags(self.setCompilers.getCompilerFlags())+'\n')
100    g.write('OUTC = -o \n')
101    self.setCompilers.popLanguage()
102    if not self.compilers.fortranIsF90:
103      raise RuntimeError('Installing MUMPS requires a F90 compiler')
104    self.setCompilers.pushLanguage('FC')
105    g.write('FC = '+self.setCompilers.getCompiler()+'\n')
106    g.write('FL = '+self.setCompilers.getCompiler()+'\n')
107    g.write('OPTF    = ' + self.setCompilers.getCompilerFlags().replace('-Wall','').replace('-Wshadow','').replace('-Mfree','') +'\n')
108    g.write('OUTF = -o \n')
109    self.setCompilers.popLanguage()
110
111    # set fortran name mangling
112    # this mangling information is for both BLAS and the Fortran compiler so cannot use the BlasLapack mangling flag
113    if self.compilers.fortranManglingDoubleUnderscore:
114      g.write('CDEFS   = -DAdd__\n')
115    elif self.compilers.fortranMangling == 'underscore':
116      g.write('CDEFS   = -DAdd_\n')
117    elif self.compilers.fortranMangling == 'caps':
118      g.write('CDEFS   = -DUPPPER\n')
119
120    g.write('AR      = '+self.setCompilers.AR+' '+self.setCompilers.AR_FLAGS+' \n')
121    g.write('LIBEXT  = .'+self.setCompilers.AR_LIB_SUFFIX+'\n')
122    g.write('RANLIB  = '+self.setCompilers.RANLIB+'\n')
123    g.write('SCALAP  = '+self.libraries.toString(self.scalapack.lib)+'\n')
124    if not self.argDB['with-mumps-serial']:
125      g.write('INCPAR  = '+self.headers.toString(self.mpi.include)+'\n')
126      g.write('LIBPAR  = $(SCALAP) '+self.libraries.toString(self.mpi.lib)+'\n')
127    else:
128      g.write('INCPAR  = -I../libseq\n')
129    g.write('INCSEQ  = -I$(topdir)/libseq\n')
130    g.write('LIBSEQ  =  $(LAPACK) -L$(topdir)/libseq -lmpiseq\n')
131    g.write('LIBBLAS = '+self.libraries.toString(self.blasLapack.dlib)+'\n')
132    g.write('OPTL    = -O -I.\n')
133    g.write('INCS = $(INCPAR)\n')
134    g.write('LIB = $(LIBPAR)\n')
135    if self.argDB['with-mumps-serial']:
136      g.write('LIBSEQNEEDED = libseqneeded\n')
137      g.write('LIBS = $(LIBSEQ)\n')
138    else:
139      g.write('LIBSEQNEEDED =\n')
140    g.close()
141    if self.installNeeded('Makefile.inc'):
142      try:
143        output1,err1,ret1  = config.package.Package.executeShellCommand('cd '+self.packageDir+' && make clean', timeout=2500, log = self.log)
144      except RuntimeError, e:
145        pass
146      try:
147        self.logPrintBox('Compiling Mumps; this may take several minutes')
148        output2,err2,ret2 = config.package.Package.executeShellCommand('cd '+self.packageDir+' &&  make alllib',timeout=2500, log = self.log)
149        libDir     = os.path.join(self.installDir, self.libdir)
150        includeDir = os.path.join(self.installDir, self.includedir)
151        self.logPrintBox('Installing Mumps; this may take several minutes')
152        self.installDirProvider.printSudoPasswordMessage()
153        output,err,ret = config.package.Package.executeShellCommand(self.installSudo+'mkdir -p '+os.path.join(self.installDir,self.libdir)+' && cd '+self.packageDir+' && '+self.installSudo+'cp -f lib/*.* '+libDir+'/. && '+self.installSudo+'mkdir -p '+includeDir+' && '+self.installSudo+'cp -f include/*.* '+includeDir+'/.', timeout=50, log = self.log)
154        if self.argDB['with-mumps-serial']:
155          output,err,ret = config.package.Package.executeShellCommand('cd '+self.packageDir+' && '+self.installSudo+'cp -f libseq/libmpiseq.a '+libDir+'/. ', timeout=25, log = self.log)
156      except RuntimeError, e:
157        raise RuntimeError('Error running make on MUMPS: '+str(e))
158      self.postInstall(output1+err1+output2+err2,'Makefile.inc')
159    return self.installDir
160
161