From cfbc62329d9c1aa502d0d6be8bd451851df77e6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ma=C5=9Blanka?= <piotr.maslanka@henrietta.com.pl> Date: Mon, 14 Dec 2020 18:39:07 +0100 Subject: [PATCH] v1.2.3 --- CHANGELOG.md | 3 ++- example/setup.py | 7 ++++-- snakehouse/__init__.py | 3 ++- snakehouse/faster_builds.py | 43 +++++++++++++++++++++++++++++++++++++ snakehouse/multibuild.py | 1 + 5 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 snakehouse/faster_builds.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 05ed176..436d5b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # v1.2.3 -* _TBA_ +* `Multibuild` will pass given kwargs to `Extension` object +* added an option to monkey-patch `distutils` to compile multicore # v1.2.2 diff --git a/example/setup.py b/example/setup.py index bcec7bf..b0832cd 100644 --- a/example/setup.py +++ b/example/setup.py @@ -1,8 +1,10 @@ from setuptools import setup -from snakehouse import Multibuild, build +from snakehouse import Multibuild, build, monkey_patch_parallel_compilation from setuptools import Extension +monkey_patch_parallel_compilation() + # note that you can include standard Extension classes in this list, those won't be touched # and will be directed directly to Cython.Build.cythonize() cython_multibuilds = [ @@ -11,7 +13,8 @@ cython_multibuilds = [ Multibuild('example_module', ['example_module/test.pyx', 'example_module/test2.pyx', 'example_module/test3/test3.pyx', 'example_module/test3/test2.pyx', - 'example_module/test_n.c']), + 'example_module/test_n.c'], + define_macros=[("CYTHON_TRACE_NOGIL", "1")]), Extension('example2.example', ['example2/example.pyx']), Multibuild('example3.example3.example3', ['example3/example3/example3/test.pyx']) ] diff --git a/snakehouse/__init__.py b/snakehouse/__init__.py index d504b6d..849c48b 100644 --- a/snakehouse/__init__.py +++ b/snakehouse/__init__.py @@ -1,4 +1,5 @@ from .build import build from .multibuild import Multibuild +from .faster_builds import monkey_patch_parallel_compilation -__version__ = '1.2.3_a1' +__version__ = '1.2.3' diff --git a/snakehouse/faster_builds.py b/snakehouse/faster_builds.py new file mode 100644 index 0000000..13c9cc3 --- /dev/null +++ b/snakehouse/faster_builds.py @@ -0,0 +1,43 @@ +import multiprocessing + +__all__ = ['monkey_patch_parallel_compilation'] + + +def monkey_patch_parallel_compilation(cores: tp.Optional[int] = None) -> None: + """ + This monkey-patches distutils to provide parallel compilation, even if you have + a single extension built from multiple .c files. + + Invoke in your setup.py file + + :param cores: amount of cores. Leave at default (None) for autodetection. + """ + if cores is None: + cores = multiprocessing.cpu_count() + + # monkey-patch for parallel compilation + def parallelCCompile(self, sources, output_dir=None, macros=None, include_dirs=None, debug=0, + extra_preargs=None, extra_postargs=None, depends=None): + # those lines are copied from distutils.ccompiler.CCompiler directly + 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) + # parallel code + import multiprocessing.pool + + def single_compile(obj): + try: + src, ext = build[obj] + except KeyError: + return + self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts) + + # evaluate everything + for _ in multiprocessing.pool.ThreadPool(cores).imap(single_compile, objects): + pass + return objects + + import distutils.ccompiler + distutils.ccompiler.CCompiler.compile = parallelCCompile diff --git a/snakehouse/multibuild.py b/snakehouse/multibuild.py index f17b06a..baba3d9 100644 --- a/snakehouse/multibuild.py +++ b/snakehouse/multibuild.py @@ -51,6 +51,7 @@ class Multibuild: All kwargs will be sent straight to Cython's Extension :param extension_name: the module name :param files: list of pyx and c files + :param kwargs: extra arguments to be passed to Extension() object """ def __init__(self, extension_name: str, files: tp.Iterator[str], **kwargs): # sanitize path separators so that Linux-style paths are supported on Windows -- GitLab