我在滥用 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_write
和 mpi_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.
您的派生数据类型不符合(至少)排名 1
和 3
的要求
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 版本将在不久的将来出错。
我有一段使用 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_write
和 mpi_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.
您的派生数据类型不符合(至少)排名 1
和 3
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 版本将在不久的将来出错。