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

Is it a bug in ifort 11.0.081 for linux by using OMP

yeg001
Beginner
421 Views

I make a program as follow. It worked fine. But it gaves wrong result if compiled with openmp.

Before call:ABCD
in subroutine, before parallel:ABCD
forrtl: severe (174): SIGSEGV, segmentation fault occurred

[cpp]subroutine para_test(get)
!$ use omp_lib
    implicit none
    character(len=*), intent(in) :: get
    write(*, *) "in subroutine, before parallel:", get
!$OMP parallel firstprivate(get)
!$OMP critical
    write(*, *)"string:", get
!$OMP end critical
!$OMP end parallel
    end subroutine para_test

program main
    implicit none
    character(len=10) :: get = "ABCD"
    write(*, *) "Before call:", get
    call para_test(get)
    stop
end[/cpp]

It seems the problem comes from the subroutine para_test(get), 'len=*'. If a explixit length was given(len=10) tocharacter variable, it is fine.
Thecharacter variable 'get' is a dummy argument in subroutine. It is not necessary to know the length of the character argument when the subroutine is compiled. So, i think that is a bug.
0 Kudos
1 Solution
Ron_Green
Moderator
421 Views
There is a partial fix for this coming in the version 11.1 compiler, which is currently in beta testing. I have confirmed the fix in this beta compiler. I modified your example a little to get more information out, note that the results are better, but there is still a new bug to enter:

[cpp]subroutine para_test(get)  
!$ use omp_lib  
    implicit none  
    character(len=*), intent(in) :: get  
    write(*, *) "in subroutine, before parallel:", get  
    write(*, *) "trimmed length is ", len_trim(get)
    write(*,* ) "len it ", len(get)
!$OMP parallel firstprivate(get)  
!$OMP critical  
    write(*, *)"string:", get  
!$OMP end critical  
!$OMP end parallel  
end subroutine para_test  
   
program main  
     implicit none  
     character(len=10) :: get = "ABCD"  
     write(*, *) "Before call:", get  
     call para_test(get)  
     stop  
end  


[/cpp]

And the 11.1 beta produces:

./omperr
Before call:ABCD
in subroutine, before parallel:ABCD
trimmed length is 4
len it 10
string:ABCD ??
string:ABCD ??
string:ABCD ??
string:ABCD ??
string:ABCD ??
string:ABCD ??
string:ABCD ??
string:ABCD ??


What's interesting is that the firstprivate appears to copy the string but we're losing the trimmed length. Adding a little more information inside the loop:


[cpp]!$OMP parallel firstprivate(get)  
!$OMP critical  
    write(*, *)"string:", get  
    write(*, *) "trimmed length is ", len_trim(get)
    write(*, *) "len get is ", len(get)
!$OMP end critical  
!$OMP end parallel  
[/cpp]
and the results:
[cpp]Before call:ABCD      
 in subroutine, before parallel:ABCD      
 trimmed length is            4
 len is          10
 string:ABCD    ??
 trimmed length is           10
 len get is           10
 string:ABCD    ??
 trimmed length is           10
 len get is           10
 string:ABCD    ??
 trimmed length is           10
 len get is           10
 string:ABCD    ??
 trimmed length is           10
 len get is           10
 string:ABCD    ??
 trimmed length is           10
 len get is           10
 string:ABCD    ??
 trimmed length is           10
 len get is           10
 string:ABCD    ??
 trimmed length is           10
 len get is           10
 string:ABCD    ??
 trimmed length is           10
 len get is           10
[/cpp]
so you see that the trimmed length information is not copied correctly for the firstprivate vars. I'll open a new bug on this.

ron

View solution in original post

0 Kudos
4 Replies
Ron_Green
Moderator
421 Views
I would agree, this does appear to be a bug. I will start a bug report.

ron
0 Kudos
Ron_Green
Moderator
422 Views
There is a partial fix for this coming in the version 11.1 compiler, which is currently in beta testing. I have confirmed the fix in this beta compiler. I modified your example a little to get more information out, note that the results are better, but there is still a new bug to enter:

[cpp]subroutine para_test(get)  
!$ use omp_lib  
    implicit none  
    character(len=*), intent(in) :: get  
    write(*, *) "in subroutine, before parallel:", get  
    write(*, *) "trimmed length is ", len_trim(get)
    write(*,* ) "len it ", len(get)
!$OMP parallel firstprivate(get)  
!$OMP critical  
    write(*, *)"string:", get  
!$OMP end critical  
!$OMP end parallel  
end subroutine para_test  
   
program main  
     implicit none  
     character(len=10) :: get = "ABCD"  
     write(*, *) "Before call:", get  
     call para_test(get)  
     stop  
end  


[/cpp]

And the 11.1 beta produces:

./omperr
Before call:ABCD
in subroutine, before parallel:ABCD
trimmed length is 4
len it 10
string:ABCD ??
string:ABCD ??
string:ABCD ??
string:ABCD ??
string:ABCD ??
string:ABCD ??
string:ABCD ??
string:ABCD ??


What's interesting is that the firstprivate appears to copy the string but we're losing the trimmed length. Adding a little more information inside the loop:


[cpp]!$OMP parallel firstprivate(get)  
!$OMP critical  
    write(*, *)"string:", get  
    write(*, *) "trimmed length is ", len_trim(get)
    write(*, *) "len get is ", len(get)
!$OMP end critical  
!$OMP end parallel  
[/cpp]
and the results:
[cpp]Before call:ABCD      
 in subroutine, before parallel:ABCD      
 trimmed length is            4
 len is          10
 string:ABCD    ??
 trimmed length is           10
 len get is           10
 string:ABCD    ??
 trimmed length is           10
 len get is           10
 string:ABCD    ??
 trimmed length is           10
 len get is           10
 string:ABCD    ??
 trimmed length is           10
 len get is           10
 string:ABCD    ??
 trimmed length is           10
 len get is           10
 string:ABCD    ??
 trimmed length is           10
 len get is           10
 string:ABCD    ??
 trimmed length is           10
 len get is           10
 string:ABCD    ??
 trimmed length is           10
 len get is           10
[/cpp]
so you see that the trimmed length information is not copied correctly for the firstprivate vars. I'll open a new bug on this.

ron
0 Kudos
Ron_Green
Moderator
421 Views
bug report number is DPD200120407
0 Kudos
jimdempseyatthecove
Honored Contributor III
421 Views

I think what is happening (someone from Intel pipe in to correct me)

is the length of GET is passed in to para_test as an unseen extra argument to the subroutine.
This length is not visible and not specifiable on the FIRSTPRIVATE and therefore not passed into the stack of the superflous thread(s) (non-team master thread). Try this:
[cpp]subroutine para_test(get)
!$ use omp_lib
    implicit none
    character(len=*), intent(in) :: get
integer :: len_get
len_get = LEN(get) ! or use LEN_TRIM write(*, *) "in subroutine, before parallel:", get !$OMP parallel firstprivate(get) shared(len_get) !$OMP critical write(*, *)"string:", get(1:len_get) !$OMP end critical !$OMP end parallel end subroutine para_test program main implicit none character(len=10) :: get = "ABCD" write(*, *) "Before call:", get call para_test(get) stop end[/cpp]

Jim Dempsey
0 Kudos
Reply