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 18eaf87d4bSBarry Smith $ python -m pip install numpy mpi4py (or pip install numpy mpi4py) 19eaf87d4bSBarry Smith $ python -m pip install petsc petsc4py (or pip install petsc petsc4py) 2093b33a5aSLisandro Dalcin 21922ada92SLisandro Dalcin.. tip:: 22922ada92SLisandro Dalcin 2393b33a5aSLisandro Dalcin You can also install the in-development versions with:: 24922ada92SLisandro Dalcin 25eaf87d4bSBarry Smith $ python -m pip install Cython numpy mpi4py 26*9dddd249SSatish Balay $ python -m pip install --no-deps https://gitlab.com/petsc/petsc/-/archive/main/petsc-main.tar.gz 27ca62002aSBarry Smith 28007ce00dSBarry Smith To set the MPI compilers use the environmental variables ``MPICC``, ``MPICXX``, ``MPIF90``. 29007ce00dSBarry Smith 30007ce00dSBarry Smith Provide any ``PETSc`` ./configure options using the environmental variable ``PETSC_CONFIGURE_OPTIONS``. 31007ce00dSBarry Smith 32007ce00dSBarry Smith Do not use the ``PETSc`` ``./configure`` options ``--with-cc``, ``--with-cxx``, ``--with-fc``, or ``--with-mpi-dir``. 33007ce00dSBarry Smith 34007ce00dSBarry Smith If ``mpi4py`` is installed the compilers will obtained from that installation and ``MPICC``, ``MPICXX``, ``MPIF90`` will be ignored. 35007ce00dSBarry Smith 36e68ebbecSBarry Smith""" 37e68ebbecSBarry Smith 3865a891e7SLisandro Dalcinimport sys, os 3996fd8cd7SLisandro Dalcinfrom setuptools import setup 4096fd8cd7SLisandro Dalcinfrom setuptools.command.install import install as _install 41cb58ab5bSLisandro Dalcinfrom distutils.util import get_platform, split_quoted 42b88f8b63SLisandro Dalcinfrom distutils.spawn import find_executable 4365a891e7SLisandro Dalcinfrom distutils import log 4412c1d45bSMatthew G Knepley 4565a891e7SLisandro Dalcininit_py = """\ 46a32381aeSLisandro Dalcin# Author: PETSc Team 47a597b971SLisandro Dalcin# Contact: petsc-maint@mcs.anl.gov 4865a891e7SLisandro Dalcin 4965a891e7SLisandro Dalcindef get_petsc_dir(): 5065a891e7SLisandro Dalcin import os 5165a891e7SLisandro Dalcin return os.path.dirname(__file__) 5265a891e7SLisandro Dalcin 53a32381aeSLisandro Dalcindef get_config(): 54a32381aeSLisandro Dalcin conf = {} 559fb7a39fSLisandro Dalcin conf['PETSC_DIR'] = get_petsc_dir() 56a32381aeSLisandro Dalcin return conf 5765a891e7SLisandro Dalcin""" 5865a891e7SLisandro Dalcin 5959e0f383SLisandro Dalcinmetadata = { 6059e0f383SLisandro Dalcin 'provides' : ['petsc'], 6196fd8cd7SLisandro Dalcin 'zip_safe' : False, 6259e0f383SLisandro Dalcin} 6359e0f383SLisandro Dalcin 6415075023SLisandro DalcinCONFIGURE_OPTIONS = [] 6515075023SLisandro Dalcin 6665a891e7SLisandro Dalcindef bootstrap(): 67cb58ab5bSLisandro Dalcin # Set PETSC_DIR and PETSC_ARCH 6865a891e7SLisandro Dalcin PETSC_DIR = os.path.abspath(os.getcwd()) 6996fd8cd7SLisandro Dalcin PETSC_ARCH = 'arch-python-' + get_platform() 7065a891e7SLisandro Dalcin os.environ['PETSC_DIR'] = PETSC_DIR 7165a891e7SLisandro Dalcin os.environ['PETSC_ARCH'] = PETSC_ARCH 7265a891e7SLisandro Dalcin sys.path.insert(0, os.path.join(PETSC_DIR, 'config')) 73af0996ceSBarry Smith sys.path.insert(0, os.path.join(PETSC_DIR, 'lib','petsc','conf')) 7459e0f383SLisandro Dalcin # Generate package __init__.py file 759fb7a39fSLisandro Dalcin from distutils.dir_util import mkpath 769fb7a39fSLisandro Dalcin pkgdir = os.path.join('config', 'pypi') 770ddf2052SLisandro Dalcin if not os.path.exists(pkgdir): mkpath(pkgdir) 789fb7a39fSLisandro Dalcin pkgfile = os.path.join(pkgdir, '__init__.py') 7996fd8cd7SLisandro Dalcin fh = open(pkgfile, 'w') 80922ada92SLisandro Dalcin fh.write(init_py) 81922ada92SLisandro Dalcin fh.close() 8215075023SLisandro Dalcin # Configure options 8315075023SLisandro Dalcin options = os.environ.get('PETSC_CONFIGURE_OPTIONS', '') 8415075023SLisandro Dalcin CONFIGURE_OPTIONS.extend(split_quoted(options)) 85007ce00dSBarry Smith for i in CONFIGURE_OPTIONS: 865f9afd5aSLawrence Mitchell if i.startswith('--with-mpi-dir='): 87007ce00dSBarry Smith raise RuntimeError("Do not use --with-mpi-dir, use the environmental variables MPICC, MPICXX, MPIF90") 885f9afd5aSLawrence Mitchell if i.startswith('--with-cc='): 89007ce00dSBarry Smith raise RuntimeError("Do not use --with-cc, use the environmental variable MPICC") 905f9afd5aSLawrence Mitchell if i.startswith('--with-cxx=') and i != "--with-cxx=0": 91007ce00dSBarry Smith raise RuntimeError("Do not use --with-cxx, use the environmental variable MPICXX") 925f9afd5aSLawrence Mitchell if i.startswith('--with-fc=') and i != "--with-fc=0": 93007ce00dSBarry Smith raise RuntimeError("Do not use --with-fc, use the environmental variable MPIF90") 94007ce00dSBarry Smith 9515075023SLisandro Dalcin if '--with-mpi=0' not in CONFIGURE_OPTIONS: 9659e0f383SLisandro Dalcin # Simple-minded lookup for MPI and mpi4py 9759e0f383SLisandro Dalcin mpi4py = mpicc = None 9859e0f383SLisandro Dalcin try: 9959e0f383SLisandro Dalcin import mpi4py 10059e0f383SLisandro Dalcin conf = mpi4py.get_config() 10159e0f383SLisandro Dalcin mpicc = conf.get('mpicc') 10259e0f383SLisandro Dalcin except ImportError: # mpi4py is not installed 103922ada92SLisandro Dalcin mpi4py = None 10415075023SLisandro Dalcin mpicc = (os.environ.get('MPICC') or 10515075023SLisandro Dalcin find_executable('mpicc')) 1061b095333SLisandro Dalcin except AttributeError: # mpi4py is too old 10759e0f383SLisandro Dalcin pass 108922ada92SLisandro Dalcin if not mpi4py and mpicc: 109922ada92SLisandro Dalcin metadata['install_requires'] = ['mpi4py>=1.2.2'] 11065a891e7SLisandro Dalcin 11196fd8cd7SLisandro Dalcindef config(prefix, dry_run=False): 11265a891e7SLisandro Dalcin log.info('PETSc: configure') 11365a891e7SLisandro Dalcin options = [ 11496fd8cd7SLisandro Dalcin '--prefix=' + prefix, 11565a891e7SLisandro Dalcin 'PETSC_ARCH='+os.environ['PETSC_ARCH'], 116cb58ab5bSLisandro Dalcin '--with-shared-libraries=1', 11711035aebSLisandro Dalcin '--with-debugging=0', 118922ada92SLisandro Dalcin '--with-c2html=0', # not needed 11965a891e7SLisandro Dalcin ] 12015075023SLisandro Dalcin if '--with-fc=0' in CONFIGURE_OPTIONS: 12115075023SLisandro Dalcin options.append('--with-sowing=0') 12215075023SLisandro Dalcin if '--with-mpi=0' not in CONFIGURE_OPTIONS: 12359e0f383SLisandro Dalcin try: 12459e0f383SLisandro Dalcin import mpi4py 12559e0f383SLisandro Dalcin conf = mpi4py.get_config() 12659e0f383SLisandro Dalcin mpicc = conf.get('mpicc') 127cb58ab5bSLisandro Dalcin mpicxx = conf.get('mpicxx') 128cb58ab5bSLisandro Dalcin mpif90 = conf.get('mpif90') 12959e0f383SLisandro Dalcin except (ImportError, AttributeError): 13059e0f383SLisandro Dalcin mpicc = os.environ.get('MPICC') or find_executable('mpicc') 131cb58ab5bSLisandro Dalcin mpicxx = os.environ.get('MPICXX') or find_executable('mpicxx') 132cb58ab5bSLisandro Dalcin mpif90 = os.environ.get('MPIF90') or find_executable('mpif90') 13359e0f383SLisandro Dalcin if mpicc: 13459e0f383SLisandro Dalcin options.append('--with-cc='+mpicc) 13515075023SLisandro Dalcin if '--with-cxx=0' not in CONFIGURE_OPTIONS: 136cb58ab5bSLisandro Dalcin if mpicxx: 137cb58ab5bSLisandro Dalcin options.append('--with-cxx='+mpicxx) 13893b33a5aSLisandro Dalcin else: 13993b33a5aSLisandro Dalcin options.append('--with-cxx=0') 14015075023SLisandro Dalcin if '--with-fc=0' not in CONFIGURE_OPTIONS: 141cb58ab5bSLisandro Dalcin if mpif90: 142cb58ab5bSLisandro Dalcin options.append('--with-fc='+mpif90) 14359e0f383SLisandro Dalcin else: 14493b33a5aSLisandro Dalcin options.append('--with-fc=0') 14593b33a5aSLisandro Dalcin options.append('--with-sowing=0') 14693b33a5aSLisandro Dalcin else: 14759e0f383SLisandro Dalcin options.append('--with-mpi=0') 14815075023SLisandro Dalcin options.extend(CONFIGURE_OPTIONS) 14915075023SLisandro Dalcin # 150cb58ab5bSLisandro Dalcin log.info('configure options:') 151cb58ab5bSLisandro Dalcin for opt in options: 152cb58ab5bSLisandro Dalcin log.info(' '*4 + opt) 15359e0f383SLisandro Dalcin # Run PETSc configure 154cb58ab5bSLisandro Dalcin if dry_run: return 1550a0dac6aSLisandro Dalcin use_config_py = False 15696fd8cd7SLisandro Dalcin if use_config_py: 157e68ebbecSBarry Smith import configure 15865a891e7SLisandro Dalcin configure.petsc_configure(options) 159e68ebbecSBarry Smith import logger 160e68ebbecSBarry Smith logger.Logger.defaultLog = None 16196fd8cd7SLisandro Dalcin else: 1620a0dac6aSLisandro Dalcin python = find_executable('python2') or find_executable('python') 1630a0dac6aSLisandro Dalcin command = [python, './configure'] + options 16496fd8cd7SLisandro Dalcin status = os.system(" ".join(command)) 16596fd8cd7SLisandro Dalcin if status != 0: raise RuntimeError(status) 16612c1d45bSMatthew G Knepley 16765a891e7SLisandro Dalcindef build(dry_run=False): 16865a891e7SLisandro Dalcin log.info('PETSc: build') 169367c215cSLisandro Dalcin # Run PETSc build 170cb58ab5bSLisandro Dalcin if dry_run: return 171367c215cSLisandro Dalcin use_builder_py = False 172367c215cSLisandro Dalcin if use_builder_py: 173e68ebbecSBarry Smith import builder 174e68ebbecSBarry Smith builder.PETScMaker().run() 175105e34d4SBarry Smith import logger 176105e34d4SBarry Smith logger.Logger.defaultLog = None 177367c215cSLisandro Dalcin else: 178367c215cSLisandro Dalcin make = find_executable('make') 17996fd8cd7SLisandro Dalcin command = [make, 'all'] 18096fd8cd7SLisandro Dalcin status = os.system(" ".join(command)) 181367c215cSLisandro Dalcin if status != 0: raise RuntimeError(status) 182e68ebbecSBarry Smith 1838c408988SSatish Balaydef install(dry_run=False): 18465a891e7SLisandro Dalcin log.info('PETSc: install') 18559e0f383SLisandro Dalcin # Run PETSc installer 186cb58ab5bSLisandro Dalcin if dry_run: return 1870a0dac6aSLisandro Dalcin use_install_py = False 188367c215cSLisandro Dalcin if use_install_py: 189105e34d4SBarry Smith import install 1908c408988SSatish Balay install.Installer().run() 19165a891e7SLisandro Dalcin import logger 19265a891e7SLisandro Dalcin logger.Logger.defaultLog = None 193367c215cSLisandro Dalcin else: 194367c215cSLisandro Dalcin make = find_executable('make') 1958c408988SSatish Balay command = [make, 'install'] 19696fd8cd7SLisandro Dalcin status = os.system(" ".join(command)) 197367c215cSLisandro Dalcin if status != 0: raise RuntimeError(status) 19899468c80SLisandro Dalcin 19996fd8cd7SLisandro Dalcinclass context(object): 20099468c80SLisandro Dalcin def __init__(self): 20199468c80SLisandro Dalcin self.sys_argv = sys.argv[:] 20299468c80SLisandro Dalcin self.wdir = os.getcwd() 20399468c80SLisandro Dalcin def enter(self): 20499468c80SLisandro Dalcin del sys.argv[1:] 20599468c80SLisandro Dalcin pdir = os.environ['PETSC_DIR'] 20699468c80SLisandro Dalcin os.chdir(pdir) 20799468c80SLisandro Dalcin return self 20899468c80SLisandro Dalcin def exit(self): 20999468c80SLisandro Dalcin sys.argv[:] = self.sys_argv 21099468c80SLisandro Dalcin os.chdir(self.wdir) 211105e34d4SBarry Smith 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 21889031a3cSLisandro Dalcin def finalize_options(self): 21989031a3cSLisandro Dalcin _install.finalize_options(self) 22089031a3cSLisandro Dalcin self.install_lib = self.install_platlib 22189031a3cSLisandro Dalcin self.install_libbase = self.install_lib 22289031a3cSLisandro Dalcin 22365a891e7SLisandro Dalcin def run(self): 22489031a3cSLisandro Dalcin root_dir = os.path.abspath(self.install_lib) 2258c408988SSatish Balay prefix = os.path.join(root_dir, 'petsc') 22699468c80SLisandro Dalcin # 22799468c80SLisandro Dalcin ctx = context().enter() 22865a891e7SLisandro Dalcin try: 22996fd8cd7SLisandro Dalcin config(prefix, self.dry_run) 23096fd8cd7SLisandro Dalcin build(self.dry_run) 2318c408988SSatish Balay install(self.dry_run) 23265a891e7SLisandro Dalcin finally: 23399468c80SLisandro Dalcin ctx.exit() 23496fd8cd7SLisandro Dalcin # 23596fd8cd7SLisandro Dalcin self.outputs = [] 2368c408988SSatish Balay for dirpath, _, filenames in os.walk(prefix): 23796fd8cd7SLisandro Dalcin for fn in filenames: 23896fd8cd7SLisandro Dalcin self.outputs.append(os.path.join(dirpath, fn)) 23996fd8cd7SLisandro Dalcin # 24096fd8cd7SLisandro Dalcin _install.run(self) 24165a891e7SLisandro Dalcin 24296fd8cd7SLisandro Dalcin def get_outputs(self): 24396fd8cd7SLisandro Dalcin outputs = getattr(self, 'outputs', []) 24496fd8cd7SLisandro Dalcin outputs += _install.get_outputs(self) 24596fd8cd7SLisandro Dalcin return outputs 246a32381aeSLisandro Dalcin 24765a891e7SLisandro Dalcindef version(): 2487d04d9c9SLisandro Dalcin import re 2497d04d9c9SLisandro Dalcin version_re = { 2507d04d9c9SLisandro Dalcin 'major' : re.compile(r"#define\s+PETSC_VERSION_MAJOR\s+(\d+)"), 2517d04d9c9SLisandro Dalcin 'minor' : re.compile(r"#define\s+PETSC_VERSION_MINOR\s+(\d+)"), 2527d04d9c9SLisandro Dalcin 'micro' : re.compile(r"#define\s+PETSC_VERSION_SUBMINOR\s+(\d+)"), 25315261b6dSSatish Balay 'release': re.compile(r"#define\s+PETSC_VERSION_RELEASE\s+([-]*\d+)"), 2547d04d9c9SLisandro Dalcin } 2557d04d9c9SLisandro Dalcin petscversion_h = os.path.join('include','petscversion.h') 25696fd8cd7SLisandro Dalcin data = open(petscversion_h, 'r').read() 2577d04d9c9SLisandro Dalcin major = int(version_re['major'].search(data).groups()[0]) 2587d04d9c9SLisandro Dalcin minor = int(version_re['minor'].search(data).groups()[0]) 2597d04d9c9SLisandro Dalcin micro = int(version_re['micro'].search(data).groups()[0]) 2607d04d9c9SLisandro Dalcin release = int(version_re['release'].search(data).groups()[0]) 26115261b6dSSatish Balay if release > 0 : 2620a0dac6aSLisandro Dalcin v = "%d.%d.%d" % (major, minor, micro) 2637d04d9c9SLisandro Dalcin else: 2640a0dac6aSLisandro Dalcin v = "%d.%d.0.dev%d" % (major, minor+1, 0) 2657d04d9c9SLisandro Dalcin return v 26659e0f383SLisandro Dalcin 26765a891e7SLisandro Dalcindef tarball(): 26850f36069SLisandro Dalcin VERSION = version() 2690a0dac6aSLisandro Dalcin if '.dev' in VERSION: return None 270a8d69d7bSBarry Smith return ('http://ftp.mcs.anl.gov/pub/petsc/release-snapshots//' 2710a0dac6aSLisandro Dalcin 'petsc-lite-%s.tar.gz#egg=petsc-%s' % (VERSION, VERSION)) 27265a891e7SLisandro Dalcin 27365a891e7SLisandro Dalcindescription = __doc__.split('\n')[1:-1]; del description[1:3] 27465a891e7SLisandro Dalcinclassifiers = """ 27596fd8cd7SLisandro DalcinDevelopment Status :: 5 - Production/Stable 27665a891e7SLisandro DalcinIntended Audience :: Developers 27765a891e7SLisandro DalcinIntended Audience :: Science/Research 27896fd8cd7SLisandro DalcinLicense :: OSI Approved :: BSD License 27996fd8cd7SLisandro DalcinOperating System :: POSIX 28065a891e7SLisandro DalcinProgramming Language :: C 28165a891e7SLisandro DalcinProgramming Language :: C++ 28265a891e7SLisandro DalcinProgramming Language :: Fortran 28365a891e7SLisandro DalcinProgramming Language :: Python 28465a891e7SLisandro DalcinTopic :: Scientific/Engineering 28565a891e7SLisandro DalcinTopic :: Software Development :: Libraries 28665a891e7SLisandro Dalcin""" 28765a891e7SLisandro Dalcin 2880a0dac6aSLisandro Dalcinif 'bdist_wheel' in sys.argv: 2890a0dac6aSLisandro Dalcin sys.stderr.write("petsc: this package cannot be built as a wheel\n") 2900a0dac6aSLisandro Dalcin sys.exit(1) 2910a0dac6aSLisandro Dalcin 29265a891e7SLisandro Dalcinbootstrap() 29365a891e7SLisandro Dalcinsetup(name='petsc', 29465a891e7SLisandro Dalcin version=version(), 29565a891e7SLisandro Dalcin description=description.pop(0), 29665a891e7SLisandro Dalcin long_description='\n'.join(description), 29765a891e7SLisandro Dalcin classifiers= classifiers.split('\n')[1:-1], 29865a891e7SLisandro Dalcin keywords = ['PETSc', 'MPI'], 29965a891e7SLisandro Dalcin platforms=['POSIX'], 300405e6c8eSLisandro Dalcin license='BSD', 30165a891e7SLisandro Dalcin 302a8d69d7bSBarry Smith url='https://www.mcs.anl.gov/petsc/', 30365a891e7SLisandro Dalcin download_url=tarball(), 30465a891e7SLisandro Dalcin 30565a891e7SLisandro Dalcin author='PETSc Team', 30699468c80SLisandro Dalcin author_email='petsc-maint@mcs.anl.gov', 30765a891e7SLisandro Dalcin maintainer='Lisandro Dalcin', 30865a891e7SLisandro Dalcin maintainer_email='dalcinl@gmail.com', 30965a891e7SLisandro Dalcin 31065a891e7SLisandro Dalcin packages = ['petsc'], 3119fb7a39fSLisandro Dalcin package_dir = {'petsc': 'config/pypi'}, 31296fd8cd7SLisandro Dalcin cmdclass={'install': cmd_install}, 31359e0f383SLisandro Dalcin **metadata) 314