1e68ebbecSBarry Smith#!/usr/bin/env python 2e68ebbecSBarry Smith 3e68ebbecSBarry Smith""" 465a891e7SLisandro DalcinPETSc: Portable, Extensible Toolkit for Scientific Computation 565a891e7SLisandro Dalcin============================================================== 665a891e7SLisandro Dalcin 765a891e7SLisandro DalcinThe Portable, Extensible Toolkit for Scientific Computation (PETSc), 865a891e7SLisandro Dalcinis a suite of data structures and routines for the scalable (parallel) 965a891e7SLisandro Dalcinsolution of scientific applications modeled by partial differential 1065a891e7SLisandro Dalcinequations. It employs the Message Passing Interface (MPI) standard for 1165a891e7SLisandro Dalcinall message-passing communication. 12922ada92SLisandro Dalcin 13*93b33a5aSLisandro Dalcin.. note:: 14*93b33a5aSLisandro Dalcin 15*93b33a5aSLisandro Dalcin To install ``PETSc`` and ``petsc4py`` (``mpi4py`` is optional 16*93b33a5aSLisandro Dalcin but highly recommended) use:: 17*93b33a5aSLisandro Dalcin 18*93b33a5aSLisandro Dalcin $ pip install numpy mpi4py 19*93b33a5aSLisandro Dalcin $ pip install petsc petsc4py 20*93b33a5aSLisandro Dalcin 21922ada92SLisandro Dalcin.. tip:: 22922ada92SLisandro Dalcin 23*93b33a5aSLisandro Dalcin You can also install the in-development versions with:: 24922ada92SLisandro Dalcin 25*93b33a5aSLisandro Dalcin $ pip install Cython numpy mpi4py 26*93b33a5aSLisandro Dalcin $ pip install --no-deps https://bitbucket.org/petsc/petsc/get/master.tar.gz 27*93b33a5aSLisandro Dalcin $ pip install --no-deps https://bitbucket.org/petsc/petsc4py/get/master.tar.gz 28922ada92SLisandro Dalcin 29e68ebbecSBarry Smith""" 30e68ebbecSBarry Smith 3165a891e7SLisandro Dalcinimport sys, os 3265a891e7SLisandro Dalcinfrom distutils.core import setup 33cb58ab5bSLisandro Dalcinfrom distutils.util import get_platform, split_quoted 34b88f8b63SLisandro Dalcinfrom distutils.spawn import find_executable 3565a891e7SLisandro Dalcinfrom distutils.command.build import build as _build 3665a891e7SLisandro Dalcinif 'setuptools' in sys.modules: 3765a891e7SLisandro Dalcin from setuptools.command.install import install as _install 3865a891e7SLisandro Dalcinelse: 3965a891e7SLisandro Dalcin from distutils.command.install import install as _install 40a32381aeSLisandro Dalcinfrom distutils.command.sdist import sdist as _sdist 4165a891e7SLisandro Dalcinfrom distutils import log 4212c1d45bSMatthew G Knepley 4365a891e7SLisandro Dalcininit_py = """\ 44a32381aeSLisandro Dalcin# Author: PETSc Team 45a597b971SLisandro Dalcin# Contact: petsc-maint@mcs.anl.gov 4665a891e7SLisandro Dalcin 4765a891e7SLisandro Dalcindef get_petsc_dir(): 4865a891e7SLisandro Dalcin import os 4965a891e7SLisandro Dalcin return os.path.dirname(__file__) 5065a891e7SLisandro Dalcin 51a32381aeSLisandro Dalcindef get_config(): 52a32381aeSLisandro Dalcin conf = {} 539fb7a39fSLisandro Dalcin conf['PETSC_DIR'] = get_petsc_dir() 54a32381aeSLisandro Dalcin return conf 5565a891e7SLisandro Dalcin""" 5665a891e7SLisandro Dalcin 5759e0f383SLisandro Dalcinmetadata = { 5859e0f383SLisandro Dalcin 'provides' : ['petsc'], 5959e0f383SLisandro Dalcin 'requires' : [], 6059e0f383SLisandro Dalcin} 6159e0f383SLisandro Dalcin 6265a891e7SLisandro Dalcindef bootstrap(): 63cb58ab5bSLisandro Dalcin # Set PETSC_DIR and PETSC_ARCH 6465a891e7SLisandro Dalcin PETSC_DIR = os.path.abspath(os.getcwd()) 6565a891e7SLisandro Dalcin PETSC_ARCH = get_platform() + '-python' 6665a891e7SLisandro Dalcin os.environ['PETSC_DIR'] = PETSC_DIR 6765a891e7SLisandro Dalcin os.environ['PETSC_ARCH'] = PETSC_ARCH 6865a891e7SLisandro Dalcin sys.path.insert(0, os.path.join(PETSC_DIR, 'config')) 69*93b33a5aSLisandro Dalcin sys.path.insert(0, os.path.join(PETSC_DIR, 'conf')) 7059e0f383SLisandro Dalcin # Generate package __init__.py file 719fb7a39fSLisandro Dalcin from distutils.dir_util import mkpath 729fb7a39fSLisandro Dalcin pkgdir = os.path.join('config', 'pypi') 730ddf2052SLisandro Dalcin if not os.path.exists(pkgdir): mkpath(pkgdir) 749fb7a39fSLisandro Dalcin pkgfile = os.path.join(pkgdir, '__init__.py') 75922ada92SLisandro Dalcin fh = open(pkgfile, 'wt') 76922ada92SLisandro Dalcin fh.write(init_py) 77922ada92SLisandro Dalcin fh.close() 7859e0f383SLisandro Dalcin # Simple-minded lookup for MPI and mpi4py 7959e0f383SLisandro Dalcin mpi4py = mpicc = None 8059e0f383SLisandro Dalcin try: 8159e0f383SLisandro Dalcin import mpi4py 8259e0f383SLisandro Dalcin conf = mpi4py.get_config() 8359e0f383SLisandro Dalcin mpicc = conf.get('mpicc') 8459e0f383SLisandro Dalcin except ImportError: # mpi4py is not installed 85922ada92SLisandro Dalcin mpi4py = None 8659e0f383SLisandro Dalcin mpicc = os.environ.get('MPICC') or find_executable('mpicc') 871b095333SLisandro Dalcin except AttributeError: # mpi4py is too old 8859e0f383SLisandro Dalcin pass 89922ada92SLisandro Dalcin if ('setuptools' in sys.modules): 90be96eb59SLisandro Dalcin metadata['zip_safe'] = False 91922ada92SLisandro Dalcin if not mpi4py and mpicc: 92922ada92SLisandro Dalcin metadata['install_requires']= ['mpi4py>=1.2.2'] 9365a891e7SLisandro Dalcin 9465a891e7SLisandro Dalcindef config(dry_run=False): 9565a891e7SLisandro Dalcin log.info('PETSc: configure') 9665a891e7SLisandro Dalcin options = [ 9765a891e7SLisandro Dalcin 'PETSC_ARCH='+os.environ['PETSC_ARCH'], 98cb58ab5bSLisandro Dalcin '--with-shared-libraries=1', 9911035aebSLisandro Dalcin '--with-debugging=0', 100922ada92SLisandro Dalcin '--with-c2html=0', # not needed 10165a891e7SLisandro Dalcin ] 10259e0f383SLisandro Dalcin # MPI 10359e0f383SLisandro Dalcin try: 10459e0f383SLisandro Dalcin import mpi4py 10559e0f383SLisandro Dalcin conf = mpi4py.get_config() 10659e0f383SLisandro Dalcin mpicc = conf.get('mpicc') 107cb58ab5bSLisandro Dalcin mpicxx = conf.get('mpicxx') 108cb58ab5bSLisandro Dalcin mpif90 = conf.get('mpif90') 10959e0f383SLisandro Dalcin except (ImportError, AttributeError): 11059e0f383SLisandro Dalcin mpicc = os.environ.get('MPICC') or find_executable('mpicc') 111cb58ab5bSLisandro Dalcin mpicxx = os.environ.get('MPICXX') or find_executable('mpicxx') 112cb58ab5bSLisandro Dalcin mpif90 = os.environ.get('MPIF90') or find_executable('mpif90') 11359e0f383SLisandro Dalcin if mpicc: 11459e0f383SLisandro Dalcin options.append('--with-cc='+mpicc) 115cb58ab5bSLisandro Dalcin if mpicxx: 116cb58ab5bSLisandro Dalcin options.append('--with-cxx='+mpicxx) 117*93b33a5aSLisandro Dalcin else: 118*93b33a5aSLisandro Dalcin options.append('--with-cxx=0') 119cb58ab5bSLisandro Dalcin if mpif90: 120cb58ab5bSLisandro Dalcin options.append('--with-fc='+mpif90) 12159e0f383SLisandro Dalcin else: 122*93b33a5aSLisandro Dalcin options.append('--with-fc=0') 123*93b33a5aSLisandro Dalcin options.append('--with-sowing=0') 124*93b33a5aSLisandro Dalcin else: 12559e0f383SLisandro Dalcin options.append('--with-mpi=0') 126cb58ab5bSLisandro Dalcin # Extra configure options 127cb58ab5bSLisandro Dalcin config_opts = os.environ.get('PETSC_CONFIGURE_OPTIONS', '') 128cb58ab5bSLisandro Dalcin config_opts = split_quoted(config_opts) 129cb58ab5bSLisandro Dalcin options.extend(config_opts) 130cb58ab5bSLisandro Dalcin log.info('configure options:') 131cb58ab5bSLisandro Dalcin for opt in options: 132cb58ab5bSLisandro Dalcin log.info(' '*4 + opt) 13359e0f383SLisandro Dalcin # Run PETSc configure 134cb58ab5bSLisandro Dalcin if dry_run: return 135e68ebbecSBarry Smith import configure 13665a891e7SLisandro Dalcin configure.petsc_configure(options) 137e68ebbecSBarry Smith import logger 138e68ebbecSBarry Smith logger.Logger.defaultLog = None 13912c1d45bSMatthew G Knepley 14065a891e7SLisandro Dalcindef build(dry_run=False): 14165a891e7SLisandro Dalcin log.info('PETSc: build') 142367c215cSLisandro Dalcin # Run PETSc build 143cb58ab5bSLisandro Dalcin if dry_run: return 144367c215cSLisandro Dalcin use_builder_py = False 145367c215cSLisandro Dalcin if use_builder_py: 146e68ebbecSBarry Smith import builder 147e68ebbecSBarry Smith builder.PETScMaker().run() 148105e34d4SBarry Smith import logger 149105e34d4SBarry Smith logger.Logger.defaultLog = None 150367c215cSLisandro Dalcin else: 151367c215cSLisandro Dalcin make = find_executable('make') 152367c215cSLisandro Dalcin status = os.system(" ".join( 153367c215cSLisandro Dalcin [make, 'all'] 154367c215cSLisandro Dalcin )) 155367c215cSLisandro Dalcin if status != 0: raise RuntimeError(status) 156e68ebbecSBarry Smith 15765a891e7SLisandro Dalcindef install(dest_dir, prefix=None, dry_run=False): 15865a891e7SLisandro Dalcin log.info('PETSc: install') 15965a891e7SLisandro Dalcin if prefix is None: 16065a891e7SLisandro Dalcin prefix = dest_dir 16165a891e7SLisandro Dalcin options = [ 16265a891e7SLisandro Dalcin '--destDir=' + dest_dir, 1634dee622bSLisandro Dalcin '--prefix=' + prefix, 16465a891e7SLisandro Dalcin ] 165cb58ab5bSLisandro Dalcin log.info('install options:') 166cb58ab5bSLisandro Dalcin for opt in options: 167cb58ab5bSLisandro Dalcin log.info(' '*4 + opt) 16859e0f383SLisandro Dalcin # Run PETSc installer 169cb58ab5bSLisandro Dalcin if dry_run: return 170367c215cSLisandro Dalcin use_install_py = True 171367c215cSLisandro Dalcin if use_install_py: 172105e34d4SBarry Smith import install 17365a891e7SLisandro Dalcin install.Installer(options).run() 17465a891e7SLisandro Dalcin import logger 17565a891e7SLisandro Dalcin logger.Logger.defaultLog = None 176367c215cSLisandro Dalcin else: 177367c215cSLisandro Dalcin make = find_executable('make') 178367c215cSLisandro Dalcin status = os.system(" ".join( 179367c215cSLisandro Dalcin [make, 'install', 'DESTDIR='+dest_dir] 180367c215cSLisandro Dalcin )) 181367c215cSLisandro Dalcin if status != 0: raise RuntimeError(status) 18299468c80SLisandro Dalcin 18399468c80SLisandro Dalcinclass context: 18499468c80SLisandro Dalcin def __init__(self): 18599468c80SLisandro Dalcin self.sys_argv = sys.argv[:] 18699468c80SLisandro Dalcin self.wdir = os.getcwd() 18799468c80SLisandro Dalcin def enter(self): 18899468c80SLisandro Dalcin del sys.argv[1:] 18999468c80SLisandro Dalcin pdir = os.environ['PETSC_DIR'] 19099468c80SLisandro Dalcin os.chdir(pdir) 19199468c80SLisandro Dalcin return self 19299468c80SLisandro Dalcin def exit(self): 19399468c80SLisandro Dalcin sys.argv[:] = self.sys_argv 19499468c80SLisandro Dalcin os.chdir(self.wdir) 195105e34d4SBarry Smith 19665a891e7SLisandro Dalcinclass cmd_build(_build): 19765a891e7SLisandro Dalcin 198a597b971SLisandro Dalcin def initialize_options(self): 199a597b971SLisandro Dalcin _build.initialize_options(self) 200a597b971SLisandro Dalcin PETSC_ARCH = os.environ.get('PETSC_ARCH', '') 201a597b971SLisandro Dalcin self.build_base = os.path.join(PETSC_ARCH, 'build-python') 202a597b971SLisandro Dalcin 20365a891e7SLisandro Dalcin def run(self): 20465a891e7SLisandro Dalcin _build.run(self) 20599468c80SLisandro Dalcin ctx = context().enter() 20665a891e7SLisandro Dalcin try: 20765a891e7SLisandro Dalcin config(self.dry_run) 20865a891e7SLisandro Dalcin build(self.dry_run) 20965a891e7SLisandro Dalcin finally: 21099468c80SLisandro Dalcin ctx.exit() 21165a891e7SLisandro Dalcin 21265a891e7SLisandro Dalcinclass cmd_install(_install): 21365a891e7SLisandro Dalcin 21441716173SLisandro Dalcin def initialize_options(self): 21541716173SLisandro Dalcin _install.initialize_options(self) 21641716173SLisandro Dalcin self.optimize = 1 21741716173SLisandro Dalcin 21865a891e7SLisandro Dalcin def run(self): 21965a891e7SLisandro Dalcin root_dir = self.install_platlib 22065a891e7SLisandro Dalcin dest_dir = os.path.join(root_dir, 'petsc') 22165a891e7SLisandro Dalcin bdist_base = self.get_finalized_command('bdist').bdist_base 22265a891e7SLisandro Dalcin if dest_dir.startswith(bdist_base): 22365a891e7SLisandro Dalcin prefix = dest_dir[len(bdist_base)+1:] 22465a891e7SLisandro Dalcin prefix = prefix[prefix.index(os.path.sep):] 22565a891e7SLisandro Dalcin else: 22665a891e7SLisandro Dalcin prefix = dest_dir 22765a891e7SLisandro Dalcin dest_dir = os.path.abspath(dest_dir) 22865a891e7SLisandro Dalcin prefix = os.path.abspath(prefix) 22999468c80SLisandro Dalcin # 23099468c80SLisandro Dalcin _install.run(self) 23199468c80SLisandro Dalcin ctx = context().enter() 23265a891e7SLisandro Dalcin try: 23365a891e7SLisandro Dalcin install(dest_dir, prefix, self.dry_run) 23465a891e7SLisandro Dalcin finally: 23599468c80SLisandro Dalcin ctx.exit() 23665a891e7SLisandro Dalcin 237a32381aeSLisandro Dalcinclass cmd_sdist(_sdist): 238a32381aeSLisandro Dalcin 239a32381aeSLisandro Dalcin def initialize_options(self): 240a32381aeSLisandro Dalcin _sdist.initialize_options(self) 241a32381aeSLisandro Dalcin self.force_manifest = 1 24299468c80SLisandro Dalcin self.template = os.path.join('config', 'manifest.in') 243a32381aeSLisandro Dalcin 24465a891e7SLisandro Dalcindef version(): 2457d04d9c9SLisandro Dalcin import re 2467d04d9c9SLisandro Dalcin version_re = { 2477d04d9c9SLisandro Dalcin 'major' : re.compile(r"#define\s+PETSC_VERSION_MAJOR\s+(\d+)"), 2487d04d9c9SLisandro Dalcin 'minor' : re.compile(r"#define\s+PETSC_VERSION_MINOR\s+(\d+)"), 2497d04d9c9SLisandro Dalcin 'micro' : re.compile(r"#define\s+PETSC_VERSION_SUBMINOR\s+(\d+)"), 2507d04d9c9SLisandro Dalcin 'patch' : re.compile(r"#define\s+PETSC_VERSION_PATCH\s+(\d+)"), 2517d04d9c9SLisandro Dalcin 'release': re.compile(r"#define\s+PETSC_VERSION_RELEASE\s+(\d+)"), 2527d04d9c9SLisandro Dalcin } 2537d04d9c9SLisandro Dalcin petscversion_h = os.path.join('include','petscversion.h') 2547d04d9c9SLisandro Dalcin data = open(petscversion_h, 'rt').read() 2557d04d9c9SLisandro Dalcin major = int(version_re['major'].search(data).groups()[0]) 2567d04d9c9SLisandro Dalcin minor = int(version_re['minor'].search(data).groups()[0]) 2577d04d9c9SLisandro Dalcin micro = int(version_re['micro'].search(data).groups()[0]) 2587d04d9c9SLisandro Dalcin patch = int(version_re['patch'].search(data).groups()[0]) 2597d04d9c9SLisandro Dalcin release = int(version_re['release'].search(data).groups()[0]) 2607d04d9c9SLisandro Dalcin if release: 2617d04d9c9SLisandro Dalcin v = "%d.%d" % (major, minor) 2627d04d9c9SLisandro Dalcin if micro > 0: 2637d04d9c9SLisandro Dalcin v += ".%d" % micro 264247a1238SLisandro Dalcin #if patch > 0: 265247a1238SLisandro Dalcin # v += ".post%d" % patch 2667d04d9c9SLisandro Dalcin else: 26761a717f9SLisandro Dalcin v = "%d.%d.dev%d" % (major, minor+1, 0) 2687d04d9c9SLisandro Dalcin return v 26959e0f383SLisandro Dalcin 27065a891e7SLisandro Dalcindef tarball(): 27150f36069SLisandro Dalcin VERSION = version() 27250f36069SLisandro Dalcin if '.dev' in VERSION: 273a32381aeSLisandro Dalcin return None 2747d562c6eSLisandro Dalcin bits = VERSION.split('.') 2757d562c6eSLisandro Dalcin if len(bits) == 2: bits.append('0') 276247a1238SLisandro Dalcin PETSC_VERSION = '.'.join(bits[:3]) 27750f36069SLisandro Dalcin return ('http://ftp.mcs.anl.gov/pub/petsc/release-snapshots/' 278a9157d91SLisandro Dalcin 'petsc-lite-%s.tar.gz#egg=petsc-%s' % (PETSC_VERSION, VERSION)) 27965a891e7SLisandro Dalcin 28065a891e7SLisandro Dalcindescription = __doc__.split('\n')[1:-1]; del description[1:3] 28165a891e7SLisandro Dalcinclassifiers = """ 28265a891e7SLisandro DalcinLicense :: Public Domain 28365a891e7SLisandro DalcinOperating System :: POSIX 28465a891e7SLisandro DalcinIntended Audience :: Developers 28565a891e7SLisandro DalcinIntended Audience :: Science/Research 28665a891e7SLisandro DalcinProgramming Language :: C 28765a891e7SLisandro DalcinProgramming Language :: C++ 28865a891e7SLisandro DalcinProgramming Language :: Fortran 28965a891e7SLisandro DalcinProgramming Language :: Python 29065a891e7SLisandro DalcinTopic :: Scientific/Engineering 29165a891e7SLisandro DalcinTopic :: Software Development :: Libraries 29265a891e7SLisandro Dalcin""" 29365a891e7SLisandro Dalcin 29465a891e7SLisandro Dalcinbootstrap() 29565a891e7SLisandro Dalcinsetup(name='petsc', 29665a891e7SLisandro Dalcin version=version(), 29765a891e7SLisandro Dalcin description=description.pop(0), 29865a891e7SLisandro Dalcin long_description='\n'.join(description), 29965a891e7SLisandro Dalcin classifiers= classifiers.split('\n')[1:-1], 30065a891e7SLisandro Dalcin keywords = ['PETSc', 'MPI'], 30165a891e7SLisandro Dalcin platforms=['POSIX'], 30265a891e7SLisandro Dalcin license='PETSc', 30365a891e7SLisandro Dalcin 30465a891e7SLisandro Dalcin url='http://www.mcs.anl.gov/petsc/', 30565a891e7SLisandro Dalcin download_url=tarball(), 30665a891e7SLisandro Dalcin 30765a891e7SLisandro Dalcin author='PETSc Team', 30899468c80SLisandro Dalcin author_email='petsc-maint@mcs.anl.gov', 30965a891e7SLisandro Dalcin maintainer='Lisandro Dalcin', 31065a891e7SLisandro Dalcin maintainer_email='dalcinl@gmail.com', 31165a891e7SLisandro Dalcin 31265a891e7SLisandro Dalcin packages = ['petsc'], 3139fb7a39fSLisandro Dalcin package_dir = {'petsc': 'config/pypi'}, 31465a891e7SLisandro Dalcin cmdclass={ 31565a891e7SLisandro Dalcin 'build': cmd_build, 31665a891e7SLisandro Dalcin 'install': cmd_install, 317a32381aeSLisandro Dalcin 'sdist': cmd_sdist, 31865a891e7SLisandro Dalcin }, 31959e0f383SLisandro Dalcin **metadata) 320