5.3. 用户级故障缓解(ULFM)

本章记录了用户级故障缓解(ULFM) Open MPI实现的特有功能和选项。

5.3.1. 快速入门

以下是关于如何使用ULFM的极简概述:

shell$ ./configure --with-ft=ulfm [...options...]
shell$ make [-j N] all install
shell$ mpicc my-ft-program.c -o my-ft-program
shell$ mpirun -n 4 --with-ft ulfm my-ft-program

5.3.2. 功能特性

该实现符合用户级故障缓解(ULFM)MPI标准草案提案。ULFM提案由MPI论坛的容错工作组开发,旨在支持MPI程序在遭受任何类型故障(硬故障或软故障)影响后继续运行。其核心原则是:任何MPI调用(点对点通信、集合通信、远程内存访问、IO等)在发生故障后都不能无限期阻塞,而必须要么成功执行,要么抛出MPI错误。相应地,这些错误并非全部致命,MPI实现将采用尽力而为的方法来维持执行环境的持续运行。

该实现产生了ULFM章节标准草案文件中通信器部分定义的三个补充错误代码和五个补充接口。

  • MPIX_ERR_PROC_FAILED 当进程故障导致MPI操作无法完成时(错误代码)。

  • MPIX_ERR_PROC_FAILED_PENDING 当与非阻塞通配符源接收匹配的潜在发送方失败时(错误代码)。

  • MPIX_ERR_REVOKED 当通信器被撤销时(错误代码)。

  • MPIX_Comm_revoke(MPI_Comm comm) 中断该通信器在所有进程上的任何待处理通信(API)。参见MPIX_Comm_revoke

  • MPIX_Comm_is_revoked(MPI_Comm comm, int *flag) 测试一个通信器当前是否已被撤销(API)。参见MPIX_Comm_is_revoked

  • MPIX_Comm_shrink(MPI_Comm comm, MPI_Comm* newcomm) 创建一个新的通信器,其中移除了原通信器中失效的进程,并将剩余进程重新命名以填补原通信器中的命名空缺(API)。参见 MPIX_Comm_shrinkMPIX_Comm_ishrink

  • MPIX_Comm_agree(MPI_Comm comm, int *flag) 对flag执行共识操作(即容错性的全归约操作,使用按位AND运算)(API)。该操作会吸收所有新发生的故障,并在参与者之间传播故障信息。参见MPIX_Comm_agree, MPIX_Comm_iagree

  • MPIX_Comm_get_failed(MPI_Comm comm, MPI_Group* failedgrp) 获取当前失败进程的组(API)。参见 MPIX_Comm_get_failed

  • MPIX_Comm_ack_failed(MPI_Comm comm, int num_to_ack, int* num_acked) 确认应用程序将忽略当前已知故障对通配符接收完成和协议返回值的影响(API)。参见MPIX_Comm_ack_failed

5.3.3. 支持的系统

OpenMPI 提供了多种 MPI 通信引擎,主要包括:

  • PML: ob1, cm, ucx

  • MTL: ofi, portals4, psm2

然而,在Open MPI v5.0.x版本中,只有ob1组件完全适配了容错支持。UCX PML已在某些配置中通过测试,但目前我们无法确认所有UCT设备都完全具备提供必要功能的能力。

ob1 使用BTL("字节传输层")组件来支持各种网络。ob1 支持多种可以相互组合使用的网络。集合操作(阻塞式和非阻塞式)在 ob1 基础上使用了优化实现。

  • 回环(发送到自身)

  • TCP协议

  • UCT (InfiniBand)

  • uGNI (Cray Gemini, Aries)

  • 共享内存(支持CMA和XPMEM的容错功能;KNEM未经测试)

  • 调优和非阻塞式集体通信

本文档后续提供了完整支持的、未测试的和禁用的组件列表。

5.3.4. ULFM 网站

更多信息(教程、示例、针对领先的Top500系统的构建说明)也可在容错研究中心的网站上获取:https://fault-tolerance.org

5.3.5. 参考文献

如果您正在寻找或想要引用ULFM的通用参考,请使用:

韦斯利·布兰德、奥雷利安·布特耶、托马斯·赫劳特、乔治·博西尔卡、杰克·J·董加拉:MPI通信能力的故障后恢复机制:设计与原理。IJHPCA 27(3): 244-254 (2013).

可从DOI 10.1177/1094342013488238获取。

5.3.6. 在Open MPI中构建ULFM支持

