如何并行地编译Cython文件?

6

我希望能够并行执行cython文件的编译。

因此,我查看了Cython.Build源文件并找到了cythonize函数的以下签名:

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

以下是关于cythonize nthreads选项的评论:

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

所以我尝试在我的setup.py文件中使用这个选项,如下:

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),
      ...)

但我的.pyx文件仍然是使用1个线程顺序编译的。

我不理解我在这里做错了什么,以及如何使用nthreads选项并行执行cythonize编译?

2个回答

14
Cython 构建过程分为两个步骤:
  1. 将 source.py 转换为 source.c
  2. 将 source.c 转换为 source.o
cythonize() 函数的 nthreads 参数控制第一个进程的并发,但不控制第二个进程。
对于第二个进程,build_ext 接受一个 -j 参数来控制构建的并发数,以此提高构建速度: python setup.py build_ext -j 4 或者如果你在构建 wheel 包,可以使用以下命令: python setup.py build_ext -j 4 bdist_wheel

您能在此回答中附上文档链接吗?build_ext 的所有参数是什么? - Parfait

6

我终于找到了一个可以并行编译我的cython文件的解决方案:

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()

5
在多个并行进程中运行setup(..),这样做会有一些意料之外的副作用吗? - rth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接