Read about our upcoming Code of Conduct on this issue

setup.py 6.05 KB
Newer Older
Pierre Augier's avatar
Pierre Augier committed
1
2
import os
import sys
Pierre Augier's avatar
Pierre Augier committed
3
from pathlib import Path
Pierre Augier's avatar
Pierre Augier committed
4

5
from time import time
Pierre Augier's avatar
Pierre Augier committed
6
7
from runpy import run_path

8
from setuptools import setup, find_packages
9

Pierre Augier's avatar
Pierre Augier committed
10
11
from transonic.dist import make_backend_files, init_transonic_extensions

12
13
14
if sys.version_info[:2] < (3, 6):
    raise RuntimeError("Python version >= 3.6 required.")

Pierre Augier's avatar
Pierre Augier committed
15
here = Path(__file__).parent.absolute()
16

Pierre Augier's avatar
Pierre Augier committed
17
sys.path.insert(0, ".")
18

Ashwin Vishnu's avatar
Ashwin Vishnu committed
19
from setup_configure import FFTW3, logger, TRANSONIC_BACKEND, get_config
Pierre Augier's avatar
Pierre Augier committed
20
from setup_build import FluidSimBuildExt
21

Pierre Augier's avatar
Pierre Augier committed
22
time_start = time()
23

Ashwin Vishnu's avatar
Ashwin Vishnu committed
24
25
# Parse site.cfg or ~/.fluidsim-site.cfg
_ = get_config()
26

Pierre Augier's avatar
Pierre Augier committed
27
28
29
30
31
32
build_dependencies_backends = {
    "pythran": ["pythran>=0.9.7"],
    "cython": ["cython"],
    "python": [],
    "numba": [],
}
33

Pierre Augier's avatar
Pierre Augier committed
34
if TRANSONIC_BACKEND not in build_dependencies_backends:
Pierre Augier's avatar
Pierre Augier committed
35
    raise ValueError(
Pierre Augier's avatar
Pierre Augier committed
36
        f"FLUIDSIM_TRANSONIC_BACKEND={TRANSONIC_BACKEND} "
Pierre Augier's avatar
Pierre Augier committed
37
38
        f"not in {list(build_dependencies_backends.keys())}"
    )
39

Pierre Augier's avatar
Pierre Augier committed
40
setup_requires = []
Pierre Augier's avatar
Pierre Augier committed
41
setup_requires.extend(build_dependencies_backends[TRANSONIC_BACKEND])
Pierre Augier's avatar
Pierre Augier committed
42
43
44
45
46

# Set the environment variable FLUIDSIM_SETUP_REQUIRES=0 if we need to skip
# setup_requires for any reason.
if os.environ.get("FLUIDSIM_SETUP_REQUIRES", "1") == "0":
    setup_requires = []
47

Pierre Augier's avatar
Pierre Augier committed
48

49
50
51
52
53
54
55
56
def long_description():
    """Get the long description from the relevant file."""
    with open(os.path.join(here, "README.rst")) as readme:
        lines = list(readme)

    idx = lines.index(".. description\n") + 1
    return "".join(lines[idx:])

Pierre Augier's avatar
Pierre Augier committed
57

58
# Get the version from the relevant file
Ashwin Vishnu's avatar
Ashwin Vishnu committed
59
60
61
62
63
64
version_module = here / "fluidsim" / "_version.py"
version_module_core = here / "lib" / "fluidsim_core" / "_version.py"
version_template = here / "fluidsim" / "_version.tpl"
if not version_module.exists() or (
    version_module_core.exists()
    # check modification time
Ashwin Vishnu's avatar
Ashwin Vishnu committed
65
66
    and version_module.stat().st_mtime
    < max(version_module_core.stat().st_mtime, version_template.stat().st_mtime)
Ashwin Vishnu's avatar
Ashwin Vishnu committed
67
68
69
70
71
72
73
74
75
76
77
):
    from string import Template

    logger.info("Writing fluidsim/_version.py")
    version_def = version_module_core.read_text()
    tpl = Template(version_template.read_text())
    version_module.write_text(tpl.substitute(version_def=version_def))
else:
    logger.info("Found fluidsim/_version.py")


78
79
80
81
82
83
84
85
86
87
88
89
90
version = run_path("fluidsim/_version.py")
__version__ = version["__version__"]
__about__ = version["__about__"]

# Get the development status from the version string
if "a" in __version__:
    devstatus = "Development Status :: 3 - Alpha"
elif "b" in __version__:
    devstatus = "Development Status :: 4 - Beta"
else:
    devstatus = "Development Status :: 5 - Production/Stable"

install_requires = [
91
    f"fluidsim-core>={__version__}",
92
93
    "h5py",
    "h5netcdf",
Pierre Augier's avatar
Pierre Augier committed
94
    "transonic>=0.4.3",
95
96
    "setuptools_scm",
    "xarray",
Pierre Augier's avatar
Pierre Augier committed
97
    "rich",
98
99
100
]

