CANN pyasc 贡献指南:从特性分级、Issue 创建到代码合入的完整实践
2026/9/18 18:00:41 网站建设 项目流程

CANN pyasc 贡献指南:从特性分级、Issue 创建到代码合入的完整实践

【免费下载链接】pyasc本项目为Python用户提供算子编程接口,支持在昇腾AI处理器上加速计算,接口与Ascend C一一对应并遵守Python原生语法。项目地址: https://gitcode.com/cann/pyasc

CANN pyasc 是一个为昇腾 AI 处理器提供 Python 算子编程接口的开源项目,其接口与 Ascend C 一一对应并遵循 Python 原生语法。本文基于仓库根目录的 CONTRIBUTING.md 贡献指南,系统梳理 pyasc 社区贡献的完整链路——特性分级(L1/L2/L3)、Issue 创建、方案评审、experimental 与 master 双分支合入流程、PR 上库要求(代码/文档交付件与合规检查),并结合仓库内的开发指南、门禁脚本与测试目录,说明一次"从 Issue 到合入"的贡献应如何落地。读完本文,你将掌握 pyasc 社区贡献的规范化流程,以及为 pyasc 新增一个 Ascend C API 的 Python 编程接口时所需准备的全部交付件。

一、贡献特性分类:L1 / L2 / L3 三级划分

参与 pyasc 贡献前,首先要判断你的变更属于哪一类特性,不同分类对应不同的贡献流程与评审深度。分类依据来自 CONTRIBUTING.md:

分类说明典型示例
L1(轻量特性)简单的新增需求 / Bug 修复 / 特性优化 / 文档纠错等(< 200 行)新增 Ascend C Python API 接口、已支持特性场景 Bug 修复、性能优化、API 文档描述错误纠正等
L2(大特性)大的功能特性 / 性能增强特性等新增当前代码框架未支持的 PASS 优化大颗粒特性等
L3(架构变更)核心接口变更 / 重大重构等对外接口目录调整、对外核心流程接口变更、端到端编译运行流程变更等

其中,L1 中的"新增 Ascend C Python API 接口"是 pyasc 社区最常见的贡献形态。以仓库 docs/developer_guide.md 中的说明,新增一个 API 接口通常涉及四个开发模块:Python 前端模块(必需)、ASC-IR 定义模块(必需)、AST 转 ASC-IR 模块(非必需)、Ascend C 代码生成模块(非必需),这与 L1 特性"< 200 行"的规模预期基本吻合。

二、L1 特性贡献流程:Issue → 提交 → 标记完成

L1 特性(含 Bug 修复、文档纠错)流程最轻量,共三步:

Step1:创建 Issue

根据变更类型创建对应类别的 Issue:

类型创建方式Issue 分配
新需求新建Requirement\|需求建议类 Issue,阐明新增特性的设计方案在评论框中输入/assign/assign @yourself
Bug 修复新建Bug-Report\|缺陷反馈类 Issue 描述 Bug在评论框中输入/assign/assign @yourself
特性优化新建Requirement\|需求建议类 Issue 说明优化点,提供设计方案在评论框中输入/assign/assign @yourself
文档纠错新建Documentation\|文档反馈类 Issue 指出文档问题在评论框中输入/assign/assign @yourself

新需求类 Issue 一般需包含以下内容:

  • 背景信息:为什么要做这个需求;
  • 价值 / 作用:该需求解决什么问题、带来什么收益;
  • 设计方案:技术路线与实现思路。

Step2:代码提交与合入

  • 若为master分支上的特性内容,遵守master 主线分支的代码提交与合入流程
  • 若为experimental分支上的特性内容,遵守experimental 分支的代码提交与合入流程

Step3:标记 Issue 已完成

代码合入并验证通过后,将对应 Issue 标记为已完成,闭环整个流程。

三、L2 与 L3 特性贡献流程:增加方案预讨论与 sig 评审

L2(大特性)与 L3(架构变更)相比 L1 多出方案预讨论sig 评审两个关键阶段,整体流程为:

Step1:创建 Issue

同 L1 类特性的创建 Issue 步骤。

Step2:方案预讨论

  • Issue 责任人找 sig 成员的 maintainer 指定架构师,进行方案预讨论,讨论形式可以是 Issue 区讨论或单独会议;
  • 预讨论完成后,架构师勾选 Issue 状态为技术评审中,之后进入下一阶段——sig 评审方案。

Step3:sig 评审方案

  • 申报 sig 评审议题:由 Issue 责任人申报评审议题;
  • 参加 sig 例会评审方案:按时参加 sig 例会进行方案评审。

评审结果分两种情况:

  • ❌ 评审未通过:可重新设计方案,继续 Step2 → Step3 流程;若需求未接纳,则流程终止。
  • ✅ 评审通过:由 Issue 责任人填写会议纪要,重点包含以下信息:
    • 评审通过结论(如有遗留问题,请记录遗留问题内容和闭环时间);
    • sig 指定的新特性合入分支名(如有)——请重点关注这一项,新特性一般先合入对应特性分支,待验证充分且稳定后再同步合入 master 分支,新特性分支名由 sig 指定;
    • sig 指定的新特性发布内容和 roadmap 节点(如有)。

