我的代码现在处于稳定版本,我想至少启用O1优化级别以获得速度。但是,我在-O1循环中发现了一个非常奇怪的MPI命令行为。
在预处理过程中,每个MPI进程需要与其他人(不一定是所有,SpeakWith
数组所用的对话)交换他们正在处理的单元格数量(cpt
)。这是以下代码的目标:
DO i=1,size(SpeakWith)
write(*,*) 'BEFORE',i
CALL MPI_SENDRECV(cpt(1+SpeakWith(i)),1,MPI_INTEGER,SpeakWith(i),ipas,n_recv,1,MPI_INTEGER,SpeakWith(i),ipas,MPI_COMM_WORLD,istat,ierr)
write(*,*) 'AFTER',i
END DO
我故意添加了一些调试write
命令。当我编译并执行没有优化标志时,一切都很好。使用-O1标志,我得到了2个MPI进程:
BEFORE 1
BEFORE 1
AFTER 1
AFTER 0
如您所见,在MPI命令期间已更改索引循环。已使用模块中声明的用户定义类i
声明USER_INT
变量:
integer, parameter :: USER_INT = SELECTED_INT_KIND(9)
cpt
和SpeakWith
具有相同类型
我怀疑使用O1标志激活的循环优化,但我仍然惊讶于编译器修改了我的代码并发生了如此严重的错误。
编辑:按要求调试的程序,其运行方式与我的代码完全相同。
PROGRAM test
USE MPI
IMPLICIT NONE
integer(kind=SELECTED_INT_KIND(9)) ::i=0,ierr=0,i_domain=0,nb_domain=1,n_recv=0,istat=0
integer(kind=SELECTED_INT_KIND(9)), dimension(:), allocatable :: SpeakWith
integer(kind=SELECTED_INT_KIND(9)), dimension(:), allocatable :: cpt
CALL MPI_INIT(ierr)
CALL MPI_COMM_RANK(MPI_COMM_WORLD,i_domain,ierr)
CALL MPI_COMM_SIZE(MPI_COMM_WORLD,nb_domain,ierr)
allocate(SpeakWith(1))
allocate(cpt(nb_domain))
cpt(:)=0
IF (i_domain==0) THEN
SpeakWith(1)=1
cpt(2)=13226
ELSE
SpeakWith(1)=0
cpt(1)=15566
END IF
DO i=1,size(SpeakWith)
write(*,*) 'BEFORE',i
CALL MPI_SENDRECV(cpt(1+SpeakWith(i)),1,MPI_INTEGER,SpeakWith(i),1,n_recv,1,MPI_INTEGER,SpeakWith(i),1,MPI_COMM_WORLD,istat,ierr)
write(*,*) 'AFTER',i
END DO
CALL MPI_FINALIZE(ierr)
END PROGRAM test