mpi_alltoall 在不等数量的网格和进程上

mpi_alltoall on nonequal number of grids and processes

我明白了MPI_alltoall的一般用法,可以用下图来描述

但实际上,进程数几乎不总是等于网格数。上述情况假设 process = grid = 4。如果数字不相等,我将有矩形网格。下面我展示了一个示例,显示了类似的 alltoall 操作,但网格和进程的数量不相等(网格 = 8,进程 = 2)。

那么我的问题就很直接了,我该如何实现呢? 我已经查看了 alltoallv,但我认为它不会起作用。 欢迎提出任何建议。 谢谢

一个“自然的”alltoall 将是

MPI_Alltoall(sbuf, 4, MPI_INT, rbuf, 4, MPI_INT, MPI_COMM_WORLD);

你最终会得到

P0 = { A0, A1, A2, A3, C0, C1, C2, C3}
P1 = { B0, B1, B2, B3, D0, D1, D2, D3}

你的情况有点复杂,你必须使用(复杂的)派生数据类型。 (注意我没有释放中间数据类型以保持代码的可读性)

    MPI_Datatype tmp, stype, rtype;

    /* derived datatype for send */
    MPI_Type_vector(2, 1, 4, MPI_INT, &tmp); /* {0, 4} */
    MPI_Type_create_resized(tmp, 0, 4, &tmp); /* next type starts at 1 */
    MPI_Type_contiguous(2, tmp, &tmp); /* {0, 4, 1, 5} */
    MPI_Type_create_resized(tmp, 0, 8, &stype); /* next type starts at 2, likely unnecessary */
    MPI_Type_commit(&stype);

    /* derived datatype for recv */
    MPI_Type_vector(2, 2, 4, MPI_INT, &tmp); /* {0, 1, 4, 5 } */
    MPI_Type_create_resized(tmp, 0, 8, &rtype); /* next type starts at 2 */
    MPI_Type_commit(&rtype);

    /* all2all */
    /* thanks to the derived datatypes :
       P0 sends {A0, B0, A1, B1} to P0 and {A2, B2, A3, B3} to P1
       P0 receives {A0, B0, .., .., A1, B1, .., ..} from itself, and
       { .., .., C0, D0, .., .., C1, D1} from P1 } */
    MPI_Alltoall(sbuf, 1, stype, rbuf, 1, rtype, MPI_COMM_WORLD);