xref: /petsc/config/BuildSystem/config/packages/MUMPS.py (revision d7cc930e14e615e9907267aaa472dd0ccceeab82)
1import config.package
2
3class Configure(config.package.Package):
4  def __init__(self, framework):
5    config.package.Package.__init__(self, framework)
6    self.version          = '5.3.3'
7    self.minversion       = '5.2.1'
8    self.versionname      = 'MUMPS_VERSION'
9    self.gitcommit        = 'v'+self.version+'-p2'
10    self.download         = ['git://https://bitbucket.org/petsc/pkg-mumps.git',
11                             'https://bitbucket.org/petsc/pkg-mumps/get/'+self.gitcommit+'.tar.gz']
12    self.download_darwin  = ['https://bitbucket.org/petsc/pkg-mumps/get/v5.2.1-p2.tar.gz']
13    self.downloaddirnames = ['petsc-pkg-mumps','MUMPS']
14    self.liblist          = [['libcmumps.a','libdmumps.a','libsmumps.a','libzmumps.a','libmumps_common.a','libpord.a'],
15                            ['libcmumps.a','libdmumps.a','libsmumps.a','libzmumps.a','libmumps_common.a','libpord.a','libpthread.a'],
16                            ['libcmumps.a','libdmumps.a','libsmumps.a','libzmumps.a','libmumps_common.a','libpord.a','libmpiseq.a'],
17                            ['libcmumps.a','libdmumps.a','libsmumps.a','libzmumps.a','libmumps_common.a','libpord.a','libpthread.a','libmpiseq.a']]
18    self.functions        = ['dmumps_c']
19    self.includes         = ['dmumps_c.h']
20    #
21    self.fc               = 1
22    self.precisions       = ['single','double']
23    self.downloadonWindows= 1
24    self.hastests         = 1
25    self.hastestsdatafiles= 1
26    return
27
28  def setupHelp(self, help):
29    import nargs
30    config.package.Package.setupHelp(self, help)
31    help.addArgument('MUMPS', '-with-mumps-serial', nargs.ArgBool(None, 0, 'Use serial build of MUMPS'))
32    return
33
34  def setupDependencies(self, framework):
35    config.package.Package.setupDependencies(self, framework)
36    self.flibs            = framework.require('config.packages.flibs',self)
37    self.blasLapack       = framework.require('config.packages.BlasLapack',self)
38    self.mpi              = framework.require('config.packages.MPI',self)
39    self.metis            = framework.require('config.packages.metis',self)
40    self.parmetis         = framework.require('config.packages.parmetis',self)
41    self.ptscotch         = framework.require('config.packages.PTScotch',self)
42    self.scalapack        = framework.require('config.packages.scalapack',self)
43    if self.argDB['with-mumps-serial']:
44      self.deps           = [self.blasLapack,self.flibs]
45      self.odeps          = [self.metis]
46    else:
47      self.deps           = [self.scalapack,self.mpi,self.blasLapack,self.flibs]
48      self.odeps          = [self.metis,self.parmetis,self.ptscotch]
49    self.openmp           = framework.require('config.packages.openmp',self)
50    return
51
52  def consistencyChecks(self):
53    config.package.Package.consistencyChecks(self)
54    if self.argDB['with-'+self.package] or self.argDB['download-'+self.package]:
55      if self.mpi.usingMPIUni and not self.argDB['with-mumps-serial']:
56        raise RuntimeError('Since you are building without MPI you must use --with-mumps-serial to install the correct MUMPS.')
57    if self.argDB['with-mumps-serial']:
58      if not self.mpi.usingMPIUni:
59        raise RuntimeError('Serial MUMPS version is only compatible with MPIUni\nReconfigure using --with-mpi=0')
60    return
61
62  def Install(self):
63    import os
64
65    if self.openmp.found:
66      #  MUMPS has no make flags for turning on/off OpenMP it just uses it if it can
67      self.usesopenmp = 'yes'
68      # use OMP_NUM_THREADS to control the number of threads used
69
70    if not self.fortran.FortranDefineCompilerOption:
71      raise RuntimeError('Fortran compiler cannot handle preprocessing directives from command line.')
72    g = open(os.path.join(self.packageDir,'Makefile.inc'),'w')
73    g.write('LPORDDIR   = $(topdir)/PORD/lib/\n')
74    g.write('IPORD      = -I$(topdir)/PORD/include/\n')
75    g.write('LPORD      = -L$(LPORDDIR) -lpord\n')
76    g.write('PLAT       = \n')
77    orderingsc = '-Dpord'
78    orderingsf = self.fortran.FortranDefineCompilerOption+'pord'
79    # Disable threads on BGL
80    if self.libraries.isBGL():
81      orderingsc += ' -DWITHOUT_PTHREAD'
82    if self.metis.found:
83      g.write('IMETIS = '+self.headers.toString(self.metis.include)+'\n')
84      g.write('LMETIS = '+self.libraries.toString(self.metis.lib)+'\n')
85      orderingsc += ' -Dmetis'
86      orderingsf += ' '+self.fortran.FortranDefineCompilerOption+'metis'
87    if self.parmetis.found:
88      g.write('IPARMETIS = '+self.headers.toString(self.parmetis.include)+'\n')
89      g.write('LPARMETIS = '+self.libraries.toString(self.parmetis.lib)+'\n')
90      orderingsc += ' -Dparmetis'
91      orderingsf += ' '+self.fortran.FortranDefineCompilerOption+'parmetis'
92    if self.ptscotch.found:
93      g.write('ISCOTCH = '+self.headers.toString(self.ptscotch.include)+'\n')
94      g.write('LSCOTCH = '+self.libraries.toString(self.ptscotch.lib)+'\n')
95      orderingsc += ' -Dscotch  -Dptscotch'
96      orderingsf += ' '+self.fortran.FortranDefineCompilerOption+'scotch '+self.fortran.FortranDefineCompilerOption+'ptscotch'
97
98    g.write('ORDERINGSC = '+orderingsc+'\n')
99    g.write('ORDERINGSF = '+orderingsf+'\n')
100    g.write('LORDERINGS  = $(LPARMETIS) $(LMETIS) $(LPORD) $(LSCOTCH)\n')
101    g.write('IORDERINGSC = $(IPARMETIS) $(IMETIS) $(IPORD) $(ISCOTCH)\n')
102    g.write('IORDERINGSF = $(ISCOTCH)\n')
103
104    g.write('RM = /bin/rm -f\n')
105    self.setCompilers.pushLanguage('C')
106    g.write('CC = '+self.setCompilers.getCompiler()+'\n')
107    g.write('OPTC    = ' + self.removeWarningFlags(self.setCompilers.getCompilerFlags())+'\n')
108    g.write('OUTC = -o \n')
109    self.setCompilers.popLanguage()
110    if not self.fortran.fortranIsF90:
111      raise RuntimeError('Installing MUMPS requires a F90 compiler')
112    self.setCompilers.pushLanguage('FC')
113    g.write('FC = '+self.setCompilers.getCompiler()+'\n')
114    g.write('FL = '+self.setCompilers.getCompiler()+'\n')
115    extra_fcflags = ''
116    if config.setCompilers.Configure.isNAG(self.setCompilers.getLinker(), self.log):
117      extra_fcflags = '-dusty -dcfuns '
118    elif config.setCompilers.Configure.isGfortran100plus(self.setCompilers.getCompiler(), self.log):
119      extra_fcflags = '-fallow-argument-mismatch '
120    g.write('OPTF    = '+extra_fcflags+self.removeWarningFlags(self.setCompilers.getCompilerFlags())+'\n')
121    if self.blasLapack.checkForRoutine('dgemmt'):
122      g.write('OPTF   += -DGEMMT_AVAILABLE \n')
123    g.write('OUTF = -o \n')
124    self.setCompilers.popLanguage()
125
126    # set fortran name mangling
127    # this mangling information is for both BLAS and the Fortran compiler so cannot use the BlasLapack mangling flag
128    if self.compilers.fortranManglingDoubleUnderscore:
129      g.write('CDEFS   = -DAdd__\n')
130    elif self.compilers.fortranMangling == 'underscore':
131      g.write('CDEFS   = -DAdd_\n')
132    elif self.compilers.fortranMangling == 'caps':
133      g.write('CDEFS   = -DUPPPER\n')
134
135    g.write('AR      = '+self.setCompilers.AR+' '+self.setCompilers.AR_FLAGS+' \n')
136    g.write('LIBEXT  = .'+self.setCompilers.AR_LIB_SUFFIX+'\n')
137    g.write('RANLIB  = '+self.setCompilers.RANLIB+'\n')
138    g.write('SCALAP  = '+self.libraries.toString(self.scalapack.lib)+'\n')
139    if not self.argDB['with-mumps-serial']:
140      g.write('INCPAR  = '+self.headers.toString(self.mpi.include)+'\n')
141      g.write('LIBPAR  = $(SCALAP) '+self.libraries.toString(self.mpi.lib)+'\n')
142    else:
143      g.write('INCPAR  = -I../libseq\n')
144    g.write('INCSEQ  = -I$(topdir)/libseq\n')
145    g.write('LIBSEQ  =  $(LAPACK) -L$(topdir)/libseq -lmpiseq\n')
146    g.write('LIBBLAS = '+self.libraries.toString(self.blasLapack.dlib)+'\n')
147    g.write('OPTL    = '+self.setCompilers.getLinkerFlags()+'\n')
148    g.write('INCS = $(INCPAR)\n')
149    g.write('LIBS = $(LIBPAR)\n')
150    if self.argDB['with-mumps-serial']:
151      g.write('LIBSEQNEEDED = libseqneeded\n')
152      g.write('LIBS = $(LIBSEQ)\n')
153    else:
154      g.write('LIBSEQNEEDED =\n')
155    g.close()
156    if self.installNeeded('Makefile.inc'):
157      try:
158        output1,err1,ret1  = config.package.Package.executeShellCommand('make clean', cwd=self.packageDir, timeout=60, log = self.log)
159      except RuntimeError as e:
160        pass
161      try:
162        self.logPrintBox('Compiling Mumps; this may take several minutes')
163        output2,err2,ret2 = config.package.Package.executeShellCommand(self.make.make_jnp+' alllib', cwd=self.packageDir, timeout=2500, log = self.log)
164        libDir     = os.path.join(self.installDir, self.libdir)
165        includeDir = os.path.join(self.installDir, self.includedir)
166        self.logPrintBox('Installing Mumps; this may take several minutes')
167        self.installDirProvider.printSudoPasswordMessage()
168        output,err,ret = config.package.Package.executeShellCommandSeq(
169          [self.installSudo+'mkdir -p '+libDir+' '+includeDir,
170           self.installSudo+'cp -f lib/*.* '+libDir+'/.',
171           self.installSudo+'cp -f include/*.* '+includeDir+'/.'
172          ], cwd=self.packageDir, timeout=60, log = self.log)
173        if self.argDB['with-mumps-serial']:
174          output,err,ret = config.package.Package.executeShellCommand([self.installSudo+'cp', '-f', 'libseq/libmpiseq.a', libDir+'/.'], cwd=self.packageDir, timeout=60, log = self.log)
175      except RuntimeError as e:
176        self.logPrint('Error running make on MUMPS: '+str(e))
177        raise RuntimeError('Error running make on MUMPS')
178      self.postInstall(output1+err1+output2+err2,'Makefile.inc')
179    return self.installDir
180
181