
CANN pyasc 算子开发MatmulApiTiling.set_fix_split 固定分块参数详解与实战【免费下载链接】pyasc本项目为Python用户提供算子编程接口支持在昇腾AI处理器上加速计算接口与Ascend C一一对应并遵守Python原生语法。项目地址: https://gitcode.com/cann/pyasc导读asc.lib.host.MatmulApiTiling.set_fix_split是 CANN pyasc 为 Python 开发者提供的 Matmul Tiling切分策略调优接口用于在 Host 侧固定 Matmul 计算中 M/N/K 三个维度的 base 分块大小base_m / base_n / base_k从而将 Tiling 结果中的分块策略从自动推导切换为人工指定。本文以 docs/python-api/lib/generated/asc.lib.host.MatmulApiTiling.set_fix_split.md 为主体结合仓库源码与单元测试系统讲解该接口的签名、参数语义、对齐约束、返回码以及如何在真实算子如 MatMulLeakyReLU 融合示例中配合get_tiling、TCubeTiling完成从 Tiling 生成到 Kernel 下发的一整套流程。读完本文你将掌握如何为 Matmul 算子固定 base 分块、规避非法 Tiling 取值并能独立校验分块参数是否满足 L0C Buffer 与分形对齐约束。一、接口总览Python 签名与 Ascend C 原型set_fix_split定义于 Host 侧 Matmul Tiling API 的 Python 封装中其函数签名与底层 C 接口一一对应。Python 接口见 python/asc/lib/host/wrappers.py 类型桩定义def set_fix_split(self, base_m_in: int -1, base_n_in: int -1, base_k_in: int -1) - int: ...对应的 Ascend C 函数原型见 python/asc/lib/host/bindings/MatmulApiTiling.cpp 的 pybind 绑定文档int32_t SetFixSplit(int32_t baseMIn -1, int32_t baseNIn -1, int32_t baseKIn -1)在 pybind 绑定层MatmulApiTiling.cpp中三个参数的默认值被显式声明为-1与 Ascend C 原型完全一致.def( set_fix_split, [](MatmulApiTilingBase self, int32_t baseMIn, int32_t baseNIn, int32_t baseKIn) { return self.SetFixSplit(baseMIn, baseNIn, baseKIn); }, base_m_in_a -1, base_n_in_a -1, base_k_in_a -1, ...从源码结构看set_fix_split通过 lambda 直接透传调用底层MatmulApiTilingBase::SetFixSplit未做额外 Python 层逻辑因此接口语义与 Ascend C 完全一致传入 -1 的维度表示该维度不固定、交由 Tiling 自动推导传入合法正整数则表示该维度的 base 分块大小强制固定为指定值。提示绑定源码中该接口的 pybind docstring 与set_double_buffer共享了同一段描述文字设置A/B/C/Bias是否使能double buffer功能……这属于文档注释的复制残留。从参数语义、约束说明与测试用例看set_fix_split的真实用途是固定 base_m / base_n / base_k 分块大小切勿被该段注释误导。二、参数说明set_fix_split共三个参数均为整型语义如下参数类型默认值含义base_m_inint-1固定 Matmul 分块后单次迭代的 M 轴长度base_m。取 -1 表示不固定由 Tiling 自动推导base_n_inint-1固定单次迭代的 N 轴长度base_n。取 -1 表示不固定base_k_inint-1固定单次迭代的 K 轴长度base_k。取 -1 表示不固定需要特别强调的是原文档参数说明一节中出现的dequant_type描述属于文档撰写时的复制错误set_fix_split并不接收任何 dequant 相关参数请以上表为准。真正的量化模式设置由同类的set_dequant_type(host.DequantType.SCALAR/TENSOR)接口负责。参数生效后的可观测结果set_fix_split设定的 base 值会最终写入 Tiling 结构体。仓库单元测试 python/test/unit/lib/host/test_matmul_api_tiling.py 验证了这一点def test_set_fix_split(asc_platform): matmul_tiling host.MatmulApiTiling(asc_platform) matmul_tiling.set_shape(32, 16, 8) ret matmul_tiling.set_fix_split(32, 16, 8) tiling asc.adv.TCubeTiling() matmul_tiling.get_tiling(tiling) assert ret 0 assert tiling.base_m 32 assert tiling.base_n 16 assert tiling.base_k 8测试同时覆盖了配套的查询接口get_base_m()、get_base_n()、get_base_k()会原样返回set_fix_split写入的 base 值见 test_matmul_api_tiling.pydef test_get_base_m(asc_platform): matmul_tiling host.MatmulApiTiling(asc_platform) matmul_tiling.set_shape(32, 16, 8) matmul_tiling.set_fix_split(32, 16, 8) base_m matmul_tiling.get_base_m() assert base_m 32这意味着 base 分块信息会贯穿Tiling 生成 → TCubeTiling 结构体 → Kernel 侧读取的完整链路Kernel 侧可直接通过tiling.base_m * tiling.base_n等字段计算迭代步长。三、返回值说明返回值含义-1设置失败通常是因为参数不满足下述约束0设置成功设置成功仅代表参数被接受。最终参数是否真正合法、能否生成可用 Tiling取决于后续get_tiling调用——若set_fix_split指定的 base 值违反约束如超过对齐上限、超出 L0C 容量get_tiling将返回失败。原文档明确指出如果 base_m 取其他超过16的值获取 Tiling 将失败。四、约束说明固定分块必须满足的两类限制固定 base 分块不是任意取值都合法必须同时满足存储容量与分形对齐两层约束。4.1 L0C Buffer 容量约束base_m × base_n 个输出元素所占的存储空间不能超过 L0C Buffer 大小即base_m * base_n * sizeof(C_TYPE) L0CSize。L0C 是 Cube 单元累加结果的存放地容量有限。当 C 矩阵数据类型变大如从 float16 换成 float32同一 base_m × base_n 占用的字节数翻倍可能突破 L0C 上限。因此选择大 base_m / base_n 时必须同步核算 C 类型字节数。4.2 分形对齐约束Fractal Alignmentbase 值必须满足硬件分形fractal存储格式的对齐要求base_m 约束base_m ceil(single_m / 16) * 16即小于等于 single_m 按 16 个元素向上对齐后的值base_n 约束base_n single_n以C0_size个元素向上对齐后的值。其中single_m为单核内 M 轴长度single_n为单核内 N 轴长度C0_size随数据类型变化对应关系如下C 数据类型C0_size个元素half / bfloat16_t16float8int8_t32int4b_t64原文档示例设single_m 12则base_m ceil(12/16)*16 16又因 base_m 必须满足分形对齐只能取 16所以 base_m 只能取 16。若取其他超过 16 的值get_tiling将失败。五、完整调用示例以下示例完整展示了set_fix_split在 MatmulApiTiling 标准配置流程中的位置源自 docs/python-api/lib/generated/asc.lib.host.MatmulApiTiling.set_fix_split.md 的调用示例import asc.lib.host as host ascendc_platform host.get_ascendc_platform() tiling host.MatmulApiTiling(ascendc_platform) # 1. 配置 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) # 2. 设置 Matmul 的形状信息 tiling.set_shape(1024, 1024, 1024) tiling.set_org_shape(1024, 1024, 1024) tiling.set_bias(True) # 3. 固定 base_m16, base_n16, base_k 交由 Tiling 自动推导 tiling.set_fix_split(16, 16, -1) # 设置固定的 base_m, base_n # 4. 使用默认 Buffer 空间配置 tiling.set_buffer_space(-1, -1, -1) # 5. 生成 Tiling 数据 tiling_data host.TCubeTiling() ret tiling.get_tiling(tiling_data)示例要点固定分块前应先通过set_shape/set_org_shape声明矩阵规模M1024, N1024, K1024set_fix_split的合法取值域以 single_m / single_n 为基准而 single 尺寸由形状与多核切分共同决定set_fix_split(16, 16, -1)表示只固定 M/N 两个维度的 baseK 维度base_k保持自动推导——这是最常见的用法set_buffer_space(-1, -1, -1)表示 L1 / L0C / UB 空间均采用默认值避免手动设置与固定分块互相冲突。六、源码级实现剖析接口从 Python 到 C 的绑定链路在 CANN pyasc 仓库中Host 侧 Matmul Tiling 接口的 Python 化实现分三层Python 类型桩python/asc/lib/host/wrappers.py声明set_fix_split的签名与默认值供类型检查与 IDE 提示使用pybind 绑定层python/asc/lib/host/bindings/MatmulApiTiling.cpp通过.def(set_fix_split, lambda ...)将 Python 调用映射到MatmulApiTilingBase::SetFixSplit并声明base_m_in/base_n_in/base_k_in三个 keyword 参数的默认值均为 -1底层 C 实现SetFixSplit属于MatmulApiTilingBase的成员方法负责把 base 值写入 Tiling 内部状态供后续get_tiling计算使用。从绑定代码的 lambda 实现return self.SetFixSplit(baseMIn, baseNIn, baseKIn);可以推断Python 层是 Ascend C 原生接口的薄封装不引入额外语义因此凡是在 Ascend C 手册中成立的约束L0C 容量、分形对齐在 pyasc 中同样严格生效。6.1 与兄弟接口的分工在MatmulApiTilingBase的接口族中与分块相关的接口还有两个注意区分接口功能差异点set_fix_split固定 base_m / base_n / base_k 为具体值强制指定取值受限set_split_range设置 baseM/baseN/baseK 的最大值和最小值设定区间而非精确值见 set_split_range 文档host.md 注明目前 Tiling 暂时不支持该功能set_double_buffer控制 A/B/C/Bias 是否使能 double buffer 及 ND2NZ/NZ2ND 转换侧重流水与格式转换与分块大小无关三者结合使用时可实现区间约束 精确固定 双缓冲的精细调优但需要注意set_split_range当前版本尚未生效分块控制实际以set_fix_split为主。七、实战案例MatMul LeakyReLU 融合算子中的固定分块仓库示例 examples/05_matmul_leakyrelu/matmul_leakyrelu.py 给出了set_fix_split的端到端实战用法。7.1 Host 侧 Tiling 生成该示例使用MultiCoreMatmulTilingMatmulApiTilingBase的子类生成 Tiling并固定较大的 base 分块def generate_tiling(m, n, k): matmul_tiling host.MultiCoreMatmulTiling(host.get_ascendc_platform()) matmul_tiling.set_a_type(host.TPosition.GM, host.CubeFormat.ND, host.DataType.DT_FLOAT16, False) matmul_tiling.set_b_type(host.TPosition.GM, host.CubeFormat.ND, host.DataType.DT_FLOAT16, False) matmul_tiling.set_c_type(host.TPosition.VECCALC, 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(2) matmul_tiling.set_org_shape(m, n, k) matmul_tiling.set_shape(m, n, k) matmul_tiling.enable_bias(True) matmul_tiling.set_traverse(host.MatrixTraverse.FIRSTM) matmul_tiling.set_fix_split(256, 128, -1) # 固定 base_m256, base_n128, base_k 自动 matmul_tiling.set_buffer_space(-1, -1, -1) tiling asc.adv.TCubeTiling() matmul_tiling.get_tiling(tiling) return tiling这里选择base_m256, base_n128的较大分块可减少迭代次数、放大 Cube 计算占比base_k-1则把 K 轴切分交给 Tiling 自动推导。该示例的 C 输出类型为DT_FLOATfloatC0_size8base_n128 恰为 8 的整数倍满足分形对齐要求。7.2 Kernel 侧消费 base 分块生成的TCubeTiling被传入 Kernel 后base 值直接参与地址偏移计算与数据搬运参数构造matmul_leakyrelu.pywith matmul.iterate() as count: relu_out_local relu_out_queue.alloc_tensor(c.dtype) matmul.get_tensor_c(relu_out_local, en_sequential_writeTrue) asc.leaky_relu(relu_out_local, relu_out_local, alpha, counttiling.base_m * tiling.base_n) relu_out_queue.enque(relu_out_local) relu_out_local relu_out_queue.deque(c.dtype) round_m tiling.single_core_m // tiling.base_m start_offset count % round_m * tiling.base_m * tiling.n count // round_m * tiling.base_n params asc.DataCopyParams( block_counttiling.base_m, block_lentiling.base_n * c.dtype.sizeof() // asc.property(asc.DEFAULT_C0_SIZE), src_stride0, dst_stride(tiling.n - tiling.base_n) * c.dtype.sizeof() // asc.property(asc.DEFAULT_C0_SIZE), ) asc.data_copy(c_global[start_offset:], relu_out_local, repeat_paramsparams) relu_out_queue.free_tensor(relu_out_local)可以看到tiling.base_m * tiling.base_n决定了 LeakyReLU 的元素处理数量round_m tiling.single_core_m // tiling.base_m决定了 M 方向的迭代轮数block_count/block_len则完全由 base 分块推导。这正说明set_fix_split的取值必须与 Kernel 侧代码约定一致——固定分块既是 Tiling 调优手段也是 Kernel 地址计算的前提。八、调优建议与使用注意事项从大分块起步在不超出 L0C 容量的前提下优先尝试较大的 base_m / base_n如示例中的 256×128减少循环迭代开销若 Kernel 侧需配合向量指令如 leaky_relu、relu还要确保base_m * base_n与向量化处理的对齐需求兼容。K 维度通常交给自动推导set_fix_split(..., -1)只固定 M/N让 base_k 由 Tiling 依据 double buffer 与流水深度自动选择往往比手工指定更稳健。先核算、后设置设置前先确认base_m * base_n * sizeof(C_TYPE) L0CSize并检查 base_m / base_n 是否满足分形对齐float 的 base_n 需为 8 的倍数half/bf16 需为 16 的倍数等否则get_tiling会直接失败。与set_buffer_space联动固定分块会显著影响 L0C/UB 占用建议保持set_buffer_space(-1, -1, -1)让框架基于固定分块自动推算剩余空间避免手动设置导致容量冲突。Tiling 与 Kernel 必须一致set_fix_split产生的 base 值会写入TCubeTiling.base_m/base_n/base_kKernel 侧的偏移计算、数据搬运参数必须与之一一对应参考 05_matmul_leakyrelu 示例否则会出现写穿或结果错位。九、小结asc.lib.host.MatmulApiTiling.set_fix_split是 pyasc Host 侧 Matmul Tiling 调优的核心接口之一它以固定 base_m / base_n / base_k的方式替代自动分块推导使开发者能够针对具体算子的访存与计算特征定制切分策略。使用该接口时需牢记两条红线L0C 容量约束与分形对齐约束其合法取值与 Kernel 侧TCubeTiling字段的消费逻辑强绑定。结合仓库单元测试test_matmul_api_tiling.py与融合算子示例matmul_leakyrelu.py开发者可以快速验证接口行为并将其安全地纳入自有算子的 Tiling 生成流程。【免费下载链接】pyasc本项目为Python用户提供算子编程接口支持在昇腾AI处理器上加速计算接口与Ascend C一一对应并遵守Python原生语法。项目地址: https://gitcode.com/cann/pyasc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考