【WRF运行报错】segmentation fault (SIGSEGV) 错误原因总结
【WRF运行报错】运行./wrf.exe显示segmentation fault (SIGSEGV) 错误
- 1 检查输入文件完整性
- 2 存在CFL错误
- 3 磁盘空间不足
- 4 内存问题
- 5 处理器数量不当
- 6 模型域设置问题
- 7 参数化方案组合出错
- 参考
在运行 WRF 模型时出现 段错误segmentation fault (SIGSEGV) 错误,通常意味着程序尝试访问无效的内存地址。这可能是由于输入数据问题、时间步长设置、物理参数化方案、内存不足、编译问题等原因导致的。
因为段错误(Segmentation Fault)通常没有清晰的错误信息,解决此类问题往往需要反复尝试。以下总结一些可能导致段错误的原因及解决方法。
1 检查输入文件完整性
如果模型在运行初期崩溃,可能是输入数据存在问题。检查 met_em* 文件中的各个变量,确保没有异常。
尽管日志显示 wrfinput_d01 和 wrfbdy_d01 文件可以正常读取:
d01 2020-07-06_00:00:00 Input data is acceptable to use: wrfbdy_d01
但 segmentation fault 仍可能由输入文件损坏或格式问题引起。你可以使用 ncdump 命令检查这些文件,确保它们没有损坏:
ncdump -h wrfinput_d01
ncdump -h wrfbdy_d01
确保文件中的时间步长、空间范围等与 namelist.input 文件中的配置一致。
2 存在CFL错误
一般的段错误可以试试缩短namelist.input中的积分步长(time_step)来解决,这也是最常见的,在论坛流传最广的解决方法。
其实是否需要减少积分步长要看是否存在 CFL 错误,如果有CFL错误才应该尝试缩短积分步长来解决问题。存在CFL错误意味着模型变得不稳定,这通常是由陡峭的地形或非常强的对流造成的。
可以通过以下命令来看error和out文件里面是否存在CFL错误:
grep -rn "cfl" rsl.*
如果看到多个CFL通知,可能是模型失败的原因。
解决方案1:减少时间步长
如果存在cfl错误,这时候就应该首先尝试减少时间步长了。
time_step的标准建议是 6dx(例如,如果dx = 30000,那么time_step应该小于等于180 )。 但是如果仍然存在CFL 错误,可以尝试将time_step减少到4dx 或 3dx 。当然,这样有时会有效,但并非总是有效,如果还是不行,就要接着往下尝试了
解决方案2:在&domains段中添加 smooth_cg_topo = .true
可以尝试在namelist.input的 &domains 部分中添加 smooth_cg_topo = .true。 如果 CFL 错误发生在边界区域,则在实际运行之前。 此选项平滑粗模型网格的外部行/列,以匹配数据附带的低分辨率地形。
解决方案3:设置 epssm = 0.2(最高 0.9)
如果 CFL 错误发生在复杂地形附近,您可以尝试设置 epssm = 0.2(最高 0.9)以查看是否有所不同。 此选项用于略微前移垂直压力梯度(或声波)的中心,以抑制三维发散。
解决方案4:设置 w_damping = 1
也可以尝试设置 w_damping = 1。该参数是垂直速度阻尼。阻尼为0时,w增加过快,导致不稳定,溢出了计算机计算上限。
3 磁盘空间不足
有时可能是磁盘空间不足的原因。 检查一下电脑还有多少空间可用于要写入的文件。 如果域很大或分辨率很高,则输出文件会大得多(有时会有几 GB)。
一般服务器应该不会有这个问题,如果是用自己的电脑要仔细检查一下这个问题
4 内存问题
分段错误可能是由于内存问题,通过调整进程的 堆栈大小(stack size)有可能得以解决。因为默认情况下,系统为每个程序分配的堆栈内存空间可能不足以支撑 WRF 等内存密集型应用的需求。通过增加堆栈大小,可以为程序提供更多的内存,避免因内存不足导致的错误。
1、设置线程堆栈大小
设置 OpenMP 相关的环境变量 MP_STACK_SIZE,它定义了 每个线程的堆栈大小。64000000 表示设置为 64MB 的堆栈空间。
在 csh 或 tcsh shell 中,setenv 用于设置环境变量:setenv MP_STACK_SIZE 64000000 (OMP_STACKSIZE)
setenv MP_STACK_SIZE 64000000 (OMP_STACKSIZE)
在 bash 或 sh shell 中,等效的命令是 export:
export MP_STACK_SIZE=64000000
2、设置 堆栈大小 为 无限制
limit stacksize unlimited 命令用于在 csh 或 tcsh 中设置当前 shell 会话的 堆栈大小 为 无限制,即允许程序占用系统中尽可能多的内存。通过将堆栈大小设置为 “unlimited”(无限制),可以让程序在需要时动态分配更多的内存,避免崩溃。
如果您使用的是 csh 或 tcsh,请尝试以下操作:
limit stacksize unlimited
如果您使用 sh 或 bash,请使用以下命令:
ulimit -s unlimited
如果ulimit -s unlimited没有用的话,这里也可以试试ulimit -s 262140。
可能还是无法解决问题,但默认堆栈大小通常非常小,会因内存不足而导致分段错误,尝试一下也没坏处。
5 处理器数量不当
使用过多或过少的处理器,或者不良的网格划分,可能导致段错误。可以参考相关文档,根据计算域的大小选择合适的处理器数量。 如何设置处理器数量,可参考-Choosing an Appropriate Number of Processors。
此外,我在另一篇博客中进行了解释和总结-【WRF运行】选择合适的处理器数量来进行并行计算。
6 模型域设置问题
假设嵌套域设置接近边缘,有可能会导致运行报错。
7 参数化方案组合出错
并不是所有的方案都允许组合使用,组合出错也会导致段错误。
参考
1、知乎-WRF运行wrf.exe出现forrtl_ severe (174)_ SIGSEGV, segmentation fault occurred问题原因与解决合集
2、WRD$MPAS-Aforum论坛-Segmentation Faults - Helpful Information