0

私の問題は、Fortran で mpi スキームを使用するときにサブルーチンを呼び出す方法がわからないことです。CONCENTRATION.f90 という名前のサブルーチンがある TRY.f90 という名前のこの小さなコードを書きました。コードを機能させるには、CONCENTRATION.f90 をどのように変更すればよいですか?

PROGRAM TRY
USE MPI

integer status(mpi_status_size)
INTEGER                 I, J, K, II, IERR, MY_ID, NUM_PROCS, PSP
INTEGER , PARAMETER             :: GRIDX =64, GRIDY=64 
REAL    , DIMENSION(gridx,gridy)    :: PSI
PSI=0
PRINT*, 'VARIABLE'

CALL MPI_INIT(IERR)
CALL MPI_COMM_RANK(MPI_COMM_WORLD,MY_ID,IERR)
CALL MPI_COMM_SIZE(MPI_COMM_WORLD,NUM_PROCS,IERR)

CALL CONCENTRATION(GRIDX, GRIDY, NUM_PROCS, MY_ID , PSI)

IF (MY_ID .NE. 0) THEN
    CALL mpi_send( PSI(1+MY_ID*GRIDX/NUM_PROCS:(MY_ID+1)*GRIDX/NUM_PROCS:1,1:GRIDY:1),&
    (GRIDX/NUM_PROCS)*GRIDY,mpi_real, 0,10,mpi_comm_world,ierr)
END IF
IF (MY_ID .EQ. 0) THEN
    DO II=1,NUM_PROCS-1
        CALL mpi_recv(PSI(1+II*GRIDX/NUM_PROCS:(II+1)*GRIDX/NUM_PROCS:1,1:GRIDY:1),&
        (GRIDX/NUM_PROCS)*GRIDY,mpi_real, &
        II,10,mpi_comm_world,status,ierr)
    END DO
 END IF

 CALL MPI_FINALIZE(IERR)
 END PROGRAM TRY 

CONCENTRATION.f90 という名前のサブルーチンを使用しています。

SUBROUTINE CONCENTRATION(GRIDX, GRIDY, NUM_PROCS, MY_ID , PSI)
implicit none

INTEGER*8, INTENT(IN)               :: GRIDX, GRIDY
INTEGER  , INTENT(IN)               :: NUM_PROCS, MY_ID
REAL*8   , DIMENSION(GRIDX,GRIDY), INTENT(OUT)  :: PSI
INTEGER*8                          I, J

DO I=1+MY_ID*GRIDX/NUM_PROCS, (MY_ID+1)*GRIDX/NUM_PROCS
    DO J=1,GRIDY
        PSI(I,J)=2.0
    END DO
END DO

END SUBROUTINE CONCENTRATION

サブルーチン CONCENTRATION.f90 に変更を加えるべきだったと思うので、現在、コードでエラーが発生しています。または、サブルーチンの呼び出し方法も変更する必要があります。

それらの変更点を教えてください。事前にご協力いただきありがとうございます

4

2 に答える 2

2

型の不一致が原因で、プログラムのセグメンテーション違反が発生しました。メインプログラムでは、次PSIの配列として宣言しましたREAL:

REAL    , DIMENSION(gridx,gridy)    :: PSI

CONCENTRATIONサブルーチンでは、別のタイプの を使用しますREAL*8:

REAL*8   , DIMENSION(GRIDX,GRIDY), INTENT(OUT)  :: PSI

デフォルトREALでは 4 バイト長ですが、REAL*8(またはDOUBLE PRECISIONまたはREAL(KIND=8)) は 8 バイト長です。したがってCONCENTRATION、それが信じているものよりも2倍小さい配列に与えており、それNUM_PROCS/2以降のすべてのランクが配列の末尾を超えて書き込み、PSIセグメンテーション違反を引き起こします。1 つのプロセスのみで実行すると、ランク 0 でも segfault が発生します。

MPI 集合操作についても読む必要があります。ここで複数の送受信を行って、達成しようとしていることを正確に実行してくださいMPI_GATHERMPI_GATHERV

于 2012-06-20T19:23:00.190 に答える
-1

concentration唯一の変更は、として宣言することreentrantです。これが Fortran 90 のデフォルトになる可能性があります (私の経験の大部分は F77 であり、reentrantそこでのデフォルトではありません。)

于 2012-06-20T17:24:22.180 に答える