Cython parallel range抛出编译器警告



我是一个Cython初学者,我只是试着玩一个玩具的例子,以获得Cython并行循环功能prange的经验。以下是我的示例代码cy_sum_parallel.pyx,它试图简单地使用prange求和二维数组。

# distutils: extra_compile_args = -fopenmp
# distutils: extra_link_args = -fopenmp
cimport cython
from cython.parallel cimport prange
@cython.boundscheck(False)
@cython.wraparound(False)
cdef double sum_with_parallel(double[:,::1] arr_2d):
    cdef:
        unsigned int i, j, M, N
        double partial_sum = 0.0
    M = arr_2d.shape[0]
    N = arr_2d.shape[1]
    for i in prange(M, nogil=True):
        for j in range(N):
            partial_sum += arr_2d[i, j]
    return partial_sum

import numpy as np
arr = np.ones(shape=(10000,10000), dtype=np.double, order='C')
def main():
    return sum_with_parallel(arr)

使用最少的setup.py脚本

from distutils.core import setup, Extension
from Cython.Build import cythonize
ext = Extension(name='cy_sum_parallel',
                sources=['cy_sum_parallel.pyx'])
setup(ext_modules=cythonize(ext))

当我运行这个setup.py脚本时,它抛出以下编译器警告:

gcc -pthread -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/home/Jian/anaconda3/include/python3.4m -c cy_sum_parallel.c -o build/temp.linux-x86_64-3.4/cy_sum_parallel.o -fopenmp
cy_sum_parallel.c: In function ‘__pyx_f_15cy_sum_parallel_sum_with_parallel._omp_fn.0’:
cy_sum_parallel.c:1388:29: warning: ‘__pyx_v_j’ may be used uninitialized in this function [-Wmaybe-uninitialized]
                     #pragma omp for lastprivate(__pyx_v_j) firstprivate(__pyx_v_i) lastprivate(__pyx_v_i)
                             ^
cy_sum_parallel.c:1316:7: note: ‘__pyx_v_j’ was declared here
   int __pyx_v_j;
       ^

我假定这个警告告诉我j被声明了,但没有初始化。所以我的问题是我应该对这个警告消息做点什么吗?以及如何?

编译后的代码似乎运行正常

import sys
sys.path.append('/home/Jian/Dropbox/Coding/Python/Cython/ex_parallel')
import cy_sum_parallel
%prun -s tottime -l 5 cy_sum_parallel.main()

,它比非并行版本提供了3的性能提升,这是在8核机器上的预期结果。

您总是可以查看生成的C代码来检查上下文。如果您想生成代码,可以使用cython -a <filename.pyx>来创建一个可浏览的html文件,或者使用cython <filename.pyx>来生成一个C文件。

代码有点复杂,使用了很多临时变量(指定为__pyx_t_*),但看起来像这样

                /* code snippet starts in an already quite nested set of for-loops */
                #ifdef _OPENMP
                #pragma omp for lastprivate(__pyx_v_j) firstprivate(__pyx_v_i) lastprivate(__pyx_v_i)
                #endif /* _OPENMP */
                for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_3; __pyx_t_2++){
                    {
                        __pyx_v_i = 0 + 1 * __pyx_t_2;
                        /* Initialize private variables to invalid values */
                        __pyx_v_j = ((unsigned int)0xbad0bad0);
                        __pyx_t_4 = __pyx_v_N;
                        for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
                          __pyx_v_j = __pyx_t_5;
                          /* etc */

我认为在这种情况下,变量__pyx_v_j将不会被初始化,如果循环的大小是0(这是什么产生的消息),但它不是在循环外使用,所以这真的无关紧要。(我省略了循环后的代码,以免占用太多空间,但您可以自己检查!)

因此忽略警告-这是一个错误的诊断。

相关内容

  • 没有找到相关文章

最新更新