pyasc MatmulApiTiling.set_c_type 详解:配置 Matmul 输出矩阵 C 的位置、格式与数据类型
【免费下载链接】pyasc本项目为Python用户提供算子编程接口,支持在昇腾AI处理器上加速计算,接口与Ascend C一一对应并遵守Python原生语法。项目地址: https://gitcode.com/cann/pyasc
asc.lib.host.MatmulApiTiling.set_c_type是 CANN pyasc 中 Host 侧 Matmul Tiling 参数生成的核心接口之一,用于声明 C 矩阵(Matmul 计算结果输出矩阵)在硬件 buffer 中的位置、数据排布格式与数据类型。本文结合 pyasc 仓库源码(pybind11 绑定、Python 类型桩与 examples 工程示例)逐层拆解该接口的签名、参数语义、枚举取值、调用时序、与 Kernel 侧的一致性要求及底层实现原理,帮助开发者在昇腾 AI 处理器上正确、高效地生成 Matmul 的 Tiling 参数。
接口概览:C 矩阵在 Tiling 中的角色
在昇腾 Matmul 计算中,A、B 为输入矩阵,C 为输出矩阵(即 A × B 的结果)。Tiling 的任务是把大矩阵切分为可以在单核、单次 Cube 计算中完成的子块,并生成 Kernel 执行所需的全部切分参数。set_c_type正是告诉 Tiling 计算器“输出矩阵 C 长什么样、放在哪里”的入口。
该接口在 pyasc 中与 Kernel 侧的asc.adv.Matmul对象创建时的 C 矩阵声明一一对应。Host 侧与 Kernel 侧对 C 矩阵的描述必须一致,否则会产生错误的对齐或切分结果。pyasc 官方总览文档 asc.lib.host 将其功能概括为:“设置 C 矩阵的位置,数据格式,数据类型,是否转置等信息,这些信息需要和 kernel 侧的设置保持一致”。
函数签名
MatmulApiTiling.set_c_type(self: libhost.MatmulApiTilingBase, pos: libhost.TPosition, type: libhost.CubeFormat, data_type: libhost.DataType) -> int对应的 Ascend C 函数原型
该接口的底层实现在 C++ 侧对应matmul_tiling::MatmulApiTilingBase::SetCType:
int32_t SetCType(TPosition pos, CubeFormat type, DataType dataType, bool isTrans = false)从 pybind11 绑定源码 可以看到,Python 侧的set_c_type通过 lambda 直接转发到 C++ 的SetCType:
.def( "set_c_type", [](MatmulApiTilingBase& self, TPosition pos, CubeFormat type, DataType dataType) { return self.SetCType(pos, type, dataType); }, "pos"_a, "type"_a, "data_type"_a, ...)需要特别说明的是:Ascend C 原型中的isTrans(C 矩阵是否转置)参数在 C++ 侧有默认值false,而在 pyasc 当前的 Python 绑定中,set_c_type仅暴露了pos、type、data_type三个参数(Python 类型桩 同样只声明这三个参数)。可以推断 Python 侧行为等价于固定使用isTrans = false,即 C 矩阵默认不转置。
参数详解
| 参数 | 类型 | 含义 | 取值要点 |
|---|---|---|---|
pos | libhost.TPosition | C 矩阵所在的 buffer 位置 | 常见为TPosition.GM(全局内存);具体可选值见下文枚举说明 |
type | libhost.CubeFormat | C 矩阵的数据格式 | 常见为CubeFormat.ND;可选ND、NZ、ZN、ZZ等 |
data_type | libhost.DataType | C 矩阵的数据类型 | 如DataType.DT_FLOAT(float32)、DataType.DT_FLOAT16等 |
is_trans(C++ 侧) | bool | C 矩阵是否转置 | 默认false;Python 绑定未暴露该参数 |
pos:C 矩阵的 buffer 位置
pos表示 C 矩阵数据所在的存储位置。该枚举类型TPosition在 Enums.cpp 中由 pybind11 完整注册,可选值包括:
GM:Global Memory,全局内存,最常用的 C 矩阵位置;A1/A2/B1/B2/C1/C2:片内多级 buffer 位置;CO1/CO2:L0C 相关位置;VECIN/VECOUT/VECCALC:向量计算相关位置;LCM/SPM/SHM/TSCM:L1 缓存等位置;MAX:枚举上限标记。
对于大多数直接输出到全局内存的场景,pos传host.TPosition.GM即可。
type:C 矩阵的数据格式
type使用CubeFormat枚举,同样注册于 Enums.cpp,可选值包括:
ND:普通二维排布(行主序连续排布),Tiling 计算中最常用;NZ:昇腾 Cube 常用的 16×16 分块格式(Z 形分形格式);ZN/ZZ/NN:其他分形组合格式;ND_ALIGN:带对齐的 ND 格式;SCALAR/VECTOR:标量/向量格式;ROW_MAJOR/COLUMN_MAJOR:行主序/列主序。
选择NZ等分形格式时,Tiling 计算器会按对应分形对齐规则(如 16 元素对齐)切分 C 矩阵;若实际数据是 ND 排布,则需要在搬运或写回阶段做格式转换。常见场景直接使用host.CubeFormat.ND。
data_type:C 矩阵的数据类型
data_type使用DataType枚举(Enums.cpp),常用取值包括:
DT_FLOAT:float32,Matmul 输出最常见类型(累加结果通常为 float32);DT_FLOAT16:float16;DT_BF16/DT_BFLOAT16:bfloat16;DT_INT8/DT_INT16/DT_INT32:整型(量化场景);DT_UINT8/DT_UINT16/DT_UINT32/DT_UINT64:无符号整型;DT_DOUBLE、DT_BOOL、DT_STRING等其他类型。
C 矩阵的数据类型必须与实际写入结果的数据类型一致,例如 A/B 为 float16、累加结果为 float32 时,C 矩阵通常声明为DT_FLOAT。
返回值说明
| 返回值 | 含义 |
|---|---|
-1 | 设置失败 |
0 | 设置成功 |
若接口返回 -1,说明pos/type/data_type的组合不被当前平台或当前 Tiling 配置支持,需检查参数是否超出枚举范围或与 Kernel 侧声明冲突。
完整调用示例
以下是 set_c_type 官方文档 给出的完整示例,展示了从创建 Tiling 对象到获取 Tiling 参数的完整流程:
import asc.lib.host as host ascendc_platform = host.get_ascendc_platform() tiling = host.MatmulApiTiling(ascendc_platform) tiling.set_a_type(host.TPosition.GM, host.CubeFormat.ND, host.DataType.DT_FLOAT16) tiling.set_b_type(host.TPosition.GM, host.CubeFormat.ND, host.DataType.DT_FLOAT16) # 设置C矩阵,buffer位置为GM,数据格式为ND,数据类型为float,默认不转置 tiling.set_c_type(host.TPosition.GM, host.CubeFormat.ND, host.DataType.DT_FLOAT) tiling.set_bias_type(host.TPosition.GM, host.CubeFormat.ND, host.DataType.DT_FLOAT) tiling.set_shape(1024, 1024, 1024) tiling.set_org_shape(1024, 1024, 1024) tiling.set_bias(True) tiling.set_buffer_space(-1, -1, -1) tiling_data = host.TCubeTiling() ret = tiling.get_tiling(tiling_data)对该示例的逐步解读:
host.get_ascendc_platform():获取当前昇腾平台的平台信息对象(PlatformAscendC),Tiling 计算器依赖它获取 AI 处理器型号及各级 buffer 容量;set_a_type/set_b_type:先声明输入矩阵 A、B(位置 GM、格式 ND、类型 float16);set_c_type:声明输出矩阵 C(位置 GM、格式 ND、类型 float32),即本接口核心用途;set_bias_type:声明 Bias 类型(与set_bias(True)配套);set_shape(m, n, k)/set_org_shape(m, n, k):设置参与计算的形状与原始完整形状,单位均为元素个数;set_buffer_space(-1, -1, -1):L1 / L0C / UB 三块 buffer 空间均使用默认值(-1 表示使用 AI 处理器对应 buffer 的完整大小);host.TCubeTiling():创建 Tiling 结果容器(对应 Kernel 侧asc.adv.TCubeTiling);get_tiling(tiling_data):执行 Tiling 计算,返回值ret非 -1 即成功,结果写入tiling_data。
其余配套接口的签名与约束可参考同目录文档:set_a_type、set_b_type、set_bias_type、set_shape、set_org_shape、enable_bias、set_buffer_space、get_tiling。
Host 与 Kernel 侧的一致性要求
set_c_type描述的信息必须与 Kernel 侧创建asc.adv.Matmul对象时对 C 矩阵的声明保持一致。在 pyasc 中,Kernel 侧通过asc.adv.MatmulType声明矩阵类型,例如 examples/04_matmul_cube_only/matmul_cube_only.py 中的写法:
matmul = asc.adv.Matmul( a=asc.adv.MatmulType(asc.TPosition.GM, asc.CubeFormat.ND, a_global.dtype, IS_TRANS_A), b=asc.adv.MatmulType(asc.TPosition.GM, asc.CubeFormat.ND, b_global.dtype, IS_TRANS_B), c=asc.adv.MatmulType(asc.TPosition.GM, asc.CubeFormat.ND, c_global.dtype), bias=asc.adv.MatmulType(asc.TPosition.GM, asc.CubeFormat.ND, bias_global.dtype), )对应的 Host 侧 Tiling 生成(同文件 generate_tiling 函数):
matmul_tiling = host.MultiCoreMatmulTiling(host.get_ascendc_platform()) matmul_tiling.set_a_type(host.TPosition.GM, host.CubeFormat.ND, host.DataType.DT_FLOAT16, IS_TRANS_A) matmul_tiling.set_b_type(host.TPosition.GM, host.CubeFormat.ND, host.DataType.DT_FLOAT16, IS_TRANS_B) matmul_tiling.set_c_type(host.TPosition.GM, host.CubeFormat.ND, host.DataType.DT_FLOAT) matmul_tiling.set_bias_type(host.TPosition.GM, host.CubeFormat.ND, host.DataType.DT_FLOAT) matmul_tiling.set_dim(USE_CORE_NUM) matmul_tiling.set_org_shape(m, n, k) matmul_tiling.set_shape(m, n, k) matmul_tiling.enable_bias(ENABLE_BIAS) matmul_tiling.set_buffer_space(-1, -1, -1) tiling = asc.adv.TCubeTiling() matmul_tiling.get_tiling(tiling)对照可见,Kernel 侧MatmulType(asc.TPosition.GM, asc.CubeFormat.ND, c_global.dtype)与 Host 侧set_c_type(host.TPosition.GM, host.CubeFormat.ND, host.DataType.DT_FLOAT)保持严格一致(本例 A/B 为 float16,C 为 float32 输出)。examples/03_matmul_mix/matmul_mix.py 中的 MIX 模式示例也采用了完全相同的配对方式。
生成 Tiling 后,通过matmul_kerneltiling.used_core_num, rt.current_stream()将 Tiling 传入 Kernel,Kernel 侧asc.adv.register_matmul(pipe, workspace, matmul, tiling)与matmul.iterate_all(c_global)依据这些参数完成分块搬运与计算(见 matmul_cube_only.py)。整个调用链中,C 矩阵的“位置—格式—类型”三元组在 Host 与 Kernel 两侧各出现一次,任何一侧的偏差都会导致切分或写回错误。
底层实现原理:pybind11 绑定与动态加载
pyasc 的asc.lib.host模块并非纯 Python 实现,而是通过 pybind11 将昇腾的 C++ Tiling 库(tiling_api、platform、register)封装为 Python 可调用的扩展模块:
- 绑定源码:bindings/MatmulApiTiling.cpp 中以
py::class_<MatmulApiTilingBase>注册了全部 Tiling 接口,set_c_type通过py::def绑定到SetCType; - 枚举注册:bindings/Enums.cpp 注册
TPosition、CubeFormat、DataType等枚举,这就是host.TPosition.GM、host.CubeFormat.ND、host.DataType.DT_FLOAT这类写法的来源; - 动态加载:loader.py 在首次访问时调用系统 C++ 编译器,将
bindings/下的 4 个源文件连同昇腾头文件目录、-ltiling_api -lplatform -lregister链接参数编译为libhost共享库,并经缓存管理器加载; - 类型桩:wrappers.py 通过
ProxyMeta/ProxyBase机制提供 IDE 可识别的类型声明,其中MatmulApiTilingBase.set_c_type的声明与绑定一致,仅包含pos、type、data_type三个参数。
这意味着set_c_type的参数校验、切分计算全部由昇腾原生 Tiling 库完成,Python 层只负责参数传递与结果容器的读写(get_tiling通过tiling.addressof()获取TCubeTiling的指针并反序列化结果,见 get_tiling 文档)。因此,只要保证传入枚举值合法且与 Kernel 侧一致,即可获得与 Ascend C 完全一致的 Tiling 行为。
常见问题与排错建议
- 返回值 -1:检查
pos、type、data_type是否取值合法(可在 Python 中通过host.TPosition.__members__、host.CubeFormat.__members__、host.DataType.__members__查看全部可选值),以及是否与 Kernel 侧MatmulType声明冲突。 - Kernel 侧结果错乱:优先核对 Host 侧
set_c_type与 Kernel 侧 C 矩阵声明的“位置—格式—类型”三元组是否完全一致;转置需求(is_trans)目前 Python 侧set_c_type未暴露独立参数,若 Kernel 侧声明了转置的 C 矩阵,需要确认当前版本支持范围。 - Tiling 计算失败排查:
get_tiling返回 -1 时,将日志级别设置为 WARNING 级别,并在日志中搜索关键字MatmulApi Tiling定位失败原因(见 get_tiling 约束说明)。 - C 矩阵对齐:当 C 矩阵数据格式为
NZ等分形格式或 M/N 不是对齐值时,Tiling 器会生成带tail信息的切分(Kernel 侧通过matmul.set_tail(tail_m, tail_n, tiling.k_a)处理边界,见 matmul_cube_only.py),使用 ND 格式 + 合理形状可简化该流程。
小结
set_c_type是 pyasc Host 侧 Matmul Tiling 配置链路(set_a_type→set_b_type→set_c_type→set_shape/set_org_shape→get_tiling)中声明输出矩阵的关键一环。掌握其参数语义(位置pos、格式type、类型data_type)、枚举取值以及与 Kernel 侧asc.adv.MatmulType的一致性要求,即可在 pyasc 中正确生成 C 矩阵相关的 Tiling 参数;配合 examples/03_matmul_mix 与 examples/04_matmul_cube_only 两个工程示例,可直接对照落地自己的 Matmul 算子。
【免费下载链接】pyasc本项目为Python用户提供算子编程接口,支持在昇腾AI处理器上加速计算,接口与Ascend C一一对应并遵守Python原生语法。项目地址: https://gitcode.com/cann/pyasc
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考