在Open MPI v5.0.x版本中,ULFM支持默认内置——也就是说,当你构建Open MPI时,除非指定--without-ft参数,否则ULFM支持将自动可用(但在运行时启用前处于非活跃状态)。

可选地,您可以指定--with-ft ulfm以确保ULFM支持功能被明确构建。

注意

ULFM容错机制不适用于OpenSHMEM。建议如果您打算使用ULFM,应通过--disable-oshmem参数禁用OpenSHMEM的构建。

5.3.7. 运行ULFM Open MPI

5.3.7.1. 构建你的应用程序

由于ULFM仍是MPI标准的扩展,在C语言中需要#include ,或在Fortran中使用use mpi_ext才能访问额外的错误代码和函数。

像往常一样编译您的应用程序,使用提供的mpiccmpifort封装器。

5.3.7.2. 运行您的应用程序

您可以通过简单地使用常规的Open MPI mpirun启动器,并添加--with-ft ulfm命令行选项(或其同义词--with-ft mpi)来启动具有容错功能的应用程序:

shell$ mpirun --with-ft ulfm ...

重要

默认情况下,运行时不会启用容错功能。 必须通过--with-ft ulfm参数手动启用。

5.3.7.3. 在批处理调度器下运行

ULFM可以在作业/批处理调度器下运行,并定期与ALPS、PBS和Slurm进行测试。一个难点在于许多作业调度器通过在任何进程失败时立即触发应用程序的"清理"来处理故障。此外,集成到PRTE中的故障检测子系统在直接启动场景中不活跃,可能没有启动器特定的替代方案。这可能导致应用程序无法检测故障并锁定。为了避免这些问题,建议您在分配内使用mpirun(例如sallocsbatchqsub),而不是直接启动。

  • SLURM已通过容错测试并获得支持。

    重要提示

    请在sallocsbatch分配中使用mpirun命令。 不支持直接使用srun启动。

  • PBS/Torque经过测试并支持容错功能。

    重要提示

    qsub分配中使用mpirun。不支持直接使用aprun启动。

  • LSF尚未经过容错测试。

5.3.7.4. 运行时调优参数

ULFM提供了多种参数来控制其运行方式。默认参数设置合理,在大多数情况下都能获得良好性能。您可以通过--mca mpi_ft_foo 来修改Open MPI的默认设置,或使用--prtemca errmgr_detector_bar 来调整PRTE选项。

重要

