pyasc 算子开发指南:MatmulApiTiling.set_matmul_config_params 自定义 MatmulConfig Tiling 参数全解析
【免费下载链接】pyasc本项目为Python用户提供算子编程接口,支持在昇腾AI处理器上加速计算,接口与Ascend C一一对应并遵守Python原生语法。项目地址: https://gitcode.com/cann/pyasc
导读
在 CANN pyasc 项目中,MatmulApiTiling 是 Host 侧用于生成 Matmul 算子 Tiling 参数的核心工具类,而set_matmul_config_params则是其中负责“自定义 MatmulConfig 参数”的关键接口:它允许开发者在不改动 Tiling 主流程的前提下,显式控制模板类型、L1 缓存 UB 计算块、数据搬运模式(ScheduleType)、矩阵循环迭代顺序(Traverse)以及 ND2NZ 转换开关,从而针对特定形状与流水场景精细调优 Tiling 生成逻辑。读完本文,你将掌握该接口的完整签名、五个参数的业务含义与默认值、调用时机约束、与 Kernel 侧 MatmulConfig 保持一致性的原则,以及它在 pyasc 仓库中的 Python 绑定实现与单元测试验证方式,能够直接在算子工程中正确使用并排查相关问题。
一、接口定位:MatmulApiTiling 家族中的“自定义配置”入口
MatmulApiTiling是 pyasc Host 侧库(asc.lib.host)为昇腾 Matmul 算子提供的一站式 Tiling 计算接口。典型用法是依次调用set_a_type/set_b_type/set_c_type声明输入输出张量类型,用set_shape/set_org_shape声明矩阵形状,再用set_buffer_space声明各存储层级空间,最后调用get_tiling产出 Tiling 数据(见 asc.lib.host.MatmulApiTiling.get_tiling.md)。
set_matmul_config_params在此流程中属于“可选的额外设置”:
- 大多数常规场景下,默认的 MatmulConfig 已经可以工作,无需调用本接口;
- 当 Matmul 对象使用了特定模板策略(如 NBuffer33),或需要对流水调度、L1 缓存、迭代顺序做定向调优时,就必须通过本接口把 MatmulConfig 参数显式传给 Tiling 计算过程。
其核心原则是:本接口中配置的参数对应的功能在 Tiling 与 Kernel 中需要保持一致,即 Host 侧 Tiling 计算使用的 MatmulConfig 参数值,必须与 Kernel 侧 Matmul 对象实际使用的 MatmulConfig 参数值保持一致,否则 Tiling 与 Kernel 会出现行为不一致,导致计算错误或性能回退。
二、函数签名与两种调用形态
2.1 对应 Ascend C 函数原型
本接口在底层对应 Ascend C 的SetMatmulConfigParams,提供了两个重载:
void SetMatmulConfigParams(int32_t mmConfigTypeIn = 1, bool enableL1CacheUBIn = false, ScheduleType scheduleTypeIn = ScheduleType::INNER_PRODUCT, MatrixTraverse traverseIn = MatrixTraverse::NOSET, bool enVecND2NZIn = false) void SetMatmulConfigParams(const MatmulConfigParams& configParams)- 第一种形态:逐参数传入 5 个配置项,每个参数都有默认值;
- 第二种形态:将 5 个配置项封装进
MatmulConfigParams结构体后整体传入。
2.2 Python 侧签名
pyasc 在 Python 层对上述两个 C++ 重载分别做了绑定(源码见 python/asc/lib/host/bindings/MatmulApiTiling.cpp),类型签名声明于 python/asc/lib/host/wrappers.py:
@overload def set_matmul_config_params(self, mm_config_type_in: int = ..., enable_l1_cache_ub_in: bool = ..., schedule_type_in: ScheduleType = ..., traverse_in: MatrixTraverse = ..., en_vec_nd2nz_in: bool = ...) -> None: ... @overload def set_matmul_config_params(self, config_params: MatmulConfigParams) -> None: ...其中MatmulConfigParams在 Python 侧同样是一个可独立构造的类:
class MatmulConfigParams(ProxyBase): def __init__(self, mm_config_type: int = ..., enable_l1_cache_ub: bool = ..., schedule_type: ScheduleType = ..., traverse: MatrixTraverse = ..., en_vec_nd2nz: bool = ...) -> None: ...该结构体在 pybind11 绑定中被注册为可读写的字段类(python/asc/lib/host/bindings/MatmulApiTiling.cpp),字段名与 C++ 侧一一对应:mm_config_type、enable_l1_cache_ub、schedule_type、traverse、en_vec_nd2nz。
三、参数详解:含义、默认值与适用场景
3.1 mm_config_type_in:Matmul 模板类型
- 含义:设置 Matmul 的模板类型,该值必须与 Matmul 对象创建时所使用的模板保持一致;
- 取值约束:当前只支持配置为 0 或 1;
- 默认值:1(见 pybind11 绑定中的
"mm_config_type"_a = 1); - 注意事项:这是与 Kernel 侧一致性要求最直接的参数之一,Tiling 与 Kernel 必须使用同一模板类型,否则生成的 Tiling 参数无法匹配 Kernel 的执行逻辑。
3.2 enable_l1_cache_ub_in:L1 缓存 UB 计算块开关
- 含义:配置是否使能 L1 缓存 UB 计算块;
- 类型:
bool,默认值为False; - 参考使能场景:MTE3 与 MTE2 流水串行较多的场景。这类场景中数据搬运(MTE2 搬运 GM→L1/L0、MTE3 搬运 L1/L0→UB)相互等待、串行执行,通过 L1 缓存 UB 计算块可以缓解搬运瓶颈,改善流水重叠;
- 注意:该开关的使能同样需要在 Tiling 与 Kernel 两侧保持一致。
3.3 schedule_type_in:数据搬运模式
- 含义:配置 Matmul 的数据搬运模式(调度类型);
- 类型:
ScheduleType枚举,默认值为ScheduleType::INNER_PRODUCT; - 可选值(以仓库代码为准):
ScheduleType.INNER_PRODUCT:内积模式,默认值;ScheduleType.OUTER_PRODUCT:外积模式,单元测试中使用了该枚举值(见 python/test/unit/lib/host/test_matmul_api_tiling.py);ScheduleType.N_BUFFER_33:NBuffer33 模板策略专用的搬运模式,详见下文约束说明。
- 典型使用:若 Matmul 对象使用 NBuffer33 模板策略(
NBuffer33MatmulPolicy),则必须显式传入ScheduleType::N_BUFFER_33,以启用 NBuffer33 模板策略的 Tiling 生成逻辑(详见第四节约束说明)。
3.4 traverse_in:矩阵运算循环迭代顺序
- 含义:Matmul 做矩阵运算的循环迭代顺序。即一次迭代计算出
[baseM, baseN]大小的 C 矩阵分片后,自动偏移到下一次迭代输出的 C 矩阵位置的偏移顺序; - 类型:
MatrixTraverse枚举,默认值为MatrixTraverse::NOSET(不设置,由 Tiling 自行决定); - 可选值:除
NOSET外,仓库中set_traverse接口的文档还给出了MatrixTraverse::FIRSTM/MatrixTraverse::FIRSTN(见 python/asc/lib/host/bindings/MatmulApiTiling.cpp),即固定沿 M 方向优先或沿 N 方向优先进行迭代分片。如果希望同时固定迭代方向,也可以配合独立的 set_traverse 接口使用; - 作用:不同的 traverse 顺序会影响 C 矩阵分片在核间与流水中的排布,进而影响局部性(如 L1/L0 命中率)与搬运开销。
3.5 en_vec_nd2nz_in:ND2NZ 使能开关
- 含义:是否使能 ND2NZ(将 ND 布局数据转换为 NZ 布局);
- 类型:
bool,默认值为False; - 背景:昇腾 Cube 单元通常以 NZ(分形)格式进行计算,若输入以 ND 格式提供,则可能需要在搬运/计算路径中插入 ND2NZ 转换。此开关用于在 Tiling 侧对该转换逻辑做显式控制,同样要求与 Kernel 侧配置一致。
3.6 config_params:MatmulConfigParams 结构体
当使用第二种重载时,需要构造MatmulConfigParams对象,一次性携带上述 5 个字段。其构造函数与字段默认值(来自 pybind11 绑定 python/asc/lib/host/bindings/MatmulApiTiling.cpp)如下:
| 字段 | 类型 | 默认值 |
|---|---|---|
mm_config_type | int32 | 1 |
enable_l1_cache_ub | bool | False |
schedule_type | ScheduleType | INNER_PRODUCT |
traverse | MatrixTraverse | NOSET |
en_vec_nd2nz | bool | False |
3.7 参数速查表
| 参数 | 含义 | 类型/枚举 | 默认值 |
|---|---|---|---|
mm_config_type_in | Matmul 模板类型,须与 Matmul 对象模板一致 | int,仅支持 0 或 1 | 1 |
enable_l1_cache_ub_in | 是否使能 L1 缓存 UB 计算块(MTE3/MTE2 流水串行场景) | bool | False |
schedule_type_in | Matmul 数据搬运模式 | ScheduleType | INNER_PRODUCT |
traverse_in | C 矩阵分片迭代偏移顺序 | MatrixTraverse | NOSET |
en_vec_nd2nz_in | 是否使能 ND2NZ | bool | False |
config_params | 上述配置的封装结构体 | MatmulConfigParams | 见 3.6 |
四、返回值与调用约束
4.1 返回值
-1表示设置失败;0表示设置成功。
(说明:底层 C++ 原型SetMatmulConfigParams的返回类型为void,文档中沿用了-1/0的返回值语义说明;在 Python 绑定层,两个重载经 pybind11 绑定后按None返回,仓库单元测试中即以assert ret is None进行校验,见 python/test/unit/lib/host/test_matmul_api_tiling.py。)
4.2 约束说明
- 调用时机:本接口必须在
GetTiling(Python 侧为get_tiling)接口之前调用。因为 MatmulConfig 参数是 Tiling 计算的输入之一,只有先完成配置,后续生成的 Tiling 参数才会携带对应的调度决策; - NBuffer33 模板策略强约束:若 Matmul 对象使用 NBuffer33 模板策略(即
MatmulPolicyNBuffer33MatmulPolicy),则在调用GetTiling接口生成 Tiling 参数前,必须通过本接口将scheduleTypeIn参数设置为ScheduleType::N_BUFFER_33,以启用 NBuffer33 模板策略的 Tiling 生成逻辑。这是本接口最典型、最刚性的使用场景——不做此设置,NBuffer33 策略的 Tiling 生成逻辑不会被启用; - 一致性约束:所有参数取值需与 Kernel 侧对应的 MatmulConfig 参数值保持一致(模板类型、L1 缓存开关、搬运模式、迭代顺序、ND2NZ 开关任一不一致都可能导致 Tiling 与 Kernel 行为失配)。
五、完整调用示例:标准 Matmul Tiling 流程
以下示例完整继承自接口文档(asc.lib.host.MatmulApiTiling.set_matmul_config_params.md),并补充了参数注释,可直接作为算子 Tiling 生成代码的骨架:
import asc.lib.host as host # 1. 获取昇腾平台信息(用于 Tiling 计算所需的平台参数) ascendc_platform = host.get_ascendc_platform() tiling = host.MatmulApiTiling(ascendc_platform) # 2. 声明 A/B/C/Bias 张量的存储位置、布局与数据类型 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) 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) # 3. 声明形状:M、N、K(元素个数),以及原始形状 tiling.set_shape(1024, 1024, 1024) tiling.set_org_shape(1024, 1024, 1024) # 4. 声明是否带 Bias、各级存储空间(-1 表示按默认策略分配) tiling.set_bias(True) tiling.set_buffer_space(-1, -1, -1) # 5. 额外设置:自定义 MatmulConfig 参数(必须在 get_tiling 之前调用) # 此处仅传模板类型 0,其余参数使用默认值: # enable_l1_cache_ub=False, schedule_type=INNER_PRODUCT, # traverse=NOSET, en_vec_nd2nz=False tiling.set_matmul_config_params(0) # 6. 生成 Tiling 数据 tiling_data = host.TCubeTiling() ret = tiling.get_tiling(tiling_data)若需要一次性携带多个自定义项,推荐使用MatmulConfigParams结构体形态:
config = host.MatmulConfigParams( mm_config_type=1, enable_l1_cache_ub=False, schedule_type=host.ScheduleType.OUTER_PRODUCT, traverse=host.MatrixTraverse.FIRSTM, en_vec_nd2nz=False, ) tiling.set_matmul_config_params(config)六、源码级原理:pybind11 绑定如何实现两个重载
6.1 C++ 绑定层
在 python/asc/lib/host/bindings/MatmulApiTiling.cpp 中,set_matmul_config_params通过两次py::def完成重载注册:
- 逐参数重载:lambda 捕获 5 个参数(
int32_t mmConfigType, bool enableL1CacheUB, ScheduleType scheduleType, MatrixTraverse traverse, bool enVecND2NZ),全部带有 pybind11 关键字默认值("mm_config_type"_a = 1、"enable_l1_cache_ub"_a = false、"schedule_type"_a = ScheduleType::INNER_PRODUCT、"traverse"_a = MatrixTraverse::NOSET、"en_vec_nd2nz"_a = false),内部直接转发到self.SetMatmulConfigParams(mmConfigType, enableL1CacheUB, scheduleType, traverse, enVecND2NZ); - 结构体重载:lambda 接收
const MatmulConfigParams& configParams,转发到self.SetMatmulConfigParams(configParams)。
因此 Python 侧既可以“按位置/关键字逐个传参”,也可以“先构造MatmulConfigParams再整体传入”,两种形态最终都会落到同一组 C++SetMatmulConfigParams重载上。
6.2 MatmulConfigParams 结构体绑定
同一个源文件(python/asc/lib/host/bindings/MatmulApiTiling.cpp)还将MatmulConfigParams注册为一个可读写字段的 pybind11 类:
- 构造函数:
py::init<int32_t, bool, ScheduleType, MatrixTraverse, bool>(),五个形参mm_config_type、enable_l1_cache_ub、schedule_type、traverse、en_vec_nd2nz均有默认值; - 字段访问:通过 5 个
def_readwrite将 C++ 侧成员mmConfigType、enableL1CacheUB、scheduleType、traverse、enVecND2NZ暴露为 Python 可读写的同名小驼峰属性。
6.3 Python 侧类型声明与导出
- 类型存根位于 python/asc/lib/host/wrappers.py 与 python/asc/lib/host/wrappers.py:
MatmulConfigParams继承ProxyBase,通过代理元类在运行时把属性/方法解析到_C加载的 C++ 对象上;set_matmul_config_params以@overload形式给出两个重载签名; - 符号导出位于 python/asc/lib/host/init.py:
MatmulConfigParams、MatrixTraverse、ScheduleType等均被加入__all__,因此开发者可以直接以host.MatmulConfigParams、host.ScheduleType.OUTER_PRODUCT、host.MatrixTraverse.FIRSTM的方式访问。
从源码结构看,这种“C++ 核心实现 + pybind11 绑定 + Python 代理封装”的三层架构,是 pyasc 将 Ascend C Tiling 能力无缝映射为 Python 原生接口的通用模式(可对照 python/asc/lib/host/bindings 下的其他绑定文件)。
七、单元测试验证:接口契约的可执行证据
仓库在 python/test/unit/lib/host/test_matmul_api_tiling.py 中为set_matmul_config_params提供了两个针对性用例:
def test_set_matmul_config_params_init(asc_platform): matmul_tiling = host.MatmulApiTiling(asc_platform) matmul_tiling.set_shape(32, 256, 64) matmul_config_params = host.MatmulConfigParams(1, False, host.ScheduleType.OUTER_PRODUCT, host.MatrixTraverse.FIRSTM, False) ret = matmul_tiling.set_matmul_config_params(matmul_config_params) assert ret is None def test_set_matmul_config_params(asc_platform): matmul_tiling = host.MatmulApiTiling(asc_platform) matmul_tiling.set_shape(32, 256, 64) ret = matmul_tiling.set_matmul_config_params(1, False, host.ScheduleType.OUTER_PRODUCT, host.MatrixTraverse.FIRSTM) assert ret is None这两个用例分别验证了:
- 结构体重载:
MatmulConfigParams(1, False, ScheduleType.OUTER_PRODUCT, MatrixTraverse.FIRSTM, False)构造与传入均可用,且无返回值异常; - 逐参数重载:位置传参
(1, False, OUTER_PRODUCT, FIRSTM)(省略默认的en_vec_nd2nz)同样可用。
它们同时印证了 Python 层该接口按None返回的行为,以及ScheduleType.OUTER_PRODUCT、MatrixTraverse.FIRSTM等枚举值的真实存在。
八、实践建议与排查要点
- 调用顺序:始终把
set_matmul_config_params放在get_tiling之前;若在get_tiling之后调用,配置不会影响已经生成的 Tiling 结果。 - 与 Kernel 侧对齐:由于“Tiling 与 Kernel 需保持一致”是硬性约束,建议在算子工程中把 MatmulConfig 的定义收敛到单一常量或配置文件,Host Tiling 与 Kernel 共同引用,避免两处手写导致漂移。
- 模板类型取值:
mm_config_type仅支持 0 或 1,且必须与 Matmul 对象创建时的模板一致,传其他值可能导致 Tiling 生成失败或行为异常。 - NBuffer33 必配:使用
NBuffer33MatmulPolicy时,schedule_type必须显式传ScheduleType.N_BUFFER_33,这是最容易遗漏的硬性前置条件。 - 按需调优:默认参数(
INNER_PRODUCT/NOSET/ 不使能 L1 缓存)在常规场景足够;仅在流水串行明显(如 MTE3 与 MTE2 相互等待)或需要固定迭代方向时,才针对性地打开 L1 缓存 UB 计算块、调整traverse或schedule_type,并在实测性能后决定是否保留。
九、延伸阅读
- 本接口所属类完整方法列表:asc.lib.host.MatmulApiTiling 系列文档(含
init、get_tiling、set_traverse、set_shape、set_buffer_space等); - Host 侧 API 总览:docs/python-api/lib/host.md 与 docs/python-api/lib/index.md;
- Python 绑定实现:python/asc/lib/host/bindings/MatmulApiTiling.cpp、python/asc/lib/host/wrappers.py;
- 单元测试:python/test/unit/lib/host/test_matmul_api_tiling.py;
- 端到端示例:仓库 examples 目录下的 Matmul 类样例(如 examples/03_matmul_mix、examples/04_matmul_cube_only、examples/05_matmul_leakyrelu)展示了完整的 Matmul 算子开发链路,可结合阅读以理解 Tiling 参数在整体流程中的位置。
【免费下载链接】pyasc本项目为Python用户提供算子编程接口,支持在昇腾AI处理器上加速计算,接口与Ascend C一一对应并遵守Python原生语法。项目地址: https://gitcode.com/cann/pyasc
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考