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

PETSc代码单进程运行正常,双进程崩溃的原因求助

问题分析与解决方案

问题根源

当以双进程模式运行时,PETSc会将总大小为1的分布式向量自动划分:其中一个进程的向量局部大小为0,另一个进程的局部大小为1。但原代码中的FormFunction函数未检查当前进程的向量局部大小,直接访问ax[0]和aF[0],局部大小为0的进程会因内存越界触发段错误(SEGV)。

修复方案

在计算残差前,先获取当前进程的向量局部大小,仅当局部存在元素时执行计算逻辑;无元素的进程直接跳过操作。

修改后的FormFunction函数

PetscErrorCode FormFunction(SNES snes, Vec x, Vec F, void *ctx) {
    PetscErrorCode ierr;
    const PetscReal  *ax;
    PetscReal        *aF;
    PetscInt         local_size;

    // 获取当前进程的向量局部大小
    ierr = VecGetLocalSize(x, &local_size); CHKERRQ(ierr);
    if (local_size == 0) return 0; // 无局部元素,直接返回

    ierr = VecGetArrayRead(x,&ax);CHKERRQ(ierr);
    ierr = VecGetArray(F,&aF);CHKERRQ(ierr);
    aF[0] = atan(ax[0]);
    ierr = VecRestoreArrayRead(x,&ax);CHKERRQ(ierr);
    ierr = VecRestoreArray(F,&aF);CHKERRQ(ierr);
    return 0;
}

可选优化:显式指定向量局部大小

如果确定问题仅涉及单元素向量,也可以在创建向量时直接指定每个进程的局部大小,避免自动划分导致的局部大小为0的情况:

// 替换原VecSetSizes调用
PetscMPIInt rank;
MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
ierr = VecSetSizes(x, (rank == 0) ? 1 : 0, 1); CHKERRQ(ierr);

不过第一种方案更通用,适用于任意大小的分布式向量。

验证结果

修改后执行双进程命令:

~/petsc/arch-darwin-c-opt/bin/mpiexec -n 2 ./atan -snes_fd

将正常输出结果,无段错误。

内容的提问来源于stack exchange,提问作者Eder Lima de Albuquerque

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 07:44:59