3

I have legacy fortran source file named pot.f, which I need to apply OpenMP to parallel as shown below,but I can error messages about unexpected end state etc. But when I comment out $OMP lines by adding additional ! in the first column, there are not errors.

It is really weird to me. Can anybody tell me what went wrong?

subroutine pot_osc(rvp,R_pot,e_pot,pe_pot,ftmp,gtmp,vtmp,natoms)
   implicit none
   include 'sizes.h'
   include 'constants.h'
   include 'omp_lib.h'

   double precision  ftmp(maxatoms,3),gtmp(3),R_pot(maxatoms,3)

   !$OMP PARALLEL WORKSHARE  SHARED(gtmp,ftmp)
   !$OMP PARALLEL NUM_THREADS(16)
      gtmp = 0d0
      ftmp = 0d0
   !$OMP END PARALLEL WORKSHARE 
   return
end

subroutine pot_asym(rvp,vtmp)
   implicit none
   include 'constants.h'  
   return
end

Error messages:

 end
   1

Error: Unexpected END statement at (1)


  subroutine pot_asym(rvp,vtmp)
  1
Error: Unclassifiable statement at (1)
1
  • I noticed you used maxatoms as first index in your arrays. My guess would be that you described three-dimensional vectors associated with each atom. I think it would be better to transpose those arrays as Fortran is column major. That way, the 3D vectors would be contiguous in memory. Commented Oct 11, 2013 at 19:37

1 Answer 1

6

You start a second parallel section in the second OpenMP directive, which is not terminated by an end parallel. So the OpenMP directive should read

!$OMP PARALLEL WORKSHARE SHARED(gtmp,ftmp) NUM_THREADS(16)
       gtmp = 0d0
       ftmp = 0d0
!$OMP END PARALLEL WORKSHARE

or if you like to keep the line break use

!$OMP PARALLEL WORKSHARE SHARED(gtmp,ftmp) &
!$OMP NUM_THREADS(16)
       gtmp = 0d0
       ftmp = 0d0
!$OMP END PARALLEL WORKSHARE

In the past, I experienced some problems with exactly this kind of initialization. It seems that when compiled with gfortran the master thread did all the work. Even worse, by means of the "first-stouch principle", the whole array was located in the memory associated with the first thread. On our CCNUMA machine this lead to a huge slowdown.

To solve this I used explicit loops to initialize:

!$OMP PARALLEL DO SHARED(gtmp,ftmp) NUM_THREADS(16)
       do i=1,maxatoms
         ftmp(i,:) = 0d0
       enddo
!$OMP END PARALLEL DO
!      No need to do three elements in parallel
       gtmp = 0d0

I don't know whether they fixed this problem, but I use this way of initialization for arrays in shared memory since then.

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

3 Comments

The array assignments inside WORKSHARE are parallelised by gfortran if the array sections syntax is used instead, e.g. gtmp(:) = 0.d0; ftmp(:,:) = 0.d0. Otherwise all the work is done in a SINGLE directive.
IIRC, at least in my gfortran 4.8, you an use also whole arrays.
thanks for the answer! intel syntax doesn't compatible with mpif90 when break line.

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.