MPI_sendrecv使用-O1标志更改循环索引

时间:2016-08-16 14:47:10

标签: optimization fortran mpi compiler-flags

我的代码现在处于稳定版本,我想至少启用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)

cptSpeakWith具有相同类型

我怀疑使用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

0 个答案:

没有答案