我在滥用 mpi_file_write_all 吗?

Am I misusing mpi_file_write_all?

我有一段使用 MPI-IO 在文件中写入数据的代码。当我使用 mpi_file_write 时效果很好,但如果我切换到集体 mpi_file_write_all,我会得到错误的结果。我是否必须改变不仅仅是调用写入函数才能使用集体写入例程?

mpi_file_write 文件包含预期的结果,4 行格式为“1 2 3 4”。

$od -f TEST  
0000000               1               2               3               4  
*  
0000100  

但是 mpi_file_write_all 结果文件不同:数据顺序错误:

$od -f TEST  
0000000               1               1               2               3  
0000020               2               4               3               4  
0000040               1               2               1               3  
0000060               2               3               4               4  
0000100  

所以我想知道我是否做错了什么。我错过了 mpi_file_writempi_file_write_all 之间的区别吗?

我使用的是 OpenMPI 3.0 版本。

      PROGRAM INDEXED
      USE MPI
      IMPLICIT NONE
      REAL :: A(4)
      INTEGER :: INDEXTYPE,FH,IERR,L,N
      INTEGER(KIND=MPI_OFFSET_KIND) :: OFFSET
      CHARACTER(LEN=MPI_MAX_LIBRARY_VERSION_STRING) :: VERSION

      N=4
      A(1)=1.0
      A(2)=2.0
      A(3)=3.0
      A(4)=4.0

      CALL MPI_INIT(IERR)
      CALL MPI_GET_LIBRARY_VERSION(VERSION,L,IERR)
      WRITE(*,*)TRIM(VERSION)
      CALL CREATE_TYPE(INDEXTYPE,N)

      CALL MPI_FILE_OPEN(MPI_COMM_WORLD, "TEST",
     &  MPI_MODE_RDWR+MPI_MODE_CREATE, MPI_INFO_NULL,FH,IERR)
      CALL MPI_CHECK_CALL(IERR)

      OFFSET=0
      CALL MPI_FILE_SET_VIEW(FH, OFFSET,MPI_REAL,
     &                       INDEXTYPE,'NATIVE',
     &                       MPI_INFO_NULL, IERR)
      CALL MPI_CHECK_CALL(IERR)

      CALL MPI_FILE_WRITE(FH,A,N,MPI_REAL,
     &                    MPI_STATUS_IGNORE,IERR)
      !CALL MPI_FILE_WRITE_ALL(FH,A,N,MPI_REAL,
      !&                        MPI_STATUS_IGNORE,IERR)

      CALL MPI_CHECK_CALL(IERR)
      CALL MPI_FILE_CLOSE(FH,IERR)
      CALL MPI_CHECK_CALL(IERR)

      CALL MPI_FINALIZE(IERR) 
      END PROGRAM INDEXED

      SUBROUTINE CREATE_TYPE(DATARES_TYPE,N)
        USE MPI
        IMPLICIT NONE
        INTEGER, INTENT(OUT) :: DATARES_TYPE
        INTEGER, INTENT(IN) :: N
        INTEGER :: IERR, MY_RANK
        INTEGER, ALLOCATABLE :: BLOCKLENS(:), DISPLACEMENTS(:)
        ALLOCATE(BLOCKLENS(N))
        ALLOCATE(DISPLACEMENTS(N))
        BLOCKLENS = 1
        CALL MPI_COMM_RANK(MPI_COMM_WORLD, MY_RANK, IERR)
        IF(MY_RANK==0)THEN
          DISPLACEMENTS(1)=0
          DISPLACEMENTS(2)=5
          DISPLACEMENTS(3)=2
          DISPLACEMENTS(4)=3
        ENDIF
        IF(MY_RANK==1)THEN
          DISPLACEMENTS(1)=4
          DISPLACEMENTS(2)=1
          DISPLACEMENTS(3)=6
          DISPLACEMENTS(4)=7
        ENDIF
        IF(MY_RANK==2)THEN
          DISPLACEMENTS(1)=8
          DISPLACEMENTS(2)=9
          DISPLACEMENTS(3)=14
          DISPLACEMENTS(4)=11
        ENDIF
        IF(MY_RANK==3)THEN
          DISPLACEMENTS(1)=12
          DISPLACEMENTS(2)=13
          DISPLACEMENTS(3)=10
          DISPLACEMENTS(4)=15
        ENDIF

        CALL MPI_TYPE_INDEXED(N, BLOCKLENS, DISPLACEMENTS,
     &                        MPI_REAL, DATARES_TYPE, IERR)
        CALL MPI_CHECK_CALL(IERR)
        CALL MPI_TYPE_COMMIT(DATARES_TYPE, IERR)
        CALL MPI_CHECK_CALL(IERR)
        DEALLOCATE(BLOCKLENS)
        DEALLOCATE(DISPLACEMENTS)
      END SUBROUTINE

      SUBROUTINE MPI_CHECK_CALL(IERR)
        USE MPI
        IMPLICIT NONE
        INTEGER, INTENT(IN) :: IERR
        INTEGER :: NERR, RESULTLEN
        CHARACTER(LEN=MPI_MAX_ERROR_STRING) :: SERR
        IF(IERR /= MPI_SUCCESS) THEN
          CALL MPI_ERROR_STRING(IERR,SERR,RESULTLEN,NERR)
          WRITE(*,*)SERR
          CALL BACKTRACE
        END IF
      END SUBROUTINE

您确实没有正确使用 MPI_File_set_view()。 来自标准(MPI 3.1,第 13.3 章)(感谢 Wei-keng Liao 的指点)

An etype (elementary datatype) is the unit of data access and positioning. It can be any MPI predefined or derived datatype. Derived etypes can be constructed by using any of the MPI datatype constructor routines, provided all resulting typemap displacements are non-negative and monotonically nondecreasing.

您的派生数据类型不符合(至少)排名 13

的要求

FWIW,

  • 如果使用来自 MPICH 的 ROM-IO,程序会崩溃,我在 https://github.com/pmodels/mpich/issues/2915 报告了这个问题,而 ROM-IO 应该 return 带有错误消息。
  • 程序 crashes/hangs 使用最新的 Open MPI v3.0.x(默认使用 ompio),但在 v3.1.x 和 master 分支上运行良好。请注意,正确的修复是修复您的代码,未来的 Open MPI 版本将在不久的将来出错。