On 05/04/2011 02:17 PM, mark florisson wrote:
On 4 May 2011 14:10, Dag Sverre Seljebotn<d.s.seljeb...@astro.uio.no>  wrote:
On 05/04/2011 01:59 PM, mark florisson wrote:

On 4 May 2011 13:54, Dag Sverre Seljebotn<d.s.seljeb...@astro.uio.no>
  wrote:

On 05/04/2011 01:48 PM, mark florisson wrote:

On 4 May 2011 13:47, mark florisson<markflorisso...@gmail.com>      wrote:

On 4 May 2011 13:45, Dag Sverre Seljebotn<d.s.seljeb...@astro.uio.no>
  wrote:

Look.

i = 42
for i in prange(n):
    f(i)
print i # want 42 whenever n == 0

Now, translate this to:

i = 42;
#pragma omp parallel for firstprivate(i) lastprivate(i)
for (temp = 0; ...; ...) {
    i = ...
}
#pragma omp parallel end
/* At this point, i == 42 if n == 0 */

Am I missing something?

Yes, 'i' may be uninitialized with nsteps>      0 (this should be valid
code). So if nsteps>      0, we need to initialize 'i' to something to
get
correct behaviour with firstprivate.

This I don't see. I think I need to be spoon-fed on this one.

So assume this code

cdef int i

for i in prange(10): ...

Now if we transform this without the guard we get

int i;

#pragma omp parallel for firstprivate(i) lastprivate(i)
for (...) { ...}

This is invalid C code, but valid Cython code. So we need to
initialize 'i', but then we get our "leave it unaffected for 0
iterations" paradox. So we need a guard.

You mean C code won't compile if i is firstprivate and not initialized?
(Sorry, I'm not aware of such things.)

It will compile and warn, but it is technically invalid, as you're
reading an uninitialized variable, which has undefined behavior. If
e.g. the variable contains a trap representation on a certain
architecture, it might halt the program (I'm not sure which
architecture that would be, but I believe they exist).

My first instinct is to initialize i to 0xbadabada. After all, its value is
not specified -- we're not violating any Cython specs by initializing it to
garbage ourselves.

The problem is that we don't know whether the user has initialized the
variable. So if we want firstprivate to suppress warnings, we should
assume that the user hasn't and do it ourselves.

I meant that if we don't care about Valgrindability, we can initialize i at the top of our function (i.e. where it says "int __pyx_v_i").

OTOH, I see that your approach with an if-test is more Valgrind-friendly, so
I'm OK with that.

Would it work to do

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

I'm assuming you mean #pragma omp parallel private(i), otherwise you
have a race (I'm not sure how much that matters for assignment). In
any case, with the private() clause 'i' would be uninitialized
afterwards. In either case it won't do anything useful.

Sorry, I meant that lastprivate(i) should go on the parallel line.

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

won't this silence the warning? At any rate, it's obvious you have a better handle on this than me, so I'll shut up now and leave you to it :-)

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

Reply via email to