On 4 May 2011 14:17, mark florisson <markflorisso...@gmail.com> 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.
The alternative would be to give 'cdef int i' initialized semantics, to whatever value we please. So instead of generating 'int i;' code, we could always generate 'int i = ...;'. But currently we don't do that. >> 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. > >> instead, to get rid of the warning without using a firstprivate? Not sure if >> there's an efficiency difference here, I suppose a good C compiler could >> compile them to the same thing. >> >> Dag Sverre >> _______________________________________________ >> cython-devel mailing list >> cython-devel@python.org >> http://mail.python.org/mailman/listinfo/cython-devel >> > _______________________________________________ cython-devel mailing list cython-devel@python.org http://mail.python.org/mailman/listinfo/cython-devel