【问题标题】:Am I misusing mpi_file_write_all?我在滥用 mpi_file_write_all 吗?
【发布时间】:2018-06-14 03:42:25
【问题描述】:

我有一段使用 MPI-IO 在文件中写入数据的代码。当我使用mpi_file_write 时效果很好,但是如果我切换到集体mpi_file_write_all 我会得到错误的结果。除了对 write 函数的调用之外,我是否需要更改更多内容才能使用集体写作例程?

对于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

【问题讨论】:

  • 我已经缩进假设您正在编写固定格式的代码。我不知道您为什么选择为 Fortran 90+ 代码执行此操作,所以如果我弄错了,请回滚该编辑(并更正行继续等)。
  • 你能用mpirun —mca io romio314 ...再试一次吗?
  • @GillesGouaillardet 我使用您建议的选项尝试了此示例,但使用mpi_file_writempi_file_write_all 使示例崩溃。该消息抱怨“双重释放或损坏”,并且回溯在调用 mpi_file_write(或 mpi_file_write_all`)时定位崩溃。
  • @francescalus 好的,谢谢。我用我在修改我正在开发的软件时必须使用的相同风格编写了这个小例子,它使用了 fortran 的新功能,但遗憾的是有一个旧的 ident 风格。所以这个例子只是习惯的力量。
  • 好的,我去看看。

标签: fortran mpi openmpi mpi-io


【解决方案1】:

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

etype(基本数据类型)是数据访问的单位,并且 定位。它可以是任何 MPI 预定义或派生的数据类型。衍生的 可以使用任何 MPI 数据类型构造函数来构造 etypes 例程,前提是所有生成的类型图位移都是 非负且单调非减。

您的派生数据类型不满足(至少)等级13 的要求

FWIW,

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

【讨论】:

  • 非常感谢您的调查和您的时间!我要修复我的代码。
猜你喜欢
  • 2011-05-07
  • 2018-04-26
  • 2015-07-30
  • 2014-10-30
  • 2011-05-31
  • 2016-07-03
  • 2015-03-29
  • 2014-03-31
  • 2016-09-16
相关资源
最近更新 更多