When will you use different counts or types for sending and receiving processes?

Many procedures in MPI that describe both sending and receiving - MPI_Sendrecv, MPI_Scatter, etc., contain arguments for counts and types for sending and receiving. For example, in Fortran the signature for MPI_Scatter is:

MPI_SCATTER(SENDBUF, SENDCOUNT, SENDTYPE, 
            RECVBUF, RECVCOUNT, RECVTYPE, ROOT, COMM, IERROR)

      

If the amount of data sent should be the same as the amount received, why is it necessary? Doesn't that just introduce the possibility of inconsistency?

What is the use case when different types / types are needed?

+3


source to share


3 answers


MPI requires the send and receive processes to agree on data type and quantity (sort of, for a recipient a point-to-point link may request more than it has sent). But MPI data types also describe the layout of data in memory, and that's a very common reason why you need to use different types for sender and receiver.

You are asking about Scatter and Fortran in particular, so let's take a look at this case. Let us consider the scattering of a matrix size*n

by rows for different processes

    |---n---|  ---
     0 0 0 0    |
a =  1 1 1 1   size
     2 2 2 2    |
               ---

      

Thus, what rank 0 gets [0 0 0 0]

, rank 1 gets [1 1 1 1]

, etc.

In Fortran, they are not contiguous in memory; so to describe the string you will need to use MPI_Type_vector

:

    call MPI_Type_vector(n, 1, size, MPI_REAL, row_type, ierr)

      

This describes n reales, but with each size-separated number in between.

On the other hand, if the get process just takes this data into the 1st array:



    real, dimension(n) :: b

      

Then it cannot use this type to describe data; b

not enough space to store n

reals, each with a space in size

between! He wants to receive data in the same way as n * MPI_REAL

. This mismatch will be the same in C if you need to send columns of data.

And so this is a common reason for specifying the type (and therefore counting) data in different ways; for the diffuser, the data must be described with a data type that includes the layout of a larger data structure containing the values ​​to be sent; but the diffuser can receive data into a different data structure with a different layout.

A working simple example follows.

program scatterdemo
    use mpi
    implicit none
    real, allocatable, dimension(:,:) :: a
    real, allocatable, dimension(:) :: b
    integer :: ierr, rank, comsize
    integer, parameter :: n=4
    integer :: i
    integer :: row_type, row_type_sized, real_size
    integer(kind=MPI_ADDRESS_KIND) :: lb=0, extent

    call MPI_Init(ierr)
    call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
    call MPI_Comm_size(MPI_COMM_WORLD, comsize, ierr)

    if (rank == 0) then
        allocate( a(comsize, n) )
        do i=1,comsize
            a(i,:) = i-1
        enddo
    endif

    allocate( b(n) )

    call MPI_Type_size(MPI_REAL, real_size, ierr)

    call MPI_Type_vector(n, 1, comsize, MPI_REAL, row_type, ierr)
    extent = real_size*1
    call MPI_Type_create_resized(row_type, lb, extent, row_type_sized, ierr)
    call MPI_Type_commit(row_type_sized, ierr)

    call MPI_Scatter(a, 1, row_type_sized, b, n, MPI_REAL, 0, MPI_COMM_WORLD, ierr)

    print *, rank, b

    if (rank == 0) deallocate (a)
    deallocate(b)

    call MPI_Finalize(ierr)

end program scatterdemo

      

and running it with six processors gives

$ mpirun -np 6 ./scatter
           0  0.0000000E+00  0.0000000E+00  0.0000000E+00  0.0000000E+00
           3   3.000000       3.000000       3.000000       3.000000
           1   1.000000       1.000000       1.000000       1.000000
           5   5.000000       5.000000       5.000000       5.000000
           2   2.000000       2.000000       2.000000       2.000000
           4   4.000000       4.000000       4.000000       4.000000

      

+6


source


When you use MPI-based types, you can view the array as n

elements of some basic numeric type, as well as one or more elements of some MPI-based type. In this case, not only the counters, but also the data types may differ, although they correspond to the same buffer.



On the other hand, it does not depend on the number of processes in the communicator. The size of the communicator is always implicit, and you do not enter it directly anywhere when calling the collective.

+2


source


For the sender, the two will be the same, but the recipients may not know how many items were received.

0


source







All Articles