Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

OpenMP newbie ask for help

joey_hylton
Beginner
555 Views

Using someone's program but changed a little to simulate my case. I want to do parallel in the main code, and call a subroutine inside the loop. The subroutine may also call other complicate subroutines. In this case, how can I define the variables as shared/private, such as i,j inside subroutine serial().

If I only use one thread, it runs okay. However, if I use more thanone thread, thereis alway error such as index of W goes to 100001 etc.

Thanks,

program smp
use
dflib
implicit none
integer, parameter
:: sz =100000
real(8), dimension(sz) :: X,W
integer :: i, IT,NT=50000,iflag =1, n =1
real(8) :: res, runtime, begtime, endtime,timef
real(8), parameter :: mlt = 1.0D+02
interface
subroutine Serial(X,W,sz)
integer,intent(in) :: sz
integer :: i,j
real(8),intent( in),dimension(sz) :: X
real(8),intent(out),dimension(sz) :: W
end subroutine Serial
end interface
do i = 1, sz
res = ran(iflag); X(i)= mlt*res*n; n=-n
enddo
write(*,*)" Program started...... "C
begtime = timef()
!$OMP PARALLEL DO

DOIT=1,NT
call Serial(X,W,sz,IT)

ENDDO
!$OMP END PARALLEL DO
endtime = timef(); runtime=endtime-begtime
write(*,'(A20,F9.4)')" Execution time is :"C,runtime
write(*,*)" Program terminated..."C
end program smp
!
subroutine Serial(X,W,sz,IT)
integer,intent(in) :: sz
integer&nb sp; :: i,j
real(8),intent( in),dimension(sz) :: X
real(8),intent(out),dimension(sz) :: W
do i=1,sz
W(i)=0.D0

call subroutinework(W)
do j=1,sz
W(i)=W(i)+DABS(x(i)+x(j))
enddo
enddo

end subroutine Serial

subroutine work(W)

integer i

real W(sz)

do i=1,sz

W(i)=works(i)

enddo

endsubroutine

0 Kudos
10 Replies
jimdempseyatthecove
Honored Contributor III
555 Views

Joey,

Add "implicit none" to all of your subroutines and see what happens.

Also, your subroutine Serial is being called from the parallel loop and is passed the iterator IT however IT is not used?

Jim Dempsey

0 Kudos
joey_hylton
Beginner
554 Views

Jim,

Thanks for reply.

Actually, this is not my real code. I real code ismuch morecomplicated than this one. I use this code to simulate my case. In my real code, I have lots of global variables in the modules, and many of them are big arrays/matrices, and will be initialized before the parallelization sections, and will not be changed ( I suppose these variables will be set as shared). Some of them will be initialized and will be changed inside the parallelization section ( I suppose these variables will be set as threadprivate and copy in at the beginning). The loop variable (as IT in this code) is private. But how about other varialbes such i,j in subroutine serial()?

In my code, I did like this:

!$OMP PARALLEL DO default(shared) private(IT) copyin(....)

DOIT=1,NT
call Serial(X,W,sz,IT)

ENDDO
!$OMP END PARALLEL DO

Here, I am trying to parallelize my code in the most highest level. I don't if it is possible or not.


0 Kudos
joey_hylton
Beginner
554 Views

Jim,

Will "IMPLICIT NONE" and "INTEGER I, J" automatically make I,J to be private in side each subroutine? My code have lots of subroutines having something like "implicit IMPLICIT REAL*8 (a-h,o-z)",and some of the variables are directly used without declairation.(Sorry, the original code is mot mine, I am try to modify it). Thanks, Joey

0 Kudos
joey_hylton
Beginner
554 Views
After changed the "implicit none"
I got new problem.

In one of my subroutines, I have to allocate some (many) arrays, and the sizes of these arrays are very large. If I defined them as this way

subroutine works(N)

implicit none

integer,intent(in)::N

real a(N),b(N),c(N)

a=0d0
...

end


this OpenMP process always give me a stack overflow error even I changed both the heap reserve and stack reserve sizes to large number, say 800,000,000

Acording to someone's suggestions, I changed the definition as

subroutine works(N)

implicit none

integer,intent(in)::N

real,save,allocatable,dimension(:) a,b,c

allocate(a(N),b(n),c(N))

a=0d0
...

end

I got an error as "attempt to fetch from allocatable variable a when it is not allocated" at the line of "a=0d0". (It is possibly for the second thread, i have not figure it out yet).
Toey_Hylton
Posts: 3
Joined: Mon Sep 22, 2008 2:32 pm
0 Kudos
Les_Neilson
Valued Contributor II
555 Views
Joey_Hylton:

Jim,

Will "IMPLICIT NONE" and "INTEGER I, J" automatically make I,J to be private in side each subroutine? My code have lots of subroutines having something like "implicit IMPLICIT REAL*8 (a-h,o-z)",and some of the variables are directly used without declairation.(Sorry, the original code is mot mine, I am try to modify it). Thanks, Joey

The "IMPLICIT REAL*8 (a-h,o-z)" means that all variable names that _begin_ with a letter "A" through to "H" or "O" through to "Z" declare variables that are, by default, double precision, unlessthe variable is explicitly declared as something else eg COMPLEX W

It also means that variable names that begin with any other letter "I" through "N" declare variables that are INTEGER by default, unless explicitly declared as something else.

The "scope" of the "IMPLICIT" declaration is the subroutine or function containing it.

The "scope" of the variables is also limited to the subroutine in which they are declared - that is they are local (private as you call them) variables;UNLESS they are exposed tootherpartsof the system by, for example, a COMMON block, MODULE orby being passed as actual arguments in a CALL to another subroutine.

Les

0 Kudos
Les_Neilson
Valued Contributor II
555 Views
Joey_Hylton:


allocate(a(N),b(n),c(N))

I got an error as "attempt to fetch from allocatable variable a when it is not allocated" at the line of "a=0d0". (It is possibly for the second thread, i have not figure it out yet).

Insituations such as this where you have lots of arrays, it is usually a good idea to (a) allocate the arrays one at a time and (b) test the status of the allocation in casea problem occurred:

integer istat
allocate(a(N), stat=istat)
if (istat /= 0) then
! error allocating the array; do something
endif

Les

0 Kudos
joey_hylton
Beginner
555 Views
I did this and found istat=151 when I use two threads, and istat=0 for one thread
0 Kudos
Les_Neilson
Valued Contributor II
555 Views

If you search the Fortran help for run-time errors you will find that error 151 means :

severe (151): Allocatable array is already allocated

Les

0 Kudos
joey_hylton
Beginner
555 Views

Les,

Thanks.

Yes, I found it out. However, how can I deal with the allocatable variables in parallelization section with OpenMP?

0 Kudos
Steven_L_Intel1
Employee
555 Views
Regarding the stack limit problem: with OpenMP, the each thread gets its own stack. The size of the stack is determined by the KMP_STACKSIZE environment variable which you can read about in the documentation.
0 Kudos
Reply