2016-03-21 18 views
1

ich einen einfachen Code geschrieben haben mir vertraut mit mpi_gather:Ausgabe mit 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 

ich verwende mpiifort von 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 

habe ich die Variable boolean zu .TRUE. nur für den Root-Prozessor (Proc 10 hier). Ich sammle dann alle boolean Werte in das Array all_booleans an den Root-Prozessor. Wenn ich die Werte von all_booleans ausgabe, würde ich erwarten, .FALSE. für alle Indizes außer myid = 10 zu erhalten, was nicht der Fall ist. Was mache ich falsch?

+0

'Aufruf mpi_gather (boolean, 1, mpi_logical, all_booleans, nprocs, mpi_logical, root_id, MPI_COMM_WORLD, ierror)' ist falsch . Es sollte lauten: 'call mpi_gather (boolean, 1, mpi_logical, all_boooles, 1, mpi_logical, root_id, mpi_comm_world, ierror) ' – Gilles

Antwort

2

Sie haben die Argumente zu mpi_gather etwas falsch. Von http://www.mpich.org/static/docs/v3.2/www3/MPI_Gather.html für die recv_count sagt es

recvcount Anzahl der Elemente für jeden einzelnen Empfang (integer, signifikant nur bei root)

Hinweis des Wort Single. also, wenn Sie Ihren Anruf ändern

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

funktioniert es für mich:

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

Ist das nicht ein bisschen redundant? d. h. ich erwarte, dass 'sendcount' und' recvcount' immer gleich sind – solalito

+2

Datentypen müssen nicht auf beiden Seiten gleich sein. Ja, Wahnsinn liegt auf dieser Route, aber es ist erlaubt ... Nicht so interessant für grundlegende Typen, aber wenn abgeleitete Typen beteiligt sind, könnte es seine Verwendung haben. –

+0

@solalito, müssen die Anzahl und die Reihenfolge der grundlegenden Datentypen (auch Typensignatur genannt) auf beiden Seiten übereinstimmen. Diese grundlegenden Datentypen könnten jedoch anders gruppiert werden in z.B. abgeleitete Datentypen. –