2017-11-30 7 views
2

ファイル内の特定の位置に書き込むデータがあります。それぞれの位置は配列で私に与えられます。現時点では、各変数を特定の位置にmpi_file_write_atで書き込むことで書きます。位置は連続的でも順序付けもされていないので、プログラムはファイル内を前後に移動します。mpi_type_indexedを順序付けされていない配列で作成する方法

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 

しかし、良いパフォーマンスを得るには、ファイルビューと一括書き込みルーチンを使用することをお勧めします。ですから、私は解決策は配列のALL_POSを配列の配列として使用してmpi_type_indexedを作成することだと思います。そして、このタイプを使ってmpi_file_set_viewでファイルを記述します。しかし、私がそれをすると、配列が配列されないたびにプログラムがクラッシュします。

以下は、私の問題を再現する最小の例です。プログラムはコンパイルされますが、segfaultです。 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 
+0

実行しているMPIライブラリとバージョンはどれですか?結果のデータ型に重複がないということは肯定的ですか? –

+0

実際にはblocklengthは常に1であり、位置はすべて異なるため、データ型に重複がないことは確かです。私はopen-mpi 1.7.2とopen-mpi 2.0.2でコードを試してみました。 – Ray

+0

私は最新のOpen MPIでも試してみます。両方のioモジュールを試してみるには、 'mpirun --mca io ompio ...'と 'mpirun --mca io romio314 ...'ができます。 Btw、両方のバージョンは現在廃止されており、v3.0.0または少なくとも2.0.2にアップグレードする必要があります –

答えて

0

派生データ型の構築にエラーがあります。

その後試験の両方ompioromio314成分とうまく動作

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

代わりに

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

であるべきです。

+0

ありがとうございました。私はそれが動作することができると確信したので、私は実際のコードのどこに間違いがあるかを把握しなければなりません。だからもう一度あなたの助けに感謝! – Ray

関連する問題