MPI实现矩阵乘法报进程非零退出码任务中止问题求助
问题原因
- 核心崩溃原因:类型不匹配:工作进程发送的
values_coords是double类型数组,但0号进程接收时定义的recv_values_coords是int类型数组,数据类型完全不匹配,接收时会发生内存越界、数据解析错误,直接触发段错误,导致进程非零退出。 - MPI资源未正确释放:矩阵维度合法性检查
if(n!=o)的逻辑写在MPI_Init之前,一旦触发检查失败直接return,没有调用MPI_Finalize释放MPI资源,会导致MPI框架报错。 - 可变长度数组(VLA)兼容性问题:代码中使用了
double values_coords[elements_number][3]这类C++标准不支持的可变长度数组,部分编译器会编译失败或者运行时出现栈溢出问题。
解决方案
按照以下要点修改代码即可正常运行:
- 将0号进程的接收缓存
recv_values_coords类型改为double,和发送端类型对齐 - 把矩阵维度检查逻辑移动到
MPI_Init之后,触发错误时先调用MPI_Finalize再退出 - 替换可变长度数组为动态内存分配,兼容C++标准
- 发送/接收时去掉数组名前的多余
&,数组名本身就是首地址,避免地址类型错误
修正后的核心代码片段
// 维度检查移到MPI初始化之后 MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); if (n!=o) { if(rank == 0) printf("Can not multiply because of the wrong shape!\n"); MPI_Finalize(); return 0; }
// 0号进程接收逻辑修改 for (int r=1;r<size;r++){ int recv_elements_number; MPI_Recv(&recv_elements_number, 1, MPI_INT, r, 403, MPI_COMM_WORLD, &status1); // 改为动态分配的double数组,和发送端类型对齐 double* recv_values_coords = new double[recv_elements_number * 3]; MPI_Recv(recv_values_coords, recv_elements_number*3, MPI_DOUBLE, r, 404, MPI_COMM_WORLD, &status2); for (int x=0;x<recv_elements_number;x++){ i = recv_values_coords[x*3 + 1]; j = recv_values_coords[x*3 + 2]; double value = recv_values_coords[x*3]; C[i][j] = value; } delete[] recv_values_coords; }
// 工作进程发送逻辑修改,去掉多余的& MPI_Send(&elements_number, 1, MPI_INT, 0, 403, MPI_COMM_WORLD); MPI_Send(values_coords, elements_number*3, MPI_DOUBLE, 0, 404, MPI_COMM_WORLD);
修改后运行3*3矩阵测试用例,会正确输出如下结果:
6 12 18 6 12 18 6 12 18
内容的提问来源于stack exchange,提问作者Era Freddy
相关产品推荐
相关产品推荐

