I have a few questions about using common blocks in parallel programming in Fortran.
My subroutines have common blocks. Do I have to declare all the common blocks and threadprivate in the parallel do region?
How do they pass information? I want seperate common clock for each thread and want them to pass information through the end of parallel region. Does it happen here?
My
Ford
subroutine changes some variables in common blocks andCondact
subroutine overwrites over them again but the function uses the values fromCondact
subroutine. Do the second subroutine and function copy the variables from the previous subroutine for each thread?program ... ! Loop which I want to parallelize !$OMP parallel DO !do I need to declear all common block and threadprivate them here? I = 1, N ... call FORD(i,j) ... !$OMP END parallel DO end program subroutine FORD(i,j) dimension zl(3),zg(3) common /ellip/ b1,c1,f1,g1,h1,d1, . b2,c2,f2,g2,h2,p2,q2,r2,d2 common /root/ root1,root2 !$OMP threadprivate (/ellip/,/root/) !this subroutine rewrite values of b1, c1 and f1 variable. CALL CONDACT(genflg,lapflg) return end subroutine SUBROUTINE CONDACT(genflg,lapflg) common /ellip/ b1,c1,f1,g1,h1,d1,b2,c2,f2,g2,h2,p2,q2,r2,d2 !$OMP threadprivate (/ellip/) ! this subroutine rewrite b1, c1 and f1 again call function f(x) RETURN END function f(x) common /ellip/ b1,c1,f1,g1,h1,d1, . b2,c2,f2,g2,h2,p2,q2,r2,d2 !$OMP threadprivate (/ellip/) ! here the function uses the value of b1, c1, f1 from CONDAT subroutine. end
How about converting the common blocks into modules?
Change
common /root/ root1, root2
touse gammax
, then make a new fileroot.f
that contains:Firstly as the comment above says I would strongly advise against the use of
common
especially in modern code, and mixing global data and parallelism is just asking for a world of pain - in fact global data is just a bad idea full stop.OK, your questions:
No,
threadprivate
is a declarative directive, and should be used only in the declarative part of the code, and it must appear after every declaration.As you suspect each thread will gets its own version of the
common
block. When you enter the first parallel region the values in the block will be undefined, unless you usecopyin
to broadcast the values from the master thread. For subsequent parallel regions the values will be retained as long as the number of threads used in each region is the same. Between regions the values in the common block will be those of the master thread.I have to admit I am unsure what you are asking here. But if you are asking whether common can be used to communicate variables between different sub-programs in OpenMP code, the answer is yes, just as in serial Fortran (note capitalisation)