My code is in a stable version now and I would like to enable at least the O1 optimization level to gain speed. However, I have found a really strange behaviour with a MPI command inside a loop with -O1.
In a preprocessing procedure, each MPI process needs to speak with the others (not necessarily all, that what the SpeakWith
array is for) to exchange the number of cells they are dealing with (cpt
). That is the goal of the following piece of code :
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
I have deliberately added some debugging write
commands. When I compile and execute with no optimization flag, everything is fine. With the -O1 flag, I get, for 2 MPI processes :
BEFORE 1
BEFORE 1
AFTER 1
AFTER 0
As you can see, the index loop has been changed during the MPI command. The i
variable has been declared with a user-defined kind USER_INT
declared in a module :
integer, parameter :: USER_INT = SELECTED_INT_KIND(9)
cpt
and SpeakWith
have the same kind
I am suspecting a loop optimization that has been activated with the O1 flag, but still I'm stunned that the compiler has modified my code and let such a serious error occurred.
EDIT : A program to debug as requested that runs exactly in the same way than in my code.
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