【问题标题】:MPI_SCATTERV in Fortran - sending rows of 2D arrayFortran 中的 MPI_SCATTERV - 发送二维数组行
【发布时间】:2017-11-22 04:57:44
【问题描述】:

我有一个二维整数数组,我想将它的行发送到每个单独的进程。我假设行数(M = 5)不能被进程数(大小 = 4)整除,所以在我的情况下,进程 0 将获得额外的行。二维数组 A 的大小为 MxN (5x10)。

这是我的代码

PROGRAM SCATTERV_MATRIX

INCLUDE 'mpif.h'

integer :: rank, size, ierr, dest, src, tag     !MPI variables
integer :: status(MPI_STATUS_SIZE)              !MPI variables

INTEGER, PARAMETER :: N = 10                    !number of columns
INTEGER, PARAMETER :: M = 5                     !number of rows
INTEGER,  ALLOCATABLE, DIMENSION(:,:) :: A      !MxN matrix A

INTEGER :: NEWTYPE, RESIZEDTYPE                 !MPI derived data types
INTEGER,  ALLOCATABLE, DIMENSION(:,:) :: LOCAL
INTEGER,  ALLOCATABLE :: SENDCOUNTS(:), DISPLS(:)
INTEGER :: RECVCOUNT, NRBUF
INTEGER :: MMIN, MEXTRA, INTSIZE, K, I, J
INTEGER :: START, EXTENT                        !(KIND=MPI_ADRESS_KIND)

CALL MPI_INIT(ierr)
CALL MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
CALL MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr)

IF ( rank == 0 ) THEN                           !allocate and create 2Darray
     ALLOCATE( A (M, N) )
     K = 1
     DO I = 1, M
        DO J = 1, N
           A(I, J) = K
           K = K + 1
        END DO
     END DO
END IF

ALLOCATE( SENDCOUNTS(0:size-1), DISPLS(0:size-1) )

MMIN = M/size               !number of rows divided by number of processors
MEXTRA = MOD(M, size)       !extra rows

K = 0
DO I = 0, size-1
   IF (I < MEXTRA) THEN             !SENDCOUNTS=(/2,1,1,1/)
       SENDCOUNTS(I) = MMIN + 1
   ELSE
       SENDCOUNTS(I) = MMIN
   END IF
   DISPLS(I) = K                    !DISPLS=(/0,2,3,4/)
   K = K + SENDCOUNTS(I)
END DO

RECVCOUNT = SENDCOUNTS(rank)
ALLOCATE( LOCAL(RECVCOUNT,N) )

CALL MPI_TYPE_VECTOR(N, 1, M, MPI_INTEGER, NEWTYPE, ierr)
CALL MPI_TYPE_COMMIT(NEWTYPE, ierr)

START = 0
CALL MPI_TYPE_SIZE(MPI_INTEGER, INTSIZE, ierr)
EXTENT = 1*INTSIZE
CALL MPI_TYPE_CREATE_RESIZED(NEWTYPE, START, EXTENT, RESIZEDTYPE, ierr)
CALL MPI_TYPE_COMMIT(RESIZEDTYPE, ierr)

LOCAL(:, :) = 0

CALL MPI_SCATTERV(                        &
A, SENDCOUNTS, DISPLS, RESIZEDTYPE,       &        
LOCAL, RECVCOUNT*N, MPI_INTEGER,          &        
0, MPI_COMM_WORLD, ierr)

WRITE(*,*) rank, ':', LOCAL

CALL MPI_FINALIZE(ierr)

END PROGRAM SCATTERV_MATRIX

成功编译后,出现“程序异常 - 访问冲突”错误。我以前的所有 Fortan MPI 程序都运行良好。代码中一定有一些错误,可能在 MPI_SCATTERV 中。 我主要关注这个answer。我将不胜感激任何建议。谢谢。

【问题讨论】:

  • 如果你使用use mpi而不是include mpif.h,编译器可以做更多的检查并且发现sidentify几种错误

标签: fortran mpi


【解决方案1】:

您的代码有错误:

INTEGER :: START, EXTENT                        !(KIND=MPI_ADRESS_KIND)

这一行应该是:

INTEGER(KIND=MPI_ADDRESS_KIND) :: START, EXTENT

在 MPI 中,任何与内存地址或类似概念(如内存位移、文件大小、文件光标等)相关的东西都不能是普通整数。您在评论中如何获得这些信息,并且您还拼错了 MPI_ADDRESS_KIND。

Vladimir F 正确地指出您应该“使用 MPI”而不是“包含 'mpif.h'”。这使编译器有机会检查数据类型。例如,gfortran 给出以下错误信息:

test.f90:59:71:

 CALL MPI_TYPE_CREATE_RESIZED(NEWTYPE, START, EXTENT, RESIZEDTYPE, ierr)
                                                                       1
Error: There is no specific subroutine for the generic 

‘mpi_type_create_resized’ at (1)

【讨论】:

  • 你完全正确!谢谢你。修复这两个错误后,程序可以运行,但无法按预期运行。问题是进程0获取二维数组
  • 问题是进程0获取二维数组的形式如下: 1. 行是1 3 5 7 9 11 13 15 17 19而不是1 2 3 4 5 6 7 8 9 10。 2. 行是2 4 6 8 10 12 14 16 18 20 而不是11 12 13 14 15 16 17 18 19 20
  • 这是 MPI 中的预期顺序。阅读 MPI 如何划分数组。
猜你喜欢
  • 2013-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-20
  • 1970-01-01
  • 2011-07-27
相关资源
最近更新 更多