1import config.package 2import os 3 4class Configure(config.package.GNUPackage): 5 def __init__(self, framework): 6 config.package.GNUPackage.__init__(self, framework) 7 self.version = '5.0.0' 8 self.download = ['https://github.com/pmodels/mpich/releases/download/v'+self.version+'/mpich-'+self.version+'.tar.gz', 9 'https://www.mpich.org/static/downloads/'+self.version+'/mpich-'+self.version+'.tar.gz', # does not always work from Python? So add in web.cels URL below 10 'https://web.cels.anl.gov/projects/petsc/download/externalpackages'+'/mpich-'+self.version+'.tar.gz'] 11 self.download_git = ['git://https://github.com/pmodels/mpich.git'] 12 self.versionname = 'MPICH_NUMVERSION' 13 self.includes = ['mpi.h'] 14 self.gitsubmodules = ['.'] 15 self.downloaddirnames = ['mpich'] 16 self.skippackagewithoptions = 1 17 self.skipMPIDependency = 1 18 return 19 20 def setupDependencies(self, framework): 21 config.package.GNUPackage.setupDependencies(self, framework) 22 self.compilerFlags = framework.require('config.compilerFlags',self) 23 self.cuda = framework.require('config.packages.CUDA',self) 24 self.hip = framework.require('config.packages.HIP',self) 25 self.hwloc = framework.require('config.packages.hwloc',self) 26 self.python = framework.require('config.packages.Python',self) 27 self.odeps = [self.cuda, self.hip, self.hwloc] 28 return 29 30 def versionToStandardForm(self,ver): 31 '''Converts from MPICH 10007201 notation to standard notation 1.0.7''' 32 # See the format at https://github.com/pmodels/mpich/blob/main/src/include/mpi.h.in#L78 33 # 1 digit for MAJ, 2 digits for MIN, 2 digits for REV, 1 digit for EXT and 2 digits for EXT_NUMBER 34 return ".".join(map(str,[int(ver)//10000000, int(ver)//100000%100, int(ver)//1000%100])) 35 36 def setupHelp(self, help): 37 config.package.GNUPackage.setupHelp(self,help) 38 import nargs 39 help.addArgument('MPICH', '-download-mpich-pm=<hydra, gforker or mpd>', nargs.Arg(None, 'hydra', 'Launcher for MPI processes')) 40 help.addArgument('MPICH', '-download-mpich-device=<ch3:nemesis or see MPICH docs>', nargs.Arg(None, None, 'Communicator for MPI processes')) 41 return 42 43 def checkDownload(self): 44 if config.setCompilers.Configure.isCygwin(self.log): 45 if config.setCompilers.Configure.isGNU(self.setCompilers.CC, self.log): 46 raise RuntimeError('Cannot download-install MPICH on Windows with cygwin compilers. Suggest installing Open MPI via cygwin installer') 47 else: 48 raise RuntimeError('Cannot download-install MPICH on Windows with Microsoft or Intel Compilers. Suggest using MS-MPI or Intel-MPI (do not use MPICH2') 49 if self.argDB['download-'+self.downloadname.lower()] and 'package-prefix-hash' in self.argDB and self.argDB['package-prefix-hash'] == 'reuse': 50 self.logWrite('Reusing package prefix install of '+self.defaultInstallDir+' for MPICH') 51 self.installDir = self.defaultInstallDir 52 self.updateCompilers(self.installDir,'mpicc','mpicxx','mpif77','mpif90') 53 return self.installDir 54 if self.argDB['download-'+self.downloadname.lower()]: 55 return self.getInstallDir() 56 return '' 57 58 def formGNUConfigureArgs(self): 59 '''MPICH has many specific extra configure arguments''' 60 args = config.package.GNUPackage.formGNUConfigureArgs(self) 61 args.append('--with-pm='+self.argDB['download-mpich-pm']) 62 args.append('--disable-java') 63 if self.hwloc.found: 64 args.append('--with-hwloc="'+self.hwloc.directory+'"') 65 args.append('--with-hwloc-prefix="'+self.hwloc.directory+'"') 66 elif 'with-hwloc' in self.framework.clArgDB and not self.argDB['with-hwloc'] : 67 args.append('--without-hwloc') 68 else: 69 args.append('--with-hwloc=embedded') 70 # make sure MPICH does not build with optimization for debug version of PETSc, so we can debug through MPICH 71 if self.compilerFlags.debugging: 72 args.append("--enable-fast=no") 73 args.append("--enable-error-messages=all") 74 mpich_device = 'ch3:sock' 75 else: 76 mpich_device = 'ch3:nemesis' 77 if self.cuda.found: 78 if not hasattr(self.cuda, 'cudaDir'): 79 raise RuntimeError('CUDA directory not detected! Mail configure.log to petsc-maint@mcs.anl.gov.') 80 args.append('--with-cuda='+self.cuda.cudaDir) 81 if hasattr(self.cuda,'cudaArch'): # MPICH's default to --with-cuda-sm=XX is 'auto', to auto-detect the arch of the visible GPUs (similar to our `native`). 82 if self.cuda.cudaArch == 'all': 83 args.append('--with-cuda-sm=all-major') # MPICH stopped supporting 'all' thus we do it with 'all-major' 84 else: 85 args.append('--with-cuda-sm='+self.cuda.cudaArch) 86 mpich_device = 'ch4:ucx' 87 elif self.hip.found: 88 args.append('--with-hip='+self.hip.hipDir) 89 mpich_device = 'ch4:ofi' # per https://github.com/pmodels/mpich/wiki/Using-MPICH-on-Crusher@OLCF 90 91 if 'download-mpich-device' in self.argDB: 92 mpich_device = self.argDB['download-mpich-device'] 93 args.append('--with-device='+mpich_device) 94 # meminit: preinitialize memory associated structures and unions to eliminate access warnings from programs like valgrind 95 # dbg: add compiler flag, -g, to all internal compiler flag i.e. MPICHLIB_CFLAGS, MPICHLIB_CXXFLAGS, MPICHLIB_FFLAGS, and MPICHLIB_FCFLAGS, to make debugging easier 96 args.append('--enable-g=meminit,dbg') 97 if not self.setCompilers.isDarwin(self.log) and config.setCompilers.Configure.isClang(self.setCompilers.CC, self.log): 98 args.append('pac_cv_have_float16=no') 99 if config.setCompilers.Configure.isDarwin(self.log): 100 args.append('--disable-opencl') 101 102 # MPICH configure errors out on certain standard configure arguments 103 args = self.rmArgs(args,['--disable-f90','--enable-f90']) 104 args = self.rmArgsStartsWith(args,['F90=','F90FLAGS=']) 105 args.append('PYTHON='+self.python.pyexe) 106 args.append('--disable-maintainer-mode') 107 args.append('--disable-dependency-tracking') 108 return args 109 110 def gitPreReqCheck(self): 111 return self.programs.autoreconf and self.programs.libtoolize 112 113 def preInstall(self): 114 if self.retriever.isDirectoryGitRepo(self.packageDir): 115 # no need to bootstrap tarballs 116 self.Bootstrap('./autogen.sh') 117 118 def Install(self): 119 '''After downloading and installing MPICH we need to reset the compilers to use those defined by the MPICH install''' 120 if 'package-prefix-hash' in self.argDB and self.argDB['package-prefix-hash'] == 'reuse': 121 return self.defaultInstallDir 122 installDir = config.package.GNUPackage.Install(self) 123 self.updateCompilers(installDir,'mpicc','mpicxx','mpif77','mpif90') 124 return installDir 125 126 def configure(self): 127 return config.package.Package.configure(self) 128