ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

CANN Runtime 快照管理 API 全解:aclrtSnapShot 进程锁定、备份、恢复与回调机制

CANN Runtime 快照管理 API 全解:aclrtSnapShot 进程锁定、备份、恢复与回调机制 CANN Runtime 快照管理 API 全解aclrtSnapShot 进程锁定、备份、恢复与回调机制【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime本文以 CANN Runtime 的快照管理接口为主体系统讲解aclrtSnapShotProcessLock / Backup / Restore / Unlock与aclrtSnapShotCallbackRegister / Unregister六组试验特性的接口契约、进程状态机、快照阶段Stage语义并结合 src/runtime/feature/snapshot 下的源码剖析备份/恢复在 Device 侧的实际执行链路帮助读者完整掌握快照功能的使用边界与底层原理。快照Snapshot是 CANN Runtime 提供的进程级 Device 资源备份与恢复机制先将当前进程锁定冻结后续运行时接口调用再把进程占用的 Device 资源备份到 Host 侧之后当 Device 资源被回收或环境发生重建时可以基于最近一次备份点将 Device 资源恢复到与备份时一致的状态最后解锁进程继续运行。由于该组接口属于试验特性Experimental Feature后续版本可能变更官方明确不支持应用于生产环境适用于对进程状态保有能力有探索性需求的场景。1. 进程状态机与快照整体流程理解快照管理的第一把钥匙是进程状态机。Runtime 内部以 rtProcessState 枚举定义了进程在快照操作中的三种合法状态状态含义进入该状态的接口RT_PROCESS_STATE_RUNNING运行态默认状态可正常调用运行时接口初始状态 /aclrtSnapShotProcessUnlockRT_PROCESS_STATE_LOCKED已锁定后续运行时接口调用被阻塞aclrtSnapShotProcessLockRT_PROCESS_STATE_BACKED_UP已备份Device 资源已保存至 Host 侧aclrtSnapShotProcessBackup据此快照操作的两条主流程备份流与恢复流在状态上的变迁为备份流Backup Flow RUNNING --[Lock]-- LOCKED --[Backup]-- BACKED_UP --[Unlock]-- RUNNING 恢复流Restore Flow BACKED_UP --[Restore]-- LOCKED --[Unlock]-- RUNNING这与各接口文档中调用前必须处于 X 状态、调用后变为 Y 状态的前置/后置条件描述完全一致Lock调用前必须为RUNNING进程默认即是调用后变为LOCKEDBackup调用前必须为LOCKED调用后变为BACKED_UP同一进程支持多次备份以最后一次备份点生效Restore调用前必须为BACKED_UP调用后回到LOCKED注意恢复完成后仍处于锁定态需要再调用 Unlock 才能继续运行Unlock调用前必须为LOCKED或BACKED_UP调用后变为RUNNING同时解除运行时接口的阻塞调用。在 acl_rt.h 中快照阶段枚举的注释同样给出了两条流程的官方定义/* * BackUp Flow: * LOCK_PRE → [aclrtSnapShotProcessLock] → BACKUP_PRE → [aclrtSnapShotProcessBackup] → BACKUP_POST → * [aclrtSnapShotProcessUnlock] - UNLOCK_POST * Restore Flow: RESTORE_PRE → [aclrtSnapShotProcessRestore] → RESTORE_POST * → [aclrtSnapShotProcessUnlock] → UNLOCK_POST */即回调阶段Stage穿插在四个核心接口之间用户注册的回调会在流程到达对应阶段时被系统自动调用。2. 接口总览与产品支持情况快照管理共提供 6 个 API均声明于 acl_rt.h接口作用调用前置状态调用后状态aclrtSnapShotProcessLock(int pid, void* reserve)锁定进程阻止后续运行时接口调用RUNNINGLOCKEDaclrtSnapShotProcessBackup(int pid, aclrtSnapShotBackupArgs* args)备份 Device 资源到 Host 侧LOCKEDBACKED_UPaclrtSnapShotProcessRestore(int pid, aclrtSnapShotRestoreArgs* args)从最近一次备份点恢复 Device 资源BACKED_UPLOCKEDaclrtSnapShotProcessUnlock(int pid, void* reserve)解锁进程解除接口阻塞LOCKED / BACKED_UPRUNNINGaclrtSnapShotCallbackRegister(stage, callback, args)注册快照阶段回调不支持重复注册——aclrtSnapShotCallbackUnregister(stage, callback)取消注册回调——六个接口的产品支持情况完全一致汇总如下引自原文档各接口的产品支持情况小节产品支持情况Ascend 950PR支持Ascend 950DT不支持Atlas A3 训练系列产品 / Atlas A3 推理系列产品支持Atlas A2 训练系列产品 / Atlas A2 推理系列产品支持Atlas 200I/500 A2 推理产品不支持Atlas 推理系列产品不支持Atlas 训练系列产品不支持IPV350不支持须知本组接口均为试验特性后续版本可能会存在变更不支持应用于生产环境中。3. 逐接口详解3.1 aclrtSnapShotProcessLock锁定进程aclError aclrtSnapShotProcessLock(int pid, void* reserve)锁定当前进程以阻止后续的运行时接口调用被阻止的范围包括Device 设置/释放内存的申请/释放/拷贝Context / Stream / Event / Notify 等资源的创建与销毁部分任务下发接口。即锁定之后进程中所有试图通过上述运行时接口改变 Device 状态的调用都会被阻塞从而保证快照窗口内 Device 状态不再演进为备份提供一致性前提。参数说明参数名输入/输出说明pid输入进程 ID当前只支持传入本进程的 ID不支持跨进程操作reserve输入预留参数当前只支持传入NULL返回值返回 0ACL_SUCCESS表示成功返回其他值表示失败错误码语义参见 aclError 说明。从 snapshot.cpp 中的aclrtSnapShotProcessLockImpl可以看到参数校验的实际执行pid与mmGetPid()当前进程 ID不一致时返回参数非法错误错误信息为 pid must be current process pid, cross-process operation is not supportedreserve非空同样判为非法参数。校验通过后才下沉调用 RTS 层的rtSnapShotProcessLock()。这说明仅支持本进程不是文档层面的约定而是入口处的硬性校验。3.2 aclrtSnapShotProcessBackup备份 Device 资源aclError aclrtSnapShotProcessBackup(int pid, aclrtSnapShotBackupArgs* args)备份快照进程中的 Device 资源并将 Device 资源保存在 Host 侧以便后续恢复。针对当前进程支持多次备份以最后一次备份点生效。参数说明参数名输入/输出说明pid输入进程 ID当前只支持传入本进程的 ID不支持跨进程操作args输入备份配置参数类型为 aclrtSnapShotBackupArgs当前只支持传入NULLaclrtSnapShotBackupArgs在头文件中的定义为见 acl_rt.htypedef struct aclrtSnapShotBackupArgs { uint32_t backupFlags; // 当前未开放配置args 整体只支持传 NULL char reserved[60]; // 预留字段 } aclrtSnapShotBackupArgs;由于结构体当前只包含预留字段因此文档与实现snapshot.cpp 中args非NULL即报参数非法要求args只能传NULL。返回值返回 0 表示成功返回其他值表示失败参见 aclError。3.3 aclrtSnapShotProcessRestore恢复 Device 资源aclError aclrtSnapShotProcessRestore(int pid, aclrtSnapShotRestoreArgs *args)恢复快照进程中的 Device 资源根据备份好的 Device 资源进行恢复从最后一次备份点进行恢复。调用前必须确保进程处于BACKED_UP状态调用后进程变为LOCKED状态仍需 Unlock 才回到RUNNING。参数说明参数名输入/输出说明pid输入进程 ID当前只支持传入本进程的 ID不支持跨进程操作args输入恢复配置参数类型为 aclrtSnapShotRestoreArgs当前只支持传入NULL约束说明重点恢复和备份需要在同一个 Device 上指 Device ID 相同即备份时占用的哪个 Device恢复时就要求同一 Device ID 可用恢复时若该 Device 已被其他进程占用则恢复失败——快照恢复的前提是目标 Device 处于可抢占/可重开状态。返回值返回 0 表示成功返回其他值表示失败参见 aclError。3.4 aclrtSnapShotProcessUnlock解锁进程aclError aclrtSnapShotProcessUnlock(int pid, void* reserve)解锁 Device 上的当前进程同时解除运行时接口的阻塞调用——即 Lock 阶段被挂起的所有运行时接口调用在 Unlock 后得以继续。前置条件调用前进程必须处于LOCKED或BACKED_UP状态调用后进程变为RUNNING状态。参数说明参数名输入/输出说明pid输入进程 ID当前只支持传入本进程的 ID不支持跨进程操作reserve输入预留参数当前只支持传入NULL返回值返回 0 表示成功返回其他值表示失败参见 aclError。4. 快照阶段回调aclrtSnapShotCallbackRegister / Unregister4.1 阶段枚举与回调签名快照流程中可注册回调的六个阶段定义于 acl_rt.htypedef enum { ACL_RT_SNAPSHOT_LOCK_PRE 0, // 锁进程之前aclrtSnapShotProcessLock 之前 ACL_RT_SNAPSHOT_BACKUP_PRE, // 备份操作开始之前 ACL_RT_SNAPSHOT_BACKUP_POST, // 备份操作完成之后 ACL_RT_SNAPSHOT_RESTORE_PRE, // 恢复操作开始之前 ACL_RT_SNAPSHOT_RESTORE_POST, // 恢复操作完成之后 ACL_RT_SNAPSHOT_UNLOCK_POST, // 进程解锁之后 } aclrtSnapShotStage; typedef uint32_t (*aclrtSnapShotCallBack)(int32_t deviceId, void* args);各阶段的触发时机类型名与语义同 aclrtSnapShotStage阶段触发时机所属流程ACL_RT_SNAPSHOT_LOCK_PRE进程锁定之前备份流ACL_RT_SNAPSHOT_BACKUP_PRE备份开始之前备份流ACL_RT_SNAPSHOT_BACKUP_POST备份完成之后备份流ACL_RT_SNAPSHOT_RESTORE_PRE恢复开始之前恢复流ACL_RT_SNAPSHOT_RESTORE_POST恢复完成之后恢复流ACL_RT_SNAPSHOT_UNLOCK_POST进程解锁之后备份流 / 恢复流回调函数签名为uint32_t callback(int32_t deviceId, void* args)系统到达指定阶段时自动调用deviceId指明当前快照操作关联的 Deviceargs是注册时传入的用户自定义指针按 rts_snapshot.h 中的注释约定回调返回 0 表示成功返回非 0 错误码表示失败。4.2 aclrtSnapShotCallbackRegisteraclError aclrtSnapShotCallbackRegister(aclrtSnapShotStage stage, aclrtSnapShotCallBack callback, void *args)注册一个回调函数该回调函数将在快照操作的指定阶段被调用。不支持重复注册——对同一阶段重复注册会被拒绝。参数说明参数名输入/输出说明stage输入指定触发回调的快照阶段类型定义参见 aclrtSnapShotStagecallback输入指向回调函数的指针。当指定的快照阶段到达时系统将自动调用此函数。函数定义typedef uint32_t (*aclrtSnapShotCallBack)(int32_t deviceId, void* args);args输入用户自定义参数指针在回调函数调用时传递可以为NULL表示不需要传递额外参数返回值返回 0 表示成功返回其他值表示失败参见 aclError。4.3 aclrtSnapShotCallbackUnregisteraclError aclrtSnapShotCallbackUnregister(aclrtSnapShotStage stage, aclrtSnapShotCallBack callback)取消注册回调函数。取消注册之后对应快照阶段将不再调用该回调函数。参数说明参数名输入/输出说明stage输入指定触发回调的快照阶段类型定义参见 aclrtSnapShotStagecallback输入待取消注册的回调函数指针函数定义同上返回值返回 0 表示成功返回其他值表示失败参见 aclError。5. 使用示例完整的备份—恢复—解锁流程结合上述接口契约一次典型的快照操作序列如下以备份流与恢复流为例#include acl/acl_rt.h #include stdio.h // 回调函数签名必须与 aclrtSnapShotCallBack 一致 uint32_t MyBackupPreCallback(int32_t deviceId, void* args) { (void)args; printf([snapshot] backup pre, deviceId%d\n, deviceId); return 0; // 返回 0 表示回调执行成功 } uint32_t MyUnlockPostCallback(int32_t deviceId, void* args) { (void)args; printf([snapshot] unlock post, deviceId%d\n, deviceId); return 0; } int main() { const int pid getpid(); // 只能传本进程 ID aclError ret; // 1. 注册阶段回调同一阶段不支持重复注册 ret aclrtSnapShotCallbackRegister(ACL_RT_SNAPSHOT_BACKUP_PRE, MyBackupPreCallback, nullptr); if (ret ! ACL_SUCCESS) { printf(register backup pre callback failed, ret%d\n, ret); return -1; } ret aclrtSnapShotCallbackRegister(ACL_RT_SNAPSHOT_UNLOCK_POST, MyUnlockPostCallback, nullptr); if (ret ! ACL_SUCCESS) { printf(register unlock post callback failed, ret%d\n, ret); return -1; } // 2. 备份流进程须处于 RUNNING 态默认即是 ret aclrtSnapShotProcessLock(pid, nullptr); // RUNNING - LOCKED if (ret ! ACL_SUCCESS) { printf(lock failed, ret%d\n, ret); return -1; } ret aclrtSnapShotProcessBackup(pid, nullptr); // LOCKED - BACKED_UP if (ret ! ACL_SUCCESS) { printf(backup failed, ret%d\n, ret); return -1; } // 3. 恢复流要求与备份在同一 Device ID 上且该 Device 未被其他进程占用 ret aclrtSnapShotProcessRestore(pid, nullptr); // BACKED_UP - LOCKED if (ret ! ACL_SUCCESS) { printf(restore failed, ret%d\n, ret); return -1; } // 4. 解锁解除运行时接口的阻塞调用进程回到 RUNNING ret aclrtSnapShotProcessUnlock(pid, nullptr); // LOCKED - RUNNING if (ret ! ACL_SUCCESS) { printf(unlock failed, ret%d\n, ret); return -1; } // 5. 按需取消回调注册 ret aclrtSnapShotCallbackUnregister(ACL_RT_SNAPSHOT_BACKUP_PRE, MyBackupPreCallback); if (ret ! ACL_SUCCESS) { printf(unregister failed, ret%d\n, ret); } return 0; }使用要点回顾pid必须为本进程 IDreserve/args当前必须为NULL严格遵守状态机Lock前必须RUNNINGBackup前必须LOCKEDRestore前必须BACKED_UPUnlock前必须LOCKED/BACKED_UP多次备份以最后一次生效恢复固定从最后一次备份点恢复且要求备份与恢复位于同一 Device ID目标 Device 被其他进程占用时恢复失败回调按阶段注册、不可重复注册取消注册后对应阶段不再触发接口为试验特性不可直接用于生产环境。6. 源码级剖析API 入口如何落到 Device 侧6.1 三层调用结构从源码结构看快照功能呈现清晰的三层结构API 入口层snapshot.cpp 中的aclrtSnapShotProcess*Impl/aclrtSnapShotCallback*Impl函数负责参数校验pid 必须等于当前进程、reserve/args必须为NULL、Profiling 打点与日志随后将aclrt枚举显式转型为rt枚举如static_castrtSnapShotStage(stage)并下沉RTS 接口层rts_snapshot.h 声明了rtSnapShotProcessLock / Unlock / Backup / Restore / GetState以及rtSnapShotCallbackRegister / Unregister并给出了六个阶段各自的注释语义值得注意的是这些 RTS 接口带有RT_DEPRECATED_MESSAGE标记说明对外正式入口是aclrt层RTS 层属于内部实现细节功能实现层src/runtime/feature/snapshot 目录包含snapshot_process_helper.cc进程级备份/恢复编排、device_snapshot.ccDevice 级内存备份/恢复、snapshot_callback_manager.cc回调管理、snapshot_callback_manager/device_snapshot的tiny平台桩实现stub以及按硬件代际区分的v100/v200_base适配器。6.2 备份链路先同步、再备份任务与内存snapshot_process_helper.cc 中的SnapShotProcessBackup()揭示了备份的完整编排SnapShotPreProcessBackup先对所有活跃 Context 执行Synchronize(-1)永不超时确保 Device 上已无任务在执行——这是快照一致性的第一步保证备份窗口内不存在执行到一半的任务逐 Device 处理遍历所有已打开的 DeviceQueryCustomAicpuProcess探测该 Device 上是否存在自定义 AICPU 进程随后调用ModelBackup对每个 Context 下的 Model 逐个检查执行器类型不是EXECUTOR_TS的 Model如 AICPU 执行类型不支持快照返回特性不支持错误尚未加载完成的 Model 会报RT_ERROR_SNAPSHOT_BACKUP_FAILED对每个可备份的 Model 执行SinkSqTasksBackup()把已下发到硬件的任务队列信息固化下来SinkTaskMemoryBackup经IDeviceSnapshotOps::OpMemoryBackup()将任务参数内存拷回 Host 侧。最后调用NpuDriver::ProcessResBackup()完成进程级资源的 Driver 侧备份。OpMemoryBackup的实现位于 device_snapshot.cc它先通过TaskHandlers中的处理器集合如HandleStreamSwitch、HandleMemWaitValue等按任务类型分别提取任务中引用的虚拟地址段汇总所有 Model 的 Stream 上需要备份的地址区间再一次性分配 Host 内存用MemCopySync将各段设备内存紧凑拷入 Host 缓冲——这正是文档所说将 Device 资源保存在 Host 侧的具体形态。6.3 恢复链路重建页表、资源 ID 与模型snapShotProcessRestore()的恢复顺序与备份严格对应、且顺序敏感SnapShotDeviceRestore重新打开所有 Devicedev-ReOpen()随后NpuDriver::ProcessResRestore()恢复进程上所有的页表信息——Device 侧内存映射是恢复的地基SnapShotResourceRestore在 Context 维度重新申请所有 Stream ID、Event ID / Notify ID / Count Notify IDStreamsRestore、EventsReAllocId、NotifiesReAllocId等。源码注释特别指出重新下发 device 上的配置任务需要在 stream 上下发任务因此必须在 stream 恢复之后做体现了资源重建的顺序约束逐 Device 恢复内存与池IDeviceSnapshotOps::OpMemoryRestore()将备份阶段保存在 Host 侧的任务参数内存经控制 Stream 异步拷回设备并同步完成ArgsPoolRestore/UbArgsPoolRestore重映射各类参数池H2D 拷贝策略相关的参数池、UB 参数池的地址ModelRestore对每个 Model 执行ReBuild()基于备份重建模型的任务结构SnapShotAclGraphRestore处理 ACL-GraphGraph 捕获模型相关资源的重建与 SqCqPool 恢复最后处理自定义 AICPU 进程场景按批单批上限 1024 个 so批量重新加载自定义 AICPU soBatchLoadCustomAicpuSo并重建 AICPU DFX 状态。从上述链路可以看出恢复 Device 资源并不是简单的内存拷贝而是页表 → 资源 ID → 任务参数内存 → 模型 → Graph → AICPU 加载态的整套重建过程这也解释了为什么文档强调恢复必须发生在与备份相同的 Device ID 上、且该 Device 不能被其他进程占用——页表与资源 ID 的重建都锚定在具体 Device 的 Driver 会话之上。7. 小结与实践建议要点说明状态机RUNNING →Lock→ LOCKED →Backup→ BACKED_UP →Restore→ LOCKED →Unlock→ RUNNING备份次数支持多次备份以最后一次备份点为准恢复约束备份与恢复必须同一 Device IDDevice 被其他进程占用则恢复失败pid 限制仅支持本进程 ID入口层强校验不支持跨进程快照参数限制reserve/args当前仅支持传NULL回调六个阶段可注册不支持重复注册回调返回 0 表示成功适用产品Ascend 950PR、Atlas A3 训练/推理系列、Atlas A2 训练/推理系列支持其余产品不支持定位试验特性后续版本可能变更不可用于生产环境如需继续深入建议按以下路径阅读仓库源码接口声明 acl_rt.h → 参数校验入口 snapshot.cpp → RTS 接口定义 rts_snapshot.h → 进程级编排 snapshot_process_helper.cc → Device 级内存备份/恢复 device_snapshot.cc。【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表