如何使用无序的位移数组创建mpi_type_indexed

时间:2017-11-30 10:04:59

标签: fortran mpi mpi-io

我有一些数据要写在文件中的特定位置。每个位置都以阵列形式提供给我。目前我通过使用mpi_file_write_at将每个变量写入特定位置来编写它们。位置既不是连续的,也不是有序的,所以程序来回进入文件。

DO I=1,SIZE(VALUES)
  POS=ALL_POS(I)
  VAL=VALUES(I)
  CALL MPI_FILE_WRITE_AT(FH,POS,VAL,1,MPI_REAL,MPI_STATUS_IGNORE,IERR)
END DO

但我知道推荐的获得良好性能的方法是使用文件视图和集体写入例程。所以我认为解决方案是创建一个mpi_type_indexed,其数组ALL_POS用作置换数组。然后使用此类型用mpi_file_set_view描述文件。但是当我这样做时,每次没有订购数组时程序都会崩溃。

下面是一个重现我的问题的最小例子。程序编译但是段错误。如果将DISPLACEMENTS(3)的值更改为优于DISPLACEMENTS(2)的值,程序将运行没有任何问题。 (对于某些低于DISPLACEMENTS(2)的值,它似乎也有效,例如99)

那么可以创建一个带有无序位移数组的索引类型并将其用作视图吗?我在文档中找不到任何相反的说法。唯一的限制似乎是blocklenghts数组,它必须只是正整数。

  PROGRAM INDEXED
    USE MPI
    IMPLICIT NONE
    REAL :: A(0:15)
    INTEGER :: INDEXTYPE,FH,IERR
    DATA A /1.0,  2.0,  3.0,  4.0,  5.0,  6.0,  7.0,  8.0,
 &          9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0 /
    INTEGER(KIND=MPI_OFFSET_KIND) :: OFFSET

    CALL MPI_INIT(IERR)
    CALL CREATE_DATARES_TYPE(INDEXTYPE)

    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,SIZE(A),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_DATARES_TYPE(DATARES_TYPE)
    USE MPI
    IMPLICIT NONE
    INTEGER, INTENT(OUT) :: DATARES_TYPE
    INTEGER :: IERR, N
    INTEGER, ALLOCATABLE :: BLOCKLENS(:), DISPLACEMENTS(:)
    N=3
    ALLOCATE(BLOCKLENS(N))
    ALLOCATE(DISPLACEMENTS(N))
    BLOCKLENS(1) = 1
    BLOCKLENS(2) = 3
    BLOCKLENS(1) = 1
    DISPLACEMENTS(1) = 2
    DISPLACEMENTS(2) = 100
    DISPLACEMENTS(3) = 51

    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

1 个答案:

答案 0 :(得分:0)

派生数据类型构造中存在错误。

应该是

BLOCKLENS(1) = 1
BLOCKLENS(2) = 3
BLOCKLENS(3) = 1

而不是

BLOCKLENS(1) = 1
BLOCKLENS(2) = 3
BLOCKLENS(1) = 1

然后,测试适用于ompioromio314组件。