我确信MPI_Gather
收集来自所有进程的数据,包括root进程本身。
如何让MPI_Gather
从所有进程中收集数据,包括root进程本身?
或者有其他替代功能吗?
答案 0 :(得分: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);
请注意,MPI_Gatherv
可能明显慢于MPI_Gather
,因为MPI实现很可能无法优化通信路径,并且会回退到收集操作的某些哑线性实现。因此,仍然可以使用MPI_Gather
并在根进程中提供一些虚拟数据。
您还可以提供MPI_IN_PLACE
作为根进程发送缓冲区的值,它不会向自身发送数据,但是您必须再次为接收缓冲区中的根数据保留位置(in -place操作期望root将其数据直接放在接收缓冲区内的正确位置:)
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);