使用 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
希望你和你的家人在承认这种情况下做得很好。
我正在开发一个程序,使用 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