基于评审结论纪要,找 sig 成员勾选 Issue 状态为已确认,并创建对应新特性分支(如有),之后进入下一阶段——合入 experimental 分支。

Step4:合入 experimental 分支

遵守 experimental 分支的代码提交与合入流程,完成代码开发与合入。

Step5:合入 master 主线分支

遵守 master 主线分支的代码提交与合入流程。此阶段有以下注意事项:

  • 准备合入master主线分支的内容,必须已合入experimental分支,且经过充分验证(如对应新增的 UT/ST 测试);
  • 准备合入master主线分支前,建议跟 sig 成员的 maintainer 对齐合入时间,避免代码被拒绝合入(可在 PR 评论区 @maintainer_gitcode_id 对齐合入时间);
  • 相较于合入experimental分支,多一步关键流程:触发 CI 门禁并通过

Step6:标记 Issue 已完成

四、双分支代码合入流程:experimental 与 master

pyasc 采用experimental(特性验证)→ master(主线发布)的双分支演进策略,两条合入路径的差异核心在于 master 多了 CI 门禁环节。

experimental 分支的代码提交与合入流程

关键流程如下:

  1. Fork 仓库:将 pyasc 仓库 fork 到自己的命名空间下;
  2. 本地开发验证:在本地完成代码开发、编译与自测;
  3. 提交 Pull Request:向 experimental 分支提交 PR;
  4. 代码检视:找 sig 成员的 Committer 进行代码检视(可在评论区 @committer_gitcode_id 提醒);
  5. 闭环检视意见:找参与代码检视的对应 Committer 确认意见已闭环,然后申请加分 lgtm/approve;
  6. 合入 experimental 分支

master 主线分支的代码提交与合入流程

关键流程如下:

  1. Fork 仓库
  2. 本地开发验证
  3. 提交 Pull Request
  4. 触发 CI 门禁并通过
    • 通过评论compile指令触发开源仓门禁,并依据 CI 检测结果进行修改;
    • 目前 CI 门禁包含以下检查项:代码编译、静态检查、UT 测试、冒烟测试
    • 如涉及 codecheck 误报,请提交给 sig 成员 Committer 屏蔽;如未及时处理,可在评论区 @committer_gitcode_id 提醒进行代码告警屏蔽处理;
  5. 代码检视:找 sig 成员的 Committer 进行代码检视;
  6. 闭环检视意见:确认意见闭环后申请加分 lgtm/approve;
  7. 合入 master 主线分支

仓库中的门禁脚本佐证

CI 门禁中的"静态检查"在仓库中有对应的可执行脚本实现,可提前在本地自查:

  • scripts/static_check.sh:对origin/master与 HEAD 之间的变更 C/C++ 文件执行两轮检查——clang-format-diff检查代码格式、clang-tidy-diff做静态分析,支持通过compile_commands.json或手动编译参数(-std=c++17 -I${PROJECT_ROOT}/include)驱动;脚本内置了TIDY_IGNORE_LIST白名单(例如python/asc/lib/runtime/print_utils.cppPrintWorkSpace符号因extern "C"ABI 需保留 PascalCase 而豁免readability-identifier-naming检查),最终输出clang-format-diff: N lines need formattingclang-tidy-diff: N error(s), N warning(s)汇总并判定 PASSED/FAILED;
  • scripts/oat_check.sh:OAT 开源合规预提交检查(Python 版,依赖oat-py>=1.0.1)。支持 PR 范围模式(基于 merge-base 收集整个 PR 的变更文件)与暂存文件模式,结合仓库根目录 OAT.xml 中的合规策略(CANN-2.0 许可证、华为版权头、禁止二进制文件类型)扫描文件,仅对Invalid File Type(非法文件类型)License Header Invalid(缺少版权头)两类问题阻断提交,并在oat_reports/result.txt中输出扫描汇总。

五、PR 上库要求:代码交付件、文档交付件与合规检查

无论走哪条合入路径,PR 上库前都必须满足以下要求。

代码交付件

  • 需提供新特性的功能实现文件和测试用例文件;
  • 如果是贡献新的 Ascend C API 的 Python 编程接口,请参考 《Ascend C Python 编程接口开发指南》,完成对应代码交付件。该指南给出了完整的四模块开发链路:
    • Python 前端模块(必需):在python/asc/language/下的adv(高阶 API)、basic(基础 API)、core(核心数据结构与枚举)、fwk(内存管理与同步控制,含 TPipe/TQue)目录中新增接口代码;
    • ASC-IR 定义模块(必需):在include/ascir/Dialect/Asc/IR/下新增 OP 节点定义(基于 MLIR/TableGen 语法);
    • AST 转 ASC-IR 模块(非必需):在python/asc/codegen/function_visitor.py中新增语法节点处理接口;
    • Ascend C 代码生成模块(非必需):实现对应 API 的 ASC-IR 转 Ascend C 代码功能,涉及lib/Target/AscendC/下的实现文件。

