news 2026/9/19 5:58:48

CANN Runtime 可选组件分阶段上库与回退实践:从编译单元准备到目标产品隔离

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CANN Runtime 可选组件分阶段上库与回退实践:从编译单元准备到目标产品隔离

CANN Runtime 可选组件分阶段上库与回退实践:从编译单元准备到目标产品隔离

【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime

本篇指南聚焦 CANN / runtime 仓库中“将某个 Runtime API 可选组件从目标产品中隔离出去”时的分步骤上库与回退方法论。它以三步 PR(自适应准备 → 工厂解耦 → 目标产品隔离)为核心骨架,规定每一步的稳定目标、包含项与不包含项、验收标准、独立回退方式以及聚合分支的正确用法,并结合仓库内 ApiImplMbuf / arch5162 的真实实现(如 api_impl_mbuf_stub.cc、arch5162.cmake)给出源码级佐证。读者读完后,将掌握在不破坏支持产品行为、不丢失公开 ABI 的前提下,把“不支持某组件”落实为“源文件不进入目标产品”的完整可验证实施路径。

1. 三步上库的整体设计与步骤关系

把“裁剪某个可选组件”从一次性大改拆成可独立验证、可独立回退的小步,是本次上库策略的核心。默认采用以下三步,其中第一步是否产生代码 PR 由模块特性决定,后两步为基本固定的通用模式:

步骤稳定目标是否固定实现
1. 自适应准备形成可独立裁剪的编译单元否;可拆文件、提公共能力、收敛注册依赖或直接跳过
2. 工厂解耦公共 Runtime 不感知具体实现,所有平台行为不变基本固定
3. 产品隔离目标产品停编译组件,ABI 桩返回不支持基本固定

依赖关系必须由依赖图证明,不能凭感觉假设。例如 Mbuf 案例中,第一步(PR4264,拆分 driver 编译单元)与第二步(PR4265,Runtime 工厂解耦)可以独立合入,但这只是该模块被验证过的结论,不是其他模块的默认结论。第三步始终依赖第二步,以及第一步中确有必要的准备。

从仓库现状看,Mbuf 组件已经走完了这条路径:api_impl_mbuf_stub.cc 提供了目标产品侧的IsImplMbufSupported() == falseCreateImplMbufAndGet() == nullptrDestroyImplMbuf(),而支持产品仍走 api_c_mbuf.cc →ApiMbuf::Instance()→ 具体实现的原始链路,正是“分步骤隔离”落地后的典型形态。

2. 第一步 PR:自适应准备

第一步只解决一个问题:让组件形成可以单独加入或移除的编译单元

  • 包含:模块特有的源文件拆分或依赖收敛,以及所有产品/UT CMake 同步。
  • 不包含:Runtime 工厂重构、目标产品能力关闭、ABI 桩。
  • 验收:所有产品能力和调用链不变,独立 CI 通过。
  • 回退:单独回退该 PR,即可恢复原编译单元布局。

若无需改动,则不创建空 PR,改为在方案中提供“可直接移除专属文件”的证据(例如专属源文件已存在、依赖已闭合、target 可单独移除)。

Mbuf 案例中,该步把NpuDriver::Mbuf*方法从混合职责的npu_driver_queue.cc原样移动到npu_driver_mbuf.cc(仓库中该文件现位于 src/runtime/driver/npu_driver_mbuf.cc),并让所有原正式/UT target 同时编译新文件。该步骤不修改 C API 路由,不修改 Runtime 创建方式,目标产品此时仍编译并支持 Mbuf。Mbuf 建议的分支和提交为:

refactor/api-mbuf-driver-split refactor: split NpuDriver Mbuf implementation

其他模块按实际障碍命名,不复用driver-split标题——第一步的具体动作必须按模块特性决定,不能机械复制 Mbuf。

3. 第二步 PR:工厂解耦

第二步是通用稳定模式,目标是让公共 Runtime 只依赖抽象契约,不再感知具体实现类型。

  • 包含:能力入口、抽象工厂、具体分配/日志下沉、Runtime 抽象调用和失败 UT。
  • 不包含:任何产品返回不支持、CMake 删除组件源文件、C API 桩。
  • 验收:所有原支持产品继续创建组件,普通与目标产品编译/UT/链接通过。
  • 回退:单独恢复公共 Runtime 直接创建具体实现的旧逻辑。