在运行时启用/禁用容错功能的主要控制选项是--with-ft ulfm(或其同义词--with-ft mpimpirun命令行选项。该选项会配置Open MPI中的多个子系统以实现容错功能。以下描述的选项最适合在使用了--with-ft ulfm选项后,用于覆盖默认行为。

5.3.7.4.1. PRTE层级选项

  • prrte_enable_ft (default: false) 控制 在mpirun中自动清理包含失败进程的应用程序。当使用 --with-ft ulfm时,此选项会自动设置为true

  • errmgr_detector_priority (default 1005) 选择基于PRRTE的故障检测器。仅当prte_enable_recovery设为true时可用。若使用(实验性的)Open MPI检测器,可将此值设为0

  • errmgr_detector_heartbeat_period (default: 5e0) 控制心跳检测周期。建议值为超时时间的1/2。

  • errmgr_detector_heartbeat_timeout (default: 1e1 seconds) 心跳超时时间(即故障检测速度)。推荐值为心跳周期的2倍。默认设置针对无故障性能进行了优化,但会降低故障检测的响应速度。在预期故障较多的环境中,可以使用不太保守的值(例如100毫秒);低于TCP轮询速率(通常为10毫秒)的值可能导致误报。

5.3.7.4.2. Open MPI 层级选项

在使用mpirun --with-ft ulfm时,某些Open MPI参数会应用默认值。这些默认值来自ft-mpi聚合MCA参数文件$installdir/share/openmpi/amca-param-sets/ft-mpi。您可以通过修改此文件中的变量设置或取消设置,或者在命令行中覆盖变量(例如--mca btl ofi,self)来调整ULFM的运行时行为。

重要

请注意,如果在运行时禁用容错功能(即未使用--with-ft ulfm参数),则不会加载ft-mpi AMCA参数文件,因此不适用于容错的组件将正常加载(这可能导致启用与未启用容错功能时的性能表现存在差异)。

  • mpi_ft_enable (default: false) 允许在运行时开启/关闭容错功能。当使用--with-ft ulfm加载聚合MCA参数文件ft-mpi时,该选项会自动设置为true。当设为false时,故障检测将被禁用;容错扩展定义的接口会被替换为非容错的虚拟实现(例如,MPIX_Comm_agree会通过MPI_Allreduce实现);以下所有其他控制选项将不再生效。

  • mpi_ft_verbose (default: 0) 增加容错活动的输出信息。值为1时将报告检测到的故障。

  • mpi_ft_detector (default: false), 已弃用 控制Open MPI级别故障检测器的激活状态。当该检测器关闭时,所有故障检测将委托给PRTE(见上文)。Open MPI级别的故障检测器属于实验性功能,其故障检测精度与性能存在权衡关系。遇到精度问题的用户可以启用更精确的模式。请参阅下方的调优参数进行调整;Open MPI故障检测器仅作用于MPI_COMM_WORLD。通过MPI_COMM_CONNECT/ACCEPTMPI_COMM_SPAWN连接的进程在发生故障时可能偶尔无法被检测到。

    注意

    该组件已弃用。故障检测现已在PRTE层面实现。有关如何调整故障检测器的信息,请参阅上文关于控制PRTE行为的章节。

  • mpi_ft_detector_thread (default: false) 控制 是否使用线程来发送和接收故障检测器的心跳信号。将此值设为"true"将同时启用 MPI_THREAD_MULTIPLE支持,这会对延迟产生显著影响(通常增加1微秒)。如果您遇到 Open MPI故障检测器误报进程故障的情况,可能需要启用此选项

    重要提示

    此选项仅在mpi_ft_detector设为true时有效。

  • mpi_ft_detector_period (default: 3e0 seconds) 心跳检测周期。建议值为超时时间的1/3。_低于100微秒的值可能会对延迟产生明显影响(通常会增加3微秒)。_

    重要提示

    该选项仅在mpi_ft_detector设为true时生效。

  • mpi_ft_detector_timeout (默认值: 1e1 秒) 心跳 超时时间(即故障检测速度)。推荐值为心跳周期的3倍。

    重要提示

    此选项仅在mpi_ft_detector设为true时有效。

5.3.8. ULFM中的已知限制

  • InfiniBand支持通过UCT BTL提供;生产运行中尚不支持通过UCX PML实现容错操作。

  • TOPO、FILE、RMA不具备容错能力。预计它们在首次故障发生前能正常工作。

5.3.9. 已修改、未测试及禁用组件

以下列出了框架和组件,并将其分为以下三类之一:

  1. 已修改: 该框架/组件已进行专门修改,确保在发生故障后仍能继续工作。

  2. 未测试: 该框架/组件尚未针对容错场景进行修改和/或测试,在发生故障后_可能_出现功能异常。

  3. 已禁用:当启用容错功能时,此框架/组件将导致未定义行为。因此,在使用--with-ft ulfm选项时该组件将被禁用(有关从ft-mpi聚合参数文件加载隐式参数的详细信息,请参阅上文)。

以下未列出的任何框架或组件均归类为未修改, 这意味着它未针对容错性进行修改,但在发生故障后仍能继续正常工作。

  • pml: MPI点对点管理层

    • monitoring, v: 未测试 (这些功能尚未修改以处理故障)

    • cm, crcpw, ucx: 已禁用

  • btl: 点对点字节传输层

    • ofi, portals4, smcuda, usnic, sm(+knem): 未经测试 (它们可能正常工作,请反馈)

  • mtl: 匹配传输层 用于某些类型网络上的MPI点对点消息传输

    • 所有 mtl 组件都被禁用

  • coll: MPI 集合通信算法

    • cuda, inter, sync, sm: 未测试 (这些功能尚未针对故障处理进行修改,但我们预期故障后行为仍能保持正确)

    • hcoll, portals4 已禁用(这些组件尚未进行容错修改,我们预期在故障后会出现未定义行为)

  • osc: MPI单边通信

    • 所有osc组件均未经测试(尚未针对故障处理进行修改,预计故障后行为未定义)

  • io: MPI I/O 及其依赖组件

    • fs: 用于MPI I/O的文件系统函数

    • fbtl: 文件字节传输层:为OMPIO提供独立读写操作的抽象层

    • fcoll: MPI I/O的集体读写操作

    • sharedfp: 用于MPI I/O的共享文件指针操作

    • 这些框架中的所有组件均未修改,未经测试 (我们预期故障后能干净地中止)

  • vprotocol: 检查点/重启组件

    • 所有vprotocol组件均未经测试

  • threads, wait-sync: 多线程等待同步对象

    • argotbots, qthreads: 已禁用 (这些组件尚未修改以处理故障;我们预计会出现故障后死锁)

5.3.10. 更新日志

5.3.10.1. ULFM集成于Open MPI

从v5.0.x版本开始,ULFM现已直接集成到Open MPI的社区版本中。以下部分描述了之前独立的ULFM版本。

5.3.10.2. ULFM 独立版本 4.0.2u1

这是一个稳定性和上游兼容性升级版本。它基于最新的Open MPI发布版(v4.0.2,2019年10月)。

  • 此版本基于Open MPI发布版本v4.0.2 (ompi #cb5f4e737a)。

  • 此版本基于ULFM主分支(ulfm #0e249ca1)。

  • 新功能

    • 对UCT BTL的支持进入测试阶段。

  • 错误修复

    • 对故障检测器中的噪声高度敏感。

    • 当BTL进度线程正在更新消息时进行撤销操作会导致死锁。

    • 一种故障检测器会持续观察一个已终止进程的情况。

    • 默认禁用外部pmix/libevent的使用(内部已修改以处理错误情况)。

    • 清理错误路径时遗留了一些未释放的RDMA注册。

    • 在出现错误时,不要过早移除orte作业/进程会话目录。

5.3.10.3. ULFM 独立版本 4.0.1u1

这是一次稳定性和上游兼容性升级。它提升了稳定性、性能,并基于最新的Open MPI版本(v4.0.1,2019年5月)。

  • 此版本基于Open MPI发布版本v4.0.1 (ompi #b780667)。

  • 此版本基于ULFM主分支(ulfm #cf8dc43f)。

  • 新功能

    • 新增 MPI_Comm_is_revoked 函数

    • ftbasic集合组件重命名为ftagree

    • 恢复了pcollreq扩展

  • 错误修复

    • 未能始终检测到节点本地同级进程的故障

    • 由于尝试通知已知失效进程,导致故障传播和检测速度变慢

    • 多线程程序中出现了死锁

    • 在编译Fortran接口时,PMPI存在一些问题

    • 在OS-X系统上出现了死锁问题

5.3.10.4. ULFM 独立版本 2.1

本次发布是一个错误修复和上游功能同步的升级版本。它提升了稳定性与性能,并基于最新的Open MPI主分支(2018年11月)。

  • ULFM现在基于Open MPI主分支(#37954b5f)。

  • ULFM调优MCA参数通过ompi_info暴露。

  • Fortran 90 绑定已更新

  • 错误修复:

    • 修正了当部分槽位被故障进程占用时,MPI_COMM_SPAWN过程中进程放置的行为。

    • MPI_COMM_SPAWN 在 Info 对象中接受进程放置指令。

    • 修复了部分NBC集合操作中的死锁问题。

    • MPI_FINALIZE中的崩溃和死锁问题已得到解决。

    • 任何返回错误状态为MPIX_PROC_FAILED_PENDING的源请求,现在可以在后续的MPI_WAIT/TEST操作中正确完成。

5.3.10.5. ULFM 独立版本 2.0

重点在于与当前Open MPI主线版本(2017年11月)的集成、性能优化和稳定性提升。

  • ULFM现在基于Open MPI主分支(#689f1be9)。它将定期更新,直到最终被合并。

  • 默认启用容错功能,并通过MCA变量进行控制。

  • 新增对多线程模式的支持(MPI_THREAD_MULTIPLE等)

  • 新增了对非阻塞集体操作(NBC)的支持。

  • 新增了对CMA共享内存传输(Vader)的支持。

  • 在MPI级别增加了高级故障检测支持。实现了《HPC系统中的故障检测与传播》中描述的算法,DOI 10.1109/SC.2016.26

  • 移除了对CID分配的特殊处理需求。

  • 在配置过程中,不可用的组件会自动从构建中移除

  • 默认情况下启用了RMA、FILES和TOPO组件,在容错执行中使用时会警告这些组件可能在故障后导致未定义行为。

  • 错误修复:

    • 在非容错构建中进行代码清理和性能优化;配置时使用--without-ft参数可获得近乎标准的Open MPI版本。

    • 在禁用FT运行时的FT构建中进行代码清理和性能清理; –mca ft_enable_mpi false 彻底禁用FT运行时活动。

    • 在某些集合操作中,部分错误情况会返回ERR_PENDING而非ERR_PROC_FAILED。

    • 某些测试可能会为ANY_SOURCE接收设置ERR_PENDING或ERR_PROC_FAILED,而非ERR_PROC_FAILED_PENDING。

5.3.10.6. ULFM 独立版本 1.1

重点在于提升稳定性、改进进程间通信的功能覆盖范围,并遵循MPI_ERR_PROC_FAILED_PENDING的最新规范。

  • 从Open MPI 1.5.5开发分支fork而来

  • 根据最新规范修订,新增了MPI_ERR_PROC_FAILED_PENDING错误代码。该错误码会从点对点的非阻塞ANY_SOURCE操作中正确返回。

  • 将MPI_ERR_PROC_FAILED、MPI_ERR_PROC_FAILED_PENDING和MPI_ERR_REVOKED别名化为对应的标准扩展名称MPIX_ERR_xxx。

  • 支持跨通信器:

    • 支持在Intercommunicators上使用阻塞版本的协议MPI_COMM_AGREE。

    • 在交互通信器上测试MPI_COMM_REVOKE。

  • 完全禁用(.ompi_ignore)了许多未经测试的组件。

  • 将默认的ORTE故障通知传播聚合延迟从1秒改为25毫秒。

  • 新增了Open MPI内部故障传播机制;现在SM域之间的故障传播是即时完成的。

  • 错误修复:

    • SendRecv 有时无法正确报告 MPI_ERR_PROC_FAILED 错误。

    • SendRecv可能会错误地更新状态,其中包含与Sendrecv的发送部分相关的错误。

    • 被撤销的发送操作现在总是会被完成或远程取消,不会再出现死锁情况。

    • 向已失效的对等节点取消发送操作时,若BTL报告相同故障,则不会触发断言。

    • 当另一个进程撤销通信器时,重复调用返回MPI_ERR_PROC_FAILED的操作最终将返回MPI_ERR_REVOKED。

5.3.10.7. ULFM 独立版本 1.0

重点一直放在提高性能上,无论是在故障发生之前还是之后。新功能列表包括:

  • 支持非阻塞版本的协议,MPI_COMM_IAGREE。

  • 符合最新的ULFM规范草案。特别是,MPI_COMM_(I)AGREE的语义已发生变化。

  • 新的协议执行算法,其复杂度与进程数量呈真正的对数关系,这将显著提升MPI_COMM_(I)AGREE和MPI_COMM_SHRINK的性能。

  • 新增执行通信器撤销的算法。MPI_COMM_REVOKE采用具有固定最大输出度的可靠广播机制,其规模随进程数量呈对数级增长。

  • 对我们传统网络层的支持进行了改进:

    • TCP:已全面测试

    • SM:已全面测试(XPMEM除外,目前仍不支持)

  • 新增对高性能网络的支持

    • Open IB: 已进行合理测试

    • uGNI: 经过合理测试

  • 调优的集体模块现已默认启用(经过合理测试),与之前的基本默认设置相比,预计将带来显著的性能提升

    • 从Open MPI回移植的PBS/ALPS修复

    • 从Open MPI回移植的OpenIB错误修复/性能优化

    • 改进上下文ID分配算法以减少Shrink操作的开销

    • 其他杂项错误修复

5.3.10.8. 二进制兼容性

ULFM Open MPI 在二进制级别上与任何兼容底层 Open MPI 主分支或发行版的版本保持兼容(参见上游 Open MPI README 中的二进制兼容性和版本号章节)。也就是说,使用兼容版 Open MPI 编译的应用程序可以通过 ULFM Open MPI 的 mpirun 和 MPI 库运行。反之,只要应用程序不使用 MPIX 函数(这些函数仅在 ULFM Open MPI 中定义),那么使用 ULFM Open MPI 编译的应用程序也可以通过兼容版 Open MPI 的 mpirun 启动,并运行在非容错的 MPI 库上。

5.3.11. 联系作者

发现了一个错误?有问题想问?想提建议?想为ULFM Open MPI做贡献?正在研究一个很酷的用例?请告诉我们!

报告错误、发送意见或提问的最佳方式是订阅用户邮件列表:ulfm+subscribe@googlegroups.com

由于垃圾邮件问题,只有订阅用户才能向这些邮件列表发帖(请确保您使用完全相同的电子邮件地址进行订阅和发帖——joe@example.com被视为与joe@mycomputer.example.com不同!)。请访问以下页面订阅邮件列表:https://groups.google.com/forum/#!forum/ulfm

提交问题和故障时,请务必包含尽可能多的额外信息。详情请参阅获取帮助部分。

感谢您的时间。