Intel® Moderncode for Parallel Architectures
Support for developing parallel programming applications on Intel® Architecture.

Pointers defined in modules and OpenMP

Jerome_B_Intel
Employee
355 Views

I am working with a program (which I did not write) which has a pointer to a derived type in a module;

[fortran]module X

type mytype

    integer x, y, z

end type mytype

type (mytype), pointer :: p_mt

end module X [/fortran]

 

This module is accessed in a subroutine;

[fortran]subroutine Loop

use X

p_mt  => GoGetOne()

p_mt % x = 7.0

...[/fortran]

So far, so good. However, subroutine Loop is accessed from with a parallel loop in another subroutine;

 

[fortran]subroutine CallLoop()

integer i

!$OMP parallel do

do i = 1 to 10000

    call Loop(i)

enddo[/fortran]

It is my understanding that p_mt is global in scope, and therefore should not be accessed from within a parallel loop. If I declare Loop as pure;

[fortran]pure subroutine Loop()[/fortran]

the compiler flags the assignment of a value to p_mt as an error.

Am I missing something? Or is this a potential bug?

 

 

0 Kudos
2 Replies
jimdempseyatthecove
Honored Contributor III
355 Views

>>It is my understanding that p_mt is global in scope, and therefore should not be accessed from within a parallel loop. If I declare Loop as pure;

It should not be modified without the cooperation of the other threads (e.g. with barrier or such).

Trying to interpret your sketch, the corrective measure would be to place a pointer inside your subroutine

[fortran]

subroutine Loop
  use X
  type (mytype), pointer :: p_mt_local
  p_mt_local  => GoGetOne()
  p_mt_local % x = 7.0
  ...
[/fortran]

Jim Dempsey

0 Kudos
Jerome_B_Intel
Employee
355 Views
You Dec 26

Jim,

 

   Your understanding agrees with mine, as does your proposed solution. My problem is that I must first convince the owners of the code that it is broken, before they will agree to a fix. For various reasons, it will not do to fix it unilaterally myself.

    The obvious solution is to put in some code to catch a race condition, where one thread modifies the pointer while another is using it. I have tried very hard to do that, without success, which leads me to wonder whether I am overlooking something. For example, perhaps OpenMP is making a private copy of the pointer, as it would do for a parallelized loop variable. It sounds like you are not aware of any such feature.

  Are you aware of any document that deals with this case specifically? If not, what documents lead to your conclusion that the pointer is global in scope?

 

 

Forum Topic:

 

The problem is not technically a race condition.

Rather it is a case of using code that is suitable for single threaded use, yet unsuitable for multi-threaded use. The fact that the code works fine in single threaded mode does not assure the same code is multi-threaded safe. In this case it is not multi-thread safe.

To the owners of the code: Either affect changes to make the code multi-thread safe, or keep to a single thread model.

By the way, the "GoGetOne()" has to be thread safe as well.

>>perhaps OpenMP is making a private copy of the pointer

Not possible in your original sketch code. You call a subroutine that USEs the module p_mt.

You could make the pointer threadprivate, however, this will not fix GoGetOne, nor will it fix other potential issues. An example is the subroutine Loop is a search and you wish to terminate the search with p_mp => the first found item.

This should have been posted in open forum so others can learn from the discussion.

Jim Dempsey

 

0 Kudos
Reply