【问题标题】:mpi gather collect datampi collect 收集数据
【发布时间】:2012-11-29 08:38:40
【问题描述】:

我确信MPI_Gather 会收集所有进程的数据,包括根进程本身。

如何让MPI_Gather 收集所有进程的数据,不包括根进程本身? 或者有什么替代功能?

【问题讨论】:

    标签: mpi collect


    【解决方案1】:

    使用MPI_Gatherv 复制MPI_Gather 的功能,但指定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 作为根进程发送缓冲区的值,它不会向自己发送数据,但是您必须再次在接收缓冲区中为根数据保留位置(就地操作期望根将其数据直接放置在接收缓冲区内的正确位置):

    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);
    

    【讨论】:

      猜你喜欢
      • 2016-01-21
      • 2011-12-13
      • 2014-08-27
      • 2020-08-09
      • 2017-02-26
      • 2013-02-16
      • 1970-01-01
      • 2012-05-16
      • 2015-11-04
      相关资源
      最近更新 更多