简体   繁体   中英

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 . Here is my sample code cy_sum_parallel.pyx which attempts to simply sum a 2-D array using 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

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:

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

Any help is highly appreciated.

You can always look at the generated C code to check the context. 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.

The code is a little convoluted, and uses a lot of temporary variables (designated __pyx_t_* ), but looks like this

                /* 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. (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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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