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 1393b33a5aSLisandro Dalcin.. note:: 1493b33a5aSLisandro Dalcin 1593b33a5aSLisandro Dalcin To install ``PETSc`` and ``petsc4py`` (``mpi4py`` is optional 1693b33a5aSLisandro Dalcin but highly recommended) use:: 1793b33a5aSLisandro Dalcin 1893b33a5aSLisandro Dalcin $ pip install numpy mpi4py 1993b33a5aSLisandro Dalcin $ pip install petsc petsc4py 2093b33a5aSLisandro Dalcin 21922ada92SLisandro Dalcin.. tip:: 22922ada92SLisandro Dalcin 2393b33a5aSLisandro Dalcin You can also install the in-development versions with:: 24922ada92SLisandro Dalcin 2593b33a5aSLisandro Dalcin $ pip install Cython numpy mpi4py 2693b33a5aSLisandro Dalcin $ pip install --no-deps https://bitbucket.org/petsc/petsc/get/master.tar.gz 2793b33a5aSLisandro Dalcin $ pip install --no-deps https://bitbucket.org/petsc/petsc4py/get/master.tar.gz 28ca62002aSBarry Smith 29007ce00dSBarry Smith To set the MPI compilers use the environmental variables ``MPICC``, ``MPICXX``, ``MPIF90``. 30007ce00dSBarry Smith 31007ce00dSBarry Smith Provide any ``PETSc`` ./configure options using the environmental variable ``PETSC_CONFIGURE_OPTIONS``. 32007ce00dSBarry Smith 33007ce00dSBarry Smith Do not use the ``PETSc`` ``./configure`` options ``--with-cc``, ``--with-cxx``, ``--with-fc``, or ``--with-mpi-dir``. 34007ce00dSBarry Smith 35007ce00dSBarry Smith If ``mpi4py`` is installed the compilers will obtained from that installation and ``MPICC``, ``MPICXX``, ``MPIF90`` will be ignored. 36007ce00dSBarry Smith 37e68ebbecSBarry Smith""" 38e68ebbecSBarry Smith 3965a891e7SLisandro Dalcinimport sys, os 4096fd8cd7SLisandro Dalcinfrom setuptools import setup 4196fd8cd7SLisandro Dalcinfrom setuptools.command.install import install as _install 42cb58ab5bSLisandro Dalcinfrom distutils.util import get_platform, split_quoted 43b88f8b63SLisandro Dalcinfrom distutils.spawn import find_executable 4465a891e7SLisandro Dalcinfrom distutils import log 4512c1d45bSMatthew G Knepley 4665a891e7SLisandro Dalcininit_py = """\ 47a32381aeSLisandro Dalcin# Author: PETSc Team 48a597b971SLisandro Dalcin# Contact: petsc-maint@mcs.anl.gov 4965a891e7SLisandro Dalcin 5065a891e7SLisandro Dalcindef get_petsc_dir(): 5165a891e7SLisandro Dalcin import os 5265a891e7SLisandro Dalcin return os.path.dirname(__file__) 5365a891e7SLisandro Dalcin 54a32381aeSLisandro Dalcindef get_config(): 55a32381aeSLisandro Dalcin conf = {} 569fb7a39fSLisandro Dalcin conf['PETSC_DIR'] = get_petsc_dir() 57a32381aeSLisandro Dalcin return conf 5865a891e7SLisandro Dalcin""" 5965a891e7SLisandro Dalcin 6059e0f383SLisandro Dalcinmetadata = { 6159e0f383SLisandro Dalcin 'provides' : ['petsc'], 6296fd8cd7SLisandro Dalcin 'zip_safe' : False, 6359e0f383SLisandro Dalcin} 6459e0f383SLisandro Dalcin 6515075023SLisandro DalcinCONFIGURE_OPTIONS = [] 6615075023SLisandro Dalcin 6765a891e7SLisandro Dalcindef bootstrap(): 68cb58ab5bSLisandro Dalcin # Set PETSC_DIR and PETSC_ARCH 6965a891e7SLisandro Dalcin PETSC_DIR = os.path.abspath(os.getcwd()) 7096fd8cd7SLisandro Dalcin PETSC_ARCH = 'arch-python-' + get_platform() 7165a891e7SLisandro Dalcin os.environ['PETSC_DIR'] = PETSC_DIR 7265a891e7SLisandro Dalcin os.environ['PETSC_ARCH'] = PETSC_ARCH 7365a891e7SLisandro Dalcin sys.path.insert(0, os.path.join(PETSC_DIR, 'config')) 74af0996ceSBarry Smith sys.path.insert(0, os.path.join(PETSC_DIR, 'lib','petsc','conf')) 7559e0f383SLisandro Dalcin # Generate package __init__.py file 769fb7a39fSLisandro Dalcin from distutils.dir_util import mkpath 779fb7a39fSLisandro Dalcin pkgdir = os.path.join('config', 'pypi') 780ddf2052SLisandro Dalcin if not os.path.exists(pkgdir): mkpath(pkgdir) 799fb7a39fSLisandro Dalcin pkgfile = os.path.join(pkgdir, '__init__.py') 8096fd8cd7SLisandro Dalcin fh = open(pkgfile, 'w') 81922ada92SLisandro Dalcin fh.write(init_py) 82922ada92SLisandro Dalcin fh.close() 8315075023SLisandro Dalcin # Configure options 8415075023SLisandro Dalcin options = os.environ.get('PETSC_CONFIGURE_OPTIONS', '') 8515075023SLisandro Dalcin CONFIGURE_OPTIONS.extend(split_quoted(options)) 86007ce00dSBarry Smith for i in CONFIGURE_OPTIONS: 875f9afd5aSLawrence Mitchell if i.startswith('--with-mpi-dir='): 88007ce00dSBarry Smith raise RuntimeError("Do not use --with-mpi-dir, use the environmental variables MPICC, MPICXX, MPIF90") 895f9afd5aSLawrence Mitchell if i.startswith('--with-cc='): 90007ce00dSBarry Smith raise RuntimeError("Do not use --with-cc, use the environmental variable MPICC") 915f9afd5aSLawrence Mitchell if i.startswith('--with-cxx=') and i != "--with-cxx=0": 92007ce00dSBarry Smith raise RuntimeError("Do not use --with-cxx, use the environmental variable MPICXX") 935f9afd5aSLawrence Mitchell if i.startswith('--with-fc=') and i != "--with-fc=0": 94007ce00dSBarry Smith raise RuntimeError("Do not use --with-fc, use the environmental variable MPIF90") 95007ce00dSBarry Smith 9615075023SLisandro Dalcin if '--with-mpi=0' not in CONFIGURE_OPTIONS: 9759e0f383SLisandro Dalcin # Simple-minded lookup for MPI and mpi4py 9859e0f383SLisandro Dalcin mpi4py = mpicc = None 9959e0f383SLisandro Dalcin try: 10059e0f383SLisandro Dalcin import mpi4py 10159e0f383SLisandro Dalcin conf = mpi4py.get_config() 10259e0f383SLisandro Dalcin mpicc = conf.get('mpicc') 10359e0f383SLisandro Dalcin except ImportError: # mpi4py is not installed 104922ada92SLisandro Dalcin mpi4py = None 10515075023SLisandro Dalcin mpicc = (os.environ.get('MPICC') or 10615075023SLisandro Dalcin find_executable('mpicc')) 1071b095333SLisandro Dalcin except AttributeError: # mpi4py is too old 10859e0f383SLisandro Dalcin pass 109922ada92SLisandro Dalcin if not mpi4py and mpicc: 110922ada92SLisandro Dalcin metadata['install_requires'] = ['mpi4py>=1.2.2'] 11165a891e7SLisandro Dalcin 11296fd8cd7SLisandro Dalcindef config(prefix, dry_run=False): 11365a891e7SLisandro Dalcin log.info('PETSc: configure') 11465a891e7SLisandro Dalcin options = [ 11596fd8cd7SLisandro Dalcin '--prefix=' + prefix, 11665a891e7SLisandro Dalcin 'PETSC_ARCH='+os.environ['PETSC_ARCH'], 117cb58ab5bSLisandro Dalcin '--with-shared-libraries=1', 11811035aebSLisandro Dalcin '--with-debugging=0', 119922ada92SLisandro Dalcin '--with-c2html=0', # not needed 12065a891e7SLisandro Dalcin ] 12115075023SLisandro Dalcin if '--with-fc=0' in CONFIGURE_OPTIONS: 12215075023SLisandro Dalcin options.append('--with-sowing=0') 12315075023SLisandro Dalcin if '--with-mpi=0' not in CONFIGURE_OPTIONS: 12459e0f383SLisandro Dalcin try: 12559e0f383SLisandro Dalcin import mpi4py 12659e0f383SLisandro Dalcin conf = mpi4py.get_config() 12759e0f383SLisandro Dalcin mpicc = conf.get('mpicc') 128cb58ab5bSLisandro Dalcin mpicxx = conf.get('mpicxx') 129cb58ab5bSLisandro Dalcin mpif90 = conf.get('mpif90') 13059e0f383SLisandro Dalcin except (ImportError, AttributeError): 13159e0f383SLisandro Dalcin mpicc = os.environ.get('MPICC') or find_executable('mpicc') 132cb58ab5bSLisandro Dalcin mpicxx = os.environ.get('MPICXX') or find_executable('mpicxx') 133cb58ab5bSLisandro Dalcin mpif90 = os.environ.get('MPIF90') or find_executable('mpif90') 13459e0f383SLisandro Dalcin if mpicc: 13559e0f383SLisandro Dalcin options.append('--with-cc='+mpicc) 13615075023SLisandro Dalcin if '--with-cxx=0' not in CONFIGURE_OPTIONS: 137cb58ab5bSLisandro Dalcin if mpicxx: 138cb58ab5bSLisandro Dalcin options.append('--with-cxx='+mpicxx) 13993b33a5aSLisandro Dalcin else: 14093b33a5aSLisandro Dalcin options.append('--with-cxx=0') 14115075023SLisandro Dalcin if '--with-fc=0' not in CONFIGURE_OPTIONS: 142cb58ab5bSLisandro Dalcin if mpif90: 143cb58ab5bSLisandro Dalcin options.append('--with-fc='+mpif90) 14459e0f383SLisandro Dalcin else: 14593b33a5aSLisandro Dalcin options.append('--with-fc=0') 14693b33a5aSLisandro Dalcin options.append('--with-sowing=0') 14793b33a5aSLisandro Dalcin else: 14859e0f383SLisandro Dalcin options.append('--with-mpi=0') 14915075023SLisandro Dalcin options.extend(CONFIGURE_OPTIONS) 15015075023SLisandro Dalcin # 151cb58ab5bSLisandro Dalcin log.info('configure options:') 152cb58ab5bSLisandro Dalcin for opt in options: 153cb58ab5bSLisandro Dalcin log.info(' '*4 + opt) 15459e0f383SLisandro Dalcin # Run PETSc configure 155cb58ab5bSLisandro Dalcin if dry_run: return 1560a0dac6aSLisandro Dalcin use_config_py = False 15796fd8cd7SLisandro Dalcin if use_config_py: 158e68ebbecSBarry Smith import configure 15965a891e7SLisandro Dalcin configure.petsc_configure(options) 160e68ebbecSBarry Smith import logger 161e68ebbecSBarry Smith logger.Logger.defaultLog = None 16296fd8cd7SLisandro Dalcin else: 1630a0dac6aSLisandro Dalcin python = find_executable('python2') or find_executable('python') 1640a0dac6aSLisandro Dalcin command = [python, './configure'] + options 16596fd8cd7SLisandro Dalcin status = os.system(" ".join(command)) 16696fd8cd7SLisandro Dalcin if status != 0: raise RuntimeError(status) 16712c1d45bSMatthew G Knepley 16865a891e7SLisandro Dalcindef build(dry_run=False): 16965a891e7SLisandro Dalcin log.info('PETSc: build') 170367c215cSLisandro Dalcin # Run PETSc build 171cb58ab5bSLisandro Dalcin if dry_run: return 172367c215cSLisandro Dalcin use_builder_py = False 173367c215cSLisandro Dalcin if use_builder_py: 174e68ebbecSBarry Smith import builder 175e68ebbecSBarry Smith builder.PETScMaker().run() 176105e34d4SBarry Smith import logger 177105e34d4SBarry Smith logger.Logger.defaultLog = None 178367c215cSLisandro Dalcin else: 179367c215cSLisandro Dalcin make = find_executable('make') 18096fd8cd7SLisandro Dalcin command = [make, 'all'] 18196fd8cd7SLisandro Dalcin status = os.system(" ".join(command)) 182367c215cSLisandro Dalcin if status != 0: raise RuntimeError(status) 183e68ebbecSBarry Smith 1848c408988SSatish Balaydef install(dry_run=False): 18565a891e7SLisandro Dalcin log.info('PETSc: install') 18659e0f383SLisandro Dalcin # Run PETSc installer 187cb58ab5bSLisandro Dalcin if dry_run: return 1880a0dac6aSLisandro Dalcin use_install_py = False 189367c215cSLisandro Dalcin if use_install_py: 190105e34d4SBarry Smith import install 1918c408988SSatish Balay install.Installer().run() 19265a891e7SLisandro Dalcin import logger 19365a891e7SLisandro Dalcin logger.Logger.defaultLog = None 194367c215cSLisandro Dalcin else: 195367c215cSLisandro Dalcin make = find_executable('make') 1968c408988SSatish Balay command = [make, 'install'] 19796fd8cd7SLisandro Dalcin status = os.system(" ".join(command)) 198367c215cSLisandro Dalcin if status != 0: raise RuntimeError(status) 19999468c80SLisandro Dalcin 20096fd8cd7SLisandro Dalcinclass context(object): 20199468c80SLisandro Dalcin def __init__(self): 20299468c80SLisandro Dalcin self.sys_argv = sys.argv[:] 20399468c80SLisandro Dalcin self.wdir = os.getcwd() 20499468c80SLisandro Dalcin def enter(self): 20599468c80SLisandro Dalcin del sys.argv[1:] 20699468c80SLisandro Dalcin pdir = os.environ['PETSC_DIR'] 20799468c80SLisandro Dalcin os.chdir(pdir) 20899468c80SLisandro Dalcin return self 20999468c80SLisandro Dalcin def exit(self): 21099468c80SLisandro Dalcin sys.argv[:] = self.sys_argv 21199468c80SLisandro Dalcin os.chdir(self.wdir) 212105e34d4SBarry Smith 21365a891e7SLisandro Dalcinclass cmd_install(_install): 21465a891e7SLisandro Dalcin 21541716173SLisandro Dalcin def initialize_options(self): 21641716173SLisandro Dalcin _install.initialize_options(self) 21741716173SLisandro Dalcin self.optimize = 1 21841716173SLisandro Dalcin 21989031a3cSLisandro Dalcin def finalize_options(self): 22089031a3cSLisandro Dalcin _install.finalize_options(self) 22189031a3cSLisandro Dalcin self.install_lib = self.install_platlib 22289031a3cSLisandro Dalcin self.install_libbase = self.install_lib 22389031a3cSLisandro Dalcin 22465a891e7SLisandro Dalcin def run(self): 22589031a3cSLisandro Dalcin root_dir = os.path.abspath(self.install_lib) 2268c408988SSatish Balay prefix = os.path.join(root_dir, 'petsc') 22799468c80SLisandro Dalcin # 22899468c80SLisandro Dalcin ctx = context().enter() 22965a891e7SLisandro Dalcin try: 23096fd8cd7SLisandro Dalcin config(prefix, self.dry_run) 23196fd8cd7SLisandro Dalcin build(self.dry_run) 2328c408988SSatish Balay install(self.dry_run) 23365a891e7SLisandro Dalcin finally: 23499468c80SLisandro Dalcin ctx.exit() 23596fd8cd7SLisandro Dalcin # 23696fd8cd7SLisandro Dalcin self.outputs = [] 2378c408988SSatish Balay for dirpath, _, filenames in os.walk(prefix): 23896fd8cd7SLisandro Dalcin for fn in filenames: 23996fd8cd7SLisandro Dalcin self.outputs.append(os.path.join(dirpath, fn)) 24096fd8cd7SLisandro Dalcin # 24196fd8cd7SLisandro Dalcin _install.run(self) 24265a891e7SLisandro Dalcin 24396fd8cd7SLisandro Dalcin def get_outputs(self): 24496fd8cd7SLisandro Dalcin outputs = getattr(self, 'outputs', []) 24596fd8cd7SLisandro Dalcin outputs += _install.get_outputs(self) 24696fd8cd7SLisandro Dalcin return outputs 247a32381aeSLisandro Dalcin 24865a891e7SLisandro Dalcindef version(): 2497d04d9c9SLisandro Dalcin import re 2507d04d9c9SLisandro Dalcin version_re = { 2517d04d9c9SLisandro Dalcin 'major' : re.compile(r"#define\s+PETSC_VERSION_MAJOR\s+(\d+)"), 2527d04d9c9SLisandro Dalcin 'minor' : re.compile(r"#define\s+PETSC_VERSION_MINOR\s+(\d+)"), 2537d04d9c9SLisandro Dalcin 'micro' : re.compile(r"#define\s+PETSC_VERSION_SUBMINOR\s+(\d+)"), 25415261b6dSSatish Balay 'release': re.compile(r"#define\s+PETSC_VERSION_RELEASE\s+([-]*\d+)"), 2557d04d9c9SLisandro Dalcin } 2567d04d9c9SLisandro Dalcin petscversion_h = os.path.join('include','petscversion.h') 25796fd8cd7SLisandro Dalcin data = open(petscversion_h, 'r').read() 2587d04d9c9SLisandro Dalcin major = int(version_re['major'].search(data).groups()[0]) 2597d04d9c9SLisandro Dalcin minor = int(version_re['minor'].search(data).groups()[0]) 2607d04d9c9SLisandro Dalcin micro = int(version_re['micro'].search(data).groups()[0]) 2617d04d9c9SLisandro Dalcin release = int(version_re['release'].search(data).groups()[0]) 26215261b6dSSatish Balay if release > 0 : 2630a0dac6aSLisandro Dalcin v = "%d.%d.%d" % (major, minor, micro) 2647d04d9c9SLisandro Dalcin else: 2650a0dac6aSLisandro Dalcin v = "%d.%d.0.dev%d" % (major, minor+1, 0) 2667d04d9c9SLisandro Dalcin return v 26759e0f383SLisandro Dalcin 26865a891e7SLisandro Dalcindef tarball(): 26950f36069SLisandro Dalcin VERSION = version() 2700a0dac6aSLisandro Dalcin if '.dev' in VERSION: return None 271*a8d69d7bSBarry Smith return ('http://ftp.mcs.anl.gov/pub/petsc/release-snapshots//' 2720a0dac6aSLisandro Dalcin 'petsc-lite-%s.tar.gz#egg=petsc-%s' % (VERSION, VERSION)) 27365a891e7SLisandro Dalcin 27465a891e7SLisandro Dalcindescription = __doc__.split('\n')[1:-1]; del description[1:3] 27565a891e7SLisandro Dalcinclassifiers = """ 27696fd8cd7SLisandro DalcinDevelopment Status :: 5 - Production/Stable 27765a891e7SLisandro DalcinIntended Audience :: Developers 27865a891e7SLisandro DalcinIntended Audience :: Science/Research 27996fd8cd7SLisandro DalcinLicense :: OSI Approved :: BSD License 28096fd8cd7SLisandro DalcinOperating System :: POSIX 28165a891e7SLisandro DalcinProgramming Language :: C 28265a891e7SLisandro DalcinProgramming Language :: C++ 28365a891e7SLisandro DalcinProgramming Language :: Fortran 28465a891e7SLisandro DalcinProgramming Language :: Python 28565a891e7SLisandro DalcinTopic :: Scientific/Engineering 28665a891e7SLisandro DalcinTopic :: Software Development :: Libraries 28765a891e7SLisandro Dalcin""" 28865a891e7SLisandro Dalcin 2890a0dac6aSLisandro Dalcinif 'bdist_wheel' in sys.argv: 2900a0dac6aSLisandro Dalcin sys.stderr.write("petsc: this package cannot be built as a wheel\n") 2910a0dac6aSLisandro Dalcin sys.exit(1) 2920a0dac6aSLisandro Dalcin 29365a891e7SLisandro Dalcinbootstrap() 29465a891e7SLisandro Dalcinsetup(name='petsc', 29565a891e7SLisandro Dalcin version=version(), 29665a891e7SLisandro Dalcin description=description.pop(0), 29765a891e7SLisandro Dalcin long_description='\n'.join(description), 29865a891e7SLisandro Dalcin classifiers= classifiers.split('\n')[1:-1], 29965a891e7SLisandro Dalcin keywords = ['PETSc', 'MPI'], 30065a891e7SLisandro Dalcin platforms=['POSIX'], 301405e6c8eSLisandro Dalcin license='BSD', 30265a891e7SLisandro Dalcin 303*a8d69d7bSBarry Smith url='https://www.mcs.anl.gov/petsc/', 30465a891e7SLisandro Dalcin download_url=tarball(), 30565a891e7SLisandro Dalcin 30665a891e7SLisandro Dalcin author='PETSc Team', 30799468c80SLisandro Dalcin author_email='petsc-maint@mcs.anl.gov', 30865a891e7SLisandro Dalcin maintainer='Lisandro Dalcin', 30965a891e7SLisandro Dalcin maintainer_email='dalcinl@gmail.com', 31065a891e7SLisandro Dalcin 31165a891e7SLisandro Dalcin packages = ['petsc'], 3129fb7a39fSLisandro Dalcin package_dir = {'petsc': 'config/pypi'}, 31396fd8cd7SLisandro Dalcin cmdclass={'install': cmd_install}, 31459e0f383SLisandro Dalcin **metadata) 315