1
votes

I have a few questions about using common blocks in parallel programming in Fortran.

  1. My subroutines have common blocks. Do I have to declare all the common blocks and threadprivate in the parallel do region?

  2. 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?

  3. My Ford subroutine changes some variables in common blocks and Condact subroutine overwrites over them again but the function uses the values from Condact 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
    
2
Global data and parallelization is generally a bad idea. Using common blocks is a worse idea. Is this an old code, or do you write something new? You definitely should first try to get rid of common blocks in your code.haraldkl
The other question is, what kind of data it is you have in the common block. Is something which is just defined for each (i,j) and reused upon each call? Or is it something to contain the result for all (i,j)?haraldkl
@haraldkl, I am trying to parallelize using open mp a very old code full of common blocks! (I know I can use module but I want to try with common block and threadprivate 1st)sam
@haraldkl, the common block variables overwritten each time upon each call. They just hold some data during the calculation process inside the subroutine. Is that what you want to know?sam
I am really sorry for you, but in your other question you asked how to get rid of those common blocks, and this really is the way to go. Believe it or not, spending the effort to get rid of them, will save you a lot of pain.haraldkl

2 Answers

1
votes

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:

  1. My subroutines has common blocks. Do I have to declare all the common block and threadprivate in the parallel do region?

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.

  1. 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?

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 use copyin 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.

  1. Are those common block accessible through the subroutine? My Ford subroutine rewrite some variables in common block and Condat subroutine rewrite over them again but the function uses the values from Condat subroutine. Is that possible rewrite and pass the common block variable using threadprivate here?

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)

0
votes

How about converting the common blocks into modules?

Change common /root/ root1, root2 to use gammax, then make a new file root.f that contains:

module root
implicit none
save
real :: root1, root2
!$omp threadprivate( root1, root2 )
end module root