【问题标题】:MPI_Gather with unequal amounts?MPI_Gather 金额不等?
【发布时间】:2014-02-14 22:07:49
【问题描述】:

我正在使用 MPI_Scatter 和 MPI_Gather 实现矩阵乘法。如果进程数均匀地划分为矩阵行数,我的代码工作正常,列数。但是,当它们不均分时,它会在 MPI_Gather 上崩溃。这是有道理的,因为 MPI_Gather 期望从每个进程中获得一定数量,而不会从最后一个进程中收到那么多。有没有办法使这项工作?我查看了 MPI_Gatherv,但我不希望数据之间有空格 - 我只是希望它接收的数量少于最后一个进程的数量。

目前,我正在使用 MPI_Scatter 向每个进程发送数量:

ceil(N/size)

其中 size 是我正在使用的进程数,N 是矩阵中的行数和列数。最后一个进程不会像其他进程那样接收到那么多的数据。当我在最后一个过程中到达数据末尾时,我确保停止进行乘法运算。如果无法更改我的 MPI_Gather 调用,我可以更改此 scatter+multiplication 部分。任何帮助表示赞赏。

【问题讨论】:

  • 现有答案是否提供了解决方案?

标签: c parallel-processing openmpi


【解决方案1】:

我认为将MPI_ScattervMPI_Gatherv 包装在辅助函数中是可行的方法。今天我写了一对这样的包装作为我暑期学校的一部分,如果你仍然需要解决方案,请随时使用它们。

void fillCounts(int rank, int size, int totalCount, int *counts, int *offsets) {
    int i;
    int n;
    int sum;

    n = totalCount / size;
    for (i = 0; i < size; i++)
    counts[i] = n;

    for (i = 0; i < totalCount % size; i++)
        counts[i] += 1;

    sum = 0;
    for (i = 0; i < size; i++) {
    offsets[i] = sum;
    sum += counts[i];
    }
}

int scatter01(const void *sendBuf, int totalCount, MPI_Datatype dataType,
                    void *recvBuf, int *recvCount,
                    int root, MPI_Comm comm) {
    int rank;
    int size;
    int *counts;
    int *offsets;
    MPI_Comm_rank(comm, &rank);
    MPI_Comm_size(comm, &size);

    counts  = alloca(size * sizeof(int));
    offsets = alloca(size * sizeof(int));
    fillCounts(rank, size, totalCount, counts, offsets);

    *recvCount = counts[rank]; 
    return MPI_Scatterv(sendBuf, counts, offsets, dataType,
                        recvBuf, counts[rank, dataType, root, comm);
}

int gather01(void *recvBuf, int totalCount, MPI_Datatype dataType,
            const void *sendBuf, int root, MPI_Comm comm) {
    int rank;
    int size;
    int *counts;
    int *offsets;
    MPI_Comm_rank(comm, &rank);
    MPI_Comm_size(comm, &size);

    counts  = alloca(size * sizeof(int));
    offsets = alloca(size * sizeof(int));
    fillCounts(rank, size, totalCount, counts, offsets);

    return MPI_Gatherv(sendBuf, counts[rank], dataType,
               recvBuf, counts, offsets, dataType, root, comm);
}

使用示例:

double globData[N];
double partData[N/size+1];
int n;

scatter01(globData, N, MPI_DOUBLE, partData, &n, 0, MPI_COMM_WORLD);
gather01 (globData, N, MPI_DOUBLE, partData,     0, MPI_COMM_WORLD);

【讨论】:

  • 谢谢。 rank 未在 fillCounts 中使用。
【解决方案2】:

MPI_Gather 用于从各个进程收集相同大小的信息。如果各个进程要收集的数组大小不同,那么我们应该使用MPI_GatherV

【讨论】:

    【解决方案3】:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-06-13
      • 1970-01-01
      • 1970-01-01
      • 2021-11-23
      • 2014-01-22
      • 2021-12-11
      • 2012-11-29
      • 1970-01-01
      相关资源
      最近更新 更多