1*6308ffc9SLisandro Dalcin#!/usr/bin/env python 2*6308ffc9SLisandro Dalcin 3*6308ffc9SLisandro Dalcin""" 4*6308ffc9SLisandro DalcinPETSc: Portable, Extensible Toolkit for Scientific Computation 5*6308ffc9SLisandro Dalcin============================================================== 6*6308ffc9SLisandro Dalcin 7*6308ffc9SLisandro DalcinThe Portable, Extensible Toolkit for Scientific Computation (PETSc), 8*6308ffc9SLisandro Dalcinis a suite of data structures and routines for the scalable (parallel) 9*6308ffc9SLisandro Dalcinsolution of scientific applications modeled by partial differential 10*6308ffc9SLisandro Dalcinequations. It employs the Message Passing Interface (MPI) standard for 11*6308ffc9SLisandro Dalcinall message-passing communication. 12*6308ffc9SLisandro Dalcin""" 13*6308ffc9SLisandro Dalcin 14*6308ffc9SLisandro Dalcinimport sys, os 15*6308ffc9SLisandro Dalcinfrom distutils.core import setup 16*6308ffc9SLisandro Dalcinfrom distutils.util import get_platform 17*6308ffc9SLisandro Dalcinfrom distutils.spawn import find_executable 18*6308ffc9SLisandro Dalcinfrom distutils.command.build import build as _build 19*6308ffc9SLisandro Dalcinif 'setuptools' in sys.modules: 20*6308ffc9SLisandro Dalcin from setuptools.command.install import install as _install 21*6308ffc9SLisandro Dalcinelse: 22*6308ffc9SLisandro Dalcin from distutils.command.install import install as _install 23*6308ffc9SLisandro Dalcinfrom distutils.command.sdist import sdist as _sdist 24*6308ffc9SLisandro Dalcinfrom distutils import log 25*6308ffc9SLisandro Dalcin 26*6308ffc9SLisandro Dalcininit_py = """\ 27*6308ffc9SLisandro Dalcin# Author: PETSc Team 28*6308ffc9SLisandro Dalcin# Contact: petsc-maint@mcs.anl.gov 29*6308ffc9SLisandro Dalcin 30*6308ffc9SLisandro Dalcindef get_petsc_dir(): 31*6308ffc9SLisandro Dalcin import os 32*6308ffc9SLisandro Dalcin return os.path.dirname(__file__) 33*6308ffc9SLisandro Dalcin 34*6308ffc9SLisandro Dalcindef get_config(): 35*6308ffc9SLisandro Dalcin conf = {} 36*6308ffc9SLisandro Dalcin conf['PETSC_DIR'] = get_petsc_dir() 37*6308ffc9SLisandro Dalcin return conf 38*6308ffc9SLisandro Dalcin""" 39*6308ffc9SLisandro Dalcin 40*6308ffc9SLisandro Dalcinmetadata = { 41*6308ffc9SLisandro Dalcin 'provides' : ['petsc'], 42*6308ffc9SLisandro Dalcin 'requires' : [], 43*6308ffc9SLisandro Dalcin} 44*6308ffc9SLisandro Dalcin 45*6308ffc9SLisandro Dalcindef bootstrap(): 46*6308ffc9SLisandro Dalcin # Set PETSC_DIR and PETSC_ARCH, 47*6308ffc9SLisandro Dalcin PETSC_DIR = os.path.abspath(os.getcwd()) 48*6308ffc9SLisandro Dalcin PETSC_ARCH = get_platform() + '-python' 49*6308ffc9SLisandro Dalcin os.environ['PETSC_DIR'] = PETSC_DIR 50*6308ffc9SLisandro Dalcin os.environ['PETSC_ARCH'] = PETSC_ARCH 51*6308ffc9SLisandro Dalcin # Generate package __init__.py file 52*6308ffc9SLisandro Dalcin from distutils.dir_util import mkpath 53*6308ffc9SLisandro Dalcin pkgdir = os.path.join('config', 'pypi') 54*6308ffc9SLisandro Dalcin pkgfile = os.path.join(pkgdir, '__init__.py') 55*6308ffc9SLisandro Dalcin if not os.path.exists(pkgdir): 56*6308ffc9SLisandro Dalcin mkpath(pkgdir) 57*6308ffc9SLisandro Dalcin if not os.path.exists(pkgfile): 58*6308ffc9SLisandro Dalcin open(pkgfile, 'wt').write(init_py) 59*6308ffc9SLisandro Dalcin # Simple-minded lookup for MPI and mpi4py 60*6308ffc9SLisandro Dalcin mpi4py = mpicc = None 61*6308ffc9SLisandro Dalcin try: 62*6308ffc9SLisandro Dalcin import mpi4py 63*6308ffc9SLisandro Dalcin conf = mpi4py.get_config() 64*6308ffc9SLisandro Dalcin mpicc = conf.get('mpicc') 65*6308ffc9SLisandro Dalcin except ImportError: # mpi4py is not installed 66*6308ffc9SLisandro Dalcin mpicc = os.environ.get('MPICC') or find_executable('mpicc') 67*6308ffc9SLisandro Dalcin except AttributeError: # mpi4py is too old 68*6308ffc9SLisandro Dalcin pass 69*6308ffc9SLisandro Dalcin if not mpi4py and mpicc: 70*6308ffc9SLisandro Dalcin if (('distribute' in sys.modules) or 71*6308ffc9SLisandro Dalcin ('setuptools' in sys.modules)): 72*6308ffc9SLisandro Dalcin metadata['install_requires']= ['mpi4py>=1.2.2'] 73*6308ffc9SLisandro Dalcin if 'setuptools' in sys.modules: 74*6308ffc9SLisandro Dalcin metadata['zip_safe'] = False 75*6308ffc9SLisandro Dalcin 76*6308ffc9SLisandro Dalcindef config(dry_run=False): 77*6308ffc9SLisandro Dalcin log.info('PETSc: configure') 78*6308ffc9SLisandro Dalcin if dry_run: return 79*6308ffc9SLisandro Dalcin options = [ 80*6308ffc9SLisandro Dalcin 'PETSC_ARCH='+os.environ['PETSC_ARCH'], 81*6308ffc9SLisandro Dalcin '--with-shared', 82*6308ffc9SLisandro Dalcin '--with-cmake=0', # not needed 83*6308ffc9SLisandro Dalcin ] 84*6308ffc9SLisandro Dalcin # MPI 85*6308ffc9SLisandro Dalcin try: 86*6308ffc9SLisandro Dalcin import mpi4py 87*6308ffc9SLisandro Dalcin conf = mpi4py.get_config() 88*6308ffc9SLisandro Dalcin mpicc = conf.get('mpicc') 89*6308ffc9SLisandro Dalcin except (ImportError, AttributeError): 90*6308ffc9SLisandro Dalcin mpicc = os.environ.get('MPICC') or find_executable('mpicc') 91*6308ffc9SLisandro Dalcin if mpicc: 92*6308ffc9SLisandro Dalcin options.append('--with-cc='+mpicc) 93*6308ffc9SLisandro Dalcin else: 94*6308ffc9SLisandro Dalcin options.append('--with-mpi=0') 95*6308ffc9SLisandro Dalcin options.append('--with-cxx=0') # XXX mpicxx? 96*6308ffc9SLisandro Dalcin options.append('--with-fc=0') # XXX mpif90? 97*6308ffc9SLisandro Dalcin # Run PETSc configure 98*6308ffc9SLisandro Dalcin status = os.system('%s %s %s' % ( 99*6308ffc9SLisandro Dalcin find_executable('python'), 100*6308ffc9SLisandro Dalcin os.path.join('config', 'configure.py'), 101*6308ffc9SLisandro Dalcin ' '.join(options), 102*6308ffc9SLisandro Dalcin )) 103*6308ffc9SLisandro Dalcin if status != 0: raise RuntimeError(status) 104*6308ffc9SLisandro Dalcin 105*6308ffc9SLisandro Dalcindef build(dry_run=False): 106*6308ffc9SLisandro Dalcin log.info('PETSc: build') 107*6308ffc9SLisandro Dalcin if dry_run: return 108*6308ffc9SLisandro Dalcin # Run PETSc builder 109*6308ffc9SLisandro Dalcin status = os.system('make all') 110*6308ffc9SLisandro Dalcin if status != 0: raise RuntimeError(status) 111*6308ffc9SLisandro Dalcin 112*6308ffc9SLisandro Dalcindef install(dest_dir, prefix=None, dry_run=False): 113*6308ffc9SLisandro Dalcin log.info('PETSc: install') 114*6308ffc9SLisandro Dalcin if dry_run: return 115*6308ffc9SLisandro Dalcin if prefix is None: 116*6308ffc9SLisandro Dalcin prefix = dest_dir 117*6308ffc9SLisandro Dalcin options = [ 118*6308ffc9SLisandro Dalcin '--destDir=' + dest_dir, 119*6308ffc9SLisandro Dalcin '--prefix=' + prefix, 120*6308ffc9SLisandro Dalcin ] 121*6308ffc9SLisandro Dalcin # Run PETSc installer 122*6308ffc9SLisandro Dalcin status = os.system('%s %s %s' % ( 123*6308ffc9SLisandro Dalcin find_executable('python'), 124*6308ffc9SLisandro Dalcin os.path.join('config', 'install.py'), 125*6308ffc9SLisandro Dalcin ' '.join(options), 126*6308ffc9SLisandro Dalcin )) 127*6308ffc9SLisandro Dalcin if status != 0: raise RuntimeError(status) 128*6308ffc9SLisandro Dalcin 129*6308ffc9SLisandro Dalcinclass context: 130*6308ffc9SLisandro Dalcin def __init__(self): 131*6308ffc9SLisandro Dalcin self.sys_argv = sys.argv[:] 132*6308ffc9SLisandro Dalcin self.wdir = os.getcwd() 133*6308ffc9SLisandro Dalcin def enter(self): 134*6308ffc9SLisandro Dalcin del sys.argv[1:] 135*6308ffc9SLisandro Dalcin pdir = os.environ['PETSC_DIR'] 136*6308ffc9SLisandro Dalcin os.chdir(pdir) 137*6308ffc9SLisandro Dalcin return self 138*6308ffc9SLisandro Dalcin def exit(self): 139*6308ffc9SLisandro Dalcin sys.argv[:] = self.sys_argv 140*6308ffc9SLisandro Dalcin os.chdir(self.wdir) 141*6308ffc9SLisandro Dalcin 142*6308ffc9SLisandro Dalcinclass cmd_build(_build): 143*6308ffc9SLisandro Dalcin 144*6308ffc9SLisandro Dalcin def initialize_options(self): 145*6308ffc9SLisandro Dalcin _build.initialize_options(self) 146*6308ffc9SLisandro Dalcin PETSC_ARCH = os.environ.get('PETSC_ARCH', '') 147*6308ffc9SLisandro Dalcin self.build_base = os.path.join(PETSC_ARCH, 'build-python') 148*6308ffc9SLisandro Dalcin 149*6308ffc9SLisandro Dalcin def run(self): 150*6308ffc9SLisandro Dalcin _build.run(self) 151*6308ffc9SLisandro Dalcin ctx = context().enter() 152*6308ffc9SLisandro Dalcin try: 153*6308ffc9SLisandro Dalcin config(self.dry_run) 154*6308ffc9SLisandro Dalcin build(self.dry_run) 155*6308ffc9SLisandro Dalcin finally: 156*6308ffc9SLisandro Dalcin ctx.exit() 157*6308ffc9SLisandro Dalcin 158*6308ffc9SLisandro Dalcinclass cmd_install(_install): 159*6308ffc9SLisandro Dalcin 160*6308ffc9SLisandro Dalcin def initialize_options(self): 161*6308ffc9SLisandro Dalcin _install.initialize_options(self) 162*6308ffc9SLisandro Dalcin self.optimize = 1 163*6308ffc9SLisandro Dalcin 164*6308ffc9SLisandro Dalcin def run(self): 165*6308ffc9SLisandro Dalcin root_dir = self.install_platlib 166*6308ffc9SLisandro Dalcin dest_dir = os.path.join(root_dir, 'petsc') 167*6308ffc9SLisandro Dalcin bdist_base = self.get_finalized_command('bdist').bdist_base 168*6308ffc9SLisandro Dalcin if dest_dir.startswith(bdist_base): 169*6308ffc9SLisandro Dalcin prefix = dest_dir[len(bdist_base)+1:] 170*6308ffc9SLisandro Dalcin prefix = prefix[prefix.index(os.path.sep):] 171*6308ffc9SLisandro Dalcin else: 172*6308ffc9SLisandro Dalcin prefix = dest_dir 173*6308ffc9SLisandro Dalcin dest_dir = os.path.abspath(dest_dir) 174*6308ffc9SLisandro Dalcin prefix = os.path.abspath(prefix) 175*6308ffc9SLisandro Dalcin # 176*6308ffc9SLisandro Dalcin _install.run(self) 177*6308ffc9SLisandro Dalcin ctx = context().enter() 178*6308ffc9SLisandro Dalcin try: 179*6308ffc9SLisandro Dalcin install(dest_dir, prefix, self.dry_run) 180*6308ffc9SLisandro Dalcin finally: 181*6308ffc9SLisandro Dalcin ctx.exit() 182*6308ffc9SLisandro Dalcin 183*6308ffc9SLisandro Dalcinclass cmd_sdist(_sdist): 184*6308ffc9SLisandro Dalcin 185*6308ffc9SLisandro Dalcin def initialize_options(self): 186*6308ffc9SLisandro Dalcin _sdist.initialize_options(self) 187*6308ffc9SLisandro Dalcin self.force_manifest = 1 188*6308ffc9SLisandro Dalcin self.template = os.path.join('config', 'manifest.in') 189*6308ffc9SLisandro Dalcin 190*6308ffc9SLisandro Dalcindef version(): 191*6308ffc9SLisandro Dalcin import re 192*6308ffc9SLisandro Dalcin version_re = { 193*6308ffc9SLisandro Dalcin 'major' : re.compile(r"#define\s+PETSC_VERSION_MAJOR\s+(\d+)"), 194*6308ffc9SLisandro Dalcin 'minor' : re.compile(r"#define\s+PETSC_VERSION_MINOR\s+(\d+)"), 195*6308ffc9SLisandro Dalcin 'micro' : re.compile(r"#define\s+PETSC_VERSION_SUBMINOR\s+(\d+)"), 196*6308ffc9SLisandro Dalcin 'patch' : re.compile(r"#define\s+PETSC_VERSION_PATCH\s+(\d+)"), 197*6308ffc9SLisandro Dalcin 'release': re.compile(r"#define\s+PETSC_VERSION_RELEASE\s+(\d+)"), 198*6308ffc9SLisandro Dalcin } 199*6308ffc9SLisandro Dalcin petscversion_h = os.path.join('include','petscversion.h') 200*6308ffc9SLisandro Dalcin data = open(petscversion_h, 'rt').read() 201*6308ffc9SLisandro Dalcin major = int(version_re['major'].search(data).groups()[0]) 202*6308ffc9SLisandro Dalcin minor = int(version_re['minor'].search(data).groups()[0]) 203*6308ffc9SLisandro Dalcin micro = int(version_re['micro'].search(data).groups()[0]) 204*6308ffc9SLisandro Dalcin patch = int(version_re['patch'].search(data).groups()[0]) 205*6308ffc9SLisandro Dalcin release = int(version_re['release'].search(data).groups()[0]) 206*6308ffc9SLisandro Dalcin if release: 207*6308ffc9SLisandro Dalcin v = "%d.%d" % (major, minor) 208*6308ffc9SLisandro Dalcin if micro > 0: 209*6308ffc9SLisandro Dalcin v += ".%d" % micro 210*6308ffc9SLisandro Dalcin if patch > 0: 211*6308ffc9SLisandro Dalcin v += ".post%d" % patch 212*6308ffc9SLisandro Dalcin else: 213*6308ffc9SLisandro Dalcin v = "%d.%d.dev%d" % (major, minor+1, 0) 214*6308ffc9SLisandro Dalcin return v 215*6308ffc9SLisandro Dalcin 216*6308ffc9SLisandro Dalcindef tarball(): 217*6308ffc9SLisandro Dalcin return None # XXX remove this line !!! 218*6308ffc9SLisandro Dalcin VERSION = version() 219*6308ffc9SLisandro Dalcin if '.dev' in VERSION: 220*6308ffc9SLisandro Dalcin return None 221*6308ffc9SLisandro Dalcin if '.post' not in VERSION: 222*6308ffc9SLisandro Dalcin VERSION = VERSION + '.post0' 223*6308ffc9SLisandro Dalcin VERSION = VERSION.replace('.post', '-p') 224*6308ffc9SLisandro Dalcin return ('http://ftp.mcs.anl.gov/pub/petsc/release-snapshots/' 225*6308ffc9SLisandro Dalcin 'petsc-lite-%s.tar.gz' % VERSION) 226*6308ffc9SLisandro Dalcin 227*6308ffc9SLisandro Dalcindescription = __doc__.split('\n')[1:-1]; del description[1:3] 228*6308ffc9SLisandro Dalcinclassifiers = """ 229*6308ffc9SLisandro DalcinLicense :: Public Domain 230*6308ffc9SLisandro DalcinOperating System :: POSIX 231*6308ffc9SLisandro DalcinIntended Audience :: Developers 232*6308ffc9SLisandro DalcinIntended Audience :: Science/Research 233*6308ffc9SLisandro DalcinProgramming Language :: C 234*6308ffc9SLisandro DalcinProgramming Language :: C++ 235*6308ffc9SLisandro DalcinProgramming Language :: Fortran 236*6308ffc9SLisandro DalcinProgramming Language :: Python 237*6308ffc9SLisandro DalcinTopic :: Scientific/Engineering 238*6308ffc9SLisandro DalcinTopic :: Software Development :: Libraries 239*6308ffc9SLisandro Dalcin""" 240*6308ffc9SLisandro Dalcin 241*6308ffc9SLisandro Dalcinbootstrap() 242*6308ffc9SLisandro Dalcinsetup(name='petsc', 243*6308ffc9SLisandro Dalcin version=version(), 244*6308ffc9SLisandro Dalcin description=description.pop(0), 245*6308ffc9SLisandro Dalcin long_description='\n'.join(description), 246*6308ffc9SLisandro Dalcin classifiers= classifiers.split('\n')[1:-1], 247*6308ffc9SLisandro Dalcin keywords = ['PETSc', 'MPI'], 248*6308ffc9SLisandro Dalcin platforms=['POSIX'], 249*6308ffc9SLisandro Dalcin license='PETSc', 250*6308ffc9SLisandro Dalcin 251*6308ffc9SLisandro Dalcin url='http://www.mcs.anl.gov/petsc/', 252*6308ffc9SLisandro Dalcin download_url=tarball(), 253*6308ffc9SLisandro Dalcin 254*6308ffc9SLisandro Dalcin author='PETSc Team', 255*6308ffc9SLisandro Dalcin author_email='petsc-maint@mcs.anl.gov', 256*6308ffc9SLisandro Dalcin maintainer='Lisandro Dalcin', 257*6308ffc9SLisandro Dalcin maintainer_email='dalcinl@gmail.com', 258*6308ffc9SLisandro Dalcin 259*6308ffc9SLisandro Dalcin packages = ['petsc'], 260*6308ffc9SLisandro Dalcin package_dir = {'petsc': 'config/pypi'}, 261*6308ffc9SLisandro Dalcin cmdclass={ 262*6308ffc9SLisandro Dalcin 'build': cmd_build, 263*6308ffc9SLisandro Dalcin 'install': cmd_install, 264*6308ffc9SLisandro Dalcin 'sdist': cmd_sdist, 265*6308ffc9SLisandro Dalcin }, 266*6308ffc9SLisandro Dalcin **metadata) 267