【问题标题】:matrix vector multiplication mpi矩阵向量乘法 mpi
【发布时间】:2016-01-23 20:47:57
【问题描述】:

我想做矩阵向量乘法。代码正在编译但未运行。谁能帮我解决这个问题?提前谢谢你。

#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 

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

【问题讨论】:

  • @Gilles 现在正在编译但未运行。请检查
  • @Gilles 其 10000.. 已在代码中编辑

标签: mpi


【解决方案1】:

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

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

最后一个a 是一个大数组,因为它被声明为double a[500*500],所以它被分配在堆栈上。阅读:Segmentation fault on large array sizes:最好的方法是将malloc() 也用于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 相当大。考虑为数组a 的大小使用诸如nlocal*n 之类的计算数字,而不是诸如DIM 之类的默认大小。这样,您将能够在较小的 n 上调试代码,并且不会浪费内存。

相同的 cmets 适用于分配为 double b[500]double x[500]bx,而如果 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 之类的调试器可以检测到与内存管理相关的此类问题。使用单个进程在您的程序上试一试!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-23
    • 2012-11-24
    • 2018-09-08
    • 2017-10-30
    • 2012-11-04
    • 2014-04-21
    • 2015-04-03
    • 2020-10-29
    相关资源
    最近更新 更多