0

I have written down a simple code using openmp in fixed form fortran.My code is running but the result produced by it is wrong.can anybody help me out?

    Implicit none   
    
    integer i,N,CHUNKSIZE
    parameter(N=100)
    parameter(CHUNKSIZE=7)
    double precision X(N), Y(N), XdotY
    integer :: threadNUM, OMP_GET_THREAD_NUM
    
    XdotY=0.0d0
!$OMP PARALLEL DO LASTPRIVATE(X,Y)
    do I=1,N
    X(I)=I
    Y(I)=I**2
    write(*,*) x(i),y(i)
    end do
!$OMP END PARALLEL DO
!$OMP PARALLEL DO 
C$OMP&REDUCTION(+:XdotY)
    do I=1,N
    XdotY = XdotY + X(I)*Y(I)
    end do
!$OMP END PARALLEL DO
    
    write(*,*)'X.Y=', XdotY
    write(*,*)'the exact answer is =', (N*(N+1)/2.0d0)**2
    
    end

Here the answer is not matching. The following is the result - X.Y= 17380000.000000000
the exact answer is = 25502500.000000000 And i am compiling it by the command - 'gfortran -fopenmp dotprod_OMP.f90 -o dotprod_OMP'.

also, i have done this in an f90 file. the following is the code - Implicit none

integer i
integer,parameter :: N=100
integer,parameter :: CHUNKSIZE=7
double precision  :: X(N), Y(N), XdotY
integer :: threadNUM, OMP_GET_THREAD_NUM

XdotY=0.0d0

!$OMP PARALLEL DO LASTPRIVATE(X,Y)
do I=1,N
X(I)=I
Y(I)=I**2
!write(*,*) x(i),y(i)
end do
!$OMP END PARALLEL DO

!$OMP PARALLEL DO 
!$OMP REDUCTION(+:XdotY)
do I=1,N
XdotY = XdotY + X(I)*Y(I)
end do
!$OMP END PARALLEL DO

write(*,*)'X.Y=', XdotY
write(*,*)'the exact answer is =', (N*(N+1)/2.0d0)**2

end

there is an error after compilation. the error shows this - 25 | !$OMP REDUCTION(+:XdotY) | 1 Error: Unclassifiable OpenMP directive at (1)

I think the reduction clause is not working. how can i solve this?

14
  • Note this code is at least Fortran90 - I have reflected this in my edits. Commented Dec 15, 2022 at 12:58
  • You haven't initialized X or Y. This code can give any answer it wants. And quite possibly a different answer every time it is run. What happens if you do initialize X and Y? Commented Dec 15, 2022 at 13:01
  • yes i have initialized like this - Commented Dec 15, 2022 at 13:06
  • 1
    Please edit the question to show the exact code you are using - please don't put code in comments, it is close to unreadable. Commented Dec 15, 2022 at 13:07
  • 1
    @VictorEijkhout as I understand it, the X and Y arrays are private to each thread, and the version that is kept at the end of the parallel region is the one from the thread that executed the last sequential iteration (i=n here). Anyway, whichever the version that is retained at the end, it is incomplete. Commented Dec 15, 2022 at 17:13

2 Answers 2

0

From the Microsoft Learn documentation of OpenMP which states that the lastprivate clause:

Specifies that the enclosing context's version of the variable is set equal to the private version of whichever thread executes the final iteration (for-loop construct) or last section.

(I also checked the OpenMP specification (v5.2) which states the same, but at much more length and with many more ifs and buts, none of which are applicable here. And I'm fairly sure that the fundamental behaviour of lastprivate hasn't changed since either OpenMP 1.0 or since when MS wrote their documentation.)

In this case lastprivate means that only the updates made to X and Y by one thread 'escape' to the rest of the program. The fact that OP writes (and my own tests confirm) that removing the clause fixes the program makes me believe that the wrong use of the clause was the problem.

Sign up to request clarification or add additional context in comments.

Comments

0

I think that a continuation should be placed on the following lines (although this may have changed with later versions of OpenMP?) !$OMP PARALLEL DO & !$OMP REDUCTION(+:XdotY)

The following modified code appears to produce the correct result.

implicit none
integer i
integer,parameter :: N=100
integer,parameter :: CHUNKSIZE=7
double precision  :: X(N), Y(N), XdotY
integer :: threadNUM, OMP_GET_THREAD_NUM

XdotY=0.0d0

!$OMP PARALLEL DO default(none) shared(x,y)
do I=1,N
   X(I)=I
   Y(I)=I**2
!write(*,*) x(i),y(i)
end do
!$OMP END PARALLEL DO

!$OMP PARALLEL DO default(none) shared(x,y) &
!$OMP REDUCTION(+:XdotY)
do I=1,N
   XdotY = XdotY + X(I)*Y(I)
end do
!$OMP END PARALLEL DO

write(*,*)'X.Y=', XdotY
write(*,*)'the exact answer is =', (N*(N+1)/2.0d0)**2

end

I have :- included implicit none and default(none) as these provide better diagnostics, Treated X and Y as shared, Provided a continuation in !$omp syntax.

I am not sure why you did no get an error without the continuation, but this may relate to the OpenMP version you have available. I am using Gfortran Ver 11.1 on Win 10. This does not support OpenMP Ver 5.

For clarification, you could report the thread number uses for each "i" in either loop.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.