简体   繁体   English

Cython并行Prange引发编译器警告

[英]Cython parallel prange throws a compiler warning

I am a Cython beginner and I just try to play with a toy example to get an experience of cython parallel loop feature prange . 我是Cython的初学者,我只是尝试玩一个玩具示例,以获取cython并行循环功能prange的经验。 Here is my sample code cy_sum_parallel.pyx which attempts to simply sum a 2-D array using prange . 这是我的示例代码cy_sum_parallel.pyx ,它尝试使用prange简单地对二维数组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)

with a minimum setup.py script 用最小的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))

When I run this the setup.py script, it throws the following compiler warnings: 当我运行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;
       ^

I presume that this warning tells me j is declared but not initialized. 我假设此警告告诉我j已声明但未初始化。 So my question is Shall I do something to this warning message? 所以我的问题是我要对此警告消息采取措施吗? and how? 如何?

The compiled code does seem to run properly 编译后的代码似乎可以正常运行

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

and it gives a performance boost of 3 over non-parallel version, which is an expected result on a 8-core machine. 与非并行版本相比,它的性能提高了3,这是在8核计算机上的预期结果。

Any help is highly appreciated. 非常感谢您的帮助。

You can always look at the generated C code to check the context. 您始终可以查看生成的C代码以检查上下文。 If you want to generate the code either use cython -a <filename.pyx> to create a browsable html file, or just cython <filename.pyx> to generate a C file in place. 如果要生成代码,请使用cython -a <filename.pyx>创建可浏览的html文件,或者仅使用cython <filename.pyx>来就地生成C文件。

The code is a little convoluted, and uses a lot of temporary variables (designated __pyx_t_* ), but looks like this 该代码有点费解,并且使用了大量临时变量(指定为__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 */

I think in this case the variable __pyx_v_j won't be initialised if the size of the loop is 0 (which is what generates the message), but it isn't used outside the loop so that really doesn't matter. 我认为在这种情况下,如果循环的大小为0(这是生成消息的原因),则不会初始化变量__pyx_v_j ,但是不会在循环外使用它,所以实际上没关系。 (I've omitted the code after the loop so as not to take up too much space, but you can check yourself!) (为了避免占用太多空间,我在循环后省略了代码,但是您可以自己检查一下!)

Therefore ignore the warning - it's a false diagnostic. 因此,请忽略警告-这是错误的诊断。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM