OpenMP and EQUIVALENCE in Fortran

General OpenMP discussion

OpenMP and EQUIVALENCE in Fortran

Postby Regal » Tue May 28, 2013 1:09 am

Hello, I have the following problem in a Fortran program.

I need to declare some common blocks as THREADPRIVATE to ensure correct data handling by the threads, but by doing so, the system reports an error during compilation with gfortran 4.4.3.:

Error: EQUIVALENCE attribute conflicts with THREADPRIVATE attribute

Of course my common blocks contain equivalenced variables and it seems that this is a known bug of the gfortran compiler. Apparently the bug is still present.

So, is there a workaround for this?

Thanks! :)
Regal
 
Posts: 15
Joined: Wed May 22, 2013 3:04 am

Re: OpenMP and EQUIVALENCE in Fortran

Postby MarkB » Tue May 28, 2013 2:23 am

It's not a bug in gfortran: using THREADPRIVATE on EQUIVALENCEd variables isn't allowed by the OpenMP standard (see Version 3.1, page 92, line 2).
The link you posted suggests that other compilers support this as an extension. I think your options are either to refactor the code to get rid of the EQUIVALENCEs, or to use a different compiler.
MarkB
 
Posts: 480
Joined: Thu Jan 08, 2009 10:12 am
Location: EPCC, University of Edinburgh

Re: OpenMP and EQUIVALENCE in Fortran

Postby Regal » Tue May 28, 2013 7:13 am

Unfortunately none of these can be applied (equivalences going very deep into the model, plus I am not sysadmin to install another compiler). So let me explain the logic behind the data manipulation; perhaps another solution may be given without using the THREADPRIVATE clause.

I have loops like this:

Code: Select all
     
      DO i = 1, n
        a_vec(i) = Ens_a_vec(i,K)
        a_str = a_vec(i)
        CALL SUBR(K)
        a_vec(i) = a_str
        Ens_a_vec(i,K) = a_vec(i)
      ENDDO


The previous loop makes part of a subroutine that takes as argument the index K and passes it to the variables. This subroutine is called inside another loop running over all possible values of K, and this is precisely the loop to parallelize. The loop over i runs sequentially.

The variables now: a_str, a_vec(i) and Ens_a_vec(i,K) are character chains. a_str is in equivalence with a series of real variables and, once initialized by a_vec(i) which in turn takes values from Ens_a_vec(i,K), it initializes at once all these real variables that are used in calculations inside SUBR(K). The two lines after the call to SUBR(K) are essentially the inverse pathway to (re)store the results in Ens_a_vec(i,K).

The problem is immediately visible if one has in mind more than one thread handling this situation. The variable a_vec(i) does not have the index K and would be the same for all threads. This is going to create quite a mess in the results.

So, any ideas on how to create individual copies, for each thread, of a_vec(i) and a_str? Please note that these variables are declared in separated "include files", which are included in the beginning of each program, and regrouped into common blocks. This is how the programs know about them.
Regal
 
Posts: 15
Joined: Wed May 22, 2013 3:04 am

Re: OpenMP and EQUIVALENCE in Fortran

Postby MarkB » Tue May 28, 2013 7:36 am

You could declare the variables with an extra dimension and use the thread ID to index this. So in place of a_vec(i) you would have a_vec(i,myid) where myid is a private variable and is assigned a value using omp_get_thread_num() inside the parallel region.

Note that for performance reasons (avoiding false sharing) it is essential to have the extra index rightmost, and, for scalars, to pad out string so that it is at least as big as a cache line (normally 64 or 128 bytes, depending on your hardware)
MarkB
 
Posts: 480
Joined: Thu Jan 08, 2009 10:12 am
Location: EPCC, University of Edinburgh

Re: OpenMP and EQUIVALENCE in Fortran

Postby Regal » Tue May 28, 2013 7:58 am

Interesting idea, thanks! I suppose I should do the same with a_str and the real variables which are in equivalence with it, right?

Also, I have inside the loop, along with a_str, a_vec(i) and Ens_a_vec(i,K), other variables b_str and b_vec(i) for which there is no Ens_b_vec(i,K). However the same initialization and restoring sequences occur as in the case of a_str and a_vec(i). For example, before the call to SUBR(K) we have a_str = a_vec(i), and after that a_vec(i) = a_str. The variable b_vec(i) is initialized by a subroutine which has nothing to do with the index K and the parallelisation. What will happen with them if more than one thread share the work? Will all the threads automatically use the same value for these variables?
Regal
 
Posts: 15
Joined: Wed May 22, 2013 3:04 am

Re: OpenMP and EQUIVALENCE in Fortran

Postby MarkB » Tue May 28, 2013 8:08 am

Regal wrote:Interesting idea, thanks! I suppose I should do the same with a_str and the real variables which are in equivalence with it, right?


Yes, though you will need to take care that the equivalancing works with the memory layout of the array version of a_str. You may need to introduce an array of reals to equivalance to a_str(), and then copy the values into scalar real variables, for instance.

Also, I have inside the loop, along with a_str, a_vec(i) and Ens_a_vec(i,K), other variables b_str and b_vec(i) for which there is no Ens_b_vec(i,K). However the same initialization and restoring sequences occur as in the case of a_str and a_vec(i). For example, before the call to SUBR(K) we have a_str = a_vec(i), and after that a_vec(i) = a_str. What will happen with them if more than one thread share the work? Will all the threads automatically use the same value for these variables?


If b_str etc. is also EQUIVALENCEd, you will likely need to treat them in the same way.
MarkB
 
Posts: 480
Joined: Thu Jan 08, 2009 10:12 am
Location: EPCC, University of Edinburgh

Re: OpenMP and EQUIVALENCE in Fortran

Postby Regal » Wed May 29, 2013 1:33 am

OK, I see.

Now that I am thinking again about it, I am wondering if declaring all these variables as private in the beginning of the parallel section would solve the problem. This would eliminate the need to redefine them with one more dimension to store the thread ID. They make part of common blocks, so the programs are aware about them. Would the fact that they are not directly visible once the loop starts, but you have to go two or three levels deep in nested subroutines, be a problem? Same for the fact that many real variables are "hidden" behind the equivalence with a chain character which appears in the common block.
Regal
 
Posts: 15
Joined: Wed May 22, 2013 3:04 am

Re: OpenMP and EQUIVALENCE in Fortran

Postby MarkB » Wed May 29, 2013 1:50 am

Regal wrote:I am wondering if declaring all these variables as private in the beginning of the parallel section would solve the problem


Unfortunately, I don't think that's going to work for two reasons:

Firstly, if a variable is EQUIVALENCEd, there are no guarantees about whether a private copy of this variable is also EQUIVALENCEd. (See Version 3.1, page 97, line 28 and following) .

Secondly, if a global variable is made private in a parallel region, and then referenced in a subroutine called inside the parallel region, it is unspecified whether this reference is to the private copy or the original variable. (See Version 3.1, page 96, lines 16-18).
MarkB
 
Posts: 480
Joined: Thu Jan 08, 2009 10:12 am
Location: EPCC, University of Edinburgh


Return to Using OpenMP

Who is online

Users browsing this forum: Google [Bot] and 13 guests