仓库中ApiImplMbuf解耦后的工厂契约清晰可见(api_impl_mbuf_stub.cc):

bool IsImplMbufSupported() { return false; } ApiMbuf* CreateImplMbufAndGet() { return nullptr; } void DestroyImplMbuf(ApiMbuf*& apiImplMbuf) { apiImplMbuf = nullptr; }

与之对应,公共入口 api_c_mbuf.cc 只通过ApiMbuf::Instance()拿到抽象实例,不再直接new/sizeof具体类型;同时通过COND_RETURN_WITH_NOLOG(error == RT_ERROR_FEATURE_NOT_SUPPORT, ACL_ERROR_RT_FEATURE_NOT_SUPPORT)将驱动侧的不支持错误码统一映射为对外 ABI 错误码。这一步是行为保持型重构:本阶段所有平台仍返回支持并创建原实现,避免把结构重构与能力变化放在同一 PR。

建议分支和提交:

refactor/api-<component>-runtime-decouple refactor: decouple Runtime from ApiImpl<Component>

4. 第三步 PR:目标产品隔离

第三步真正把“目标产品不支持该组件”落实为源文件不进入目标产品。它必须基于前置步骤实际合入后的最新origin/master重新执行。

  • 包含:目标平台能力关闭、目标 CMake 删除源文件、公开 C API 桩、平台 UT 和设计文档更新。
  • 不包含:支持产品行为调整、无关模块裁剪、第一步/第二步已合入内容。
  • 验收:目标对象文件缺失、ABI 集合一致、not-support UT、支持产品 UT、链接和全 CI 通过。
  • 回退:优先单独回退本 PR,即可恢复目标产品组件能力;前两步可保留。

在 arch5162(不使用 Mbuf 的目标平台)构建配置 arch5162.cmake 中可以看到隔离后的形态:api_c_mbuf.cc作为17 个 stub 的 weak real provider编译进目标库,api_impl_mbuf_stub.cc(而非真实实现api_impl_mbuf.cc)进入libruntime_api_impl_src_files,同时借助arch5162_unsupported_runtime_api.def(src/runtime/cmake/arch5162_unsupported_runtime_api.def)与generate_runtime_api_stubs生成统一的 API 桩;目标库链接选项保持-Wl,--no-undefined-Wl,--gc-sections,并用-Wl,-Bsymbolic保证桩语义不被意外覆盖。支持产品则继续走原链路,不经过平台不支持桩

建议分支和提交:

refactor/<target>-api-<component>-isolation refactor: isolate Api<Component> from <target>

5. 聚合分支:验证手段,不是交付方式

前置 PR 尚未合入时,可维护一个包含完整三步的聚合分支,用于证明最终编译、行为、ABI 和体积收益。但聚合分支不能替代分步骤 PR,其正确用法如下:

  1. 先判断第一步与第二步是否存在技术依赖。
  2. 可独立时,两者分别基于master验证和提交。
  3. 有依赖时,第二步必须等待第一步实际合入,再基于最新master提交。
  4. 前两步实际合入后,将第三步重放到最新master
  5. 确认第三步 diff 只剩目标平台差异、桩、UT 和必要文档,再运行完整 CI。

不要把尚未合入的前置提交永久保留在第三步 PR 中并宣称已完成拆分。第三步合入前应重放,使其最终 diff 只保留目标平台差异、ABI 桩、UT 和文档。

6. 冲突处理与回退

每次前置 PR 合入后,后续步骤需要与主线保持同步,推荐流程:

  1. 获取最新origin/master
  2. 在隔离 worktree 中重放后续单提交。
  3. 按 hunk 解决 CMake、平台 API 和 Runtime 生命周期冲突。
  4. 重新检查 diff 边界和单提交历史。
  5. 完整重跑本地验证和线上 CI。

故障回退顺序通常为:第三步 → 第二步 → 第一步。若第一步与第二步经证明独立,则只回退引入问题的步骤,不做捆绑回退。每一步都应支持“单独回退该 PR 即恢复原状”,这是分步上库可被接受的前提。

7. PR 描述与上库纪律

