MPI_BCAST 和 MPI_SCATTER 之间的区别,关于内存要求

问题描述 投票:0回答:0

我正在尝试将 FORTRAN 示例代码与 MPI 并行化。 EXAMPLE1.f90 由 MPI_BCAST 并行化,EXAMPLE2.f90 由 MPI_SCATTER 并行化。我自己的理解是,与 MPI_BCAST 相比,MPI_SCATTER 可以减少机器上的内存需求。

谁能看看我的示例代码并告诉我我是否正确使用了 MPI_SCATTER?提前谢谢你。

MODULE MOU
CONTAINS

SUBROUTINE PRO (br)
IMPLICIT NONE
INTEGER, PARAMETER               ::      dp = SELECTED_REAL_KIND(15,14)
REAL (KIND=dp)                   ::      br(:,:,:)
INTEGER                          ::      i, j, k

DO i = 1, 807, 1
   DO j = 1, 31, 1
      DO k = 1, 35, 1
         br(i,j,k) = (i*0.85+3.1)/(5.7-j)*(k**3-3.6)*DSQRT(br(i,j,k))
      END DO
   END DO
END DO

RETURN
END SUBROUTINE PRO

END MODULE MOU


PROGRAM EXAMPLE1
USE MPI
USE MOU
IMPLICIT NONE
INTEGER, PARAMETER               ::      dp = SELECTED_REAL_KIND(15,14)
INTEGER                          ::      i, j, k, l
REAL (KIND=dp), ALLOCATABLE      ::      ar(:,:,:,:)
INTEGER                          ::      world_size, world_rank, ierr

CALL MPI_INIT(ierr)
CALL MPI_COMM_SIZE(MPI_COMM_WORLD,world_size,ierr)
CALL MPI_COMM_RANK(MPI_COMM_WORLD,world_rank,ierr)

ALLOCATE (ar(807,1006,31,35))
IF (world_rank == 0) THEN
   DO i = 1, 807, 1
      DO j = 1, 1006, 1
         DO k = 1, 31, 1
            DO l = 1, 35, 1
               ar(i,j,k,l) = (i+1)*(j/0.5-6.3)*(DSQRT(k+3.9))/(l**2+8.3)
            END DO
         END DO
      END DO
   END DO
END IF
CALL MPI_BARRIER(MPI_COMM_WORLD,ierr)
CALL MPI_BCAST(ar,35*31*1006*807,MPI_DOUBLE,0,MPI_COMM_WORLD,ierr)
ALLOCATE (br(807,31,35))
ALLOCATE (cr(807,31,35))
cr = 0.0d0
DO i = 1006, 1
   IF (MOD(i-1,world_size) /= world_rank) CYCLE
   br = ar(:,i,:,:)
   CALL PRO(br)
   IF (world_rank == 0) THEN
      cr = cr + br
      DO j = 1, world_size-1, 1
         IF (i-1+j == 1006) EXIT
         k = i+j+10000
         CALL MPI_RECV(cr,807,MPI_DOUBLE,j,k,MPI_COMM_WORLD,MPI_STATUS_IGNORE,ierr)
      END DO
   ELSE
      k = i+10000
      CALL MPI_SEND(br,807,MPI_DOUBLE,0,k,MPI_COMM_WORLD,ierr)
   END IF
END DO
IF (worl_rank == 0) THEN
   OPEN(UNIT=3, FILE='data.dat', STATUS='REPLACE')
   DO i = 1, 807, 1
      DO j = 1, 31, 1
         WRITE (UNIT=3, FMT=*) cr(i,j,:)
      END DO
   END DO
   DEALLOCATE (ar)
   DEALLOCATE (br)
   DEALLOCATE (cr)
   CLOSE (UNIT=3)
END IF
STOP
END PROGRAM EXAMPLE1
MODULE MOU
CONTAINS

SUBROUTINE PRO (br)
IMPLICIT NONE
INTEGER, PARAMETER               ::      dp = SELECTED_REAL_KIND(15,14)
REAL (KIND=dp)                   ::      br(:,:,:)
INTEGER                          ::      i, j, k

DO i = 1, 807, 1
   DO j = 1, 31, 1
      DO k = 1, 35, 1
         br(i,j,k) = (i*0.85+3.1)/(5.7-j)*(k**3-3.6)*DSQRT(br(i,j,k))
      END DO
   END DO
END DO

RETURN
END SUBROUTINE PRO

END MODULE MOU


PROGRAM EXAMPLE2
USE MPI
USE MOU
IMPLICIT NONE
INTEGER, PARAMETER               ::      dp = SELECTED_REAL_KIND(15,14)
INTEGER                          ::      i, j, k, l
REAL (KIND=dp), ALLOCATABLE      ::      ar(:,:,:,:)
INTEGER                          ::      world_size, world_rank, ierr

CALL MPI_INIT(ierr)
CALL MPI_COMM_SIZE(MPI_COMM_WORLD,world_size,ierr)
CALL MPI_COMM_RANK(MPI_COMM_WORLD,world_rank,ierr)

ALLOCATE (ar(807,1006,31,35))
IF (world_rank == 0) THEN
   DO i = 1, 807, 1
      DO j = 1, 1006, 1
         DO k = 1, 31, 1
            DO l = 1, 35, 1
               ar(i,j,k,l) = (i+1)*(j/0.5-6.3)*(DSQRT(k+3.9))/(l**2+8.3)
            END DO
         END DO
      END DO
   END DO
END IF
CALL MPI_BARRIER(MPI_COMM_WORLD,ierr)
ALLOCATE (br(807,31,35))
CALL MPI_SCATTER(ar,35*31*807,MPI_DOUBLE,br,35*31*807,MPI_DOUBLE,35*31*807,MPI_COMM_WORLD,ierr)
ALLOCATE (cr(807,31,35))
cr = 0.0d0
DO i = 1006, 1
   IF (MOD(i-1,world_size) /= world_rank) CYCLE
   CALL PRO(br)
   IF (world_rank == 0) THEN
      cr = cr + br
      DO j = 1, world_size-1, 1
         IF (i-1+j == 1006) EXIT
         k = i+j+10000
         CALL MPI_RECV(cr,807,MPI_DOUBLE,j,k,MPI_COMM_WORLD,MPI_STATUS_IGNORE,ierr)
      END DO
   ELSE
      k = i+10000
      CALL MPI_SEND(br,807,MPI_DOUBLE,0,k,MPI_COMM_WORLD,ierr)
   END IF
END DO
IF (worl_rank == 0) THEN
   OPEN(UNIT=3, FILE='data.dat', STATUS='REPLACE')
   DO i = 1, 807, 1
      DO j = 1, 31, 1
         WRITE (UNIT=3, FMT=*) cr(i,j,:)
      END DO
   END DO
   DEALLOCATE (ar)
   DEALLOCATE (br)
   DEALLOCATE (cr)
   CLOSE (UNIT=3)
END IF
STOP
END PROGRAM EXAMPLE2
mpi fortran90
© www.soinside.com 2019 - 2024. All rights reserved.