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

问题描述

我了解MPI_alltoall的一般用法,可以通过下图进行描述

enter image description here

但是在实践中,进程数几乎不总是等于网格数。上面的例子假设process = grid =4。如果数字不相等,我将得到矩形网格。在下面的示例中,我展示了一个类似的allall操作,但是网格和进程的数量不相等(grid = 8,process = 2)。

enter image description here

那么我的问题非常简单,我应该如何实现? 我查看了alltoallv,但是我认为它不会起作用。 欢迎任何建议。 谢谢

解决方法

一个“自然”的小人物会是

MPI_Alltoall(sbuf,4,MPI_INT,rbuf,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,&tmp); /* {0,4} */
    MPI_Type_create_resized(tmp,&tmp); /* next type starts at 1 */
    MPI_Type_contiguous(2,tmp,5} */
    MPI_Type_create_resized(tmp,8,&stype); /* next type starts at 2,likely unnecessary */
    MPI_Type_commit(&stype);

    /* derived datatype for recv */
    MPI_Type_vector(2,2,5 } */
    MPI_Type_create_resized(tmp,&rtype); /* next type starts at 2 */
    MPI_Type_commit(&rtype);

    /* all2all */
    /* thanks to the derived datatypes :
       P0 sends {A0,B0,B1} to P0 and {A2,B3} to P1
       P0 receives {A0,..,..} from itself,and
       { ..,D1} from P1 } */
    MPI_Alltoall(sbuf,rtype,MPI_COMM_WORLD);