MPI错误EXIT CODE: 139的解决方案
好气好气好气!
为了记录这次痛点,时隔这么久再次更新文章!
1.报错问题
在mpi编程时遇到这个问题:
===================================================================================
= BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
= EXIT CODE: 139
= CLEANING UP REMAINING PROCESSES
= YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
===================================================================================
YOUR APPLICATION TERMINATED WITH THE EXIT STRING: Segmentation fault (signal 11)
This typically refers to a problem with your application.
Please see the FAQ page for debugging suggestions
2.原(报错)代码
#include <iostream>
#include <mpi.h>
using namespace std;
int main(int argc, char* argv[]) {
int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (rank == 0) {
int num_row = 1;
double x[] = { 1.0, 2.0 ,3.0 };
double b[] = { 1.0, 2.5, 5.3, 3.1 };
for (int cur_tid = 1; cur_tid < size; cur_tid++)
{
MPI_Send(&num_row, 1, MPI_INT, cur_tid, 0, MPI_COMM_WORLD);
MPI_Send(&(x[0]), 3, MPI_DOUBLE, cur_tid, 0, MPI_COMM_WORLD);
MPI_Send(&(b[0]), 4, MPI_DOUBLE, cur_tid, 0, MPI_COMM_WORLD);
}
}
else {
int num_row = 0;
double* x = new double(3);
double* b = new double(4);
MPI_Recv(&num_row, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
MPI_Recv(&(x[0]), 3, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
MPI_Recv(&(b[0]), 5, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
cout << "I am thread " << rank << " and the num_row is " << num_row << endl;
cout << "I am thread " << rank << " and x1 is " << x[1] << endl;
cout << "I am thread " << rank << " and b1 is " << b[1] << endl;
}
MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();
return 0;
}
3.报错原因
经多方查找,并未找到解决方案。
在该链接(需科学上网)上看到说MPI_Recv()
接收的元素太多了。但是我并没有get到这个作者的点。现在恍然大悟。
今天看到一篇文章才发现,原来我在非0进程中定义了一个错误的变量,其中double* x = new double(3)
表示动态分配一个double型存储单元,将这个单元地址赋给x
,即x
指向这个单元。 而我的本意是定义一个大小为3的数组!
所以应该修改为double *x=new double[3]
。这样才表明是申请3个double型存储单元!!!
简言之,我的错误原因是没有分清double* x = new double(3)
和double* x = new double[3]
的区别。修改完成后,MPI_Recv()
接收的元素和MPI_Send()
发送的元素就匹配上了,也就不存在内存溢出的错误了。
4.修改后(正确)代码
#include <iostream>
#include <mpi.h>
using namespace std;
int main(int argc, char* argv[]) {
int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (rank == 0) {
int num_row = 1;
double x[] = { 1.0, 2.0 ,3.0 };
double b[] = { 1.0, 2.5, 5.3, 3.1 };
for (int cur_tid = 1; cur_tid < size; cur_tid++)
{
MPI_Send(&num_row, 1, MPI_INT, cur_tid, 0, MPI_COMM_WORLD);
MPI_Send(&(x[0]), 3, MPI_DOUBLE, cur_tid, 0, MPI_COMM_WORLD);
MPI_Send(&(b[0]), 4, MPI_DOUBLE, cur_tid, 0, MPI_COMM_WORLD);
}
}
else {
int num_row = 0;
double* x = new double[3];//注意,就是这一行
double* b = new double[4];//注意,就是这一行
MPI_Recv(&num_row, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
MPI_Recv(&(x[0]), 3, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
MPI_Recv(&(b[0]), 5, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
cout << "I am thread " << rank << " and the num_row is " << num_row << endl;
cout << "I am thread " << rank << " and x1 is " << x[1] << endl;
cout << "I am thread " << rank << " and b1 is " << b[1] << endl;
}
MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();
return 0;
}
5.总结
如果你的错误和我不一样,那一定要好好检查发送和接受的大小问题,本质上应该是一致的。这个错误烦了我好几天,一直没找到原因,最终发现是我的基础没打牢,错误居然就是一个中括号和小括号的区别,还需要继续努力呀!
转载请注明来源https://blog.csdn.net/qq_44273006/article/details/122024821