program main_mpi_test
use mpi
implicit none
integer(kind=8) :: n
integer(kind=8) :: max_optical_depth
integer(kind=8) :: bin
integer(kind=8) :: tmax
integer(kind=8) :: sum_scatt
integer(kind=8) :: i,j,k
real(kind=8) :: rad
real(kind=8), dimension(:), allocatable :: send_results, recv_results
integer :: nrank, nproc,ierr,root
call MPI_INIT(ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD, nrank, ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD, nproc, ierr)
call MPI_BARRIER(MPI_COMM_WORLD, ierr)
root = 0
max_optical_depth = 10
bin = 10
tmax = max_optical_depth*bin
allocate(send_results(tmax))
allocate(recv_results(tmax))
do i = nrank+1, tmax, nproc
rad = real(i)/real(bin)
send_results(i) = rad
print*,'send', rad, send_results(i)
end do
call MPI_BARRIER(MPI_COMM_WORLD, ierr)
call MPI_REDUCE(send_results, recv_results, tmax, MPI_DOUBLE_PRECISION, &
MPI_SUM, root, MPI_COMM_WORLD, ierr)
if (nrank ==0) then
do i = 1, tmax
rad = real(i)/real(bin)
print*,'recv',rad, recv_results(i)
end do
end if
call MPI_FINALIZE(ierr)
deallocate(send_results)
deallocate(recv_results)
end program main_mpi_test
This is my code.
I use MPI_REDUCE. And I use mpiifort compiler.
And the problem is when I print recv_results,
the value of rad and recv_results must be equal, but it shows Nan or a large number about 1e186 at a some locations in the array.
In other locations, rad and recv_results have the same value.
How can I solve this problem?
Your program has quite a lot of problems.
real(8)andinteger(8)is bad practice. They are not portable, may not do what you expect, and may not even be supported by a compiler. Learn about Fortran kinds from your favourite Fortran book or tutorial, and the links Vladimir provides (Fortran: integer*4 vs integer(4) vs integer(kind=4) and Fortran 90 kind parameter) are useful supporting material. My preferred way would be to use theiso_fortran_envstandard module, see my program belowinteger(8)does (if it is supported) it is unlikely to be compatible with the MPI library. MPI is defined (for most routines) in terms of default Fortran integers, so I strongly suggest you use default Fortran integerssend_results. Thus any results are possible as you observe. Uninitialized things can take any value, only by luck will they be zero.Realfunction with only one argument converts that argument to a value of default real kind, which is not what you want here. This is closely related to 1) above, but to get the kind you want you need to supply that kind. See my program belowMPI_Barrierin the code below is completely unnecessary and just wastes times -MPI_Reduceis already blocking. As a rule of thumb you never need an mpi_barrier except for measuring timing, debugging, and possibly when using shared memory( For the purists I should also probably call
MPI_Type_create_f90_realbut I'll be lazy and assumeMPI_DOUBLE_PRECISIONmaps toreal64)Anyway, here's my program, and it working with gfortran, ifort and ifx