首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用滑动访问的MPI共享内存通信

问使用滑动访问的MPI共享内存通信
EN

Stack Overflow用户
提问于 2019-08-07 12:01:31
回答 1查看 190关注 0票数 0

我有两个关于使用mpi共享内存通信的问题。

1)如果我的MPI级别是唯一写入窗口的级别,那么是否有必要使用mpi_win_lock和mpi_win_unlock?我知道我的应用程序永远不会让其他人试图写到那个窗口。它们只读取窗口的内容,而我确保它们是在MPI_BARRIER之后读取的,因此窗口的内容已经更新。

2)在我的应用程序中,我有一个MPI级别,它分配一个共享窗口,需要由1:N其他MPI级别读取。

MPI级别1只应改为: rma(1:10)

MPI等级2只应改为rma(11:20)。

MPI等级N只应改为rma(10*(N1)+1:10*N)

目前,所有1到N级别都在查询整个共享窗口,即使用MPI_WIN_SHARED_QUERY的大小"10*N“。

我要问的是,是否可以应用MPI_WIN_SHARED_QUERY函数,使MPI级别1只能从1:10访问窗口,从11:20访问2级等等。

这样,每个级别都可以从1:10进行本地访问,但它们引用的是共享窗口的不同块吗?这个是可能的吗?

非常感谢!

更新

根据下面的答案,我似乎做了我想做的事。但是它在使用MPI_WIN_SHARED_QUERY时不起作用。

但是,我不明白本地指针是如何自动指向数组的不同部分的。它怎么知道怎么做。您正在做的唯一一件事是执行大小为c_f_pointer的nlocal=5调用,它如何知道,例如,rma 3级必须从16-20开始访问5个位置。我真的不清楚,我担心它是否可以携带,即我可以依赖它吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-11 15:31:13

首先,我建议使用MPI_Win_fence进行同步,而不是使用MPI_Barrier --这可以确保像屏障一样在时间上同步,但也可以确保窗口上的所有操作都是可见的(例如,写入应该被刷新到内存中)。

如果您使用MPI_Win_allocate_shared(),那么您将自动实现您想要的结果--每个级别都会得到一个指向其本地部分的指针。但是,内存是连续的,所以您可以通过对数组元素进行过索引/下标来访问所有内存(您只需使用普通的Fortran指针来指向纯粹按秩0分配的数组的一个分段,但我认为MPI_Win_allocate_shared()更优雅)。

下面是一些说明这一点的代码--创建了一个共享数组,由级别0初始化,但由所有级别读取。

这在我的笔记本电脑上似乎还不错:

代码语言:javascript
复制
me@laptop:~$ mpirun -n 4 ./rmatest
 Running on            4  processes with n =           20
 Rank            2  in COMM_WORLD is rank            2  in nodecomm on node laptop
 Rank            3  in COMM_WORLD is rank            3  in nodecomm on node laptop
 Rank            0  in COMM_WORLD is rank            0  in nodecomm on node laptop
 Rank            1  in COMM_WORLD is rank            1  in nodecomm on node laptop
 rank, noderank, arr:            0           0           1           2           3           4           5
 rank, noderank, arr:            3           3          16          17          18          19          20
 rank, noderank, arr:            2           2          11          12          13          14          15
 rank, noderank, arr:            1           1           6           7           8           9          10

尽管在一般情况下,这将只适用于同一共享内存节点中的所有级别。

代码语言:javascript
复制
program rmatest

  use iso_c_binding, only: c_ptr, c_f_pointer

  use mpi

  implicit none

! Set the size of the road

  integer, parameter :: nlocal = 5
  integer :: i, n
  integer, dimension(MPI_STATUS_SIZE) :: status

  integer, pointer, dimension(:) :: rma

  integer :: comm, nodecomm, nodewin
  integer :: ierr, size, rank, nodesize, noderank, nodestringlen
  integer(MPI_ADDRESS_KIND) :: winsize
  integer :: intsize, disp_unit
  character*(MPI_MAX_PROCESSOR_NAME) :: nodename
  type(c_ptr) :: baseptr

  comm = MPI_COMM_WORLD

  call MPI_Init(ierr)

  call MPI_Comm_size(comm, size, ierr)
  call MPI_Comm_rank(comm, rank, ierr)

  ! Create node-local communicator

  call MPI_Comm_split_type(comm, MPI_COMM_TYPE_SHARED, rank, &
                           MPI_INFO_NULL, nodecomm, ierr)

  ! Check it all went as expected

  call MPI_Get_processor_name(nodename, nodestringlen, ierr)
  call MPI_Comm_size(nodecomm, nodesize, ierr)
  call MPI_Comm_rank(nodecomm, noderank, ierr)

  n = nlocal*nodesize

  if (rank == 0) then

     write(*,*) "Running on ", size, " processes with n = ", n

  end if

  write(*,*) "Rank ", rank," in COMM_WORLD is rank ", noderank, &
             " in nodecomm on node ", nodename(1:nodestringlen)

  call MPI_Type_size(MPI_INTEGER, intsize, ierr)

  winsize = nlocal*intsize

  ! displacements counted in units of integers

  disp_unit = intsize

  call MPI_Win_allocate_shared(winsize, disp_unit, &
       MPI_INFO_NULL, nodecomm, baseptr, nodewin, ierr)

  ! coerce baseptr to a Fortran array: global on rank 0, local on others

  if (noderank == 0) then

     call c_f_pointer(baseptr, rma, [n])

  else

     call c_f_pointer(baseptr, rma, [nlocal])

  end if

  ! Set the local arrays

  rma(1:nlocal) = 0

  ! Set values on noderank 0

  call MPI_Win_fence(0, nodewin, ierr)

  if (rank == 0) then
     do i = 1, n
        rma(i) = i
     end do
  end if

  call MPI_Win_fence(0, nodewin, ierr)

  ! Print the values  

  write(*,*) "rank, noderank, arr: ", rank, noderank, (rma(i), i=1,nlocal)

  call MPI_Finalize(ierr)

end program rmatest
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57394050

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档