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