按仓库当前模板(.gitcode/PULL_REQUEST_TEMPLATE.zh-CN.md)填写 PR,并至少说明:

  • 本步骤解决的单一问题不包含项
  • 与前后步骤的技术依赖和推荐合入顺序;
  • 支持产品行为等价、目标产品不支持语义;
  • ABI、对象缺失、链接、大小和 UT 证据;
  • 实际本地命令和线上流水线 ID;
  • 独立回退方式。

代码变化后立即更新线上 PR 描述并回读确认。CI 失败修复后,替换过期验证结论,不保留“计划通过”式表述——只有实际结束且目标任务成功的流水线才能写成通过,警告、跳过和不可读日志要单独记录。推送和创建/更新 PR 前,读取仓库gitcode-prSkill 与 .gitcode/PULL_REQUEST_TEMPLATE.zh-CN.md,并且只在用户明确授权后执行线上写操作

8. 配套参考:方法与验证矩阵

本指南是runtime-api-component-isolationSkill 的提交规范部分,与以下仓库文档配套使用,可获取更完整的实施细节:

  • method.md:建立调用链、编译单元和产品矩阵,判断组件是否适合隔离,以及第一/二/三步的设计边界。
  • mbuf-case.md:PR4264 / PR4265 / PR4254 验证出的 Mbuf 完整案例,以及“可迁移”与“不可机械复用”的假设清单。
  • risk-and-validation.md:风险矩阵与验证矩阵,覆盖 ABI、链接、CMake、生命周期、静态副作用、体积、覆盖率与回退等 12 个风险域,并给出nm -Dldd -rruntime.cc.o.d依赖检查等常用证据命令。

这三份文档与本指南共同构成一套“分析 → 实施 → 验证 → 分步上库与回退”的完整闭环,适用于需要把ApiXxx/ApiImplXxx从特定芯片或构建 target 中编译隔离出去的任何 Runtime 可选组件。

【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 5:57:35

React Native与鸿蒙跨平台快递柜系统开发实践

1. 项目背景与核心价值在快递物流行业&#xff0c;末端配送环节的效率直接影响用户体验和运营成本。传统快递柜系统往往存在几个痛点&#xff1a;取件码生成规则单一、包裹状态更新不及时、查询功能简陋、表单交互体验差。这个React Native鸿蒙跨平台项目正是为了解决这些实际问…

作者头像 李华
网站建设 2026/9/19 5:57:21

微信小游戏资源管理:YooAsset的Tag与Group策略实战

1. 微信小游戏资源管理的核心矛盾与YooAsset的切入逻辑微信小游戏这个平台&#xff0c;做过的都懂&#xff0c;它跟传统的App或者端游完全是两个世界。首包体积被卡得死死的&#xff0c;微信官方对主包有硬性上限&#xff0c;超过这个线连审核都过不了。但玩家又不傻&#xff0…

作者头像 李华
网站建设 2026/9/19 5:56:47

Unity血条组件扩展:基于FUI Element的声明式绑定与生命周期管理

1. 为什么血条不能只靠“写死数值”——FUI Element 扩展的底层动因在 Unity 项目里做 UI&#xff0c;尤其是游戏类项目&#xff0c;血条&#xff08;Health Bar&#xff09;几乎是每个角色、每个敌人、甚至每个可交互物件的标配。但你有没有遇到过这样的情况&#xff1a;刚做完…

作者头像 李华
网站建设 2026/9/19 5:53:50

Jetson边缘AI实战复盘:从系统烧录到YOLOv5与Qwen大模型部署全链路

1. 为什么值得做一次系统复盘Jetson边缘嵌入式实战课程走到第十讲&#xff0c;回头把前九讲的内容串一遍&#xff0c;这件事本身就比再学一个新模型更有价值。我见过太多人学Jetson的方式是“东一榔头西一棒槌”——今天跟着教程刷个系统&#xff0c;明天抄个YOLOv5的部署脚本&…

作者头像 李华
网站建设 2026/9/19 5:52:46

WT3000A M系列对接AI大模型:边缘终端到模型侧全链路架构

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/19 5:51:23

本地网关统一管理多AI编程Agent的API Key与用量

说实话&#xff0c;我一开始也没把这事放在心上。装了三四个AI编程Agent之后&#xff0c;突然发现自己手里攒了一堆API Key&#xff1a;DeepSeek一个、豆包一个、通义一个&#xff0c;GitHub Copilot算一个&#xff0c;还有各平台送的体验额度。更要命的是&#xff0c;这些Key散…

作者头像 李华