矩阵向量乘法mpi

时间:2015-10-24 10:34:44

标签: mpi

我想做矩阵向量乘法。代码正在编译但未运行。任何人都可以帮我解决问题吗?提前谢谢。

#include "mpi.h" 
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <time.h>
#define DIM 500

int main(int argc, char *argv[])
{
    int i, j, n=10000; 
    int nlocal;        /* Number of locally stored rows of A */ 
    double *fb;
    double a[DIM * DIM], b[DIM], x[DIM];     /* Will point to a buffer that stores the entire vector b */ 
    int npes, myrank; 
    MPI_Status status; 

    MPI_Init(&argc, &argv);

    /* Get information about the communicator */ 
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
    MPI_Comm_size(MPI_COMM_WORLD, &npes);  

    /* Allocate the memory that will store the entire vector b */ 
    fb = (double*)malloc(npes * sizeof(double)); 
    nlocal = n / npes; 

    /* Gather the entire vector b on each processor using MPI's ALLGATHER operation */ 
    MPI_Allgather(b, nlocal, MPI_DOUBLE, fb, nlocal, MPI_DOUBLE, MPI_COMM_WORLD); 

    /* Perform the matrix-vector multiplication involving the locally stored submatrix */ 
    for (i = 0; i < nlocal; i++) { 
        x[i] = 0.0; 
        for (j = 0; j < n; j++) 
            x[i] += a[i * n + j] * fb[j]; 
    } 
    free(fb);
    MPI_Finalize();   
} //end main 

请帮助我运行代码。感谢。

1 个答案:

答案 0 :(得分:1)

问题可能来自fb = (double*)malloc(npes * sizeof(double));fb = (double*)malloc(n * sizeof(double));应为npes。实际上,n是进程数,a是向量的总长度。

此外,数组a[i * n + j]的大小为500x500 = 250000。如果n = 10000,这足以存储25行......您使用的是400个进程吗?如果您使用的少于400个进程a尝试在数组结束后读取。它会触发未定义的行为,例如分段错误。

最后double a[500*500]是一个大数组,因为它被声明为malloc(),所以它被分配在堆栈上。阅读:Segmentation fault on large array sizes:最好的方法是使用a nlocal*n,适当的大小(此处为double *a=malloc(nlocal*n*sizeof(double)); if(a==NULL){fprintf(stderr,"process %d : malloc failed\n",npes);exit(1);} ... free(a); )。

n=10000

nlocal*n相当大。考虑使用a等计算数字作为数组DIM的大小,而不是默认大小,例如n。这样,您就可以在较小的b上调试代码,并且不会浪费内存。

相同的评论适用于分配为xdouble b[500]的{​​{1}}和double x[500],而n=10000则需要更大的数组。再次考虑使用malloc()使用适当的数字,而不是定义的值DIM=500

double *b=malloc(n*sizeof(double));
if(b==NULL){fprintf(stderr,"process %d : malloc failed\n",npes);exit(1);}
...
free(b);

double *x=malloc(nlocal*sizeof(double));
if(x==NULL){fprintf(stderr,"process %d : malloc failed\n",npes);exit(1);}
...
free(x);

valgrind之类的调试器可以检测与内存管理相关的问题。使用一个过程在您的程序上试一试!