좋은 입력 매개 변수를 가진 gfortran 대기 전송 모델 코드에서 MPI_REDUCE 호출로 며칠 동안 싸워 왔지만 마스터의 recvbuf에서 매우 불합리한 결과를 반환합니다. 다음과 같이 나는 간단한 예에서 문제를 복제 할 수있었습니다 :MPI_REDUCE가 1000x1000x6 REAL 배열에 대해 잘못된 답을 반환합니다.
PROGRAM TEST
USE mpi
IMPLICIT NONE
INTEGER my_rank, size, ierror
INTEGER, PARAMETER :: nx=1000, ny=1000, nz=6
INTEGER :: buffsize
REAL, DIMENSION(nx, ny, nz) :: u, v
call MPI_INIT(ierror)
call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierror)
call MPI_COMM_RANK(MPI_COMM_WORLD, my_rank, ierror)
PRINT *, 'my_rank, size: ', my_rank, size
buffsize = nx*ny*nz
u = my_rank + 1
PRINT *, 'PE: ', my_rank, ', Before reduce, SHAPE(u): ', SHAPE(u)
PRINT *, 'PE: ', my_rank, ', Before reduce, SUM(u): ', SUM(u)
CALL MPI_REDUCE(u, v, buffsize, MPI_REAL, &
& MPI_SUM, 0, MPI_COMM_WORLD, ierror)
CALL MPI_BARRIER(MPI_COMM_WORLD, ierror)
PRINT *, 'PE: ', my_rank, ', after reduce, ierror: ', ierror
PRINT *, 'PE: ', my_rank, ', after reduce, SUM(u): ', SUM(u)
PRINT *, 'PE: ', my_rank, ', after reduce, SUM(v): ', SUM(v)
CALL MPI_FINALIZE(ierror)
END PROGRAM test
이 반환
는mpirun -np 2 ./test3
my_rank, size: 0 2
my_rank, size: 1 2
PE: 1 , Before reduce, SHAPE(u): 1000 1000 6
PE: 0 , Before reduce, SHAPE(u): 1000 1000 6
PE: 0 , Before reduce, SUM(u): 6000000.00
PE: 1 , Before reduce, SUM(u): 12000000.0
PE: 0 , after reduce, ierror: 0
PE: 1 , after reduce, ierror: 0
PE: 1 , after reduce, SUM(u): 12000000.0
PE: 0 , after reduce, SUM(u): 6000000.00
PE: 1 , after reduce, SUM(v): 0.00000000
PE: 0 , after reduce, SUM(v): 18407592.0
PE0은 마지막에 SUM (V)로 18000000.0을 보여주는 "해야" 선.
코드에서 nz 매개 변수를 6에서 5로 설정하면 올바른 결과가 생성됩니다. 정말 헷갈리는 점은 gfortran 5.3과 openmpi를 사용하는 AWS EC2 인스턴스, mpich를 사용하는 노트북의 gfortran 5.4, c) openmpi를 사용하는 워크 스테이션의 gfortran 4.4에 동일한 값을 반환한다는 것입니다.
배열의 유형을 DOUBLE PRECISION으로 변경하면 (MPI_REDUCE 호출에서 지정하는 것과 같이) 훨씬 큰 배열의 경우에도 잘 작동합니다. REAL보다는 REAL4를 사용하면 같은 결과가 나옵니다.
나는 이것이 단순해야한다는 것을 알고 있으며 나는 여기서 진짜 바보가되고있다. 그러나 나는 이것을 이해하지 못하고있다. 내 버퍼 크기가 2^31-1보다 작은 정수 값이어야한다는 몇 가지 제안을 읽었습니다.하지만 여기서는 확실합니다.
Fortran은 실제로'sum'의 작동 방식을 지정하지 않고 결과에 "프로세서에 종속적 인 합계와 같은 값을가집니다"라고 지정합니다. 다른 컴파일러는이 문제를 [이 다른 질문] (https://stackoverflow.com/q/25316371)에서 볼 수있는 것처럼 구현 품질 문제로 간주합니다. – francescalus