solalito
solalito

Reputation: 1209

Issue with mpi_gather

I have written a simple code to familiarize myself with 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

I am using mpiifort from ifort version 14.0.2:

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

I set the variable boolean to .TRUE. only for the root processor (proc 10 here). I then gather all the boolean values into the array all_booleans to the root processor. When I output the values of all_booleans, I would expect to get .FALSE. for all indices except for myid = 10, which is not the case. What am I doing wrong?

Upvotes: 1

Views: 233

Answers (1)

Ian Bush
Ian Bush

Reputation: 7433

You've got the arguments to mpi_gather slightly wrong. From http://www.mpich.org/static/docs/v3.2/www3/MPI_Gather.html for the recv_count it says

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

Note the word single. so if you change your call to

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

it works for me:

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

Upvotes: 2

Related Questions