Matrix 矩阵乘以MPI(分段故障)
我最近开始学习MPI,你可能已经猜到了,我已经遇到了一个我自己无法解决的错误 我想写一个将两个矩阵相乘的程序。然而,我还没有走到那一步,事实上,我一开始就坚持播放矩阵Matrix 矩阵乘以MPI(分段故障),matrix,segmentation-fault,mpi,Matrix,Segmentation Fault,Mpi,我最近开始学习MPI,你可能已经猜到了,我已经遇到了一个我自己无法解决的错误 我想写一个将两个矩阵相乘的程序。然而,我还没有走到那一步,事实上,我一开始就坚持播放矩阵 #define MASTER 0 if (rank == MASTER) { A = (double *) malloc(N * N * sizeof(double)); B = (double *) malloc(N * N * sizeof(double)); matFillRa
#define MASTER 0
if (rank == MASTER) {
A = (double *) malloc(N * N * sizeof(double));
B = (double *) malloc(N * N * sizeof(double));
matFillRand(N, A);
matFillRand(N, B);
}
if (rank == MASTER) {
P = (double *) malloc(N * N * sizeof(double));
}
matMulMPI(N, A, B, P);
if (rank == MASTER) {
printMatrix(N, P);
}
(理论上)进行数学运算的函数如下:
void matMulMPI(long N, double *a, double *b, double *c) {
long i, j, k;
int rank, size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Bcast(&N, 1, MPI_LONG, MASTER, MPI_COMM_WORLD);
MPI_Bcast(b, N*N, MPI_DOUBLE, MASTER, MPI_COMM_WORLD);
printMatrix(N, b);
//TO-DO: Broadcast A
//TO-DO: Do Math
}
这个广播不起作用。我得到以下信息:
*处理接收到的信号信号:分段故障(11)信号代码:无效权限(2)地址失败:0x401560信号:
分段故障(11)信号代码:权限无效(2)失败
地址:0x401560[0]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x10340)[0x7fc3ede6b340][1]
/lib/x86_64-linux-gnu/libc.so.6(+0x981c0)[0x7fc3edb2e1c0][2]
/usr/lib/libmpi.so.1(蛋白石转换器解包+0x105)[0x7fc3ee1788d5][
3]
/usr/lib/openmpi/lib/openmpi/mca\u pml\u ob1.so(mca\u pml\u ob1\u recv\u frag\u callback\u match+0x460)
[0x7fc3e6587630][4]
/usr/lib/openmpi/lib/openmpi/mca_btl_sm.so(mca_btl_sm_component_progress+0x487)
[0x7fc3e572a137][5]/usr/lib/libmpi.so.1(opal_进度+0x5a)
[0x7fc3ee1849ea][6]
/usr/lib/libmpi.so.1(ompi\u请求\u默认\u等待+0x16d)[0x7fc3ee0d1c0d]
[ 7]
/usr/lib/openmpi/lib/openmpi/mca\u coll\u tuned.so(ompi\u coll\u tuned\u bcast\u intra\u generic+0x49e)
[0x7fc3e486da9e][8]
/usr/lib/openmpi/lib/openmpi/mca\u coll\u tuned.so(ompi\u coll\u tuned\u bcast\u intra\u二项式+0xb7)
[0x7fc3e486df27][9]
/usr/lib/openmpi/lib/openmpi/mca\u coll\u tuned.so(ompi\u coll\u tuned\u bcast\u intra\u dec\u fixed+0xcc)
[0x7fc3e486573c][10]
/usr/lib/openmpi/lib/openmpi/mca\u coll\u sync.so(mca\u coll\u sync\u bcast+0x64)
[0x7fc3e4a7d6a4][11]/usr/lib/libmpi.so.1(MPI_Bcast+0x13d)
[0x7fc3ee0df78d][12]。/matMul()[0x4011a9][13]。/matMul()[0x401458]
[14] /lib/x86_64-linux-gnu/libc.so.6(libc_start_main+0xf5)
[0x7fc3edab7ec5][15]。/matMul()[0x400b49]
错误消息结束[0]/lib/x86_64-linux-gnu/libpthread.so.0(+0x10340)[0x7fa4a1fe5340][1]
/lib/x86_64-linux-gnu/libc.so.6(+0x981c0)[0x7fa4a1ca81c0][2]
/usr/lib/libmpi.so.1(蛋白石转换器解包+0x105)[0x7fa4a22f28d5][
3]
/usr/lib/openmpi/lib/openmpi/mca\u pml\u ob1.so(mca\u pml\u ob1\u recv\u frag\u callback\u match+0x460)
[0x7fa49a701630][4]
/usr/lib/openmpi/lib/openmpi/mca_btl_sm.so(mca_btl_sm_component_progress+0x487)
[0x7fa4998a4137][5]/usr/lib/libmpi.so.1(蛋白石进度+0x5a)
[0x7fa4a22fe9ea][6]
/usr/lib/libmpi.so.1(ompi\u请求\u默认\u等待+0x16d)[0x7fa4a224bc0d]
[ 7]
/usr/lib/openmpi/lib/openmpi/mca\u coll\u tuned.so(ompi\u coll\u tuned\u bcast\u intra\u generic+0x4e0)
[0x7fa4989e7ae0][8]
/usr/lib/openmpi/lib/openmpi/mca\u coll\u tuned.so(ompi\u coll\u tuned\u bcast\u intra\u二项式+0xb7)
[0x7fa4989e7f27][9]
/usr/lib/openmpi/lib/openmpi/mca\u coll\u tuned.so(ompi\u coll\u tuned\u bcast\u intra\u dec\u fixed+0xcc)
[0x7fa4989df73c][10]
/usr/lib/openmpi/lib/openmpi/mca\u coll\u sync.so(mca\u coll\u sync\u bcast+0x64)
[0x7fa498bf76a4][11]/usr/lib/libmpi.so.1(MPI_Bcast+0x13d)
[0x7fa4a225978d][12]。/matMul()[0x4011a9][13]。/matMul()[0x401458]
[14] /lib/x86_64-linux-gnu/libc.so.6(libc_start_main+0xf5)
[0x7fa4a1c31ec5][15]。/matMul()[0x400b49]
错误消息结束*
--------------------------------------------------------------------------mpirun注意到,节点上的进程级别为2,PID为12466
rtidev5.etf.bg.ac.rs在信号11(分段故障)时退出。
--------------------------------------------------------------------------共有2个进程被杀死(有些可能是在清理过程中被mpirun杀死的)
我已经弄明白了。所有进程(不仅仅是主进程)都需要首先分配内存 因此,丢失的行是
void matMulMPI(long N, double *a, double *b, double *c) {
...
MPI_Bcast(&N, 1, MPI_LONG, MASTER, MPI_COMM_WORLD);
b = (double *) malloc(N * N * sizeof(double));
MPI_Bcast(b, N*N, MPI_DOUBLE, MASTER, MPI_COMM_WORLD);
...
}
我已经弄明白了。所有进程(不仅仅是主进程)都需要首先分配内存 因此,丢失的行是
void matMulMPI(long N, double *a, double *b, double *c) {
...
MPI_Bcast(&N, 1, MPI_LONG, MASTER, MPI_COMM_WORLD);
b = (double *) malloc(N * N * sizeof(double));
MPI_Bcast(b, N*N, MPI_DOUBLE, MASTER, MPI_COMM_WORLD);
...
}
为了澄清为什么会出现这种情况:广播意味着广播后的每个进程都将在
MPI\u Bcast
的第一个参数中存储数据。在主进程上,它是发送缓冲区,但在其他进程上,它是接收缓冲区。无论如何,如果在调用MPI\u Bcast
之前没有在每个进程上分配数据,那么您将尝试将数据存储在未分配的缓冲区中。这只是为了澄清为什么会出现这种情况:广播意味着广播后的每个进程都将在MPI\u Bcast
的第一个参数中存储数据。在主进程上,它是发送缓冲区,但在其他进程上,它是接收缓冲区。无论如何,如果在调用MPI\u Bcast
之前未在每个进程上分配数据,则将尝试将数据存储在未分配的缓冲区中。