在 MPI C 中将矩阵和向量相乘

Posted

技术标签:

【中文标题】在 MPI C 中将矩阵和向量相乘【英文标题】:Multiplying Matrix and Vector in MPI C 【发布时间】:2021-01-20 06:39:45 【问题描述】:

我当前的 MPI 类有一个任务,我必须乘以 2x3 矩阵

1 2 3

4 5 6

由 3x1 向量 7 8 9

我被告知假设我们只有 2 个处理器。

我有以下实现,但我陷入僵局,我不知道为什么。


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

int main(void)

    int comm_sz; /* number of processes*/
    int my_rank; /* my process rank */
    int m, n;
    double* Matrix;
    double* Vector;
    double* Result;
    double* localMatrix;

    MPI_Comm comm;


    FILE *fptr = fopen("mv-data.txt", "r");
    MPI_Init(NULL, NULL);
    comm = MPI_COMM_WORLD;
    MPI_Comm_size(comm, &comm_sz);
    MPI_Comm_rank(comm, &my_rank);

    if (my_rank == 0)
    
        fscanf(fptr,"%d", m);
        fscanf(fptr, "%d", n);
    
    MPI_Bcast(m, 1, MPI_INT, 0, comm);
    MPI_Bcast(n,1,MPI_INT, 0, comm);


    if (my_rank==0)
    
    Matrix = malloc(m*n * sizeof(double));

    for(int i = 0; i<m; i++)
        for(int j=0; j< n; j++)
            fscanf(fptr, "%lf", &Matrix[i*n+j]);

    Vector = malloc(n*sizeof(double));

    for (int i = 0; i < n; i++)
        fscanf(fptr,"%lf", &Vector[i]);


    Result = malloc(m * sizeof(double));



    for (int row = 0; row < m; row++)
    
        localMatrix = malloc(m*sizeof(double));
        for(int column = 0; column < n; column++)
            localMatrix[column] = Matrix[row*n + column];

        MPI_Send(localMatrix, n, MPI_DOUBLE, row % comm_sz, 0, comm);
    

    
    MPI_Bcast(Vector, n, MPI_DOUBLE, 0,comm);
    MPI_Recv(localMatrix, n, MPI_DOUBLE, 0, 0, comm, MPI_STATUS_IGNORE);
    Result[my_rank] = 0;
    for(int i = 0; i < n; i++)
    
        Result[my_rank] += localMatrix[i] * Vector[i];
    

    if (my_rank = 0)
    
        for (int i = 0; i < m; i++)
            printf("%d", Result[i]);
    

    return 0;


我想不出任何其他方法可以将此进程发送到主处理器而不会导致死锁。 任何帮助将不胜感激。

【问题讨论】:

使用集体操作:分散矩阵,广播向量并收集结果。 if(tank == 0) 只会保留在代码的开头和结尾。 【参考方案1】:

rank 0 中,您正在使用阻止MPI_Send。然后其他进程调用集合MPI_Bcast,而不是匹配的MPI_Recv。这可能导致死锁(缓冲可以发生在MPI_Send 内部,也可以避免死锁)。见下文:

if (my_rank==0)

   for (int row = 0; row < m; row++)
   
      MPI_Send(localMatrix, n, MPI_DOUBLE, row % comm_sz, 0, comm);
   

MPI_Bcast(Vector, n, MPI_DOUBLE, 0,comm); // COLLECTIVE - PROCESS MAY GET STUCK HERE
MPI_Recv(localMatrix, n, MPI_DOUBLE, 0, 0, comm, MPI_STATUS_IGNORE);

你可以试试这样的,

if (my_rank==0)

   for (int row = 0; row < m; row++)
   
      MPI_Send(localMatrix, n, MPI_DOUBLE, row % comm_sz, 0, comm);
   
 else

      MPI_Recv(localMatrix, n, MPI_DOUBLE, 0, 0, comm, MPI_STATUS_IGNORE);

MPI_Bcast(Vector, n, MPI_DOUBLE, 0,comm);

这肯定会避免死锁。此外,您的代码中存在问题。例如,

MPI_Recv(localMatrix, n, MPI_DOUBLE, 0, 0, comm, MPI_STATUS_IGNORE);

将导致分段错误,因为未分配 localMatrix 的内存。访问ResultVector 也会导致分段错误,因为您没有在其他进程(例如:rank 1 到 N-1) 中为其分配内存,除了 rank 0强>.

【讨论】:

以上是关于在 MPI C 中将矩阵和向量相乘的主要内容,如果未能解决你的问题,请参考以下文章

一个n阶行(列)向量与矩阵相乘得到啥?

如何在sas中将每一行与另一个矩阵元素的每一行相乘?

正交矩阵和它的转置矩阵相乘不是单位矩阵是怎么回事

向量乘矩阵表示啥?

矩阵和向量相乘

用Mac OS X 10.7的vecLib框架将矩阵和向量相乘的问题