Enclosed is a short (< 100 lines) fortran code example that uses shared memory.
It seems to me it behaves wrongly if openmpi is used.
Compiled with SGI/mpt , it gives the right result.
To fail, the code must be run on a single node.
It creates two groups of 2 processes each. Within each group memory is shared.
The error is that the two groups get the same memory allocated, but they should
not.
Tested with openmpi 1.8.4, 1.8.5, 1.10.2 and gfortran, intel 13.0, intel 14.0
all fail.
The call:
call MPI_Win_allocate_shared(win_size, disp_unit, MPI_INFO_NULL, comm_group,
cp1, win, ierr)
Should allocate memory only within the group. But when the other group
allocates memory, the pointers from the two groups point to the same address in
memory.
Could you please confirm that this is the wrong behaviour?
Best regards,
Peter Wind
program shmem_mpi
!
! in this example two groups are created, within each group memory is shared.
! Still the other group get allocated the same adress space, which it shouldn't.
!
! Run with 4 processes, mpirun -np 4 a.out
use mpi
use, intrinsic :: iso_c_binding, only : c_ptr, c_f_pointer
implicit none
! include 'mpif.h'
integer, parameter :: nsize = 100
integer, pointer :: array(:)
integer :: num_procs
integer :: ierr
integer :: irank, irank_group
integer :: win
integer :: comm = MPI_COMM_WORLD
integer :: disp_unit
type(c_ptr) :: cp1
type(c_ptr) :: cp2
integer :: comm_group
integer(MPI_ADDRESS_KIND) :: win_size
integer(MPI_ADDRESS_KIND) :: segment_size
call MPI_Init(ierr)
call MPI_Comm_size(comm, num_procs, ierr)
call MPI_Comm_rank(comm, irank, ierr)
disp_unit = sizeof(1)
call MPI_COMM_SPLIT(comm, irank*2/num_procs, irank, comm_group, ierr)
call MPI_Comm_rank(comm_group, irank_group, ierr)
! print *, 'irank=', irank, ' group rank=', irank_group
if (irank_group == 0) then
win_size = nsize*disp_unit
else
win_size = 0
endif
call MPI_Win_allocate_shared(win_size, disp_unit, MPI_INFO_NULL, comm_group, cp1, win, ierr)
call MPI_Win_fence(0, win, ierr)
call MPI_Win_shared_query(win, 0, segment_size, disp_unit, cp2, ierr)
call MPI_Win_fence(0, win, ierr)
CALL MPI_BARRIER(comm, ierr)! allocations finished
! print *, 'irank=', irank, ' size ', segment_size
call c_f_pointer(cp2, array, [nsize])
array(1)=0;array(2)=0
CALL MPI_BARRIER(comm, ierr)!
77 format(4(A,I3))
if(irank<num_procs/2)then
if (irank_group == 0)array(1)=11
CALL MPI_BARRIER(comm, ierr)
print 77, 'Group 0, rank', irank, ': array ', array(1), ' ',array(2)
CALL MPI_BARRIER(comm, ierr)!Group 1 not yet start writing
CALL MPI_BARRIER(comm, ierr)!Group 1 finished writing
print 77, 'Group 0, rank', irank, ': array ', array(1),' ',array(2)
if(array(1)==11.and.array(2)==0)then
print *,irank,' correct result'
else
print *,irank,' wrong result'
endif
else
CALL MPI_BARRIER(comm, ierr)
CALL MPI_BARRIER(comm, ierr)!Group 0 finished writing
print 77, 'Group 1, rank', irank, ': array ', array(1),' ',array(2)
if (irank_group == 0)array(2)=22
CALL MPI_BARRIER(comm, ierr)
print 77, 'Group 1, rank', irank, ': array ', array(1),' ',array(2)
if(array(1)==0.and.array(2)==22)then
print *,irank,' correct result'
else
print *,irank,' wrong result'
endif
endif
call MPI_Finalize(ierr)
end program