我想做矩阵向量乘法。代码正在编译但未运行。任何人都可以帮我解决问题吗?提前谢谢。
#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
请帮助我运行代码。感谢。
答案 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
上调试代码,并且不会浪费内存。
相同的评论适用于分配为x
和double 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之类的调试器可以检测与内存管理相关的问题。使用一个过程在您的程序上试一试!