文档交付件

  • 新特性 README 文档为必选,其余文档可视情况提供;
  • 如果是贡献新的 Ascend C API 的 Python 编程接口,请参考 《Ascend C Python 编程接口开发指南》,完成对应文档交付件,其中 Python 接口资料(必需)的具体开发方法可参考 API 文档自动生成工具使用指南。

合规检查

  • 代码是否符合 《C++ 编程规范》(项目内文档,基本参考 LLVM 代码风格并结合项目特点做约束)和 Python 的 PEP8 规范(pyproject.toml中配置了ruff(line-length 120)与yapf(column_limit 120)作为自动格式化工具);
  • 代码是否编译通过;
  • Markdown 文档语法是否符合规范。

PR 提交

  • 通过git命令提交目标分支 PR;
  • 检查 PR 标题是否清晰、PR 描述是否规范(指明更改内容和原因、是否关联对应 Issue);
  • 检查是否签署 CLA。

六、贡献落地示例:以新增一个 Ascend C Python 接口为例

结合 docs/developer_guide.md,以基础 API 中最典型的双目矢量运算接口add(对应 Ascend C 的Add)为例,说明一份 L1 特性 PR 应包含的完整交付件:

1. Python 前端模块实现(python/asc/language/basic/vec_binary.py)

接口按"@overload声明重载 +@require_jit实现"的模式编写,覆盖 L0/L1/L2 三种重载形态(连续 count 模式、mask 逐 bit 模式、mask 数组模式):

@overload def add(dst: LocalTensor, src0: LocalTensor, src1: LocalTensor, count: int, is_set_mask: bool = True) -> None: ... @overload def add(dst: LocalTensor, src0: LocalTensor, src1: LocalTensor, mask: int, repeat_times: int, repeat_params: BinaryRepeatParams, is_set_mask: bool = True) -> None: ... @overload def add(dst: LocalTensor, src0: LocalTensor, src1: LocalTensor, mask: List[int], repeat_times: int, repeat_params: BinaryRepeatParams, is_set_mask: bool = True) -> None: ... @require_jit @set_binary_docstring(cpp_name="Add", append_text="按元素求和。") def add(dst: LocalTensor, src0: LocalTensor, src1: LocalTensor, *args, **kwargs) -> None: builder = global_builder.get_ir_builder() op_impl("add", dst, src0, src1, args, kwargs, builder.create_asc_AddL0Op, builder.create_asc_AddL1Op, builder.create_asc_AddL2Op)

2. ASC-IR 定义(include/ascir/Dialect/Asc/IR/Base.td)

Add 属于双目矢量计算 API,可直接复用仓库提供的BinaryTemplateL0123Op模板,一行完成 L0/L1/L2/L3 四个 Op 的定义:

defm Add : BinaryTemplateL0123Op<"add", "Add", "operator+">;

3. UT 测试用例(代码交付件中的必需项)

  • Python 前端 UT:在 python/test/unit/language/basic/test_vector_binary.py 中编写测试,通过mock_launcher_run桩函数验证编译与执行流程,运行命令:

    pytest ./python/test/unit/language/basic/test_vector_binary.py
  • ASC-IR / 代码生成 UT:采用 MLIR 的 lit 框架,测试文件位于 test/Target/AscendC/,用CHECK指令断言 ASC-IR 能正确翻译为 Ascend C 代码。

4. 文档交付件:新特性 README 为必选;Python 接口资料按 API 文档自动生成工具使用指南 生成(可见@set_binary_docstring装饰器正是该自动生成机制的入口)。

5. 合规与门禁自查:本地先跑ruff check --fixyapf -i --parallel -r规范 Python 代码(工具配置见 pyproject.toml),再按 scripts/static_check.sh 与 scripts/oat_check.sh 的逻辑自查 C++ 风格与开源合规,最后在 PR 中评论compile触发 CI 门禁(编译、静态检查、UT、冒烟测试四项),全部通过后找 Committer 检视并申请 lgtm/approve 合入。

七、常见问题与注意事项

  • master 与 experimental 的关系:任何准备进入 master 的内容都必须先在 experimental 分支合入并经过充分验证,这是两条分支流程最本质的区别;
  • CI 门禁误报处理:如遇 codecheck 误报,应提交给 sig 成员 Committer 屏蔽,而不是绕过门禁强行合入;
  • 新特性分支:L2/L3 特性经 sig 评审通过后,一般先合入 sig 指定的特性分支,验证稳定后再同步 master,切勿在评审通过前直接向 master 提交;
  • 交付件完整性:新增 Ascend C Python 接口时,Python 前端代码、ASC-IR 定义、UT 用例、Python 接口资料与 README 缺一不可,可对照 docs/developer_guide.md 的"开发内容"与"交付件"清单逐项核对;
  • 仓库定位:本仓库为只读的公开仓库,贡献者通过 Fork + PR 方式参与,不直接修改主线代码。

【免费下载链接】pyasc本项目为Python用户提供算子编程接口,支持在昇腾AI处理器上加速计算,接口与Ascend C一一对应并遵守Python原生语法。项目地址: https://gitcode.com/cann/pyasc

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询