- 人工智能
- 深度学习
- 算子库
- CANN
- Ascend
【免费下载链接】asc-devkit
本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C++标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。
Conv3DBackpropFilter 是 3D 卷积反向传播中计算权重梯度(GradWeight)的关键算子,其核函数执行效率高度依赖 Tiling 切分策略。Ascend C 在ConvBackpropApi命名空间中提供了一套 Conv3DBackpropFilter Tiling API,用户只需传入 Input、GradOutput、GradWeight 的位置(TPosition)、格式(ConvFormat)与数据类型(ConvDtype)以及 Shape、Padding、Stride、Dilation 等参数,即可自动获得核函数侧所需的完整 Tiling 参数。本文将结合 asc-devkit 仓库的源码与测试用例,完整解析这套接口的调用流程、每个成员接口的原型与参数含义、输出结构体的字段语义,以及底层 Tiling 切分算法的工作原理。
一、接口全景与获取 Tiling 的流程
Conv3DBackpropFilter Tiling API 归属于高阶 API(adv_api),用于在 Host 侧生成 Conv3DBackpropFilter 核函数(Kernel)计算所需的 Tiling 参数。其核心思路是:开发者不需要自行设计数据切分、搬运与计算策略,只需描述张量类型与算子属性,由库自动完成 Tiling 计算。
使用流程共分三步:
- 创建单核 Tiling 对象:实例化
ConvBackpropApi::Conv3dBpFilterTiling,推荐传入platform_ascendc::PlatformAscendC硬件平台信息以获得更好的兼容性。 - 设置参数:通过
SetInputType、SetWeightType、SetGradOutputType设置三个张量的位置、格式和数据类型;通过SetInputShape、SetWeightShape、SetGradOutputShape设置各自 Shape;若算子存在 Padding、Stride、Dilation,再调用对应的 Set 接口补齐属性。 - 调用
GetTiling获取结果:传入optiling::Conv3DBackpropFilterTilingData(或AscendC::tiling::Conv3DBackpropFilterTilingData)输出结构体,返回值不为 -1 即表示 Tiling 计算成功。
完整使用样例(与官方文档一致,可直接复制):
#include "tiling/conv_backprop/conv3d_bp_filter_tiling.h" optiling::Conv3DBackpropFilterTilingData tilingData; auto ascendcPlatform = platform_ascendc::PlatformAscendCManager::GetInstance(); ConvBackpropApi::Conv3dBpFilterTiling conv3dBpDwTiling(*ascendcPlatform); conv3dBpDwTiling.SetWeightType( ConvCommonApi::TPosition::GM, ConvCommonApi::ConvFormat::FRACTAL_Z_3D, ConvCommonApi::ConvDtype::FLOAT32); conv3dBpDwTiling.SetInputType( ConvCommonApi::TPosition::GM, ConvCommonApi::ConvFormat::NDC1HWC0, ConvCommonApi::ConvDtype::FLOAT16); conv3dBpDwTiling.SetGradOutputType( ConvCommonApi::TPosition::GM, ConvCommonApi::ConvFormat::NDC1HWC0, ConvCommonApi::ConvDtype::FLOAT16); conv3dBpDwTiling.SetGradOutputShape(n, c, d, h, w); conv3dBpDwTiling.SetInputShape(n, c, d, h, w); conv3dBpDwTiling.SetWeightShape(cout, cin, d, h, w); conv3dBpDwTiling.SetPadding(padFront, padBack, padUp, padDown, padLeft, padRight); conv3dBpDwTiling.SetStride(strideD, strideH, strideW); conv3dBpDwTiling.SetDilation(dilationD, dilationH, dilationW); int ret = conv3dBpDwTiling.GetTiling(tilingData); // 如果 ret = -1, 获取tiling结果失败需要包含的头文件(conv3d_bp_filter_tiling.h):
#include "tiling/conv_backprop/conv3d_bp_filter_tiling.h"二、构造函数:创建单核 Tiling 对象
Conv3dBpFilterTiling提供无参、带参两类构造函数,并继承自基类Conv3dBpFilterTilingBase。带参构造函数需要传入硬件平台信息,推荐使用以获得更好的兼容性。
函数原型
- 无参构造函数:
Conv3dBpFilterTiling()- 带参构造函数(传入
platform_ascendc::PlatformAscendC):
explicit Conv3dBpFilterTiling(const platform_ascendc::PlatformAscendC& ascendcPlatform)- 带参构造函数(传入
PlatformInfo):当platform_ascendc::PlatformAscendC无法在 Tiling 运行时获取时,需要用户自行构造PlatformInfo结构体透传:
explicit Conv3dBpFilterTiling(const PlatformInfo& platform)- 基类构造函数(
Conv3dBpFilterTilingBase):
Conv3dBpFilterTilingBase() explicit Conv3dBpFilterTilingBase(const platform_ascendc::PlatformAscendC& ascendcPlatform) explicit Conv3dBpFilterTilingBase(const PlatformInfo& platform)从 conv3d_bp_filter_tiling.h 可以看到,Conv3dBpFilterTiling : public Conv3dBpFilterTilingBase,三个构造函数分别对应默认构造、PlatformAscendC 构造与 PlatformInfo 构造,且均声明为explicit,防止隐式类型转换。
PlatformInfo 结构说明
PlatformInfo用于获取芯片版本以及 AI Core 中各个硬件单元提供的内存大小等仅针对单个 AI Core 的信息,其结构定义如下:
struct PlatformInfo { platform_ascendc::SocVersion socVersion; uint64_t l1Size = 0; uint64_t l0CSize = 0; uint64_t ubSize = 0; uint64_t l0ASize = 0; uint64_t l0BSize = 0; };各字段获取方式:
| 字段 | 说明 | 获取方式 |
|---|---|---|
| socVersion | 芯片版本 | 通过GetSocVersion获取并透传 |
| l1Size / l0ASize / l0BSize / l0CSize / ubSize | AI Core 各硬件单元存储空间大小 | 通过GetCoreMemSize获取并透传 |
[!NOTE] 不推荐通过直接填值构造 PlatformInfo 的方式调用构造函数,例如
PlatformInfo(, 1024, 1024, ..)。
两类平台信息的职责差异
platform_ascendc::PlatformAscendC:用于获取硬件平台的全局信息以支撑 Tiling 计算,例如硬件平台的核数等。PlatformInfo:用于获取芯片版本以及 AI Core 中各个硬件单元提供的内存大小等单核信息。
从 conv3d_bp_filter_tiling_base.cpp 的实现可见,构造函数会将平台信息存入受保护的成员platformInfo,后续Compute()中的 L0/L1 容量合法性判断(如IsCurBlockL1L0Invalid()比较l0ASize、l0BSize、l1Size)都依赖该成员。
使用样例
- 无参构造函数:
Convolution3DBackprop::Conv3dBpFilterTiling tiling; tiling.SetWeightType(ConvCommonApi::TPosition::GM, ConvCommonApi::ConvFormat::FRACTAL_Z_3D, ConvCommonApi::ConvDtype::FLOAT32); ... optiling::Conv3DBackpropFilterTilingData tilingData; int ret = tiling.GetTiling(tilingData); // if ret = -1, gen tiling failed ...- 带参构造函数:
auto ascendcPlatform = platform_ascendc::PlatformAscendC(context->GetPlatformInfo()); ConvBackpropApi::Conv3dBpFilterTiling tiling(ascendcPlatform); tiling.SetWeightType( ConvCommonApi::TPosition::GM, Convolution3DBackprop::ConvFormat::FRACTAL_Z_3D, ConvCommonApi::ConvDtype::FLOAT32); ... optiling::Conv3DBackpropFilterTilingData tilingData; int ret = tiling.GetTiling(tilingData); // if ret = -1, gen tiling failed三、GetTiling:获取 Tiling 参数
GetTiling是整个 Tiling 对象的出口,负责执行参数校验、Tiling 计算并将结果写入输出结构体。
函数原型
int64_t GetTiling(optiling::Conv3DBackpropFilterTilingData& tiling) int64_t GetTiling(AscendC::tiling::Conv3DBackpropFilterTilingData& tiling)两种重载分别支持optiling与AscendC::tiling命名空间下的 Tiling 结构体,便于不同 Host 侧工程接入。
返回值说明
- 返回值不为 -1:Tiling 计算成功,用户可以使用该 Tiling 结构的值。
- 返回值为-1:Tiling 计算失败,该 Tiling 结果无法使用。
底层实现原理
从 conv3d_bp_filter_tiling.cpp 的实现可见,GetTiling内部逻辑为:
- 调用
Compute()执行 Tiling 计算;若返回 -1,记录TILING_LOG_ERROR("can not gen conv3d api tiling")并直接返回 -1。 - 计算成功后调用
SetFinalTiling(tiling)将内部计算结果写入输出结构体。 - 调用
PrintTilingData()输出调试日志(TILING_LOG_DEBUG 级别),便于定位问题。
而Compute()的核心流程是(conv3d_bp_filter_tiling.cpp):
CheckInputParam()校验参数合法性;ShapeInitCalc()完成形状推导;SetBasicBlockAttrsTiling()初始化 MatMul 三轴(M/N/K)规模;InitTilingValue()初始化 DoubleBuffer 等默认开关(默认开启 L0 A/B 双缓冲);- 依据
strideHW与 kernelHW 的整除关系选择MultiCoreSplitMN()(MTE1 压力大时优先切 MN)或MultiCoreSplitK()(沿 K 方向切分)。
调用示例
#include "tiling/conv_backprop/conv3d_bp_filter_tiling.h" optiling::Conv3DBackpropFilterTilingData tilingData; auto ascendcPlatform = platform_ascendc::PlatformAscendCManager::GetInstance(); ConvBackpropApi::Conv3dBpFilterTiling conv3dBpDwTiling(*ascendcPlatform); conv3dBpDwTiling.SetWeightType( ConvCommonApi::TPosition::GM, ConvCommonApi::ConvFormat::FRACTAL_Z_3D, ConvCommonApi::ConvDtype::FLOAT32); conv3dBpDwTiling.SetInputType( ConvCommonApi::TPosition::GM, ConvCommonApi::ConvFormat::NDC1HWC0, ConvCommonApi::ConvDtype::FLOAT16); conv3dBpDwTiling.SetGradOutputType( ConvCommonApi::TPosition::GM, ConvCommonApi::ConvFormat::NDC1HWC0, ConvCommonApi::ConvDtype::FLOAT16); conv3dBpDwTiling.SetInputShape(n, c, d, h, w); conv3dBpDwTiling.SetGradOutputShape(n, c, d, h, w); conv3dBpDwTiling.SetWeightShape(cout, cin, d, h, w); conv3dBpDwTiling.SetPadding(padFront, padBack, padUp, padDown, padLeft, padRight); conv3dBpDwTiling.SetStride(strideD, strideH, strideW); conv3dBpDwTiling.SetDilation(dilationD, dilationH, dilationW); int ret = conv3dBpDwTiling.GetTiling(tilingData); // 获取tiling参数 // 使用AscendC::tiling命名空间中的Tiling结构体获取tiling参数 AscendC::tiling::Conv3DBackpropFilterTilingData tilingDataNotOp; ret = conv3dBpDwTiling.GetTiling(tilingDataNotOp);四、TConv3DBpFilterTiling 结构体:Kernel 侧消费的 Tiling 数据
TConv3DBpFilterTiling结构体包含 Conv3dBackpropFilter 算子的规格信息及 Tiling 切分算法的相关参数,会被传递给核函数(Kernel)侧,用于数据切分、数据搬运和计算。用户通过调用GetTiling接口获取该结构体,当前暂不支持用户自定义配置其中的参数。
该结构体在 conv3d_bp_filter_tilingdata.h 中通过BEGIN_TILING_DATA_DEF / TILING_DATA_FIELD_DEF / END_TILING_DATA_DEF宏定义,并通过REGISTER_TILING_DATA_CLASS注册为可序列化的 Tiling 数据结构。
张量 Shape 与算子属性字段
| 参数名称 | 说明 |
|---|---|
| batch | 输入 GradOutput 的 Batch,单位元素。 |
| cin | 输入 Input 的 Channel,单位元素。 |
| cout | 输入 GradOutput 的 Channel,单位元素。 |
| cin1G / cout1G | 预留参数,用户无需感知。 |
| dout / ho / wo | 输入 GradOutput 的 Depth / Height / Width,单位元素。 |
| di / hi / wi | 输入 Input 的 Depth / Height / Width,单位元素。 |
| dk / hk / wk | 输出 Weight 的 Depth / Height / Width,单位元素。 |
| group | 预留参数,用户无需感知。 |
| strideD / strideH / strideW | 卷积反向计算中 Stride 的 Depth / Height / Width,单位元素。 |
| padFront / padBack | 卷积反向计算中 Padding 的 Depth 维前/后方向,单位元素。 |
| padUp / padDown | 卷积反向计算中 Padding 的 Height 维上/下方向,单位元素。 |
| padLeft / padRight | 卷积反向计算中 Padding 的 Width 维左/右方向,单位元素。 |
| dilationD / dilationH / dilationW | 卷积反向计算中 Dilation 的 Depth / Height / Width,单位元素。 |
| channelSize | 当前输入数据类型下 C0 的大小,目前只支持取值为 16。 |
缓存与切分控制字段
| 参数名称 | 说明 |
|---|---|
| al0Pbuffer / bl0Pbuffer / cl0Pbuffer | L0 上 A/B/C 的 Pingpong 标志:1 表示不开启 DoubleBuffer,2 表示开启 DoubleBuffer。 |
| al1Pbuffer / bl1Pbuffer | L1 上 A/B 的 Pingpong 标志:1 表示不开启 DoubleBuffer,2 表示开启 DoubleBuffer。 |
| baseM / baseK / baseN | L0 上 M / K / N 方向大小,单位元素。 |
| m0 / k0 / n0 | L0 上最小分形 M / K / N 方向大小。 |
| stepM / stepN | 矩阵在 L1 中缓存的 buffer M / N 方向上 baseM / baseN 的倍数。 |
| stepKa / stepKb | 矩阵在 L1 中缓存的 buffer K 方向上 baseK 的倍数(A 侧与 B 侧)。 |
| iterateOrder | 预留参数,用户无需感知。 |
| bl1Bound | L1 中载入 GradOutput 矩阵的最大数据量。 |
| hf32Flag | 预留参数,用户无需感知。 |
| singleCoreDK / singleCoreGroup | 预留参数,用户无需感知。 |
| singleCoreCout | 单核 M 方向上计算 cout 数据量的大小,单位元素。 |
| singleCoreHo | 单核 K 方向上计算 ho 数据量的大小,单位元素。 |
| singleCoreBatch | 单核上 batch 的大小,单位元素。 |
| singleCoreCin | 单核 N 方向上计算 cin 数据量的大小,单位元素。 |
| totalL1Size | L1 size 大小,单位元素。 |
| singleCoreM / singleCoreN / singleCoreK | 单核上 M / N / K 的大小,单位元素。 |
说明:
totalL1Size属于Conv3DBpFilterParams子结构(见 conv3d_bp_filter_tilingdata.h),最终由SetFinalTiling写入tiling.params.totalL1Size。singleCoreM/N/K则保存在独立的TConv3DBpFilterBasicBlockTiling子结构中,对应 Kernel 侧的基本块 Tiling 信息(conv3d_bp_filter_tilingdata.h)。
五、Shape 设置接口:SetInputShape / SetWeightShape / SetGradOutputShape
三个 Shape 设置接口分别描述三个参与反向卷积的张量维度。注意实际卷积维度是正向过程定义的,反向传播的 Shape 推导在底层ShapeInitCalc()中完成。
SetWeightShape:设置权重矩阵 Weight 的形状
函数原型:
void SetWeightShape(int64_t cout, int64_t cin, int64_t d, int64_t h, int64_t w)| 参数名 | 输入/输出 | 描述 |
|---|---|---|
| cout | 输入 | 设置 GradOutput 的 Channel 值。 |
| cin | 输入 | 设置 Input 的 Channel 值。 |
| d | 输入 | 设置 Weight 的 Depth 值。 |
| h | 输入 | 设置 Weight 的 Height 值。 |
| w | 输入 | 设置 Weight 的 Width 值。 |
调用示例:
auto ascendcPlatform = platform_ascendc::PlatformAscendCManager::GetInstance(); ConvBackpropApi::Conv3dBpFilterTiling conv3dBpDwTiling(*ascendcPlatform); conv3dBpDwTiling.SetWeightShape(cout, cin, d, h, w);SetInputShape:设置特征矩阵 Input 的形状
函数原型:
void SetInputShape(int64_t n, int64_t c, int64_t d, int64_t h, int64_t w)| 参数名 | 输入/输出 | 描述 |
|---|---|---|
| n | 输入 | 输入 Input 的 Batch 值。 |
| c | 输入 | 输入 Input 的 Channel 值。 |
| d | 输入 | 输入 Input 的 Depth 值。 |
| h | 输入 | 输入 Input 的 Height 值。 |
| w | 输入 | 输入 Input 的 Width 值。 |
调用示例:
auto ascendcPlatform = platform_ascendc::PlatformAscendCManager::GetInstance(); ConvBackpropApi::Conv3dBpFilterTiling conv3dBpDwTiling(*ascendcPlatform); conv3dBpDwTiling.SetInputShape(n, c, d, h, w);SetGradOutputShape:设置 GradOutput 的形状
函数原型:
void SetGradOutputShape(int64_t n, int64_t c, int64_t d, int64_t h, int64_t w)| 参数名 | 输入/输出 | 描述 |
|---|---|---|
| n | 输入 | 输入 GradOutput 的 Batch 值。 |
| c | 输入 | 输入 GradOutput 的 Channel 值。 |
| d | 输入 | 输入 GradOutput 的 Depth 值。 |
| h | 输入 | 输入 GradOutput 的 Height 值。 |
| w | 输入 | 输入 GradOutput 的 Width 值。 |
调用示例:
auto ascendcPlatform = platform_ascendc::PlatformAscendCManager::GetInstance(); ConvBackpropApi::Conv3dBpFilterTiling conv3dBpDwTiling(*ascendcPlatform); conv3dBpDwTiling.SetGradOutputShape(n, c, d, h, w);底层字段映射
从 conv3d_bp_filter_tiling_base.cpp 的实现可见,三个接口分别写入shapeInfo结构:
SetInputShape(n, c, d, h, w)→orgN / orgCi / orgDi / orgHi / orgWiSetWeightShape(cout, cin, d, h, w)→orgCo / orgCi / orgkD / orgkH / orgkWSetGradOutputShape(n, c, d, h, w)→orgN / orgCo / orgDo / orgHo / orgWo
其中orgkD/orgkH/orgkW为卷积核尺寸,orgDo/orgHo/orgWo为 GradOutput 尺寸,orgDi/orgHi/orgWi为 Input 尺寸——这三组维度正是后续 MatMul 化(im2col 思想)时 M/N/K 三轴计算的基础。
六、Type 设置接口:SetInputType / SetWeightType / SetGradOutputType
Type 设置接口用于声明张量的内存位置、数据格式与数据类型。这些信息必须与核函数(Kernel)侧的设置保持一致,否则 Tiling 与 Kernel 实际读取的数据布局不匹配会导致错误结果。
通用原型与参数语义
三个接口的原型相同,只是作用对象不同:
void SetWeightType(ConvCommonApi::TPosition pos, ConvCommonApi::ConvFormat format, ConvCommonApi::ConvDtype dtype) void SetInputType(ConvCommonApi::TPosition pos, ConvCommonApi::ConvFormat format, ConvCommonApi::ConvDtype dtype) void SetGradOutputType(ConvCommonApi::TPosition pos, ConvCommonApi::ConvFormat format, ConvCommonApi::ConvDtype dtype)| 参数名 | 输入/输出 | 描述 |
|---|---|---|
| pos | 输入 | 张量在内存上的位置(TPosition),当前仅支持TPosition::GM。 |
| format | 输入 | 张量的数据格式(ConvFormat)。 |
| dtype | 输入 | 张量的数据类型(ConvDtype)。 |
各张量当前支持的取值
| 接口 | pos | format | dtype |
|---|---|---|---|
| SetWeightType | 仅支持TPosition::GM | 仅支持ConvFormat::FRACTAL_Z_3D | 仅支持ConvDtype::FLOAT32 |
| SetInputType | 仅支持TPosition::GM | 仅支持ConvFormat::NDC1HWC0 | 支持ConvDtype::FLOAT16、ConvDtype::BF16 |
| SetGradOutputType | 仅支持TPosition::GM | 仅支持ConvFormat::NDC1HWC0 | 支持ConvDtype::FLOAT16、ConvDtype::BF16 |
关键枚举定义
ConvFormat定义于 conv_common.h(ConvCommonApi命名空间),其中与本算子相关的两种格式:
NDC1HWC0:Input/GradOutput 的 5D 分形格式,C0 维度为 16(即 channelSize),适合向量与矩阵加载;FRACTAL_Z_3D:Weight 的 3D 分形格式,是 Cube 矩阵运算(L0A/L0B 搬运)要求的分形布局。
TPosition定义于 matmul_tiling_base.h,取值为GM、A1、A2、B1、B2、C1、C2、CO1、CO2、VECIN、VECOUT、VECCALC等逻辑位置,与物理内存的映射关系可参考 通用说明和约束 中的 TPosition 映射表(例如 GM 对应 Global Memory、CO1 对应 L0C Buffer)。当前版本该算子三个张量均限定在 GM。
从源码实现看(conv3d_bp_filter_tiling_base.cpp),三个接口分别将三元组写入descInfo.weightType / fMapType / outBackpropType(ConvBpType结构,包含 format、dtype、pos 三个字段),供后续格式合法性检查与数据类型字节数推导(dtypeByte_,决定 L0/L1 容量计算)使用。
调用示例
auto ascendcPlatform = platform_ascendc::PlatformAscendCManager::GetInstance(); ConvBackpropApi::Conv3dBpFilterTiling conv3dBpDwTiling(*ascendcPlatform); conv3dBpDwTiling.SetWeightType( ConvCommonApi::TPosition::GM, ConvCommonApi::ConvFormat::FRACTAL_Z_3D, ConvCommonApi::ConvDtype::FLOAT32);七、算子属性设置接口:SetPadding / SetStride / SetDilation
这三个接口描述正向卷积过程中的卷积属性。注意语义约定:文档中这些参数描述的是卷积正向过程中 Input 的 Padding 方向与 Stride/Dilation 大小,反向传播时底层算法会据此推导 GradWeight 的计算窗口。
SetPadding:设置 Pad 信息
函数原型:
void SetPadding(int64_t padFront, int64_t padBack, int64_t padUp, int64_t padDown, int64_t padLeft, int64_t padRight)| 参数名 | 输入/输出 | 描述 |
|---|---|---|
| padFront | 输入 | 卷积正向过程中 Input Depth 维度的前方向 Padding 大小。 |
| padBack | 输入 | 卷积正向过程中 Input Depth 维度的后方向 Padding 大小。 |
| padUp | 输入 | 卷积正向过程中 Input Height 维度的上方向 Padding 大小。 |
| padDown | 输入 | 卷积正向过程中 Input Height 维度的下方向 Padding 大小。 |
| padLeft | 输入 | 卷积正向过程中 Input Width 维度的左方向 Padding 大小。 |
| padRight | 输入 | 卷积正向过程中 Input Width 维度的右方向 Padding 大小。 |
调用示例:
auto ascendcPlatform = platform_ascendc::PlatformAscendCManager::GetInstance(); ConvBackpropApi::Conv3dBpFilterTiling conv3dBpDwTiling(*ascendcPlatform); conv3dBpDwTiling.SetPadding(padFront, padBack, padUp, padDown, padLeft, padRight);SetStride:设置 Stride 信息
函数原型:
void SetStride(int64_t strideD, int64_t strideH, int64_t strideW)| 参数名 | 输入/输出 | 描述 |
|---|---|---|
| strideD | 输入 | 卷积正向过程中 Depth 方向 Stride 的大小。 |
| strideH | 输入 | 卷积正向过程中 Height 方向 Stride 的大小。 |
| strideW | 输入 | 卷积正向过程中 Width 方向 Stride 的大小。 |
调用示例:
auto ascendcPlatform = platform_ascendc::PlatformAscendCManager::GetInstance(); ConvBackpropApi::Conv3dBpFilterTiling conv3dBpDwTiling(*ascendcPlatform); conv3dBpDwTiling.SetStride(strideD, strideH, strideW);SetDilation:设置 Dilation 信息
函数原型:
void SetDilation(int64_t dilationD, int64_t dilationH, int64_t dilationW)| 参数名 | 输入/输出 | 描述 |
|---|---|---|
| dilationD | 输入 | 卷积核 Weight 的 Depth 方向扩张大小。 |
| dilationH | 输入 | 卷积核 Weight 的 Height 方向扩张大小。 |
| dilationW | 输入 | 卷积核 Weight 的 Width 方向扩张大小。 |
调用示例:
auto ascendcPlatform = platform_ascendc::PlatformAscendCManager::GetInstance(); ConvBackpropApi::Conv3dBpFilterTiling conv3dBpDwTiling(*ascendcPlatform); conv3dBpDwTiling.SetDilation(dilationD, dilationH, dilationW);底层字段映射
从 conv3d_bp_filter_tiling_base.cpp 的实现可见,三个接口分别写入attrInfo结构的padFront/padBack/padUp/padDown/padLeft/padRight、strideD/strideH/strideW、dilationD/dilationH/dilationW。这些属性在 Tiling 计算中被用于:
MultiCoreSplitMN的切分决策:strideHW = strideH * strideW,当strideHW > 1且kernelHW % 16 == 0 || 16 % kernelHW == 0时选择切 MN 而非切 K;- L1B 装载量估算:
CalBL1Bound()中通过hiCal = (hoCal - 1) * strideH + (orgkH - 1) * dilationH + 1反推 Input 侧窗口高度,进而计算 B 侧 L1 占用; ShrinkBaseBlock()中对基本块的 L1/L0 合法性收缩。
八、Tiling 切分算法源码级解析
了解了所有接口之后,再看一眼底层算法有助于理解输出结构体中各字段的由来。Conv3DBackpropFilter 的 Tiling 本质是把反向卷积转化为 Cube 上的 MatMul 问题:
- M 轴:
cout1_g * channelSize(输出通道分形); - N 轴:
orgkH * orgkW * cin1_g * channelSize,若不单独切分 dk 则将orgkD合并进 N 轴; - K 轴:
CeilAlign(orgHo * orgWo, channelSize)(GradOutput 空间尺寸对齐到 C0)。
(对应代码见 conv3d_bp_filter_tiling.cpp 的SetBasicBlockAttrsTiling()。)
随后算法在基本块(basic block)层面做 L0/L1 容量适配:
InitBaseMNK()(conv3d_bp_filter_tiling.cpp):按 M/N/K 是否切分选择 128/256 等默认基本块尺寸,并依据channelSize=16(BLOCK_CUBE)做搬运对齐;FLOAT32 时 baseK 减半以适配 L0 容量。UpdateStepMNK()(conv3d_bp_filter_tiling.cpp):根据 L1 深度(depthA1/depthB1)与 DoubleBuffer 开关推导stepM/stepN/stepKa/stepKb,并保证 K 方向步长互为整数倍关系。IsCurBlockL1L0Invalid()(conv3d_bp_filter_tiling.cpp):分别校验 L0A(alignedBaseK * baseM * dtypeByte * DB_ON)、L0B 与 L1(A 侧 + B 侧)占用是否超出platformInfo.l0ASize/l0BSize/l1Size。ShrinkBaseBlock()(conv3d_bp_filter_tiling.cpp):当基本块超出 L1/L0 时,先沿 K 方向以 C0(16)为步长收缩,再收缩 M/N,最后做 M/K 方向回调补偿,尽量贴近容量上限又不越界。
最终由SetFinalTiling/SetFinalBasickBlockTiling(conv3d_bp_filter_tiling.cpp)把内部计算结果写入TConv3DBpFilterTiling的各个字段,其中m0/k0/n0固定为BLOCK_CUBE(16)/channelSize(16)/BLOCK_CUBE(16),即最小分形尺寸;singleCoreCout/singleCoreHo/singleCoreCin等则由singleCoreM/singleCoreK/singleCoreN换算得到。
九、测试用例与可验证依据
仓库中的单元测试与网络级测试可以直接验证接口的调用方式与预期输出,可作为二次开发的参考模板:
- 网络级测试test_conv3d_backprop_filter_api_tiling_network.cpp:
NetWorks_001:SetWeightShape(128, 17, 1, 3, 3)、SetInputShape(1, 128, 17, 257, 257)、SetGradOutputShape(1, 128, 17, 128, 128)、SetStride(1, 2, 2),调用GetTiling后断言返回 0,并校验基本块结果为(128, 1152, 512);NetWorks_002:同时验证了optiling::Conv3DBackpropFilterTilingData与AscendC::tiling::Conv3DBackpropFilterTilingData两种输出结构体的GetTiling重载。
- 功能测试test_conv3d_backprop_filter_api_tiling_func.cpp:覆盖无参/带参构造、
CheckInputAttr(group 合法性)、CheckInputShape(卷积核尺寸合法性)、CheckInputFormat(Weight 必须为 FRACTAL_Z_3D)以及 HF32 开关设置等校验路径。
这些用例同时印证了文档中的两个关键点:一是SetWeightType的格式必须为FRACTAL_Z_3D,否则CheckInputFormat()返回 false 导致 Tiling 失败;二是GetTiling返回 0 表示成功(文档约定"不为 -1 即成功")。
十、使用注意事项小结
- Type 信息必须与 Kernel 侧一致:
SetInputType/SetWeightType/SetGradOutputType描述的是数据在内存中的真实布局,若与核函数侧设置不一致,Tiling 切分与 Kernel 实际搬运将错位,导致计算结果错误。 - 位置限定 GM:当前版本 Input、GradOutput、Weight 的位置均只支持
TPosition::GM;Weight 格式仅支持FRACTAL_Z_3D,Input/GradOutput 格式仅支持NDC1HWC0。 - dtype 组合约束:Weight 为
FLOAT32,Input/GradOutput 为FLOAT16或BF16;从InitBaseMNK中dtypeByte_ == FLOAT32分支可知,FLOAT32 会触发 baseK 减半适配,属于算法已处理的既定路径。 - channelSize 固定为 16:结构体中的
channelSize字段目前只支持 16,基本块切分均以 16(BLOCK_CUBE)为对齐单位。 - 返回值语义:
GetTiling返回 -1 表示失败(参数校验不过或 Tiling 无法生成),返回其他值(如 0)表示成功;失败时可通过 TILING_LOG 查看错误原因。 - 头文件路径:Host 侧 Tiling 代码包含
tiling/conv_backprop/conv3d_bp_filter_tiling.h即可;高阶 API 配套 Host Tiling 接口需要链接libtiling_api.a,API 头文件目录为${INSTALL_DIR}/asc/include/adv_api(详见 通用说明和约束)。
十一、与 Kernel 侧接口的衔接
本套 Tiling API 产出的TConv3DBpFilterTiling结构体正是 Conv3DBackpropFilter Kernel 侧 Init 接口 消费的输入:Kernel 侧通过Init读取结构体中的 batch/cin/cout、各维尺寸、Padding/Stride/Dilation、L0/L1 各 buffer 的 Pingpong 开关、baseM/baseK/baseN、stepM/stepN/stepKa/stepKb 以及 singleCore 系列字段,据此完成数据搬运、分形切分与 Cube 计算循环。这种"Host 侧 Tiling 自动生成 + Kernel 侧按结构体驱动"的分工,使得开发者无需手工推导复杂的 5D 卷积反向切分逻辑,即可获得与硬件存储层级(L1/L0A/L0B/L0C)容量匹配的高效实现。
- 人工智能
- 深度学习
- 算子库
- CANN
- Ascend
【免费下载链接】asc-devkit
本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C++标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。
相关推荐
基于 Ascend C RmsNorm 高阶 API 实现 RMSNorm 归一化算子实战指南(附 Tiling 原理与源码解析)
基于 Ascend C RmsNorm 高阶 API 实现 RMSNorm 归一化算子实战指南(附 Tiling 原理与源码解析) 导读 本文以 asc dev
人工智能深度学习算子库CANNAscendAscend C 算子开发:Conv3DBackpropInput Tiling 的 SetGradOutputShape 接口详解
Ascend C 算子开发:Conv3DBackpropInput Tiling 的 SetGradOutputShape 接口详解 导读 SetGradOut
人工智能深度学习算子库CANNAscendAscend C Matmul 高阶 API 矩阵乘法样例解析:matmul_advanced_api 从 Tiling 到 Kernel 的完整实践
Ascend C Matmul 高阶 API 矩阵乘法样例解析:matmul_advanced_api 从 Tiling 到 Kernel 的完整实践 导读 本
人工智能深度学习算子库CANNAscend
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考