传递 MPI_Gather 不等于 sendtype 的 recvtype 的目的是什么?

What's the purpose of passing MPI_Gather a recvtype not equal to the sendtype?

考虑下面引用的函数 MPI_GatherMPICH docs。它接受参数 sendtyperecvtype.
什么时候不传递相同的类型才有意义,例如MPI_FLOATMPI_DOUBLE,对于两者?

我问是因为必须将相同的参数传递两次似乎没有用,所以 MPI 可能有理由同时接受接收和发送类型。

MPI_Gather
Gathers together values from a group of processes

Synopsis

int MPI_Gather(const void *sendbuf, int sendcount, MPI_Datatype sendtype,
               void *recvbuf, int recvcount, MPI_Datatype recvtype,
               int root, MPI_Comm comm)

Input Parameters

sendbuf
    starting address of send buffer (choice)
sendcount
    number of elements in send buffer (integer)
sendtype
    data type of send buffer elements (handle)
recvcount
    number of elements for any single receive (integer, significant only at root)
recvtype
    data type of recv buffer elements (significant only at root) (handle)
root
    rank of receiving process (integer)
comm
    communicator (handle)

Output Parameters

recvbuf
     address of receive buffer (choice, significant only at root)

MPI 只需要匹配的签名。

例如,您可以发送 10 MPI_INT 并接收 1 个派生数据类型,它是 10 MPI_INT.

的向量

为了完整起见,我还引用了 Gilles 的回答。

MPI only requires matching signatures.

For example you could send 10 MPI_INT and receive 1 derived datatype which is a vector of 10 MPI_INT.

contains the very helpful remark about a "derived datatype" which led me to this explanation by Victor Eijkhout at the Texas Advanced Computing Center.

A vector type describes a series of blocks, all of equal size, spaced with a constant stride. [...] The vector datatype gives the first non-trivial illustration that datatypes can be different on the sender and receiver. If the sender sends b blocks of length l each, the receiver can receive them as b*l contiguous elements, either as a contiguous datatype, or as a contiguous buffer of an elementary type; see figure . In this case, the receiver has no knowledge of the stride of the datatype on the sender.

[...] In this example a vector type is created only on the sender, in order to send a strided subset of an array; the receiver receives the data as a contiguous block.

As an example of this datatype, consider the example of transposing a matrix, for instance to convert between C and Fortran arrays [...] Suppose that a processor has a matrix stored in C, row-major, layout, and it needs to send a column to another processor. If the matrix is declared as int M,N; double mat[M][N], then a column has M blocks of one element, spaced N locations apart. In other words:

MPI_Datatype MPI_column;
MPI_Type_vector( 
    /* count= */ M, /* blocklength= */ 1, /* stride= */ N,
    MPI_DOUBLE, &MPI_column );

Sending the first column is easy:

MPI_Send( mat, 1,MPI_column, ... );

The second column is just a little trickier: you now need to pick out elements with the same stride, but starting at A .

MPI_Send( &(mat[0][1]), 1,MPI_column, ... );

You can make this marginally more efficient (and harder to read) by replacing the index expression by mat+1 .