Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
Welcome to the Intel Community. If you get an answer you like, please mark it as an Accepted Solution to help others. Thank you!
26742 Discussions

"Bug" report: data-sharing attribute for variables declared in BLOCK within openmp block

Martin1
New Contributor I
667 Views

The recently published openmp 5.1 specification thankfully clarified the data-sharing attributes for variables declared in a block...end block construct within an openmp block, see "2.21.1.1 Variables Referenced in a Construct". Except for when a SAVE attribute is used, those variables must now be private. Current ifort "Intel(R) 64, Version 2021.1 Build 20201112_000000" uses the default(..) attribute. In case of default(shared), the compiler does not conform to 5.1 as far as I can see.

The following program demonstrates the problem (compile with ifort -qopenmp):

program omp_block

use OMP_LIB

!$omp parallel default(shared)
block
   integer :: i

   i = omp_get_thread_num()
!$omp barrier
   print *,i, omp_get_thread_num()
end block
!$omp end parallel

end program omp_block

 

As a side note, in the same section in the standard mentioned above, data-sharing attributes for associate constructs within openmp blocks was also clarified (there have been questions regarding this in this forum a year ago or so). The relevant passage is:

An associate name that may appear in a variable definition context is shared if its association occurs outside of the construct and otherwise it has the same data-sharing attribute as the selector with which it is associated.

Unfortunately, the formulation is somewhat confusing. If the selector is somehing like array(i) where array is shared and i is private. What is the relevant data-sharing attribute? That of array or that of i?

Making "a" in "associate(a => array(i))" shared because array was shared does not make much sense, does it? Here is a small contrived piece of code to show the problem (again compile with ifort -qopenmp). The code shows that ifort uses the data sharing attribute of array "a".

program omp_assoc

use OMP_LIB

integer :: i
integer, dimension(:), allocatable :: a

allocate(a(1:omp_get_max_threads()), source=-1)

!$omp parallel default(shared) private(i)
i = omp_get_thread_num()
associate(k => a(i))
!$omp barrier
   k = i
!$omp barrier
   print *, k, a(i), i
end associate
!$omp end parallel

deallocate(a)

end program omp_assoc

 Any thoughts about that?

0 Kudos
1 Solution
Barbara_P_Intel
Moderator
527 Views

I filed CMPLRIL0-33561 for the issue with the BLOCK and private/shared variables. I get the right answers if I change "default(shared)" to "default(private).

I'll keep you posted on the progress to a fix for these 2 bugs.


View solution in original post

14 Replies
Johannes_Rieke
New Contributor III
658 Views

Insteresting, OpenMP 5.1 supports now officially SUBMODULES and BLOCK constructs.

Still open since over a year: Which Fortran (2008/2018) features are supported by OneAPI Fortran compilers in OpenMP blocks (ifort and ifx, old question is found here).

@ Intel team/ Barbara: Do you have an update to this question?

Similar, this page for compatability to OpenMP 5.1 respectively 5.0 is not updated for OneAPI. An update would be welcome.

I suggest, that these information could help in this current question, too.

Johannes_Rieke
New Contributor III
655 Views

your second example fails to run if one activates bounds checking:

D:\02_Fortran\99_test\OneAPI2021_OMP_test>ifort /traceback /check:bounds /Qopenmp omp_test.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.1.2 Build 20201208_000000
Copyright (C) 1985-2020 Intel Corporation.  All rights reserved.

Microsoft (R) Incremental Linker Version 14.28.29335.0
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:omp_test.exe
-subsystem:console
-incremental:no
-defaultlib:libiomp5md.lib
-nodefaultlib:vcomp.lib
-nodefaultlib:vcompd.lib
omp_test.obj

D:\02_Fortran\99_test\OneAPI2021_OMP_test>omp_test
forrtl: severe (408): fort: (11): Subscript #1 of the array A has value 0 which is less than the lower bound of 1

Image              PC                Routine            Line        Source
omp_test.exe       00007FF7490061EC  Unknown               Unknown  Unknown
omp_test.exe       00007FF74900140B  MAIN__                     12  omp_test.f90
libiomp5md.dll     00007FFB34C238F3  Unknown               Unknown  Unknown
libiomp5md.dll     00007FFB34B74047  Unknown               Unknown  Unknown
libiomp5md.dll     00007FFB34B75C14  Unknown               Unknown  Unknown
libiomp5md.dll     00007FFB34B2EF6B  Unknown               Unknown  Unknown
omp_test.exe       00007FF74900120D  MAIN__                     10  omp_test.f90
omp_test.exe       00007FF7490510FE  Unknown               Unknown  Unknown
omp_test.exe       00007FF7490514BC  Unknown               Unknown  Unknown
KERNEL32.DLL       00007FFBA99D37E4  Unknown               Unknown  Unknown
ntdll.dll          00007FFBABFECB61  Unknown               Unknown  Unknown

 

Have you had activated checks?

Johannes_Rieke
New Contributor III
653 Views

Changing line 11

i = omp_get_thread_num()+1

fixes this.

This is the result then for my 16 thread CPU:

