-
Notifications
You must be signed in to change notification settings - Fork 199
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Modern setup.py: CMake-Driven, Multi-Dimensional
This adds a new, project-centric setup.py file. With this file, all dimensions (2D, 3D, RZ) of WarpX can be built and packaged at once, using the CMake build logic. Build & install: ```bash pip wheel -v . pip install *whl ```
- Loading branch information
Showing
6 changed files
with
310 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
include README.md LEGAL.txt LICENSE.txt | ||
include pyproject.toml | ||
include requirements.txt | ||
global-include CMakeLists.txt *.cmake *.in | ||
recursive-include Source * | ||
recursive-include Python * | ||
|
||
# see .gitignore | ||
prune cmake-build* | ||
prune .spack-env* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
[build-system] | ||
requires = ["setuptools>38.6", "wheel", "cmake>=3.15.0,<4.0.0"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
numpy~=1.15.0 | ||
periodictable~=1.5.3 | ||
picmistandard==0.0.13 | ||
scipy~=1.6.0 # picmistandard bug: https://github.com/picmi-standard/picmi/pull/34 | ||
# optional, some used for testing: | ||
# yt | ||
# openpmd-api | ||
# openpmd-viewer | ||
# matplotlib |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,235 @@ | ||
import os | ||
import re | ||
import sys | ||
import platform | ||
import subprocess | ||
|
||
from setuptools import setup, Extension | ||
from setuptools.command.build_ext import build_ext | ||
from distutils.version import LooseVersion | ||
|
||
|
||
class CMakeExtension(Extension): | ||
def __init__(self, name, sourcedir=''): | ||
Extension.__init__(self, name, sources=[]) | ||
self.sourcedir = os.path.abspath(sourcedir) | ||
|
||
|
||
class CMakeBuild(build_ext): | ||
def run(self): | ||
try: | ||
out = subprocess.check_output(['cmake', '--version']) | ||
except OSError: | ||
raise RuntimeError( | ||
"CMake 3.15.0+ must be installed to build the following " + | ||
"extensions: " + | ||
", ".join(e.name for e in self.extensions)) | ||
|
||
cmake_version = LooseVersion(re.search( | ||
r'version\s*([\d.]+)', | ||
out.decode() | ||
).group(1)) | ||
if cmake_version < '3.15.0': | ||
raise RuntimeError("CMake >= 3.15.0 is required") | ||
|
||
for ext in self.extensions: | ||
self.build_extension(ext) | ||
|
||
def build_extension(self, ext): | ||
extdir = os.path.abspath(os.path.dirname( | ||
self.get_ext_fullpath(ext.name) | ||
)) | ||
# required for auto-detection of auxiliary "native" libs | ||
if not extdir.endswith(os.path.sep): | ||
extdir += os.path.sep | ||
|
||
r_dim = re.search(r'warpx_(2|3|rz)(?:d*)', ext.name) | ||
dims = r_dim.group(1).upper() | ||
|
||
cmake_args = [ | ||
'-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + | ||
os.path.join(extdir, "pywarpx"), | ||
'-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=' + extdir, | ||
#'-DCMAKE_PYTHON_OUTPUT_DIRECTORY=' + extdir, | ||
'-DWarpX_DIMS=' + dims, | ||
'-DWarpX_APP:BOOL=OFF', | ||
'-DWarpX_LIB:BOOL=ON', | ||
#'-DPython_EXECUTABLE=' + sys.executable, | ||
#'-DWarpX_USE_PYTHON:BOOL=ON', | ||
## variants | ||
'-DWarpX_COMPUTE=' + WarpX_COMPUTE, | ||
'-DWarpX_MPI:BOOL=' + WarpX_MPI, | ||
'-DWarpX_OPENPMD:BOOL=' + WarpX_OPENPMD, | ||
'-DWarpX_PSATD:BOOL=' + WarpX_PSATD, | ||
'-DWarpX_QED:BOOL=' + WarpX_QED, | ||
## skip building cli tools, examples & tests | ||
## note: CLI tools provided as console scripts | ||
#'-DWarpX_BUILD_CLI_TOOLS:BOOL=OFF', | ||
#'-DWarpX_BUILD_EXAMPLES:BOOL=' + BUILD_EXAMPLES, | ||
#'-DWarpX_BUILD_TESTING:BOOL=' + BUILD_TESTING, | ||
## static/shared libs | ||
'-DBUILD_SHARED_LIBS:BOOL=' + BUILD_SHARED_LIBS, | ||
## Unix: rpath to current dir when packaged | ||
## needed for shared (here non-default) builds and ADIOS1 | ||
## wrapper libraries | ||
'-DCMAKE_BUILD_WITH_INSTALL_RPATH:BOOL=ON', | ||
'-DCMAKE_INSTALL_RPATH_USE_LINK_PATH:BOOL=OFF', | ||
# Windows: has no RPath concept, all `.dll`s must be in %PATH% | ||
# or same dir as calling executable | ||
] | ||
if WarpX_OPENPMD.upper() in ['1', 'ON', 'TRUE', 'YES']: | ||
cmake_args += [ | ||
'-DHDF5_USE_STATIC_LIBRARIES:BOOL=' + HDF5_USE_STATIC_LIBRARIES, | ||
'-DADIOS_USE_STATIC_LIBS:BOOL=' + ADIOS_USE_STATIC_LIBS, | ||
] | ||
if sys.platform == "darwin": | ||
cmake_args.append('-DCMAKE_INSTALL_RPATH=@loader_path') | ||
else: | ||
# values: linux*, aix, freebsd, ... | ||
# just as well win32 & cygwin (although Windows has no RPaths) | ||
cmake_args.append('-DCMAKE_INSTALL_RPATH=$ORIGIN') | ||
|
||
cfg = 'Debug' if self.debug else 'Release' | ||
build_args = ['--config', cfg] | ||
|
||
if platform.system() == "Windows": | ||
cmake_args += [ | ||
'-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}'.format( | ||
cfg.upper(), | ||
os.path.join(extdir, "pywarpx") | ||
) | ||
] | ||
if sys.maxsize > 2**32: | ||
cmake_args += ['-A', 'x64'] | ||
else: | ||
cmake_args += ['-DCMAKE_BUILD_TYPE=' + cfg] | ||
|
||
build_args += ['--parallel', BUILD_PARALLEL] | ||
|
||
env = os.environ.copy() | ||
env['CXXFLAGS'] = '{} -DVERSION_INFO=\\"{}\\"'.format( | ||
env.get('CXXFLAGS', ''), | ||
self.distribution.get_version() | ||
) | ||
if not os.path.exists(self.build_temp): | ||
os.makedirs(self.build_temp) | ||
subprocess.check_call( | ||
['cmake', ext.sourcedir] + cmake_args, | ||
cwd=self.build_temp, | ||
env=env | ||
) | ||
subprocess.check_call( | ||
['cmake', '--build', '.'] + build_args, | ||
cwd=self.build_temp | ||
) | ||
# note that this does not call install; | ||
# we pick up artifacts directly from the build output dirs | ||
|
||
|
||
with open('./README.md', encoding='utf-8') as f: | ||
long_description = f.read() | ||
|
||
# Allow to control options via environment vars. | ||
# Work-around for https://github.com/pypa/setuptools/issues/1712 | ||
# note: changed default for SHARED, MPI, TESTING and EXAMPLES | ||
WarpX_COMPUTE = os.environ.get('WarpX_COMPUTE', 'OMP') | ||
WarpX_MPI = os.environ.get('WarpX_MPI', 'OFF') | ||
WarpX_OPENPMD = os.environ.get('WarpX_OPENPMD', 'OFF') | ||
WarpX_PSATD = os.environ.get('WarpX_PSATD', 'OFF') | ||
WarpX_QED = os.environ.get('WarpX_QED', 'OFF') | ||
# TODO: QED tables (require boost) | ||
WarpX_DIMS = os.environ.get('WarpX_DIMS', '2;3;RZ') | ||
BUILD_PARALLEL = os.environ.get('BUILD_PARALLEL', '2') | ||
BUILD_SHARED_LIBS = os.environ.get('WarpX_BUILD_SHARED_LIBS', | ||
'OFF') | ||
#BUILD_TESTING = os.environ.get('WarpX_BUILD_TESTING', | ||
# 'OFF') | ||
#BUILD_EXAMPLES = os.environ.get('WarpX_BUILD_EXAMPLES', | ||
# 'OFF') | ||
# openPMD-api sub-control | ||
HDF5_USE_STATIC_LIBRARIES = os.environ.get('HDF5_USE_STATIC_LIBRARIES', 'OFF') | ||
ADIOS_USE_STATIC_LIBS = os.environ.get('ADIOS_USE_STATIC_LIBS', 'OFF') | ||
|
||
# https://cmake.org/cmake/help/v3.0/command/if.html | ||
if WarpX_MPI.upper() in ['1', 'ON', 'TRUE', 'YES']: | ||
WarpX_MPI = "ON" | ||
else: | ||
WarpX_MPI = "OFF" | ||
|
||
cxx_modules = [] # allowed values: warpx_2d, warpx_3d, warpx_rz | ||
for dim in [x.lower() for x in WarpX_DIMS.split(';')]: | ||
name = dim if dim == "rz" else dim + "d" | ||
cxx_modules.append(CMakeExtension("warpx_" + name)) | ||
|
||
# Get the package requirements from the requirements.txt file | ||
install_requires = [] | ||
with open('./requirements.txt') as f: | ||
install_requires = [line.strip('\n') for line in f.readlines()] | ||
if WarpX_MPI == "ON": | ||
install_requires.append('mpi4py>=2.1.0') | ||
|
||
# keyword reference: | ||
# https://packaging.python.org/guides/distributing-packages-using-setuptools | ||
setup( | ||
name='pywarpx', | ||
# note PEP-440 syntax: x.y.zaN but x.y.z.devN | ||
version = '21.01', | ||
packages = ['pywarpx'], | ||
package_dir = {'pywarpx': 'Python/pywarpx'}, | ||
author='Jean-Luc Vay, David P. Grote, Maxence Thévenet, Rémi Lehe, Andrew Myers, Weiqun Zhang, Axel Huebl, et al.', | ||
author_email='jlvay@lbl.gov, grote1@llnl.gov, maxence.thevenet@desy.de, rlehe@lbl.gov, atmyers@lbl.gov, WeiqunZhang@lbl.gov, axelhuebl@lbl.gov', | ||
maintainer='Axel Huebl, David P. Grote, Rémi Lehe', # wheel/pypi packages | ||
maintainer_email='axelhuebl@lbl.gov, grote1@llnl.gov, rlehe@lbl.gov', | ||
description='WarpX is an advanced electromagnetic Particle-In-Cell code.', | ||
long_description=long_description, | ||
long_description_content_type='text/markdown', | ||
keywords=('WarpX openscience mpi hpc research pic particle-in-cell ' | ||
'plasma laser-plasma accelerator modeling simulation'), | ||
url='https://ecp-warpx.github.io', | ||
project_urls={ | ||
'Documentation': 'https://warpx.readthedocs.io', | ||
'Doxygen': 'https://warpx.readthedocs.io/en/latest/_static/doxyhtml/index.html', | ||
#'Reference': 'https://doi.org/...', (Paper and/or Zenodo) | ||
'Source': 'https://github.com/ECP-WarpX/WarpX', | ||
'Tracker': 'https://github.com/ECP-WarpX/WarpX/issues', | ||
}, | ||
ext_modules=cxx_modules, | ||
cmdclass=dict(build_ext=CMakeBuild), | ||
# scripts=['warpx_2d', 'warpx_3d', 'warpx_rz'], | ||
zip_safe=False, | ||
python_requires='>=3.6, <3.10', | ||
# tests_require=['pytest'], | ||
install_requires=install_requires, | ||
# see: src/bindings/python/cli | ||
#entry_points={ | ||
# 'console_scripts': [ | ||
# 'warpx_3d = warpx.3d.__main__:main' | ||
# ] | ||
#}, | ||
extras_require={ | ||
'all': ['openPMD-api~=0.13.0', 'openPMD-viewer~=1.1.0', 'yt~=3.6.1', 'matplotlib'], | ||
}, | ||
# cmdclass={'test': PyTest}, | ||
# platforms='any', | ||
classifiers=[ | ||
'Development Status :: 4 - Beta', | ||
'Natural Language :: English', | ||
'Environment :: Console', | ||
'Intended Audience :: Science/Research', | ||
'Operating System :: OS Independent', | ||
'Topic :: Scientific/Engineering', | ||
'Topic :: Scientific/Engineering :: Physics', | ||
'Programming Language :: C++', | ||
'Programming Language :: Python :: 3', | ||
'Programming Language :: Python :: 3.6', | ||
'Programming Language :: Python :: 3.7', | ||
'Programming Language :: Python :: 3.8', | ||
'Programming Language :: Python :: 3.9', | ||
('License :: OSI Approved :: ' | ||
'BSD License'), # TODO: use real SPDX: BSD-3-Clause-LBNL | ||
], | ||
# new PEP 639 format | ||
license='BSD-3-Clause-LBNL', | ||
license_files = ['LICENSE.txt', 'LEGAL.txt'], | ||
) | ||
|