[Cython] prange CEP updated

mark florisson markflorisson88 at gmail.com
Wed May 4 13:30:04 CEST 2011


On 4 May 2011 13:15, Dag Sverre Seljebotn <d.s.seljebotn at astro.uio.no> wrote:
> On 05/04/2011 12:59 PM, mark florisson wrote:
>>
>> On 4 May 2011 12:45, Dag Sverre Seljebotn<d.s.seljebotn at astro.uio.no>
>>  wrote:
>>>
>>> On 05/04/2011 12:00 PM, mark florisson wrote:
>>>>
>>>> There are two remaining issue. The first is warnings for potentially
>>>> uninitialized variables for prange(). When you do
>>>>
>>>> for i in prange(start, stop, step): ...
>>>>
>>>> it generates code like
>>>>
>>>> nsteps = (stop - start) / step;
>>>> #pragma omp parallel for lastprivate(i)
>>>> for (temp = 0; temp<    nsteps; temp++) {
>>>>     i = start + temp * step;
>>>>     ...
>>>> }
>>>>
>>>> So here it will complain about 'i' being potentially uninitialized, as
>>>> it might not be assigned to in the loop. However, simply assigning 0
>>>> to 'i' can't work either, as you expect zero iterations not to touch
>>>> it. So for now, we have a bunch of warnings, as I don't see a
>>>> __attribute__ to suppress it selectively.
>>>
>>> Isn't this is orthogonal to OpenMP -- even if it said "range", your
>>> testcase
>>> could get such a warning? If so, the fix is simply to initialize i in
>>> your
>>> testcase code.
>>
>> No, the problem is that 'i' needs to be lastprivate, and 'i' is
>> assigned to in the loop body. It's irrelevant whether 'i' is assigned
>> to before the loop. I think this is the case because the spec says
>> that lastprivate variables will get the value of the private variable
>> of the last sequential iteration, but it cannot at compile time know
>> whether there might be zero iterations, which I believe the spec
>> doesn't have anything to say about. So basically we could guard
>> against it by checking if nsteps>  0, but the compiler doesn't detect
>> this, so it will still issue a warning even if 'i' is initialized (the
>> warning is at the place of the lastprivate declaration).
>
> Ah. But this is then more important than I initially thought it was. You are
> saying that this is the case:
>
> cdef int i = 0
> with nogil:
>    for i in prange(n):
>        ...
> print i # garbage when n == 0?

I think it may be, depending on the implementation. With libgomp it
return 0. With the check it should also return 0.

> It would be in the interest of less semantic differences w.r.t. range to
> deal better with this case.
>
> Will it silence the warning if we make "i" firstprivate as well as
> lastprivate? firstprivate would only affect the case of zero iterations,
> since we overwrite with NaN if the loop is entered...

Well, it wouldn't be NaN, it would be start + step * temp :) But, yes,
that works. So we need both the check and an initialization in there:

if (nsteps > 0) {
    i = 0;
    #pragma omp parallel for firstprivate(i) lastprivate(i)
    for (temp = 0; ...; ...) ...
}

Now any subsequent read of 'i' will only issue a warning if 'i' is not
initialized before the prange() by the user. So if you leave your
index variable uninitialized (because you know in advance nsteps will
be greater than zero), you'll still get a warning. But at least you
will be able to shut up the compiler :)

> Dag
> _______________________________________________
> cython-devel mailing list
> cython-devel at python.org
> http://mail.python.org/mailman/listinfo/cython-devel
>


More information about the cython-devel mailing list