2016-03-21 32 views
1

我写了一个简单的代码来自己熟悉与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 

我使用mpiifort从ifort 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 

我设置变量boolean.TRUE.仅用于根处理器(这里是proc 10)。然后我将所有boolean值收集到数组all_booleans到根处理器。当我输出all_booleans的值时,除了myid = 10之外,我预计会得到.FALSE.,但情况并非如此。我究竟做错了什么?

+0

'调用mpi_gather(布尔值,1,mpi_logical,all_booleans,nprocs,mpi_logical,root_id,MPI_COMM_WORLD,IERROR)'是错误的。它应该读取'调用mpi_gather(布尔,1,mpi_logical,all_booleans,1,mpi_logical,root_id,mpi_comm_world,错误)' – Gilles

回答

2

你有mpi_gather的参数有点不对。从http://www.mpich.org/static/docs/v3.2/www3/MPI_Gather.html为recv_count它说

recvcount 任何单一接收元素个数(整数,只有从根本显著)

注意一字单。因此,如果你改变你的呼叫

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 
+0

是不是有点多余?即我期望'sendcount'和'recvcount'将始终是相同的 – solalito

+2

数据类型不一定是相同的。是的,疯狂在于这条路线,但它是被允许的......对于基本类型并不是那么有趣,但是当涉及派生类型时,它可能有其用途。 –

+0

@solalito,双方的基本数据类型(也称为类型签名)的计数和排序必须匹配。但是这些基本数据类型可以不同地分组为例如派生数据类型。 –