OpenMPI单Rank崩溃时未终止其他Rank的问题及实现咨询
如何感知MPI进程崩溃并终止所有相关进程
一、让Rank 0感知Rank 1的崩溃
MPI默认的错误处理逻辑是:当某个进程崩溃时,不会主动通知其他存活进程(除非你手动配置了对应的错误处理器)。要让Rank 0感知到Rank 1的崩溃,有两种实用方案:
1. 捕获MPI_Recv的错误返回值
默认情况下,MPI_Recv在接收失败(比如发送方崩溃)时会直接触发MPI_Abort终止整个程序,但你可以通过修改错误处理器,让它返回错误码而非直接终止,这样就能在代码中捕获并处理崩溃事件:
#include <mpi.h> #include <stdio.h> #include <stdlib.h> #include <signal.h> int main(int argc, char** argv) { MPI_Init(&argc, &argv); int world_rank, world_size; MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); MPI_Comm_size(MPI_COMM_WORLD, &world_size); if (world_size < 2) { fprintf(stderr, "World size must be greater than 1 for %s\n", argv[0]); MPI_Abort(MPI_COMM_WORLD, 1); } // 替换默认错误处理器:返回错误码,而非直接终止程序 MPI_Errhandler old_handler; MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_RETURN, &old_handler); int number; if (world_rank == 1) { number = -1; MPI_Send(&number, 1, MPI_INT, 0, 0, MPI_COMM_WORLD); raise(SIGSEGV); } else if (world_rank == 0) { MPI_Status status; int err_code = MPI_Recv(&number, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &status); if (err_code != MPI_SUCCESS) { char err_msg[MPI_MAX_ERROR_STRING]; int msg_len; MPI_Error_string(err_code, err_msg, &msg_len); fprintf(stderr, "Rank 0 detected error: %.*s\n", msg_len, err_msg); // 主动触发全局终止 MPI_Abort(MPI_COMM_WORLD, err_code); } printf("Process 0 received number %d from process 1\n", number); } printf("rank %d finalize\n", world_rank); MPI_Comm_set_errhandler(MPI_COMM_WORLD, old_handler, NULL); // 恢复原错误处理器 MPI_Finalize(); return 0; }
当Rank 1崩溃后,Rank 0的MPI_Recv会返回MPI_ERR_PROC_FAILED类的错误码,你可以捕获这个信号并执行自定义逻辑(比如主动终止所有进程)。
2. 异步通信+周期性状态检查
如果你需要非阻塞地监控进程状态,可以结合MPI_Irecv和MPI_Comm_test_inter来周期性检测通信器内的进程存活情况:
// 仅Rank 0部分示例代码 MPI_Request req; MPI_Irecv(&number, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &req); while (1) { int is_completed; MPI_Test(&req, &is_completed, &status); if (is_completed) { printf("Process 0 received number %d from process 1\n", number); break; } // 检查通信器是否有进程失效 int has_failed; MPI_Comm_test_inter(MPI_COMM_WORLD, &has_failed); if (has_failed) { fprintf(stderr, "Rank 0 detected that some process has crashed\n"); MPI_Abort(MPI_COMM_WORLD, 1); } // 短暂休眠避免CPU占用过高 usleep(100000); }
二、让mpirun在Rank 1崩溃时自动杀死Rank 0
不同MPI实现(Open MPI、MPICH等)都提供了命令行参数,用于控制进程崩溃时的全局行为:
1. Open MPI场景
使用--abort-on-error参数,只要有一个进程崩溃,mpirun就会自动终止所有剩余进程:
mpirun --abort-on-error -np 2 ./your_mpi_program
也可以通过MCA参数更精细地控制:
mpirun -mca orte_abort_on_non_zero_status 1 -np 2 ./your_mpi_program
2. MPICH场景
使用-abort-on-error参数,实现相同的全局终止逻辑:
mpiexec -abort-on-error -np 2 ./your_mpi_program
内容的提问来源于stack exchange,提问作者JACK M
相关产品推荐
相关产品推荐

