Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use cython distutils directives #2509

Merged
merged 21 commits into from
Jul 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
3583ffb
Converting yt/geometry to use cythonize
matthewturk Mar 29, 2020
512d5af
Fix particle_oct_container build
matthewturk Mar 29, 2020
34c4823
Extending lib_exts cythonize
matthewturk Mar 30, 2020
fb4b208
Continuing to convert to use cythonize
matthewturk Mar 30, 2020
feb8d76
Move remaining vanilla libs into cythonize
matthewturk Mar 30, 2020
5c3c458
Continuing to convert files that need arguments
matthewturk Mar 30, 2020
ff9f157
Almost done converting to cythonize
matthewturk Mar 30, 2020
f744424
Attempting to convert embree imports
matthewturk Mar 30, 2020
53d28f8
Go to globs everywhere
matthewturk Mar 30, 2020
27fcc58
Switch back to the overridden build_ext
matthewturk Mar 30, 2020
20838e6
Only import Cython as needed
matthewturk Mar 30, 2020
25dd71b
Move more of the extension construction to setupext.py
matthewturk Mar 31, 2020
13628f5
Merge branch 'yt-4.0' of github.com:yt-project/yt into cython_distuti…
matthewturk Apr 17, 2020
daa203d
Fix vec3_ops cimport for case when we don't have pyembree
matthewturk Apr 17, 2020
1597e7d
Merge branch 'yt-4.0' of github.com:yt-project/yt into cython_distuti…
matthewturk Apr 20, 2020
7afe579
change omp_args to empty list
matthewturk Apr 29, 2020
e247c16
Merge branch 'master' of github.com:yt-project/yt into cython_distuti…
matthewturk Jun 22, 2020
6817056
fix renamed module cimports
matthewturk Jun 22, 2020
262b5a9
Merge branch 'master' of github.com:yt-project/yt into cython_distuti…
matthewturk Jun 29, 2020
9c721a0
add embree_mesh files to gitignore
munkm Jul 1, 2020
3551424
modify mesh_traversal path in test_install_script
munkm Jul 1, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ yt/utilities/lib/interpolators.c
yt/utilities/lib/kdtree.c
yt/utilities/lib/lenses.c
yt/utilities/lib/line_integral_convolution.c
yt/utilities/lib/mesh_construction.cpp
yt/utilities/lib/mesh_intersection.cpp
yt/utilities/lib/mesh_samplers.cpp
yt/utilities/lib/mesh_traversal.cpp
yt/utilities/lib/embree_mesh/mesh_construction.cpp
yt/utilities/lib/embree_mesh/mesh_intersection.cpp
yt/utilities/lib/embree_mesh/mesh_samplers.cpp
yt/utilities/lib/embree_mesh/mesh_traversal.cpp
yt/utilities/lib/mesh_triangulation.c
yt/utilities/lib/mesh_utilities.c
yt/utilities/lib/pixelization_routines.cpp
Expand Down
378 changes: 29 additions & 349 deletions setup.py

Large diffs are not rendered by default.

147 changes: 142 additions & 5 deletions setupext.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import os
import platform
import contextlib
import glob
import os
import shutil
import subprocess
import sys
from sys import platform as _platform
import tempfile
from concurrent.futures import ThreadPoolExecutor as Pool

from distutils import log
from distutils.ccompiler import new_compiler
from distutils.ccompiler import new_compiler, CCompiler
from distutils.sysconfig import customize_compiler
from distutils.errors import CompileError, LinkError
from distutils.version import LooseVersion
from pkg_resources import resource_filename
from subprocess import Popen, PIPE
from setuptools.command.build_ext import build_ext as _build_ext
from setuptools.command.sdist import sdist as _sdist


