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 13922ada92SLisandro Dalcin.. tip:: 14922ada92SLisandro Dalcin 15eb1799d5SSatish Balay You can also install `petsc-master`_ with:: 16922ada92SLisandro Dalcin 17eb1799d5SSatish Balay $ pip install petsc==master 18922ada92SLisandro Dalcin 19eb1799d5SSatish Balay .. _petsc-master: https://bitbucket.org/petsc/ 20eb1799d5SSatish Balay petsc/get/master.tar.gz#egg=petsc-master 21e68ebbecSBarry Smith""" 22e68ebbecSBarry Smith 2365a891e7SLisandro Dalcinimport sys, os 2465a891e7SLisandro Dalcinfrom distutils.core import setup 25cb58ab5bSLisandro Dalcinfrom distutils.util import get_platform, split_quoted 26b88f8b63SLisandro Dalcinfrom distutils.spawn import find_executable 2765a891e7SLisandro Dalcinfrom distutils.command.build import build as _build 2865a891e7SLisandro Dalcinif 'setuptools' in sys.modules: 2965a891e7SLisandro Dalcin from setuptools.command.install import install as _install 3065a891e7SLisandro Dalcinelse: 3165a891e7SLisandro Dalcin from distutils.command.install import install as _install 32a32381aeSLisandro Dalcinfrom distutils.command.sdist import sdist as _sdist 3365a891e7SLisandro Dalcinfrom distutils import log 3412c1d45bSMatthew G Knepley 3565a891e7SLisandro Dalcininit_py = """\ 36a32381aeSLisandro Dalcin# Author: PETSc Team 37a597b971SLisandro Dalcin# Contact: petsc-maint@mcs.anl.gov 3865a891e7SLisandro Dalcin 3965a891e7SLisandro Dalcindef get_petsc_dir(): 4065a891e7SLisandro Dalcin import os 4165a891e7SLisandro Dalcin return os.path.dirname(__file__) 4265a891e7SLisandro Dalcin 43a32381aeSLisandro Dalcindef get_config(): 44a32381aeSLisandro Dalcin conf = {} 459fb7a39fSLisandro Dalcin conf['PETSC_DIR'] = get_petsc_dir() 46a32381aeSLisandro Dalcin return conf 4765a891e7SLisandro Dalcin""" 4865a891e7SLisandro Dalcin 4959e0f383SLisandro Dalcinmetadata = { 5059e0f383SLisandro Dalcin 'provides' : ['petsc'], 5159e0f383SLisandro Dalcin 'requires' : [], 5259e0f383SLisandro Dalcin} 5359e0f383SLisandro Dalcin 5465a891e7SLisandro Dalcindef bootstrap(): 55cb58ab5bSLisandro Dalcin # Set PETSC_DIR and PETSC_ARCH 5665a891e7SLisandro Dalcin PETSC_DIR = os.path.abspath(os.getcwd()) 5765a891e7SLisandro Dalcin PETSC_ARCH = get_platform() + '-python' 5865a891e7SLisandro Dalcin os.environ['PETSC_DIR'] = PETSC_DIR 5965a891e7SLisandro Dalcin os.environ['PETSC_ARCH'] = PETSC_ARCH 6065a891e7SLisandro Dalcin sys.path.insert(0, os.path.join(PETSC_DIR, 'config')) 6105762b81SDavid A Ham sys.path.insert(0, os.path.join(PETSC_DIR, 'conf')) 6259e0f383SLisandro Dalcin # Generate package __init__.py file 639fb7a39fSLisandro Dalcin from distutils.dir_util import mkpath 649fb7a39fSLisandro Dalcin pkgdir = os.path.join('config', 'pypi') 650ddf2052SLisandro Dalcin if not os.path.exists(pkgdir): mkpath(pkgdir) 669fb7a39fSLisandro Dalcin pkgfile = os.path.join(pkgdir, '__init__.py') 67922ada92SLisandro Dalcin fh = open(pkgfile, 'wt') 68922ada92SLisandro Dalcin fh.write(init_py) 69922ada92SLisandro Dalcin fh.close() 7059e0f383SLisandro Dalcin # Simple-minded lookup for MPI and mpi4py 7159e0f383SLisandro Dalcin mpi4py = mpicc = None 7259e0f383SLisandro Dalcin try: 7359e0f383SLisandro Dalcin import mpi4py 7459e0f383SLisandro Dalcin conf = mpi4py.get_config() 7559e0f383SLisandro Dalcin mpicc = conf.get('mpicc') 7659e0f383SLisandro Dalcin except ImportError: # mpi4py is not installed 77922ada92SLisandro Dalcin mpi4py = None 7859e0f383SLisandro Dalcin mpicc = os.environ.get('MPICC') or find_executable('mpicc') 791b095333SLisandro Dalcin except AttributeError: # mpi4py is too old 8059e0f383SLisandro Dalcin pass 81922ada92SLisandro Dalcin if ('setuptools' in sys.modules): 82be96eb59SLisandro Dalcin metadata['zip_safe'] = False 83922ada92SLisandro Dalcin if not mpi4py and mpicc: 84922ada92SLisandro Dalcin metadata['install_requires']= ['mpi4py>=1.2.2'] 8565a891e7SLisandro Dalcin 8665a891e7SLisandro Dalcindef config(dry_run=False): 8765a891e7SLisandro Dalcin log.info('PETSc: configure') 8865a891e7SLisandro Dalcin options = [ 8965a891e7SLisandro Dalcin 'PETSC_ARCH='+os.environ['PETSC_ARCH'], 90cb58ab5bSLisandro Dalcin '--with-shared-libraries=1', 9111035aebSLisandro Dalcin '--with-debugging=0', 92922ada92SLisandro Dalcin '--with-c2html=0', # not needed 93*ac02ff6dSBarry Smith '--with-sowing=0', 94*ac02ff6dSBarry Smith '--with-fc=0', 95*ac02ff6dSBarry Smith '--with-cxx=0', 96922ada92SLisandro Dalcin #'--with-cmake=0', 9765a891e7SLisandro Dalcin ] 9859e0f383SLisandro Dalcin # MPI 9959e0f383SLisandro Dalcin try: 10059e0f383SLisandro Dalcin import mpi4py 10159e0f383SLisandro Dalcin conf = mpi4py.get_config() 10259e0f383SLisandro Dalcin mpicc = conf.get('mpicc') 103cb58ab5bSLisandro Dalcin mpicxx = conf.get('mpicxx') 104cb58ab5bSLisandro Dalcin mpif90 = conf.get('mpif90') 10559e0f383SLisandro Dalcin except (ImportError, AttributeError): 10659e0f383SLisandro Dalcin mpicc = os.environ.get('MPICC') or find_executable('mpicc') 107cb58ab5bSLisandro Dalcin mpicxx = os.environ.get('MPICXX') or find_executable('mpicxx') 108cb58ab5bSLisandro Dalcin mpif90 = os.environ.get('MPIF90') or find_executable('mpif90') 10959e0f383SLisandro Dalcin if mpicc: 11059e0f383SLisandro Dalcin options.append('--with-cc='+mpicc) 111cb58ab5bSLisandro Dalcin if mpicxx: 112cb58ab5bSLisandro Dalcin options.append('--with-cxx='+mpicxx) 113cb58ab5bSLisandro Dalcin if mpif90: 114cb58ab5bSLisandro Dalcin options.append('--with-fc='+mpif90) 11559e0f383SLisandro Dalcin else: 11659e0f383SLisandro Dalcin options.append('--with-mpi=0') 117cb58ab5bSLisandro Dalcin # Extra configure options 118cb58ab5bSLisandro Dalcin config_opts = os.environ.get('PETSC_CONFIGURE_OPTIONS', '') 119cb58ab5bSLisandro Dalcin config_opts = split_quoted(config_opts) 120cb58ab5bSLisandro Dalcin options.extend(config_opts) 121cb58ab5bSLisandro Dalcin log.info('configure options:') 122cb58ab5bSLisandro Dalcin for opt in options: 123cb58ab5bSLisandro Dalcin log.info(' '*4 + opt) 12459e0f383SLisandro Dalcin # Run PETSc configure 125cb58ab5bSLisandro Dalcin if dry_run: return 126e68ebbecSBarry Smith import configure 12765a891e7SLisandro Dalcin configure.petsc_configure(options) 128e68ebbecSBarry Smith import logger 129e68ebbecSBarry Smith logger.Logger.defaultLog = None 13012c1d45bSMatthew G Knepley 13165a891e7SLisandro Dalcindef build(dry_run=False): 13265a891e7SLisandro Dalcin log.info('PETSc: build') 133367c215cSLisandro Dalcin # Run PETSc build 134cb58ab5bSLisandro Dalcin if dry_run: return 135367c215cSLisandro Dalcin use_builder_py = False 136367c215cSLisandro Dalcin if use_builder_py: 137e68ebbecSBarry Smith import builder 138e68ebbecSBarry Smith builder.PETScMaker().run() 139105e34d4SBarry Smith import logger 140105e34d4SBarry Smith logger.Logger.defaultLog = None 141367c215cSLisandro Dalcin else: 142367c215cSLisandro Dalcin make = find_executable('make') 143367c215cSLisandro Dalcin status = os.system(" ".join( 144367c215cSLisandro Dalcin [make, 'all'] 145367c215cSLisandro Dalcin )) 146367c215cSLisandro Dalcin if status != 0: raise RuntimeError(status) 147e68ebbecSBarry Smith 14865a891e7SLisandro Dalcindef install(dest_dir, prefix=None, dry_run=False): 14965a891e7SLisandro Dalcin log.info('PETSc: install') 15065a891e7SLisandro Dalcin if prefix is None: 15165a891e7SLisandro Dalcin prefix = dest_dir 15265a891e7SLisandro Dalcin options = [ 15365a891e7SLisandro Dalcin '--destDir=' + dest_dir, 1544dee622bSLisandro Dalcin '--prefix=' + prefix, 15565a891e7SLisandro Dalcin ] 156cb58ab5bSLisandro Dalcin log.info('install options:') 157cb58ab5bSLisandro Dalcin for opt in options: 158cb58ab5bSLisandro Dalcin log.info(' '*4 + opt) 15959e0f383SLisandro Dalcin # Run PETSc installer 160cb58ab5bSLisandro Dalcin if dry_run: return 161367c215cSLisandro Dalcin use_install_py = True 162367c215cSLisandro Dalcin if use_install_py: 163105e34d4SBarry Smith import install 16465a891e7SLisandro Dalcin install.Installer(options).run() 16565a891e7SLisandro Dalcin import logger 16665a891e7SLisandro Dalcin logger.Logger.defaultLog = None 167367c215cSLisandro Dalcin else: 168367c215cSLisandro Dalcin make = find_executable('make') 169367c215cSLisandro Dalcin status = os.system(" ".join( 170367c215cSLisandro Dalcin [make, 'install', 'DESTDIR='+dest_dir] 171367c215cSLisandro Dalcin )) 172367c215cSLisandro Dalcin if status != 0: raise RuntimeError(status) 17399468c80SLisandro Dalcin 17499468c80SLisandro Dalcinclass context: 17599468c80SLisandro Dalcin def __init__(self): 17699468c80SLisandro Dalcin self.sys_argv = sys.argv[:] 17799468c80SLisandro Dalcin self.wdir = os.getcwd() 17899468c80SLisandro Dalcin def enter(self): 17999468c80SLisandro Dalcin del sys.argv[1:] 18099468c80SLisandro Dalcin pdir = os.environ['PETSC_DIR'] 18199468c80SLisandro Dalcin os.chdir(pdir) 18299468c80SLisandro Dalcin return self 18399468c80SLisandro Dalcin def exit(self): 18499468c80SLisandro Dalcin sys.argv[:] = self.sys_argv 18599468c80SLisandro Dalcin os.chdir(self.wdir) 186105e34d4SBarry Smith 18765a891e7SLisandro Dalcinclass cmd_build(_build): 18865a891e7SLisandro Dalcin 189a597b971SLisandro Dalcin def initialize_options(self): 190a597b971SLisandro Dalcin _build.initialize_options(self) 191a597b971SLisandro Dalcin PETSC_ARCH = os.environ.get('PETSC_ARCH', '') 192a597b971SLisandro Dalcin self.build_base = os.path.join(PETSC_ARCH, 'build-python') 193a597b971SLisandro Dalcin 19465a891e7SLisandro Dalcin def run(self): 19565a891e7SLisandro Dalcin _build.run(self) 19699468c80SLisandro Dalcin ctx = context().enter() 19765a891e7SLisandro Dalcin try: 19865a891e7SLisandro Dalcin config(self.dry_run) 19965a891e7SLisandro Dalcin build(self.dry_run) 20065a891e7SLisandro Dalcin finally: 20199468c80SLisandro Dalcin ctx.exit() 20265a891e7SLisandro Dalcin 20365a891e7SLisandro Dalcinclass cmd_install(_install): 20465a891e7SLisandro Dalcin 20541716173SLisandro Dalcin def initialize_options(self): 20641716173SLisandro Dalcin _install.initialize_options(self) 20741716173SLisandro Dalcin self.optimize = 1 20841716173SLisandro Dalcin 20965a891e7SLisandro Dalcin def run(self): 21065a891e7SLisandro Dalcin root_dir = self.install_platlib 21165a891e7SLisandro Dalcin dest_dir = os.path.join(root_dir, 'petsc') 21265a891e7SLisandro Dalcin bdist_base = self.get_finalized_command('bdist').bdist_base 21365a891e7SLisandro Dalcin if dest_dir.startswith(bdist_base): 21465a891e7SLisandro Dalcin prefix = dest_dir[len(bdist_base)+1:] 21565a891e7SLisandro Dalcin prefix = prefix[prefix.index(os.path.sep):] 21665a891e7SLisandro Dalcin else: 21765a891e7SLisandro Dalcin prefix = dest_dir 21865a891e7SLisandro Dalcin dest_dir = os.path.abspath(dest_dir) 21965a891e7SLisandro Dalcin prefix = os.path.abspath(prefix) 22099468c80SLisandro Dalcin # 22199468c80SLisandro Dalcin _install.run(self) 22299468c80SLisandro Dalcin ctx = context().enter() 22365a891e7SLisandro Dalcin try: 22465a891e7SLisandro Dalcin install(dest_dir, prefix, self.dry_run) 22565a891e7SLisandro Dalcin finally: 22699468c80SLisandro Dalcin ctx.exit() 22765a891e7SLisandro Dalcin 228a32381aeSLisandro Dalcinclass cmd_sdist(_sdist): 229a32381aeSLisandro Dalcin 230a32381aeSLisandro Dalcin def initialize_options(self): 231a32381aeSLisandro Dalcin _sdist.initialize_options(self) 232a32381aeSLisandro Dalcin self.force_manifest = 1 23399468c80SLisandro Dalcin self.template = os.path.join('config', 'manifest.in') 234a32381aeSLisandro Dalcin 23565a891e7SLisandro Dalcindef version(): 2367d04d9c9SLisandro Dalcin import re 2377d04d9c9SLisandro Dalcin version_re = { 2387d04d9c9SLisandro Dalcin 'major' : re.compile(r"#define\s+PETSC_VERSION_MAJOR\s+(\d+)"), 2397d04d9c9SLisandro Dalcin 'minor' : re.compile(r"#define\s+PETSC_VERSION_MINOR\s+(\d+)"), 2407d04d9c9SLisandro Dalcin 'micro' : re.compile(r"#define\s+PETSC_VERSION_SUBMINOR\s+(\d+)"), 2417d04d9c9SLisandro Dalcin 'patch' : re.compile(r"#define\s+PETSC_VERSION_PATCH\s+(\d+)"), 2427d04d9c9SLisandro Dalcin 'release': re.compile(r"#define\s+PETSC_VERSION_RELEASE\s+(\d+)"), 2437d04d9c9SLisandro Dalcin } 2447d04d9c9SLisandro Dalcin petscversion_h = os.path.join('include','petscversion.h') 2457d04d9c9SLisandro Dalcin data = open(petscversion_h, 'rt').read() 2467d04d9c9SLisandro Dalcin major = int(version_re['major'].search(data).groups()[0]) 2477d04d9c9SLisandro Dalcin minor = int(version_re['minor'].search(data).groups()[0]) 2487d04d9c9SLisandro Dalcin micro = int(version_re['micro'].search(data).groups()[0]) 2497d04d9c9SLisandro Dalcin patch = int(version_re['patch'].search(data).groups()[0]) 2507d04d9c9SLisandro Dalcin release = int(version_re['release'].search(data).groups()[0]) 2517d04d9c9SLisandro Dalcin if release: 2527d04d9c9SLisandro Dalcin v = "%d.%d" % (major, minor) 2537d04d9c9SLisandro Dalcin if micro > 0: 2547d04d9c9SLisandro Dalcin v += ".%d" % micro 255247a1238SLisandro Dalcin #if patch > 0: 256247a1238SLisandro Dalcin # v += ".post%d" % patch 2577d04d9c9SLisandro Dalcin else: 25861a717f9SLisandro Dalcin v = "%d.%d.dev%d" % (major, minor+1, 0) 2597d04d9c9SLisandro Dalcin return v 26059e0f383SLisandro Dalcin 26165a891e7SLisandro Dalcindef tarball(): 26250f36069SLisandro Dalcin VERSION = version() 26350f36069SLisandro Dalcin if '.dev' in VERSION: 264a32381aeSLisandro Dalcin return None 2657d562c6eSLisandro Dalcin bits = VERSION.split('.') 2667d562c6eSLisandro Dalcin if len(bits) == 2: bits.append('0') 267247a1238SLisandro Dalcin PETSC_VERSION = '.'.join(bits[:3]) 26850f36069SLisandro Dalcin return ('http://ftp.mcs.anl.gov/pub/petsc/release-snapshots/' 269a9157d91SLisandro Dalcin 'petsc-lite-%s.tar.gz#egg=petsc-%s' % (PETSC_VERSION, VERSION)) 27065a891e7SLisandro Dalcin 27165a891e7SLisandro Dalcindescription = __doc__.split('\n')[1:-1]; del description[1:3] 27265a891e7SLisandro Dalcinclassifiers = """ 27365a891e7SLisandro DalcinLicense :: Public Domain 27465a891e7SLisandro DalcinOperating System :: POSIX 27565a891e7SLisandro DalcinIntended Audience :: Developers 27665a891e7SLisandro DalcinIntended Audience :: Science/Research 27765a891e7SLisandro DalcinProgramming Language :: C 27865a891e7SLisandro DalcinProgramming Language :: C++ 27965a891e7SLisandro DalcinProgramming Language :: Fortran 28065a891e7SLisandro DalcinProgramming Language :: Python 28165a891e7SLisandro DalcinTopic :: Scientific/Engineering 28265a891e7SLisandro DalcinTopic :: Software Development :: Libraries 28365a891e7SLisandro Dalcin""" 28465a891e7SLisandro Dalcin 28565a891e7SLisandro Dalcinbootstrap() 28665a891e7SLisandro Dalcinsetup(name='petsc', 28765a891e7SLisandro Dalcin version=version(), 28865a891e7SLisandro Dalcin description=description.pop(0), 28965a891e7SLisandro Dalcin long_description='\n'.join(description), 29065a891e7SLisandro Dalcin classifiers= classifiers.split('\n')[1:-1], 29165a891e7SLisandro Dalcin keywords = ['PETSc', 'MPI'], 29265a891e7SLisandro Dalcin platforms=['POSIX'], 29365a891e7SLisandro Dalcin license='PETSc', 29465a891e7SLisandro Dalcin 29565a891e7SLisandro Dalcin url='http://www.mcs.anl.gov/petsc/', 29665a891e7SLisandro Dalcin download_url=tarball(), 29765a891e7SLisandro Dalcin 29865a891e7SLisandro Dalcin author='PETSc Team', 29999468c80SLisandro Dalcin author_email='petsc-maint@mcs.anl.gov', 30065a891e7SLisandro Dalcin maintainer='Lisandro Dalcin', 30165a891e7SLisandro Dalcin maintainer_email='dalcinl@gmail.com', 30265a891e7SLisandro Dalcin 30365a891e7SLisandro Dalcin packages = ['petsc'], 3049fb7a39fSLisandro Dalcin package_dir = {'petsc': 'config/pypi'}, 30565a891e7SLisandro Dalcin cmdclass={ 30665a891e7SLisandro Dalcin 'build': cmd_build, 30765a891e7SLisandro Dalcin 'install': cmd_install, 308a32381aeSLisandro Dalcin 'sdist': cmd_sdist, 30965a891e7SLisandro Dalcin }, 31059e0f383SLisandro Dalcin **metadata) 311