다른 서브 루틴을 포함하는 서브 루틴을 포함하는 모듈이 있습니다. 외부 서브 루틴에는 내부 서브 루틴을 호출하는 병렬 OpenMP 영역이 있습니다. 코드가 컴파일되지 않고 오류없이 실행되지만 결과가 올바르지 않습니다.OpenMP 지역에서 내부 서브 루틴 호출
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
내가 인텔 디버거 idb
를 실행하는 경우, 그것은 나에게 subroutine b
내부 SIGSEGV를 표시합니다. 이제 subroutine a
안에있는 subroutine b
의 내용을 수동으로 바꾸고 OMP 절을 그대로 유지하면 SIGSEGV 오류가 발생하지 않고 결과가 정확합니다.
편집 : 전체 코드는 여기에 있습니다 : https://github.com/mikolchon/cfd/blob/master/cfd2/calcRHS.f90 그것은 오일러 유체 방정식을 해결하기 위해 서브 루틴을 포함하는 모듈입니다. 나는 idb
를 실행하면, 다음을 줄 것이다 :
EDIT2을 : 그냥이 오류를 재현 작은 예를 작성하는 관리 :
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
이 프로그램은 1.000000 1.000000 1.000000 1.000000 1.000000
을 인쇄해야합니다. OpenMP를
ifort name.f90 -openmp -check bounds -traceback -O0
없이 잘 작동 - - (컴파일러 14.0.2 ifort입니다)
ifort name.f90 -check bounds -traceback -O0
바운드에서 배열 인덱스를 제공합니다 다음은 서로 다른 컴파일 플래그 나는 시도했다.
ifort name.f90 -openmp -check bounds -traceback
-O0
를 사용할 때 오류가 표시됩니다, 그래서 기본적으로
을 작동합니다. 그렇다고해서
-O0
을 사용하지 않으면 오류가 없다는 것을 의미하지는 않습니다 (원래 코드가 잘못된 결과를 나타 내기 때문에이 말을합니다). 내가 명시 적으로 인덱스
i
를 전달하는 경우 또한, 즉 :
이
....
call sub1(i)
....
contains
subroutine sub1(i)
integer i
....
다음 -O0
컴파일, 다시 작동합니다. 그래서 내 질문에 OpenMP가 변수 i
을 하위 서브 루틴에 상속하는 데 어려움을 겪고 있다는 것입니다.
나머지 코드를 추가하지 않으면 대답 할 수 없습니다. 어쩌면'b'는 실 금고가 아니지만 누가 알 수 있습니다. –
어림짐작은 코드가 어떻게 보이는지 몇 문장으로 설명해야한다면, 설명하지 말고 코드를 게시하십시오. –
컴파일러 옵션은 무엇입니까? '-openmp'는'재귀 적 (recursive) '을 시행해야하지만 다른 옵션들도이를 망칠 수 있습니다. –