mpi_shared内存的想法是在进程之间创建一个窗口,此想法对于其中一个进程具有共享内存的节点中的进程是可行的,但是也可以为2之间的进程创建一个窗口节点?我的意思是在节点1和节点2的所有进程之间创建一个窗口? 例如我有2个节点,每个节点有4个进程。 我有一个简单的代码,其中我在一个节点中使用了mpi_shared_memory(在4个进程中),每个进程都会更新2d数组的一部分(此数组在代码中称为矩阵),然后,所有进程都可以直接访问这个共享数组。 我的意思是在该例程结束时,每个过程都将看到数组的完整版本。
此代码适用于单个节点,但我想知道如何在2个节点(8个进程中)中获得相同的结果?
program mpi_shared
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_PTR, C_F_POINTER
use mpi
implicit none
integer :: win,hostcomm,hostrank
INTEGER(KIND=MPI_ADDRESS_KIND) :: windowsize
INTEGER :: disp_unit,my_rank,ierr,total, i
TYPE(C_PTR) :: baseptr,baseptr2
integer, POINTER :: matrix(:,:)
integer,allocatable :: arrayshape(:)
call MPI_INIT( ierr )
call MPI_COMM_RANK(MPI_COMM_WORLD,my_rank, ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD,total,ierr)
CALL MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_SHARED, 0,&
MPI_INFO_NULL, hostcomm,ierr)
CALL MPI_Comm_rank(hostcomm, hostrank,ierr)
allocate(arrayshape(2))
arrayshape=[4,3]
if (hostrank == 0) then
windowsize = int(10**4,MPI_ADDRESS_KIND)*8_MPI_ADDRESS_KIND
else
windowsize = 0_MPI_ADDRESS_KIND
end if
disp_unit = 1
CALL MPI_Win_allocate_shared(windowsize, disp_unit, MPI_INFO_NULL,&
hostcomm, baseptr, win, ierr)
if (hostrank /= 0) then
CALL MPI_Win_shared_query(win, 0, windowsize, disp_unit, baseptr,&
ierr)
end if
CALL C_F_POINTER(baseptr, matrix,arrayshape)
if (hostrank == 0) then
matrix=0
endif
call MPI_WIN_FENCE(0, win, ierr)
if (hostrank == 0) then
matrix(1,:)=1
elseif (hostrank == 1) then
matrix(2,:)=2
elseif (hostrank == 2) then
matrix(3,:)=3
elseif (hostrank == 3) then
matrix(4,:)=4
endif
call MPI_WIN_FENCE(0, win, ierr)
write(*,*) 'iam rank',hostrank,'with matrix= ',matrix
call MPI_WIN_FENCE(0, win, ierr)
call MPI_BARRIER(MPI_COMM_WORLD,ierr)
call MPI_Win_free(win,ierr)
call MPI_FINALIZE(IERR)
end program
答案 0 :(得分:1)
原则上,非常聪明的MPI实现可以通过提供一个软件层来覆盖底层硬件的细节来完成这种事情。但是实际上,从定义上讲,没有节点是内存的不相连区域,因此共享内存窗口仅限于单个节点。而且,如果默认情况下使用MPI进行编程,则您确实应该考虑分布式对象,这在大多数情况下会导致代码更具可伸缩性。