How to perform cython files compilation in parallel?
Asked Answered
H

2

5

I would like to perform cython files compilation in parallel.

So, I take a look at Cython.Build source file, and find the following signature for cythonize function:

def cythonize(module_list, exclude=None, nthreads=0, aliases=None,
              quiet=False, force=False, language=None,
              exclude_failures=False, **options):

And the following comment about cythonize nthreads option:

"For parallel compilation, set the 'nthreads' option to the number of
concurrent builds."

So I tried to use this option in my setup.py file, like that:

from setuptools import setup
from Cython.Build import cythonize
from Cython.Distutils.extension import Extension

EXTENSIONS = [Extension(...)
              ...
              Extension(...)]

setup(name='...',
      ...
      ext_modules=cythonize(EXTENSIONS, nthreads=8),
      ...)

But my .pyx files are still compiled sequentially using 1 thread.

I do not understand what I am doing wrong here and how to use nthreads option to perform cythonize compilation in parallel ?

Hathaway answered 24/6, 2016 at 12:49 Comment(0)
H
5

I finally found a solution to compile my cython file in parallel:

from setuptools import setup
from Cython.Build import cythonize
from Cython.Distutils.extension import Extension

NB_COMPILE_JOBS = 8

EXTENSIONS = [Extension(...)
              ...
              Extension(...)]

def setup_given_extensions(extensions):
    setup(name='...',
          ...
          ext_modules=cythonize(extensions),
          ...)

def setup_extensions_in_sequential():
    setup_given_extensions(EXTENSIONS)

def setup_extensions_in_parallel():
    cythonize(EXTENSIONS, nthreads=NB_COMPILE_JOBS)
    pool = multiprocessing.Pool(processes=NB_COMPILE_JOBS)
    pool.map(setup_given_extensions, EXTENSIONS)
    pool.close()
    pool.join()

if "build_ext" in sys.argv:
    setup_extensions_in_parallel()
else:
    setup_extensions_in_sequential()
Hathaway answered 10/11, 2016 at 16:53 Comment(1)
Running setup(..) in several parallel processes, couldn't it have some unexpected side effects?Shumway
H
15

Cython builds are a two step process:

  1. source.py to source.c
  2. source.c to source.o

The nthreads argument to cythonize() controls the concurrency of the first process, but not the second.

For the second process build_ext takes a -j argument to control the concurrency of builds, so you can speed up your builds like this:

python setup.py build_ext -j 4

Or if you are building a wheel, you can use:

python setup.py build_ext -j 4 bdist_wheel

Hailstone answered 8/4, 2020 at 15:42 Comment(1)
Can you link documentation to this answer? What are all the args to build_ext?Skydive
H
5

I finally found a solution to compile my cython file in parallel:

from setuptools import setup
from Cython.Build import cythonize
from Cython.Distutils.extension import Extension

NB_COMPILE_JOBS = 8

EXTENSIONS = [Extension(...)
              ...
              Extension(...)]

def setup_given_extensions(extensions):
    setup(name='...',
          ...
          ext_modules=cythonize(extensions),
          ...)

def setup_extensions_in_sequential():
    setup_given_extensions(EXTENSIONS)

def setup_extensions_in_parallel():
    cythonize(EXTENSIONS, nthreads=NB_COMPILE_JOBS)
    pool = multiprocessing.Pool(processes=NB_COMPILE_JOBS)
    pool.map(setup_given_extensions, EXTENSIONS)
    pool.close()
    pool.join()

if "build_ext" in sys.argv:
    setup_extensions_in_parallel()
else:
    setup_extensions_in_sequential()
Hathaway answered 10/11, 2016 at 16:53 Comment(1)
Running setup(..) in several parallel processes, couldn't it have some unexpected side effects?Shumway

© 2022 - 2024 — McMap. All rights reserved.