asc-devkit 和 ascendc 算子编译过程

asc-devkit 是 Ascend C 的类库和语言扩展层源码仓(include/ + impl/ 头文件与模板实现),编译器(毕昇 ASC,随 CANN 安装)是另一个独立组件——你写的算子代码 #include asc-devkit 的头文件后,由毕昇 ASC 编译成硬件指令。两者是“库 + 编译器”的协作关系,不是“通过 asc-devkit 提交给编译器”的嵌套关系。

编译链路里各自的位置

你的算子代码(*.asc / kernel)
        │  #include "basic_api/xxx.h"
        ▼
asc-devkit 库层(include/basic_api + impl/basic_api)   ← 本次任务改这里
        │  模板实例化后调用 *Impl / 内建函数
        ▼
毕昇 ASC 编译器(CANN 安装,独立于仓库)                ← 不改
        │  处理 __ubuf__/__gm__/__vector__ 等语言关键字
        ▼
昇腾 950 硬件指令

asc-devkit 仓库里放的是纯 C++ 模板封装层include/ 下是 API 声明(基础 API 约 57 个头文件),impl/ 下是对应实现(约 244 个文件),外加样例和测试。编译器不在仓库里——任务书 3.1 节说的“毕昇 ASC 编译器”是你环境里装好的,目标架构值要和 CANN 版本匹配。

为什么本任务只改 asc-devkit 就能实现

关键在于判断:指针化所需的底层能力,编译器是否已经支持? 答案是已经支持:

  1. __ubuf__ 裸指针本身就是编译器级关键字,属于 SIMD 内建地址空间限定符,编译器早已原生支持 __ubuf__ float* 这类指针的声明、传参和运算。任务书范式示例里 __ubuf__ float xPtr[blockLength] 这种写法,现有编译器就能编过。
  2. 指针式编程范式在语言扩展层(C API)已经存在——asc-devkit 的官方描述明确说语言扩展层“基于指针编程,支持数组式内存分配与指针型计算接口”,且 Ascend 950 系列已支持这种模式。也就是说,指针写法不是新语言特性,只是 Basic API 这一层之前没开放对应入口。
  3. 本任务的改造是纯模板元编程GetUnderlyingPtrif constexpr (std::is_pointer_v<U>) 在编译期分派,裸指针原样返回、Tensor 走 GetPhyAddr(),最后都汇入既有 *Impl。这整个过程发生在头文件模板层,对编译器来说就是普通的 C++ 模板实例化,毕昇 ASC 编译它没有任何障碍。
  4. 不触碰语言语义:任务书 3.4 节明确“不得擅自变更 *Impl 数值语义”,你改的是 *Impl 之上的封装层,让同一个对外 API 既接受 Tensor 又接受指针,底层指令完全复用。
    所以整个改造的编译期闭环是:改 asc-devkit 头文件 → 你的算子代码 include 新头文件 → 毕昇 ASC 照常编译(它看到的只是多了几个模板重载)→ 硬件执行行为不变。

什么情况下才需要动编译器

作为边界判断:如果任务要求的是新增语言关键字(比如发明一个 __ubufx__ 地址空间)、修改 __ubuf__ 指针的位宽或寻址语义、或者让编译器自动完成 Tensor→指针的隐式转换——那才需要改编译器前端,工作量级完全不同。本任务不属于这类:它只是把已经存在的指针能力,通过 C++ 模板这一层“接线”接到 Basic API 的对外接口上,属于库层适配工作,所以全部变更收敛在 include/basic_apiimpl/basic_api 两个目录内即可交付。
一句话总结:asc-devkit 是库,毕昇 ASC 是编译器,二者分工明确;本任务的指针化扩展 100% 落在库层模板封装上,编译器零改动。

毕昇编译器的开源情况

算部分开源:毕昇编译器整个家族都基于开源的 LLVM 构建,鲲鹏版和部分组件已有开源仓库,CANN 也已宣布"全面开源开放"(开源了 50 余个源码仓);但你本任务用到的昇腾异构编译器(毕昇 ASC,处理 __ubuf__/__vector__ 那部分)随 CANN 商用包安装,社区可贡献的开源接口是 asc-devkit 这一类仓库——这正是任务书把改造范围限定在 asc-devkit 的现实原因之一。

毕昇编译器与昇腾软件栈的开源状态

组件基础/来源开源状态社区可否直接改
LLVM 上游开源基金会项目完全开源可以(llvm.org)
毕昇编译器(鲲鹏版)基于 LLVM 深度优化的 fork已开源,有独立仓库,并入 openEuler/OEPKGS 软件源可以,走对应开源仓
毕昇 ASC(昇腾异构编译器,支持 __ubuf__ 等语言扩展)毕昇编译器的异构分支随 CANN 安装包分发;CANN 已"分层解耦与开源,开放运行时、算子编译等全层级接口",开源 50 余个源码仓有开源仓库组织(GitCode/AtomGit 上的 cann 组织),但异构编译前端的社区贡献渠道与 asc-devkit 不同
CANN(含驱动、runtime、算子库、通信库)华为自研2025 年起宣布全面开源开放,组件分仓分包可以,走 GitCode/AtomGit 的 cann 组织仓库
asc-devkit(Ascend C 类库 + 语言扩展层)基于 C++ 模板封装完全开源,GitCode 上有完整贡献指南和社区任务体系可以,本任务的 PR 就提交在这里
几个关键事实支撑这个判断:毕昇编译器官方描述明确是"基于开源 LLVM 软件开发"的编译器,其鲲鹏版在 OEPKGS 和 openEuler 社区有对应仓库;华为在 2025–2026 年的官方口径是 CANN “全面开源开放……已完成分层解耦与开源,开放运行时、算子编译等全层级接口,已开源 50 余个源码仓”;同时毕昇编译器层面"开放 AscendNPU IR 接口,通过开源社区持续输出技术能力"。但注意措辞的差别——"开放接口"和"可对编译器本体提 PR"是两回事:昇腾侧异构编译器的二进制随 CANN 安装包走版本发布(任务书 3.1 节要求"目标架构值须与已安装 CANN 版本和编译器匹配"就是这个原因),社区对它的参与更多是通过 IR 接口和周边仓库,而不是像 asc-devkit 这样直接改源码合 master。

对你这个任务意味着什么

回到你前两个问题的链条上,现在可以把整条逻辑串起来:

  1. 编译器虽然大半开源(LLVM 基底 + CANN 开源战略),但改它不是本任务的路径。 指针化所需的 __ubuf__ 裸指针能力,毕昇 ASC 编译器已经原生支持,语言扩展层的 C API 也已提供指针式编程范式,所以不存在"必须动编译器"的需求缺口。
  2. asc-devkit 是整个链路里开放度最高、贡献流程最成熟的接口——它有明确的贡献指南(基础 API 贡献指南)、社区任务体系、PR 评审规范,这正是任务书把 79 个接口、245 个重载的改造全部收敛到 include/basic_apiimpl/basic_api 的现实依据。
  3. 即便你想顺手改编译器,也不该混入本 PR:任务书第 7.3 条明确"勿将已排除符号或他分册混入本 PR 范围",昇腾异构编译器的变更属于完全不同的仓和发版节奏,混入只会导致 PR 被打回。
    一句话总结:编译器大体站在开源的 LLVM 和 CANN 开源战略之上,但"开源"不等于"这个任务该去改它"——本任务的全部闭环都在 asc-devkit 库层,编译器以已安装版本的形式作为稳定依赖存在,这正是任务设计上最省力也最不易踩坑的切分方式。
Logo

鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。

更多推荐