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

BLOCK, END BLOCK statements not threadsafe

Andrew_Smith
New Contributor III
812 Views

I have run accross random results using a BLOCK, END BLOCK contstruct. My application was multi-threaded. When I move the local declarations into the parent procedure and remove the BLOCK construct the results become repeatable.

I am using implied AUTOMATIC for the project via /Qopenmp.

The help file does not mention this limitation of your implementation. Is it a bug or intentional ?

Using Visual Fortran Compiler XE 15.0.5.280.

0 Kudos
10 Replies
jimdempseyatthecove
Honored Contributor III
812 Views

IVF document:

...
A BLOCK construct cannot appear inside a structured block of an OpenMP* directive.
...

I do not know why there is this restriction.

Jim Dempsey

0 Kudos
Kevin_D_Intel
Employee
812 Views

It appears perhaps F2008 Standard related but I’m not finding supportive details so I’ll inquire w/Development. I expect it relates to this error that will be issued when the restriction is violated:

error #7936: This statement or directive is not permitted within the block of an OpenMP* WORKSHARE or OpenMP* PARALLEL WORKSHARE directive.

0 Kudos
Kevin_D_Intel
Employee
812 Views

Here's some clarification. Correction, it is not F2008 Standard related rather it relates to a lack of meaning in terms of the OpenMP API.

The Developers indicate support could be implemented in the future. I’m told, when the OpenMP API documents what it means to have a BLOCK inside an OMP directive. It’s a question of variable scoping – a local inside the BLOCK inside an OMP block couldn’t appear on the SHARED etc lists of the OMP directive – they’re not visible in that scope.  If that just means all BLOCK locals inside OMP are PRIVATE, end of discussion, then that’s a simple definition.

0 Kudos
jimdempseyatthecove
Honored Contributor III
331 Views

>> It’s a question of variable scoping – a local inside the BLOCK inside an OMP block couldn’t appear on the SHARED etc lists of the OMP directive – they’re not visible in that scope.  If that just means all BLOCK locals inside OMP are PRIVATE, end of discussion, then that’s a simple definition.

 

Two situations:

1) the scope of the BLOCK is inside the parallel region

For block variables declared with SAVE (if that be permitted), then they are shared. 

For block variables that are automatic (not SAVE) then they are on the thread's stack and thus are private.

 

2) The scope of the BLOCK contains a parallel region

Then the scope of the BLOCK variables can be declared either shared or private (or default).

 

Note, the above situations are analogous to if the BLOCK were replaced with a contained procedure.

1) The CALL to the contained procedure is inside the parallel region

For contained procedure local variables declared with SAVE, then they are shared. 

For contained procedure local variables that are automatic (not SAVE) then they are on the thread's stack and thus are private.

2) The contained procedure contains a parallel region

Then the scope of the contained procedure variables can be declared either shared or private (or default).

 

I do not see any issue that presents a problem...

Unless the implementation makes the BLOCK variables (those not SAVE) static.

 

Jim Dempsey

0 Kudos
Andrew_Smith
New Contributor III
812 Views
If all BLOCK locals were private inside an OMP construct then my application should have worked. I was not attempting to share any of them. So the BLOCK construct should work OK in a recursive routine provided the routine is not inside an openMP construct ?
0 Kudos
jimdempseyatthecove
Honored Contributor III
812 Views

Andrew,

You might have success in cutting the block out of the code and replacing it with:

   call MyBlock()

and make MyBlock a contains subroutine.

This will place the code out of line, but it may permit you to do what you want.

Jim Dempsey

0 Kudos
jimdempseyatthecove
Honored Contributor III
812 Views

>>So the BLOCK construct should work OK in a recursive routine provided the routine is not inside an openMP construct ?

Yes

Note, the contains subroutine will permit the subroutine to see the containing procedures variables without passing them as dummy's

Jim Dempsey

0 Kudos
Nicholas_B_
Beginner
812 Views

I think there have been a number of bugs with block contructs, possibly including:

  1. final routines not called when variable goes out of scope (DPD200379085 fixed in 16 update 2)
  2. allocatable variables not deallocated when variable goes out of scope
  3. variables in block construct being saved (DPD200408259 not fixed: https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/616394 ). Using automatic attribute extension may be aworkaround.

Nick

0 Kudos
Andrew_Smith
New Contributor III
353 Views

I have been avoiding block constructs for 8 years now. Are they now thread safe in openMP regions ?

And are the other issues mentioned by Nicholas_B_ now fixed ?

0 Kudos
Steve_Lionel
Honored Contributor III
323 Views

BLOCK variables are permitted to have the SAVE attribute.

0 Kudos
Reply