if FFTW3:
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
    from textwrap import dedent
    from warnings import warn

    fft_extras_msg = dedent(
        """
        *********************************************************************

        FFTW was detected, but pyfftw and fluidfft will not be auto-installed
        (which was the case in previous fluidsim versions). To do so, instead
        of:

            pip install fluidsim

        specify "extras":

            pip install "fluidsim[fft]"

        *********************************************************************
    """
    )
    warn(fft_extras_msg)
122

Pierre Augier's avatar
Pierre Augier committed
123

124
def transonize():
125
126
127
128
129
130
131

    paths = [
        "fluidsim/base/time_stepping/pseudo_spect.py",
        "fluidsim/base/output/increments.py",
        "fluidsim/operators/operators2d.py",
        "fluidsim/operators/operators3d.py",
        "fluidsim/solvers/ns2d/solver.py",
132
133
        "fluidsim/solvers/ns3d/strat/solver.py",
        "fluidsim/solvers/ns3d/forcing.py",
134
        "fluidsim/util/mini_oper_modif_resol.py",
135
        "fluidsim/base/output/spatiotemporal_spectra.py",
136
        "fluidsim/solvers/ns3d/output/spatiotemporal_spectra.py",
137
        "fluidsim/solvers/ns2d/output/spatiotemporal_spectra.py",
138
    ]
Pierre Augier's avatar
Pierre Augier committed
139
    make_backend_files([here / path for path in paths], backend=TRANSONIC_BACKEND)
140

Pierre Augier's avatar
Pierre Augier committed
141

142
143
144
def create_pythran_extensions():
    import numpy as np

145
    compile_arch = os.getenv("CARCH", "native")
Pierre Augier's avatar
Pierre Augier committed
146
    extensions = init_transonic_extensions(
147
        "fluidsim",
Pierre Augier's avatar
Pierre Augier committed
148
        backend=TRANSONIC_BACKEND,
149
        include_dirs=np.get_include(),
150
        compile_args=("-O3", f"-march={compile_arch}", "-DUSE_XSIMD"),
151
    )
Pierre Augier's avatar
Pierre Augier committed
152
153
154
    return extensions


155
def create_extensions():
Pierre Augier's avatar
Pierre Augier committed
156
    if "egg_info" in sys.argv or "dist_info" in sys.argv:
157
        return []
Pierre Augier's avatar
Pierre Augier committed
158

Pierre Augier's avatar
Pierre Augier committed
159
160
161
162
    logger.info(
        f"Running fluidsim setup.py ({sys.argv[1:]}) "
        f"on platform {sys.platform}\n " + __about__
    )
Pierre Augier's avatar
Pierre Augier committed
163

164
165
    transonize()

166
    ext_modules = create_pythran_extensions()
167
168
169
170

    logger.info(
        "The following extensions could be built if necessary:\n"
        + "".join([ext.name + "\n" for ext in ext_modules])
Pierre Augier's avatar
Pierre Augier committed
171
172
    )

173
174
    return ext_modules

Pierre Augier's avatar
Pierre Augier committed
175
176
177

setup(
    version=__version__,
178
    long_description=long_description(),
Pierre Augier's avatar
Pierre Augier committed
179
180
    author="Pierre Augier",
    author_email="pierre.augier@legi.cnrs.fr",
Pierre Augier's avatar
Pierre Augier committed
181
    url="https://foss.heptapod.net/fluiddyn/fluidsim",
Pierre Augier's avatar
Pierre Augier committed
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
    license="CeCILL",
    classifiers=[
        # How mature is this project? Common values are
        # 3 - Alpha
        # 4 - Beta
        # 5 - Production/Stable
        devstatus,
        "Intended Audience :: Science/Research",
        "Intended Audience :: Education",
        "Topic :: Scientific/Engineering",
        "License :: OSI Approved :: GNU General Public License v2 (GPLv2)",
        # actually CeCILL License (GPL compatible license for French laws)
        #
        # Specify the Python versions you support here. In particular,
        # ensure that you indicate whether you support Python 2,
        # Python 3 or both.
        "Programming Language :: Python",
        "Programming Language :: Python :: 3",
        "Programming Language :: Python :: 3.6",
Pierre Augier's avatar
Pierre Augier committed
201
        "Programming Language :: Python :: 3.7",
202
        "Programming Language :: Python :: 3.8",
Pierre Augier's avatar
Pierre Augier committed
203
204
    ],
    packages=find_packages(exclude=["doc", "examples"]),
Pierre Augier's avatar
Pierre Augier committed
205
    setup_requires=setup_requires,
Pierre Augier's avatar
Pierre Augier committed
206
    install_requires=install_requires,
207
208
    cmdclass={"build_ext": FluidSimBuildExt},
    ext_modules=create_extensions(),
Pierre Augier's avatar
Pierre Augier committed
209
210
)

Pierre Augier's avatar
Pierre Augier committed
211
logger.info(f"Setup completed in {time() - time_start:.3f} seconds.")