You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:00:27