运行混合MPI / OpenMP时,我遇到以下问题 使用GNU和英特尔编译器以及OpenMPI编写代码。代码很大(商业) 写在Fortran。它使用GNU编译器编译并运行良好 但与英特尔编译器崩溃。
我在程序停止工作时监控了部分代码, 它具有以下结构:
subroutine test(n,dy,dy)
integer :: i
integer, parameter :: n=6
real*8 :: dx(num),dy(num), ener
ener=0.0
!$omp parallel num_threads(2)
!$omp do
do i=1,100
ener = ener + funct(n,dx,dy) + i
enddo
!$omp end do
!$omp end parallel
end subroutine test
并且函数funct具有以下结构:
real*8 function funct(n,dx,dy)
integer :: n
real*8 :: dx(*),dy(*)
funct = 0.0
do i=1,n
funct = funct + dx(i)+dy(i)
enddo
end function funct
具体而言,代码在funct
内停止(使用英特尔)。该
程序能够得到funct
的结尾,但只有一个线程
请求的两个能够返回值,我检查
通过打印线程号码。
这个问题仅针对英特尔编译器,对于GNU我没有得到 问题。
我发现,避免这个问题的一种方法是使用普通数组
在funct
内如下:
real*8 function funct(n,dx,dy)
integer :: n
real*8 :: dx(n),dy(n)
但我的观点是我不明白发生了什么。
我的猜测是,在英特尔的情况下,编译器不能
计算dx
内dy
和funct
的长度,但我是。{
不确定。我试着用一个小的重现这个问题
Fortran计划,但我无法看到这个问题。
欢迎任何评论。
一次更新:我消除了竞争条件的问题(这是 不是真正的问题,我在这里写的是代码的结构)。
我意识到子程序test
正在从另一个子程序中调用
upper
将dx,dy定义为指针:
subroutine upper
real*8,save,pointer :: dx(:)=>Null(), dy(:)=>Null()
....
call test(n,dx,dy)
...
end subroutine upper
我现在所做的是用allocatables替换指针:
subroutine upper
real*8,save,dimension(:),allocatable :: dx,dy
....
allocate(dx(n),dy(n))
call test(n,dx,dy)
...
end subroutine upper
我不知道英特尔的问题。我不知道会是什么 指针和可分配的区别。
感谢。