使用 MPI (C) 的乘积矩阵向量 - 无法正常工作

Product matrix-vector using MPI (C) - doesn't work properly

希望你和你的家人在承认这种情况下做得很好。

我正在开发一个程序,使用 C 中的多线程 (MPI) 将矩阵和向量相乘。它是:

#include <mpi.h>
#include <stdio.h>

int main(int argc, char *argv[])
{

int rank, size;

int mat[2][3] = {{1, 2, 3}, {4, 5, 6}};
int vector[3] = {7, 8, 9};
int vecRes[3] = {50, 122};

int nbLigMat = sizeof(mat) / sizeof(mat[0]);
int nbColMat = sizeof(mat[0]) / sizeof(int);

MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);

int sendbuf[sizeof(vector) / sizeof(mat[0])], recvbuf, recvcounts[size];

if (size == nbColMat)
{
    for (int i = 0; i < nbLigMat; i++)
        sendbuf[i] = mat[i][rank] * vector[rank];

    for (int i = 0; i < size; i++)
        recvcounts[i] = 1;

    MPI_Reduce_scatter(sendbuf, &recvbuf, recvcounts, MPI_INT, MPI_SUM, MPI_COMM_WORLD);

    if (rank < nbLigMat)
        printf("Processeur num %d / outputVector[%d] : %d\n", rank, rank, recvbuf);
}
else
{
    if (rank == 0)
    {
        printf("Le nombre de processeurs necessaires est : %d\n", nbColMat);
    }
}

MPI_Finalize();

return 0;
}

它确实适用于以下 matrix/vector 对夫妇: {{1, 2}, {3, 4}} 和 {5, 6}; {{1, 2, 3}, {4, 5, 6}} 和 {7, 8, 9}; {{1, 2, 3, 4}, {5, 6, 7, 8}} 和 {9, 10, 11, 12} 但例如 {{1, 2, 3}, {4, 5, 6 }, {7, 8, 9}} 和 {10, 11, 12},结果应该是 {68, 167, 266} 但我的输出向量是 {68, 167, 476}。

我意识到,我不知道是什么原因,我的输入向量中的元素在每个进程的开始和第一个 for 循环之间发生了变化,即使我没有与之交互:

在进程 0 中,我的输入向量在第一个循环中变成了 {40, 11, 12},在最后变成了 {40, 280, 12}。在进程 1 中,{55, 11, 12} 然后是 {55, 88, 12}。在 p2 中,{72, 11, 12} 然后是 {72, 108, 12}。这些数字与第一个循环中 mat[i][rank]*vector[rank] 计算的结果数字匹配,但我不明白它们是如何进入我的输入向量的。

也许我对 MPI 的工作原理理解有误,但我没能弄清楚这些数字是如何到达那里并覆盖我的输入向量的。希望解释的够清楚..

我认为错误是在sendbuf的维度上。如果我 运行 你的例子有 {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}} 和 {10, 11, 12} 那么:

sizeof(vector) / sizeof(mat[0]) = 1

太小了,例如在你的循环中,你将值分配给 sendbuf 从 i = 0 到 i = nbLigMat-1.

如果我将 sendbuf 的定义替换为:

int sendbuf[nbLigMat], recvbuf, recvcounts[size];

然后我得到正确答案:

Processeur num 0 / outputVector[0] : 68
Processeur num 1 / outputVector[1] : 167
Processeur num 2 / outputVector[2] : 266