mpi收集数据

Nur*_*lan 0 mpi collect

我确信MPI_Gather从所有进程收集数据,包括根进程本身.

如何MPI_Gather从所有进程中收集数据,包括根进程本身?或者有其他替代功能吗?

Hri*_*iev 6

复制的功能MPI_Gather使用MPI_Gatherv,但指定0的块大小为根排名来代替.像这样的东西:

int rank, size, disp = 0;
int *cnts, *displs;

MPI_Comm_size(MPI_COMM_WORLD, &size);

cnts = malloc(size * sizeof(int));
displs = malloc(size * sizeof(int));
for (rank = 0; rank < size; rank++)
{
    cnts[i] = (rank != root) ? count : 0;
    displs[i] = disp;
    disp += cnts[i];
}

MPI_Comm_rank(MPI_COMM_WORLD, &rank);

MPI_Gatherv(data, cnts[rank], data_type,
            bigdata, cnts, displs, data_type,
            root, MPI_COMM_WORLD);

free(displs); free(cnts);
Run Code Online (Sandbox Code Playgroud)

请注意,这MPI_Gatherv可能会明显慢于MPI_Gather因为MPI实现很可能无法优化通信路径,并且会回退到收集操作的某些哑线性实现.因此,仍然可以使用MPI_Gather并在根进程中提供一些虚拟数据.

您还可以提供MPI_IN_PLACE根进程发送缓冲区的值,它不会向自己发送数据,但是您必须再次为接收缓冲区中的根数据保留位置(就地操作期望根目录将其数据直接放在接收缓冲区内的正确位置):

if (rank != root)
    MPI_Gather(data, count, data_type,
               NULL, count, data_type, root, MPI_COMM_WORLD);
else
    MPI_Gather(MPI_IN_PLACE, count, data_type,
               big_data, count, data_type, root, MPI_COMM_WORLD);
Run Code Online (Sandbox Code Playgroud)