asc.language.adv.Matmul.iterate_batch
- Matmul.iterate_batch(tensor: BaseTensor, batch_a: int, batch_b: int, en_sequential_write: bool, matrix_stride_a: int = 0, matrix_stride_b: int = 0, matrix_stride_c: int = 0, en_partial_sum: bool = False, en_atomic: int = 0, sync: bool = True, wait_iterate_batch: bool | None = None) None
- Matmul.iterate_batch(tensor: BaseTensor, en_partial_sum, en_atomic, en_sequential_write: bool, matrix_stride_a: int = 0, matrix_stride_b: int = 0, matrix_stride_c: int = 0, sync: bool = True) None
该接口提供批量处理Matmul的功能,调用一次iterate_batch,可以计算出多个singleCoreM * singleCoreN大小的C矩阵。
对应的Ascend C函数原型
template <bool sync = true, bool waitIterateBatch = false> __aicore__ inline void IterateBatch(const GlobalTensor<DstT>& gm, uint32_t batchA, uint32_t batchB, bool enSequentialWrite, const uint32_t matrixStrideA = 0, const uint32_t matrixStrideB = 0, const uint32_t matrixStrideC = 0, const bool enPartialSum = false, const uint8_t enAtomic = 0)
template <bool sync = true> __aicore__ inline void IterateBatch(const LocalTensor<DstT>& ubCmatrix, uint32_t batchA, uint32_t batchB, bool enSequentialWrite, const uint32_t matrixStrideA = 0, const uint32_t matrixStrideB = 0, const uint32_t matrixStrideC = 0, const bool enPartialSum = false, const uint8_t enAtomic = 0)
__aicore__ inline void IterateBatch(const GlobalTensor<DstT>& gm, bool enPartialSum, uint8_t enAtomic, bool enSequentialWrite, const uint32_t matrixStrideA = 0, const uint32_t matrixStrideB = 0, const uint32_t matrixStrideC = 0)
__aicore__ inline void IterateBatch(const LocalTensor<DstT>& ubCmatrix, bool enPartialSum, uint8_t enAtomic, bool enSequentialWrite, const uint32_t matrixStrideA = 0, const uint32_t matrixStrideB = 0, const uint32_t matrixStrideC = 0)
参数说明
tensor: C矩阵。类型为GlobalTensor或LocalTensor。
batch_a: 左矩阵的batch数。
batch_b: 右矩阵的batch数。
en_sequential_write: 是否开启连续写模式。
matrix_stride_a: A矩阵源操作数相邻nd矩阵起始地址间的偏移,单位是元素,默认值是0。
matrix_stride_b: B矩阵源操作数相邻nd矩阵起始地址间的偏移,单位是元素,默认值是0。
matrix_stride_c: 该参数预留,开发者无需关注。
en_partial_sum: 是否将矩阵乘的结果累加于现有的CO1数据,默认值为false。
en_atomic: 是否开启Atomic操作,默认值为0。
sync: 设置同步或者异步模式。
wait_iterate_batch: 是否需要通过wait_iterate_batch接口等待iterate_batch执行结束,仅在异步场景下使用。
约束说明
该接口只支持Norm模板,即BatchMatmul只支持Norm模板。
对于BSNGD、SBNGD、BNGS1S2 Layout格式,输入A、B矩阵按分形对齐后的多Batch数据总和应小于L1 Buffer的大小;对于NORMAL Layout格式没有这种限制,但需通过MatmulConfig配置输入A、B矩阵多Batch数据大小与L1 Buffer的大小关系;
对于BSNGD、SBNGD、BNGS1S2 Layout格式,称左矩阵、右矩阵的G轴分别为a_layout_info_g、b_layout_info_g,则a_layout_info_g / batch_a = b_layout_info_g / batch_b;对于NORMAL Layout格式,batch_a、batch_b必须满足倍数关系。
如果接口输出到Unified Buffer上,输出C矩阵大小Base_m*Base_n应小于分配的Unified Buffer内存大小。
如果接口输出到Unified Buffer上,且单核计算的N方向大小single_core_n非32字节对齐,C矩阵的CubeFormat仅支持ND_ALIGN格式,输出C矩阵片时,自动将single_core_n方向上的数据补齐至32字节。
对于BSNGD、SBNGD Layout格式,输入输出只支持ND格式数据。对于BNGS1S2、NORMAL Layout格式, 输入支持ND/NZ格式数据。
对于BSNGD、SBNGD Layout格式,不支持连续写模式。
该接口不支持量化模式,即不支持set_quant_scalar、set_quant_vector接口。
BSNGD场景,不支持一次计算多行SD,需要算子程序中循环计算,即(a_layout_info_n * a_layout_info_g) / batch_a、(b_layout_info_n * b_layout_info_g) / batch_b均为整数。
异步模式不支持iterate_batch搬运到UB上。
当使能MixDualMaster(双主模式)场景时,即模板参数enableMixDualMaster设置为true,不支持使用该接口。
使用该接口时,A矩阵、B矩阵不支持int4b_t类型的输入,即BatchMatmul不支持int4b_t类型的矩阵输入。
调用示例
# 定义matmul type a_type = asc.adv.MatmulType(asc.TPosition.GM, asc.CubeFormat.ND, asc.half, False, asc.LayoutMode.BSNGD) b_type = asc.adv.MatmulType(asc.TPosition.GM, asc.CubeFormat.ND, asc.half, True, asc.LayoutMode.BSNGD) c_type = asc.adv.MatmulType(asc.TPosition.GM, asc.CubeFormat.ND, asc.float, False, asc.LayoutMode.BNGS1S2) bias_type = asc.adv.MatmulType(asc.TPosition.GM, asc.CubeFormat.ND, asc.float) mm = asc.adv.Matmul(a_type, b_type, c_type, bias_type) asc.adv.register_matmul(pipe, mm) mm.init(tiling) batch_c = batch_a if batch_b > batch_c: batch_c = batch_b g_lay = tiling.a_layout_info_g if tiling.b_layout_info > g_lay: g_lay = tiling.b_layout_info_g for_extent = tiling.a_layout_info_b * tiling.a_layout_info_n * g_lay / tiling.batch_num for i in range(for_extent): batch_offset_a = i * tiling.a_layout_info_d * batch_a batch_offset_b = i * tiling.b_layout_info_d * batch_b mm.set_tensor_a(gm_a[batch_offset_a], is_transpose_a_in) mm.set_tensor_b(gm_b[batch_offset_b], is_transpose_b_in) idx_c = i * batch_c if tiling.c_layout_info_g == 1 and (tiling.b_layout_info_g != 1 or tiling.a_layout_info_g != 1): d = tiling.b_layout_info_g if tiling.a_layout_info_g > d: d = tiling.a_layout_info_g idx_c = idx_c // d if tiling.is_bias: batch_offset_bias = idx_c * tiling.c_layout_info_s2 mm.ste_bias(gm_bias[batch_offset_bias]) batch_offset_c = idx_c * tiling.c_layout_info_s2 if c_type.layout == asc.LayoutMode.BNGS1S2: batch_offset_c = idx_c * tiling.c_layout_infos2 * tiling.c_layout_info_s1 mm.iterate_batch(tensor=gm_c[offsetc], batch_a=batch_a, batch_b=batch_b, en_sequential_write=False)