0

我的问题是我在 Fortran 中使用 mpi 方案时不知道如何调用子例程。我编写了这个名为 TRY.f90 的小代码,其中有一个名为 CONCENTRATION.f90 的子例程。我应该如何更改 CONTENTRATION.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(or DOUBLE PRECISIONor REAL(KIND=8)) 是 8 个字节长。因此,您提供CONCENTRATION的数组比它认为的要小 2 倍,并且从NUM_PROCS/2后面的所有等级都写入到PSI数组的末尾,从而导致段错误。如果您仅使用一个进程运行,那么即使排名 0 也会出现段错误。

您还应该阅读有关 MPI 集合操作的信息。MPI_GATHERMPI_GATHERV在此处执行您想要实现的多次发送和接收。

于 2012-06-20T19:23:00.190 回答
-1

唯一的变化是声明concentrationreentrant. 这可能是 Fortran 90 的默认设置。(我的大部分经验是 F77,reentrant并不是默认设置。)

于 2012-06-20T17:24:22.180 回答