MPI_Win_create导致的RMA基本问题,当大小为非零时,参数NULL基本指针中的Null指针无效

时间:2019-08-15 01:38:25

标签: fortran window mpi

我正在使用最新的MPICH稳定版本(3.3)在Fortran 90中工作

我想让MPI_Window在根进程上公开一个数组,而通信器中的所有其他进程都调用MPI_Get将数组复制到它们自己的“本地”副本中。

不幸的是,在MPI_Win_create(base,...)的非根进程中提供MPI_BOTTOM作为“ base”参数会导致错误

  

MPI_Win_create(192):MPI_Win_create(base = {nil),size = 0,disp_unit = 1275069467,MPI_INFO_NULL,MPI_COMM_WORLD,win = 0x7ffcb343d9fc)失败

     

MPI_Win_create(156):如果大小不为零,则参数NULL基本指针中的空指针无效

我一直在研究教科书示例pg。 61图3.2,使用高级MPI,消息传递界面的现代功能,Gropp,Hoefler,Thakur,Lusk。

除了kind(MPI_ADDRESS_KIND)外,我还应该使用替代MPI_BOTTOM吗?这是在不真正暴露其内部内存而只是访问另一个进程的内存的进程上初始化MPI_Window的正确方法吗?

很明显,将base的参数更改为已分配的(非null)数组是可行的,但这会更改后面的GET的行为,因此它不起作用(创建无效的内存访问)。

我不知道为什么运行时错误专门指出空基指针对于非零大小无效,因为我在对mpi_win_create(MPI_BOTTOM, 0, MPI_INTEGER, ...)的调用中明确地将大小指定为0。

这是我为本示例提供的所有代码。它设置缓冲区并尝试为每个进程创建窗口。在两次MPI_Fence调用之间有一个注释掉的部分,该部分是所有非根进程尝试进行GET的部分。

program main
  use mpi

  implicit none
  integer :: ierr, procno, nprocs, comm

  integer, allocatable :: root_data(:), local_data(:)
  integer, parameter :: root = 0, NUM_ELEMENTS = 10

  integer :: win

  integer :: i

  !======================================

  call mpi_init(ierr)
  comm = mpi_comm_world
  call mpi_comm_rank(comm, procno, ierr)
  call mpi_comm_size(comm, nprocs, ierr)

  !======================================
  if (procno .eq. root) then
    allocate(root_data(1:NUM_ELEMENTS))
    do i=1,NUM_ELEMENTS
      root_data(i) = i
    enddo

    call mpi_win_create(root_data, NUM_ELEMENTS, MPI_INTEGER, &
                        MPI_INFO_NULL, comm, win, ierr)
  else
    allocate(local_data(1:NUM_ELEMENTS))
    local_data = 0
    call mpi_win_create(MPI_BOTTOM, 0, MPI_INTEGER, &
                        MPI_INFO_NULL, comm, win, ierr)
  endif

  !======================================
  call mpi_win_fence(0, win, ierr)

  !if (procno .ne. root) then 
  !  call mpi_get(local_data, NUM_ELEMENTS, MPI_INTEGER, &
  !               root, 0, NUM_ELEMENTS, MPI_INTEGER, &
  !               win, ierr)
  !endif

  call mpi_win_fence(0, win, ierr)
  !======================================

  if (procno .ne. root) then
    print *, "proc", procno
    print *, local_data
  endif

  !======================================
  call MPI_Win_free(win, ierr)

  call mpi_finalize(ierr)
end program main

预期结果是每个进程都打印其local_data。版本,在这种情况下,由于MPI_Get已被注释掉,因此该版本应为十个0。

我遇到了运行时错误。

1 个答案:

答案 0 :(得分:0)

size的{​​{1}}参数的类型为MPI_Win_create()

然后,我能够同时使用MPICH 3.3和最新的Open MPI成功运行修改后的版本

INTEGER(KIND=MPI_ADDRESS_KIND)