ufruf eines internen Unterprogramms innerhalb der OpenMP-Regi
Ich habe ein Modul, das eine Unterroutine enthält, die eine andere Unterroutine enthält. Das äußere Unterprogramm hat eine parallele OpenMP-Region, in der ich das innere Unterprogramm aufrufe. Der Code wird ohne Fehler kompiliert und ausgeführt, die Ergebnisse sind jedoch nicht korrekt.
module my_module
contains
subroutine a(...)
*...some variables*
!$OMP PARALLEL DO DEFAULT(PRIVATE) SHARED(...)
*...do some work*
call b(...)
!$OMP END PARALLEL DO
contains
subroutine b(...)
*...some variables*
*...do some work*
end subroutine b
end subroutine a
end my module
Wenn ich den Intel Debugger starteidb
, es wird mir ein SIGSEGV in @ zeigsubroutine b
. Wenn ich nun den Inhalt von @ manuell ersetsubroutine b
Innerhalbsubroutine a
Anstatt es aufzurufen und die OMP-Klauseln beizubehalten, wird kein SIGSEGV-Fehler ausgegeben, und die Ergebnisse sind jetzt korrekt.
BEARBEITEN Vollständiger Code ist hier:https: //github.com/mikolchon/cfd/blob/master/cfd2/calcRHS.f9 Es ist ein Modul, das eine Subroutine zum Lösen von Euler-Flüssigkeitsgleichungen enthält. Wenn ich das @ staridb
, es wird folgendes geben:
EDIT2: Habe gerade ein kleineres Beispiel geschrieben, das diesen Fehler reproduziert:
module some_module
implicit none
contains
subroutine sub0()
real :: a(5)
integer :: i
a(:) = 0
!$OMP PARALLEL DO DEFAULT(PRIVATE) SHARED(a)
do i = 1, 5
call sub1()
end do
!$OMP END PARALLEL DO
print*, a(:)
contains
subroutine sub1()
a(i) = a(i) + 1
end subroutine sub1
end subroutine sub0
end module some_module
program main
use some_module
implicit none
call sub0()
end program main
Das Programm sollte drucken1.000000 1.000000 1.000000 1.000000 1.000000
. Folgendes sind verschiedene Kompilierungsflags, die ich ausprobiert habe: (Compiler ist ifort 14.0.2)
ifort name.f90 -check bounds -traceback -O0
- funktioniert gut ohne OpenMP
ifort name.f90 -openmp -check bounds -traceback -O0
- gibt den Array-Index außerhalb der Grenzen aus.
ifort name.f90 -openmp -check bounds -traceback
- wird funktioniere
Also im Grunde wird der Fehler zeigen, wenn ich-O0
. Dies bedeutet jedoch nicht, dass der Fehler nicht auftritt, wenn ich @ nicht verwend-O0
(Ich sage das, weil mein ursprünglicher Code falsche Ergebnisse liefert). Auch, wenn ich den Index @ übergebi
explizit, das heißt:
....
call sub1(i)
....
contains
subroutine sub1(i)
integer i
....
und dann kompilieren mit-O0
, es wird wieder funktionieren. Mein Verdacht ist also, dass OpenMP Probleme hat, die Variable @ zu erbei
zu seinen untergeordneten Unterprogrammen.