CCODE = """
Expand Down Expand Up @@ -124,12 +130,32 @@ def check_for_openmp():
return using_openmp


def check_for_pyembree():
def check_for_pyembree(std_libs):
embree_libs = []
embree_aliases = {}
try:
fn = resource_filename("pyembree", "rtcore.pxd")
except ImportError:
return None
return os.path.dirname(fn)
return embree_libs, embree_aliases

embree_prefix = os.path.abspath(read_embree_location())
embree_inc_dir = os.path.join(embree_prefix, 'include')
embree_lib_dir = os.path.join(embree_prefix, 'lib')
if in_conda_env():
conda_basedir = os.path.dirname(os.path.dirname(sys.executable))
embree_inc_dir.append(os.path.join(conda_basedir, 'include'))
embree_lib_dir.append(os.path.join(conda_basedir, 'lib'))

if _platform == "darwin":
embree_lib_name = "embree.2"
else:
embree_lib_name = "embree"

embree_aliases['EMBREE_INC_DIR'] = ['yt/utilities/lib/', embree_inc_dir]
embree_aliases['EMBREE_LIB_DIR'] = [embree_lib_dir]
embree_aliases['EMBREE_LIBS'] = std_libs + [embree_lib_name]
embree_libs += ['yt/utilities/lib/embree_mesh/*.pyx']
return embree_libs, embree_aliases

def in_conda_env():
return any(s in sys.version for s in ("Anaconda", "Continuum"))
Expand Down Expand Up @@ -206,3 +232,114 @@ def read_embree_location():
shutil.rmtree(tmpdir)

return rd

def get_cpu_count():
if platform.system() == "Windows":
return 0

cpu_count = os.cpu_count()
try:
user_max_cores = int(os.getenv('MAX_BUILD_CORES', cpu_count))
except ValueError as e:
raise ValueError(
"MAX_BUILD_CORES must be set to an integer. " +
"See above for original error.").with_traceback(e.__traceback__)
max_cores = min(cpu_count, user_max_cores)
return max_cores


def install_ccompiler():
def _compile(
self, sources, output_dir=None, macros=None, include_dirs=None,
debug=0, extra_preargs=None, extra_postargs=None, depends=None,
):
"""Function to monkey-patch distutils.ccompiler.CCompiler"""
macros, objects, extra_postargs, pp_opts, build = self._setup_compile(
output_dir, macros, include_dirs, sources, depends, extra_postargs
)
cc_args = self._get_cc_args(pp_opts, debug, extra_preargs)

for obj in objects:
try:
src, ext = build[obj]
except KeyError:
continue
self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts)

# Return *all* object filenames, not just the ones we just built.
return objects

CCompiler.compile = _compile

def create_build_ext(lib_exts, cythonize_aliases):
class build_ext(_build_ext):
# subclass setuptools extension builder to avoid importing cython and numpy
# at top level in setup.py. See http://stackoverflow.com/a/21621689/1382869
def finalize_options(self):
try:
import cython
import numpy
except ImportError:
raise ImportError(
"""Could not import cython or numpy. Building yt from source requires
cython and numpy to be installed. Please install these packages using
the appropriate package manager for your python environment.""")
if LooseVersion(cython.__version__) < LooseVersion('0.26.1'):
raise RuntimeError(
"""Building yt from source requires Cython 0.26.1 or newer but
Cython %s is installed. Please update Cython using the appropriate
package manager for your python environment.""" %
cython.__version__)
if LooseVersion(numpy.__version__) < LooseVersion('1.13.3'):
raise RuntimeError(
"""Building yt from source requires NumPy 1.13.3 or newer but
NumPy %s is installed. Please update NumPy using the appropriate
package manager for your python environment.""" %
numpy.__version__)
from Cython.Build import cythonize
# Override the list of extension modules
self.distribution.ext_modules[:] = cythonize(
lib_exts,
aliases = cythonize_aliases,
compiler_directives={'language_level': 2},
nthreads=get_cpu_count(),
)
_build_ext.finalize_options(self)
# Prevent numpy from thinking it is still in its setup process
# see http://stackoverflow.com/a/21621493/1382869
if isinstance(__builtins__, dict):
# sometimes this is a dict so we need to check for that
# https://docs.python.org/3/library/builtins.html
__builtins__["__NUMPY_SETUP__"] = False
else:
__builtins__.__NUMPY_SETUP__ = False
import numpy
self.include_dirs.append(numpy.get_include())

def build_extensions(self):
self.check_extensions_list(self.extensions)

ncpus = get_cpu_count()
if ncpus > 0:
with Pool(ncpus) as pool:
pool.map(self.build_extension, self.extensions)
else:
super().build_extensions()


class sdist(_sdist):
# subclass setuptools source distribution builder to ensure cython
# generated C files are included in source distribution.
# See http://stackoverflow.com/a/18418524/1382869
def run(self):
# Make sure the compiled Cython files in the distribution are up-to-date
from Cython.Build import cythonize
cythonize(
lib_exts,
aliases = cythonize_aliases,
compiler_directives={'language_level': 2},
nthreads=get_cpu_count(),
)
_sdist.run(self)

return build_ext, sdist
2 changes: 1 addition & 1 deletion tests/test_install_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
]

DEPENDENCY_IMPORT_TESTS = {
'embree': "from yt.utilities.lib import mesh_traversal",
'embree': "from yt.utilities.lib.embree_mesh import mesh_traversal",
}


Expand Down
2 changes: 2 additions & 0 deletions yt/frontends/artio/_artio_caller.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# distutils: sources = ARTIO_SOURCE
# distutils: include_dirs = LIB_DIR_GEOM_ARTIO
cimport cython
import numpy as np
cimport numpy as np
Expand Down
2 changes: 2 additions & 0 deletions yt/frontends/ramses/io_utils.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# distutils: libraries = STD_LIBS
# distutils: include_dirs = LIB_DIR
cimport cython
cimport numpy as np
import numpy as np
Expand Down
2 changes: 2 additions & 0 deletions yt/geometry/fake_octree.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# distutils: include_dirs = LIB_DIR
# distutils: libraries = STD_LIBS
"""
Make a fake octree, deposit particle at every leaf

