在FORTRAN 90中使用MPI_Type_Create_Subarray

3

这与早期关于“使用MPI_Send/Recv在Fortran 90中处理多维数组块”的讨论有关。我的数组是实数类型的三维数组,例如5x5x5,即x(1:5,1:5,1:5)。如果我想要发送我的数组的以下部分:

x(2:3,2:5,4:5)

从0进程向1进程发送消息,我正在使用以下测试程序。
program mpi
implicit none
include "mpif.h"

integer :: ierr,myid,nprocs,status(mpi_status_size),i,j,k,&
&          starts(3),newsize(3),oldsize(3)
real    :: x(1:5,1:5,1:5),y(1:5,1:5,1:5),z(2:3,2:5,4:5)
integer :: arr

call mpi_init(ierr)
call mpi_comm_rank(mpi_comm_world,myid,ierr)
call mpi_comm_size(mpi_comm_world,nprocs,ierr)

if(myid == 0) then
  x = 0.0
  call random_number(x)
  starts = (/2,2,4/)
  newsize = (/2,4,2/)
  oldsize = (/5,5,5/)
  call mpi_type_create_subarray(3,oldsize,newsize,starts,mpi_order_fortran, &
  & mpi_real,arr,ierr)
  call mpi_type_commit(arr,ierr)
  call mpi_send(x,1,arr,1,1,mpi_comm_world,ierr)
  do i = 2,3
    do j = 2,5
      do k = 4,5
        print*,'#1',x(i,j,k)
      enddo
    enddo
  enddo
  print*,' '
else
  y = 0.0
  call mpi_recv(z,16,mpi_real,0,1,mpi_comm_world,status,ierr)
  do i = 2,3
    do j = 2,5
      do k = 4,5
        print*,'#2',z(i,j,k)
      enddo
    enddo
  enddo
endif

call mpi_finalize(ierr)

stop
end

我遇到了与“start”数组相关的运行时错误。它的元素必须是0或1。我错过了什么?这个的正确形式是什么?我没有找到使用FORTRAN的例子。

1个回答

2
标准规定array_of_starts(即你的starts)从0开始索引,而不是从1开始!因此,如果Fortran编号从1开始,则必须减去1。因此,你的starts数组应为(/ 1, 1, 3 /)
MPI 3.0标准,第4.1.3章中得知:
建议用户:在Fortran程序中,如果一个特定维度的子数组的起始坐标为N,并且数组索引从1开始,则该维度的array_of_starts条目为n-1。(建议到此结束。)

1
谢谢提供信息。如果一个数组从负索引开始,比如父数组x(-n:n,-m:m),我想发送块x(-2:0,:),现在应该是什么起始数组呢? - Madhurjya
2
@Madhurjya,从-n的偏移量为-2(-2)-(-n)= n-2。对于第二个维度,偏移量为0 - Hristo Iliev
谢谢Alexander和Hristo!你们的讨论对我帮助很大。 - Madhurjya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接