2012年5月11日 星期五

Compile 314.mgrid fail, resolved!

Compile 314.mgrid error:

==========================================================================
/usr/bin/gfortran-4.4.2                -fopenmp -O3 -m32 -march=prescott -mmmx -msse -msse2 -msse3 -msse4 -mfpmath=sse -fforce-addr -fivopts -fsee -ftree-vectorize -pipe    mgrid.f     -o mgrid
Error from make 'specmake  build 2> make.err | tee make.out':
mgrid.f: In function 'resid':
mgrid.f:365: error: lastprivate variable 'i2' is private in outer context
mgrid.f:365: error: lastprivate variable 'i1' is private in outer context
mgrid.f: In function 'psinv':
mgrid.f:408: error: lastprivate variable 'i2' is private in outer context
mgrid.f:408: error: lastprivate variable 'i1' is private in outer context
==========================================================================

Related Post:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33904
And in the following post, OPENMP confirms that is a bug in mgrid.f
http://openmp.org/pipermail/omp/2007/001101.html

Bug description:

>
>Hi!
>
>Is
>
>      SUBROUTINE foo(a, b, n)
>      DOUBLE PRECISION a, b
>      INTEGER*8 i1, i2, i3, n
>      DIMENSION a(n,n,n), b(n,n,n)
>!$OMP PARALLEL
>!$OMP+DEFAULT(SHARED)
>!$OMP+PRIVATE(I3)
>!$OMP DO
>!$OMP+LASTPRIVATE(I1,I2)
>      DO i3 = 2, n-1, 1
>       DO i2 = 2, n-1, 1
>        DO i1 = 2, n-1, 1
>         a(i1, i2, i3) = b(i1, i2, i3);
>  600    CONTINUE
>        ENDDO
>       ENDDO
>      ENDDO
>!$OMP END DO NOWAIT
>!$OMP END PARALLEL
>      RETURN
>      END
>
>valid?  My reading of the standard is it is not, because both I1
>and I2 are sequential loop iterator vars in a parallel construct
>and as such should be predetermined private rather than implicitly
>determined shared (OpenMP 2.5, 2.8.1.1).  It is not present
>in any of the clauses on the parallel construct which could possibly
>override it.  2.8.3.5 about the lastprivate clause in the 
>first restriction
>says that the vars can't be private in the parallel region.
>Several other compilers accept this code though.
>
>In OpenMP 3.0 draft the wording is even clear, because it talks there
>about the loop iterators being predetermined private in a task region,
>and !$omp do doesn't create a new task region.
>
>Or am I wrong with this?
>
>Thanks.
>
> Jakub
He is right!!!

Solution:


!$OMP+DEFAULT(SHARED)
with:
!$OMP+SHARED(I1,I2)

makes the code compile successfully with gfortran. 
Alternatively, keeping DEFAULT(SHARED) and fusing the OMP PARALLEL
clause with the OMP DO clause (i.e. using OMP PARALLEL DO) also solves
the problem.



























沒有留言:

張貼留言