Expand Down
2 changes: 2 additions & 0 deletions yt/geometry/grid_container.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# distutils: include_dirs = LIB_DIR
# distutils: libraries = STD_LIBS
"""
Matching points on the grid to specific grids

Expand Down
2 changes: 2 additions & 0 deletions yt/geometry/grid_visitors.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# distutils: include_dirs = LIB_DIR
# distutils: libraries = STD_LIBS
"""
Grid visitor functions

Expand Down
3 changes: 3 additions & 0 deletions yt/geometry/oct_container.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# distutils: sources = yt/utilities/lib/tsearch.c
# distutils: include_dirs = LIB_DIR
# distutils: libraries = STD_LIBS
"""
Oct container

Expand Down
2 changes: 2 additions & 0 deletions yt/geometry/oct_visitors.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# distutils: include_dirs = LIB_DIR
# distutils: libraries = STD_LIBS
"""
Oct visitor functions

Expand Down
2 changes: 2 additions & 0 deletions yt/geometry/particle_deposit.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# distutils: include_dirs = LIB_DIR
# distutils: libraries = STD_LIBS
"""
Particle Deposition onto Cells

Expand Down
3 changes: 3 additions & 0 deletions yt/geometry/particle_oct_container.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# distutils: include_dirs = LIB_DIR_EWAH
# distutils: language = c++
# distutils: libraries = STD_LIBS
"""
Oct container tuned for Particles

Expand Down
2 changes: 2 additions & 0 deletions yt/geometry/particle_smooth.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# distutils: include_dirs = LIB_DIR
# distutils: libraries = STD_LIBS
"""
Particle smoothing in cells

Expand Down
2 changes: 2 additions & 0 deletions yt/geometry/selection_routines.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# distutils: include_dirs = LIB_DIR
# distutils: libraries = STD_LIBS
"""
Geometry selection routines.

Expand Down
1 change: 1 addition & 0 deletions yt/utilities/cython_fortran_utils.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# distutils: libraries = STD_LIBS
cimport numpy as np
import numpy as np
import cython
Expand Down
2 changes: 2 additions & 0 deletions yt/utilities/lib/allocation_container.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@

# distutils: libraries = STD_LIBS
"""
An allocation container and memory pool

Expand Down
1 change: 1 addition & 0 deletions yt/utilities/lib/alt_ray_tracers.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# distutils: libraries = STD_LIBS
"""