D:\02_Fortran\99_test\OneAPI2021_OMP_test>omp_test
           6          -1          12
           6          -1           4
           6          -1          13
           6           6          16
           6          -1          11
           6          -1           3
           6          -1           5
           6          -1           6
           6          -1          14
           6          -1          10
           6          -1           1
           6          -1           2
           6          -1           8
           6          -1           7
           6          -1          15
           6          -1           9

 

Martin1
New Contributor I
650 Views

You are right, thanks for spotting this. I have a macro _OMP_THREADS_NUM_ which does add the 1 automatically for just that reason...

Martin1
New Contributor I
620 Views

I am not sure who marked this thread as solved?! (The small bug was just a mistake when copying the code into the forum.) The second question about interpretation of the standard regarding data-sharing attributes of a selector if the selector consists of shared as well as private part has not been touched so far. Moreover, questions by Johannes_Rieke and myself about supported features (in particular openmp 5.1 and sharing-attributes for block within a parallel region) are still open as well.

Barbara_P_Intel
Moderator
604 Views

I'll answer the easy questions/comments first while I research the rest.


I'm glad SOMEONE reads The Survey of OpenMP Features article. It's on my TO DO list to update for oneAPI.


There is an separate article regarding OpenMP and Fortran Standards features that are currently implemented in ifx, https://software.intel.com/content/www/us/en/develop/articles/fortran-language-and-openmp-features-i....


As with earlier versions of the OpenMP and Fortran Standards new features will be added over time, including OpenMP 5.1.



jimdempseyatthecove
Black Belt
598 Views

IMHO

Associate(x=>y)

the "x" should (must) be located on the stack of the calling context.
When not in parallel region in procedure this would be the procedures stack (of the calling context)
When in parallel region of a procedure, then this wold be the thread's stack.

It makes no sense to have this shared inside a parallel region...
... because x does not exist prior to the Associate.

Note, (this may be fixed), there is/was an issue when you used a default(none), the compiler would complain that x was neither shared nor private. I am not sure of the behavior about block declared variables (not named outside parallel region) as to if the compiler complains or not. The hack fix was to declare a same named variable in the outer context of the parallel region.

Jim Dempsey

Steve_Lionel
Black Belt Retired Employee
593 Views

Jim, x is not its own thing - it is sort of a "view" into y.  It makes no sense to me to have the "locality" of the associating entity different from that of the selector.

jimdempseyatthecove
Black Belt
576 Views

case 1

Integer :: X
Real :: Y(10)

associate(x => Y(5:6))
...
end associate

In the above, inside the associate, x is a "view" into Y

case 2

! Integer :: X ! *** no X in outer scope
Real :: Y(10)

associate(x => Y(5:6))
...
end associate

In the above, inside the associate, x is a "view" into Y

Now consider case 3

! Integer :: X ! *** no X in outer scopt
Real :: Y(10)

!$omp parallel, default(none), shared(Y)
associate(x => Y(5:6))
...
end associate
...
!$omp end parallel

In the above, OpenMP balks at X not being shared nor private

--------- the above is one issue -----------

Separate issue:

case 1

Integer :: X
Real :: Y(10)

!$omp parallel, default(none), shared(X, Y)
foo = foo * X ! use shared integer X
...
associate(x => Y(omp_get_thread_num()))
... ! X is no longer the shared integer :: X
... ! X is now a REAL cell of Y *** but is it shared or private (this should be private)
end associate
...
!$omp end parallel

The above of it makes a difference in the "locality" of X (of each X).

Jim Dempsey

Martin1
New Contributor I
564 Views

Technically a "view" must be somehow realised, e.g. as a pointer to the memory location of the selector, as a class or array descriptor etc. This data needs to be stored somewhere, at best temporarily in a register, but generally on some stack. And that should be on the thread-private stack (so kind of thead-private). As Jim has noted, it just does not make sense to have this view description data be shared. On the other side the selector itself should not change its data-sharing attribute, as stated in omp5.1 standard.

In my example above (with the output provided by Johannes) with associate(k=>a(i)), the whole of array a should remain shared as is indeed done by ifort. However, the last thread which creates the view "k", deteremines it for all threads (as the view data is not shared), After the barrier, all threads write to the same array element a(i_view_of_last_thread), where the last thread to write, determines the value of this array element. The expected result should be a(i)=i for all 1<=i<=num_threads. In the given ouput, thread 16 created the view, thread 6 wrote last.

Martin1
New Contributor I
563 Views

Edit: "... which creates the view "k", deteremines it for all threads (as the view data *is shared*)

Barbara_P_Intel
Moderator
529 Views

I confirmed that there are no new OpenMP features in ifort 2021.1.1 or 2021.1.2.

I filed a bug (CMPLRLLVM-25539) regarding omp_associate.F90. I get similar results with ifort and ifx.

Next up ... omp_block.F90.


Barbara_P_Intel
Moderator
528 Views

I filed CMPLRIL0-33561 for the issue with the BLOCK and private/shared variables. I get the right answers if I change "default(shared)" to "default(private).

I'll keep you posted on the progress to a fix for these 2 bugs.


View solution in original post

Martin1
New Contributor I
520 Views
Thanks a lot. I have to admit that I did not consider the possibility, that a construct from F03 or F08 standard took more than 10 years to make its way into the openmp standard (where in the meantime lots of far more advanced stuff was added...).
Reply