CANN pyasc 算子开发:asc.language.adv.get_ib_share_norm_config 详解与 IBShare Matmul 模板实战
【免费下载链接】pyasc本项目为Python用户提供算子编程接口,支持在昇腾AI处理器上加速计算,接口与Ascend C一一对应并遵守Python原生语法。项目地址: https://gitcode.com/cann/pyasc
asc.language.adv.get_ib_share_norm_config是 CANN pyasc(Python 算子编程接口,接口与 Ascend C 一一对应并遵守 Python 原生语法)中用于配置IBShare Matmul 模板的核心函数。本文围绕该 API 的函数签名、六个关键配置参数、返回值 MatmulConfig 的底层实现与典型调用链路展开,帮助你在昇腾 AI 处理器上正确配置并启动 IBShare 模板的矩阵乘法算子,并理解其在多 Batch、L1 Buffer 缓存等场景下的调优思路。
函数定位:IBShare 模板的自定义配置入口
在 pyasc 的asc.language.adv高级编程接口中,Matmul 相关 API 提供了一组“配置模板”风格的快捷函数,包括get_basic_config、get_ib_share_norm_config、get_mm_config、get_normal_config、get_mdl_config等,它们统一返回MatmulConfig结构体,供asc.adv.Matmul构造函数使用。
其中get_ib_share_norm_config专用于配置 IBShare 模板的参数并获取自定义 IBShare 模板。从 pyasc 源码看,IBShare 模板在配置体系中是一类独立模式:在 python/asc/language/adv/matmul.py 的get_mm_config实现中,当配置模式为CONFIG_IBSHARE时,会设置norm=False、ib_share=True,最终写入MatmulConfig.do_ib_share_norm字段;而get_ib_share_norm_config则通过该字段的组合直接生成一份 IBShare 配置,无需手动维护一长串构造函数参数。
asc.adv.get_ib_share_norm_config(intrinsics_limit: bool | None = False, batch_loop: bool | None = False, is_vec_nd2_nz: bool | None = False, bmm_mode: BatchMode | None = BatchMode.BATCH_LESS_THAN_L1, is_double_cache: bool | None = False, en_unit_flag: bool | None = True) -> MatmulConfig该函数在 pyasc 中定义于 python/asc/language/adv/matmul.py,并导出于asc.language.adv命名空间(见 python/asc/language/adv/init.py)。
提示:函数参数均带默认值,且源码中显式处理了
None入参,将其回落为默认值(matmul.py)。因此无论传None还是不传参,行为一致。
对应的 Ascend C 函数原型
get_ib_share_norm_config与 Ascend C 中的GetIBShareNormConfig一一对应,是后者在 Python 侧的封装。其 C++ 原型为:
__aicore__ constexpr MatmulConfig GetIBShareNormConfig(const bool intrinsicsLimit = false, const bool batchLoop = false, const bool isVecND2NZ = false, const BatchMode bmmMode = BatchMode::BATCH_LESS_THAN_L1, const bool isDoubleCache = false, const bool enUnitFlag = true)可以看到 Python 参数与 C++ 参数按位置一一映射:intrinsics_limit → intrinsicsLimit、batch_loop → batchLoop、is_vec_nd2_nz → isVecND2NZ、bmm_mode → bmmMode、is_double_cache → isDoubleCache、en_unit_flag → enUnitFlag,这正体现了 pyasc 项目“接口与 Ascend C 一一对应”的设计原则。
参数详解与取值语义
该函数共六个可选参数,覆盖了 IBShare 模板在循环搬数、Batch 切分、数据布局转换、L1 缓存策略与同步标志五个维度的配置。下面结合默认值与源码实现逐一说明。
intrinsics_limit(默认 False):内轴循环搬数开关
对应 Ascend C 参数intrinsicsCheck,用于控制大内轴场景下的数据搬入方式:
False(默认):当左矩阵或右矩阵在单核上内轴(K 维)大于等于 65535时,不使能循环执行数据的搬入;True:当左矩阵或右矩阵在单核上内轴大于等于 65535 时,使能循环执行数据的搬入。
内轴即 Matmul 的 K 维。当 K 很大(≥65535)时,一次性搬入可能受指令/寄存器资源限制,使能循环搬入可以分次搬运数据,属于面向超大 K 维场景的可靠性开关。该参数在 pyasc 中映射为MatmulConfig.intrinsics_check字段。
bmm_mode(默认 BatchMode.BATCH_LESS_THAN_L1):Batch 数据量与 L1 的容量关系
对应batchMode,用于描述 Batch(多 batch 矩阵乘)数据总量与 L1 Buffer 大小的相对关系,取值来自 python/asc/language/core/enums.py 中的BatchMode枚举:
| 取值 | 语义 |
|---|---|
BatchMode.BATCH_LESS_THAN_L1 | 多 batch 数据总和 < L1 Buffer Size(默认值) |
BatchMode.BATCH_LARGE_THAN_L1 | 多 batch 数据总和 > L1 Buffer Size |
BatchMode.SINGLE_LARGE_THAN_L1 | 单 batch 数据总和 > L1 Buffer Size |
该枚举在 C 侧对应batchMode::BATCH_LESS_THAN_L1等值。从源码看,batch_mode取值被约束在[1, 2, 3]范围内(对应上述三种模式,matmul.py),传入其他值会触发参数校验失败。正确设置该参数有助于编译器/运行时决定数据在 L1 中的驻留与复用策略。
batch_loop(默认 False):多 Batch 循环开关
对应isNBatch,控制是否按多 Batch 方式循环计算:
False(默认):不使能多 Batch;True:使能多 Batch。
当需要一次处理多个 batch 的矩阵乘(BMM)且各 batch 可共享同一份 L1 缓存流程时,可将其置为True,配合bmm_mode共同描述多 batch 场景。该参数在 pyasc 中映射为MatmulConfig.is_n_batch字段。
is_vec_nd2_nz(默认 False):vector 指令 ND2NZ 转换开关
对应enVecND2NZ,控制是否通过 vector 指令完成 ND 到 NZ 的数据布局转换:
False(默认):不使能通过 vector 指令进行 ND2NZ;True:使能通过 vector 指令进行 ND2NZ。
昇腾 Cube 单元对数据布局有特定偏好(NZ 分形布局),当输入为 ND 布局时通常需要格式转换。使能该选项后由 vector 单元承担转换任务,可能改善整体流水,但会占用 vector 指令周期,需结合算子负载权衡。该参数映射为MatmulConfig.en_vec_nd2nz。
is_double_cache(默认 False):L1 双缓存开关
对应enableDoubleCache,控制 L1 Buffer 上的缓存块数:
False(默认):L1 Buffer 上同时缓存一块数据;True:使能 L1 Buffer 上同时缓存两块数据(双缓冲)。
双缓存允许在计算当前块的同时预取下一块数据,是隐藏搬运时延、提升流水并行度的常见手段,代价是 L1 占用翻倍,需保证数据量在 L1 容量范围内。该参数映射为MatmulConfig.enable_double_cache。
en_unit_flag(默认 True):UnitFlag 功能开关
对应enUnitFlag:
False:不使能 UnitFlag 功能;True(默认):使能 UnitFlag 功能。
UnitFlag 是 IBShare 模板中的同步/完成标志机制,用于标记计算单元完成状态。默认开启即可;仅当确认不需要该机制时再关闭。该参数映射为MatmulConfig.en_unit_flag。
返回值:MatmulConfig 结构体
函数返回MatmulConfig结构体,其 Python 定义位于 python/asc/language/adv/types.py。这是一个继承自IRValue的配置类,构造函数包含do_norm、do_basic_block、do_multi_data_load、intrinsics_check、is_n_batch、en_vec_nd2nz、en_unit_flag、do_ib_share_norm、batch_mode、enable_double_cache等几十个字段。
get_ib_share_norm_config在内部正是通过一次MatmulConfig(...)构造完成参数注入(matmul.py):
mm_config = MatmulConfig(intrinsics_check=intrinsics_limit, is_n_batch=batch_loop, en_vec_nd2nz=is_vec_nd2_nz, batch_mode=bmm_mode, enable_double_cache=is_double_cache, en_unit_flag=en_unit_flag) return mm_config注意该调用未显式传入do_ib_share_norm,而是采用默认值False;真正将模板切换为 IBShare 模式、并把该配置标记为 IBShare 模板的,是后续Matmul对象与get_matmul_api_tiling等接口的配合使用(下文“调用链路”部分详述)。
从MatmulConfig的构造过程可以看到,配置对象最终通过 IR Builder 的create_asc_ConstructOp生成asc_MatmulConfigType类型的 IR 句柄(types.py),即配置在编译期被静态展开进 IR,属于编译期常量,这也是该系列 API 支持constexpr语义的 Python 侧体现。
调用示例与完整链路
原文档给出的标准调用示例如下:
mm_cfg = asc.adv.get_ib_share_norm_config() mm = asc.adv.Matmul(a_type, b_type, c_type, bias_type, mm_cfg) asc.adv.register_matmul(pipe, workspace, mm, tiling) mm.set_tensor_a(gm_a) mm.set_tensor_b(gm_b) mm.set_bias(gm_bias) mm.iterate_all(gm_c)整个链路可拆解为四步:
- 生成配置:
get_ib_share_norm_config()产出MatmulConfig。需要定制时显式传入参数,例如超大 K 维场景可写get_ib_share_norm_config(intrinsics_limit=True),多 batch 且总量超出 L1 时可写get_ib_share_norm_config(batch_loop=True, bmm_mode=asc.BatchMode.BATCH_LARGE_THAN_L1)。 - 构造 Matmul 对象:
asc.adv.Matmul(a_type, b_type, c_type, bias_type, mm_cfg)将配置传入 Matmul 模板实例。其中a_type/b_type/c_type/bias_type为asc.adv.MatmulType,描述各矩阵的位置(如TPosition.GM)、格式(如CubeFormat.ND)、数据类型(如asc.float16)与布局(如LayoutMode.BSNGD)——可参考 python/test/unit/language/adv/test_matmul.py 中 MatmulType 的构造方式。 - 注册 Matmul:
asc.adv.register_matmul(pipe, workspace, mm, tiling)完成模板与 TPipe、workspace 以及 tiling 的绑定(函数定义见 matmul.py),此时 Matmul 配置中的do_ib_share_norm等标志会随注册过程进入后续的 IR 生成与 Pass 处理流程(matmul.py)。 - 绑定输入输出并迭代计算:
set_tensor_a/set_tensor_b/set_bias绑定全局内存中的 A、B 矩阵与 bias,iterate_all(gm_c)遍历全部计算切片并把结果写入输出张量gm_c。
该 API 的可用性同样被仓库单元测试覆盖:在 python/test/unit/language/adv/test_matmul.py 的test_get_config相关用例中,asc.adv.get_ib_share_norm_config()被直接调用并随kernel_get_config一并执行,验证了其在 JIT 编译流程中的可用性。
IBShare 模板与相邻配置模板的关系
在asc.language.adv的模板体系中,IBShare 与 Normal、MDL、SpecialMDL 等模式由MatmulConfigMode区分。从get_mm_config的实现(matmul.py)可以推断:
CONFIG_NORM→do_norm=True(Normal 模板);CONFIG_MDL→do_multi_data_load=True(多路数据加载模板);CONFIG_SPECIALMDL→do_special_mdl=True(特化 MDL 模板);CONFIG_IBSHARE→do_ib_share_norm=True(IBShare 模板),此时do_norm=False。
可见 IBShare 是与 Normal 互斥的独立模板分支,其特点是借助多核/多 batch 之间共享 L1 Buffer 来提升缓存利用率,因此本函数专门围绕 L1 容量关系(bmm_mode)、双缓存(is_double_cache)、多 batch 循环(batch_loop)等维度开放配置项。若你的场景需要 Normal 模板,则应使用 get_normal_config;需要 MDL 模板则使用 get_mdl_config。
实战建议与注意事项
- 默认配置即可起步:
get_ib_share_norm_config()全默认参数即可用于多数常规 IBShare 场景,先跑通功能,再按瓶颈定向调参。 - K 维极大时关注 intrinsics_limit:单核内轴 ≥ 65535 时建议评估
intrinsics_limit=True,避免单次搬数过大。 - 多 batch 场景组合使用 batch_loop 与 bmm_mode:先估算所有 batch 数据总量与 L1 Buffer 的相对大小,再选择
BATCH_LESS_THAN_L1/BATCH_LARGE_THAN_L1/SINGLE_LARGE_THAN_L1;二者共同决定 L1 驻留策略。 - 访存密集时评估双缓存:
is_double_cache=True可隐藏搬运时延,但 L1 占用翻倍,需确认数据量不超容量;同时 IBShare 本身依赖 L1 共享,二者叠加时应复核 Buffer 预算。 - ND 输入可尝试 is_vec_nd2_nz:若输入为 ND 布局且 Cube 侧格式转换成为瓶颈,可开启 vector 指令 ND2NZ 转换,但要注意 vector 与 cube 指令的流水平衡。
- UnitFlag 默认保持开启:除非有明确的同步机制替换方案,否则保持
en_unit_flag=True。 - 参数可传 None:pyasc 实现中将所有
None入参显式回落为默认值,因此显式传None与不传等价,便于上层框架统一生成调用代码。
相关文档导航
- 本 API 文档:asc.language.adv.get_ib_share_norm_config
- 同系列配置模板:get_basic_config、get_mm_config、get_normal_config、get_mdl_config、get_special_mdl_config
- Matmul 模板主接口:asc.language.adv.Matmul.init、register_matmul、iterate_all
- 高级接口总览:adv
- 更多实战示例可参考仓库 examples、[examples/04_matmul_cube_only/README.md) 下的 Matmul 相关用例
【免费下载链接】pyasc本项目为Python用户提供算子编程接口,支持在昇腾AI处理器上加速计算,接口与Ascend C一一对应并遵守Python原生语法。项目地址: https://gitcode.com/cann/pyasc
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考