[Cython] prange CEP updated
Dag Sverre Seljebotn
d.s.seljebotn at astro.uio.no
Wed May 4 13:39:20 CEST 2011
On 05/04/2011 01:30 PM, mark florisson wrote:
> 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,
Doh.
> 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; ...; ...) ...
> }
Why do you need the if-test? Won't simply
#pragma omp parallel for firstprivate(i) lastprivate(i)
for (temp = 0; ...; ...) ...
do the job -- any initial value will be copied into all threads,
including the "last" thread, even if there are no iterations?
Dag Sverre
More information about the cython-devel
mailing list