mpi_gather 的问题

Issue with mpi_gather

我写了一个简单的代码来熟悉一下mpi_gather:

program main
    use mpi 
    implicit none
    integer :: myid, ierror, root_id, nprocs, ii
    logical :: boolean
    logical, dimension(:), allocatable :: all_booleans

    call mpi_init(ierror)
    call mpi_comm_rank(mpi_comm_world,myid,ierror)
    call mpi_comm_size(mpi_comm_world, nprocs, ierror)

    if(myid==0) then
        print '(A9,I2)', "nprocs = ", nprocs
        print*, "************************************************************"
        print*, "From each processor"
    end if
    call mpi_barrier(mpi_comm_world,ierror)

    boolean = .FALSE.
    root_id = 10
    if(myid==root_id) then
        boolean = .TRUE.
        allocate(all_booleans(0:nprocs-1))
    end if

    print '(A7,I2,A11,L2)', "myid = ", myid, " boolean = ", boolean
    call mpi_barrier(mpi_comm_world,ierror)

    call mpi_gather(boolean, 1, mpi_logical, all_booleans, nprocs, mpi_logical, root_id,            &   
                & mpi_comm_world, ierror)

    call mpi_barrier(mpi_comm_world,ierror)
    if(myid==root_id) then
        print*, "******************************************************************"
        print *, "From the root processor, proc # : ", myid
        do ii=0,nprocs-1
            print '(A9,I2,A3,L2)', "processor ", ii, " = ", all_booleans(ii)
        end do
    end if
    call mpi_barrier(mpi_comm_world,ierror)

    if(myid==root_id) then
        print*, "******************************************************************"
        print*, "From each processor"
    end if
    call mpi_barrier(mpi_comm_world,ierror)
    print '(A7,I2,A11,L2)', "myid = ", myid, " boolean = ", boolean
    call mpi_barrier(mpi_comm_world,ierror)

    call mpi_finalize(ierror)

end program main

我正在使用来自 ifort 版本 14.0.2 的 mpiifort

nprocs = 12
 ************************************************************
 From each processor
myid =  0 boolean =  F
myid =  1 boolean =  F
myid =  3 boolean =  F
myid =  4 boolean =  F
myid =  5 boolean =  F
myid =  6 boolean =  F
myid =  7 boolean =  F
myid =  8 boolean =  F
myid =  9 boolean =  F
myid = 10 boolean =  T
myid = 11 boolean =  F
myid =  2 boolean =  F
 ******************************************************************
 From the root processor, proc # :           10
processor 0 =  F
processor 1 =  T
processor 2 =  F
processor 3 =  T
processor 4 =  T
processor 5 =  T
processor 6 =  T
processor 7 =  T
processor 8 =  T
processor 9 =  T
processor10 =  T
processor11 =  T
 ******************************************************************
 From each processor
myid =  0 boolean =  F
myid =  1 boolean =  F
myid =  2 boolean =  F
myid =  3 boolean =  F
myid =  4 boolean =  F
myid =  5 boolean =  F
myid =  6 boolean =  F
myid =  7 boolean =  F
myid =  8 boolean =  F
myid =  9 boolean =  F
myid = 10 boolean =  T
myid = 11 boolean =  F

我仅为根处理器(此处为 proc 10)将变量 boolean 设置为 .TRUE.。然后我将所有 boolean 值收集到数组 all_booleans 到根处理器。当我输出 all_booleans 的值时,我希望所有索引都得到 .FALSE.,但 myid = 10 除外,但事实并非如此。我做错了什么?

你对 mpi_gather 的论点有点错误。从 http://www.mpich.org/static/docs/v3.2/www3/MPI_Gather.html 到 recv_count 它说

recvcount number of elements for any single receive (integer, significant only at root)

注意单身这个词。因此,如果您将呼叫更改为

call mpi_gather(boolean, 1, mpi_logical, all_booleans, 1, mpi_logical, root_id,            &   
            & mpi_comm_world, ierror)

对我有用:

Wot now? mpif90 gath.f90
Wot now? mpirun -np 12 ./a.out
nprocs = 12
 ************************************************************
 From each processor
myid = 11 boolean =  F
myid =  3 boolean =  F
myid =  7 boolean =  F
myid =  8 boolean =  F
myid =  0 boolean =  F
myid =  4 boolean =  F
myid =  9 boolean =  F
myid = 10 boolean =  T
myid =  6 boolean =  F
myid =  2 boolean =  F
myid =  5 boolean =  F
myid =  1 boolean =  F
 ******************************************************************
 From the root processor, proc # :           10
processor 0 =  F
processor 1 =  F
processor 2 =  F
processor 3 =  F
processor 4 =  F
processor 5 =  F
processor 6 =  F
processor 7 =  F
processor 8 =  F
processor 9 =  F
processor10 =  T
processor11 =  F
 ******************************************************************
 From each processor
myid =  6 boolean =  F
myid = 11 boolean =  F
myid =  0 boolean =  F
myid =  2 boolean =  F
myid =  1 boolean =  F
myid =  3 boolean =  F
myid =  7 boolean =  F
myid =  9 boolean =  F
myid =  5 boolean =  F
myid = 10 boolean =  T
myid =  4 boolean =  F
myid =  8 boolean =  F