Expand Down
2 changes: 2 additions & 0 deletions yt/utilities/lib/amr_kdtools.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@

# distutils: libraries = STD_LIBS
"""
AMR kD-Tree Cython Tools

Expand Down
2 changes: 2 additions & 0 deletions yt/utilities/lib/basic_octree.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@

# distutils: libraries = STD_LIBS
"""
A refine-by-two AMR-specific octree

Expand Down
1 change: 1 addition & 0 deletions yt/utilities/lib/bitarray.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# distutils: libraries = STD_LIBS
"""
Bit array functions

Expand Down
4 changes: 4 additions & 0 deletions yt/utilities/lib/bounding_volume_hierarchy.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# distutils: libraries = STD_LIBS
# distutils: include_dirs = LIB_DIR
# distutils: extra_compile_args = OMP_ARGS
# distutils: extra_link_args = OMP_ARGS
cimport cython
import numpy as np
cimport numpy as np
Expand Down
2 changes: 2 additions & 0 deletions yt/utilities/lib/contour_finding.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# distutils: libraries = STD_LIBS
# distutils: include_dirs = LIB_DIR_GEOM
"""
A two-pass contour finding algorithm

Expand Down
6 changes: 6 additions & 0 deletions yt/utilities/lib/cykdtree/kdtree.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# distutils: libraries = STD_LIBS
# Note that we used to include the empty c_kdtree.cpp file, but that seems to break cythonize.
# distutils: sources = yt/utilities/lib/cykdtree/c_utils.cpp
# distutils: depends = yt/utilities/lib/cykdtree/c_kdtree.hpp, yt/utilities/lib/cykdtree/c_utils.hpp
# distutils: language = c++
# distutils: extra_compile_args = -std=c++03
import cython
import numpy as np
cimport numpy as np
Expand Down
5 changes: 5 additions & 0 deletions yt/utilities/lib/cykdtree/utils.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# distutils: libraries = STD_LIBS
# distutils: sources = yt/utilities/lib/cykdtree/c_utils.cpp
# distutils: depends = yt/utilities/lib/cykdtree/c_utils.hpp
# distutils: language = c++
# distutils: extra_compile_args = -std=c++03
import numpy as np
cimport numpy as np
cimport cython
Expand Down
5 changes: 5 additions & 0 deletions yt/utilities/lib/cyoctree.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# distutils: libraries = STD_LIBS
# distutils: extra_link_args = OMP_ARGS
# distutils: extra_compile_args = OMP_ARGS
# distutils: include_dirs = LIB_DIR
# distutils: language = c++
"""
CyOctree building, loading and refining routines

Expand Down
2 changes: 2 additions & 0 deletions yt/utilities/lib/depth_first_octree.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@

# distutils: libraries = STD_LIBS
"""
This is a recursive function to return a depth-first octree

Expand Down
2 changes: 2 additions & 0 deletions yt/utilities/lib/distance_queue.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@

# distutils: libraries = STD_LIBS
"""
Distance queue implementation

Expand Down
1 change: 1 addition & 0 deletions yt/utilities/lib/element_mappings.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# distutils: libraries = STD_LIBS
"""
This file contains coordinate mappings between physical coordinates and those
defined on unit elements, as well as doing the corresponding intracell
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# distutils: include_dirs = EMBREE_INC_DIR
# distutils: library_dirs = EMBREE_LIB_DIR
# distutils: libraries = EMBREE_LIBS
# distutils: language = c++
"""
This file contains the ElementMesh classes, which represent the target that the
rays will be cast at when rendering finite element data. This class handles
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cimport pyembree.rtcore as rtc
cimport pyembree.rtcore_ray as rtcr
cimport pyembree.rtcore_geometry as rtcg
from yt.utilities.lib.mesh_construction cimport Patch, Tet_Patch
from .mesh_construction cimport Patch, Tet_Patch
cimport cython

cdef void patchIntersectFunc(Patch* patches,
Expand Down
Loading