- 人工智能
- 深度学习
- 算子库
- CANN
- Ascend
【免费下载链接】asc-devkit
本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C++标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。
SetDilation是昇腾 Ascend C 高级算子开发中Conv3DBackpropInput Tiling系列接口的一员,用于设置三维卷积核在 Depth/Height/Width 三个方向上的 Dilation(膨胀/扩张)大小,是配置膨胀卷积(Dilated Convolution)反传 Tiling 的关键入口。本文以仓库中的 API 参考文档为主体,结合 Tiling 基类实现、参数校验逻辑与单元测试,完整讲解该接口的原型、参数含义、底层存储与校验约束,并给出可直接落地的调用示例,帮助读者在 Conv3DBackpropInput(含等价场景 Conv3DTranspose)算子开发中正确配置 dilation 并理解其对 Tiling 计算的影响。
功能说明:Dilation 在反卷积 Tiling 中的定位
SetDilation的功能是设置 Dilation 信息,即卷积核 Weight 在 Depth/Height/Width 三个方向的扩张大小。
在三维卷积中,dilation(也称空洞卷积/膨胀卷积参数)用于在不增加卷积核参数量的前提下扩大感受野。对一个尺寸为 k 的卷积核,施加扩张大小 dilation 后,其实际参与运算的"等效卷积核尺寸"为:
dilatedKernelSize = (k - 1) * dilation + 1该公式在仓库的 Tiling 实现中反复出现,例如 conv3d_bp_input_tiling.cpp 的CheckCalPads中:
int64_t filterDDilation = (shapeInfo.orgkD - 1) * attrInfo.dilationD + 1; int64_t filterHDilation = (shapeInfo.orgkH - 1) * attrInfo.dilationH + 1; int64_t filterWDilation = (shapeInfo.orgkW - 1) * attrInfo.dilationW + 1;在 Conv3DBackpropInput(反卷积)场景下,dilation 是正向卷积过程的属性:Tiling 侧需要根据它反推出正向卷积时的等效卷积核尺寸,从而完成输入梯度(dx)输出 shape 的校验与 backprop padding 的计算。因此,SetDilation并不是独立可用的接口,而是整个"设置 Tiling 输入参数 → 调用GetTiling获取 Tiling 结果"流程中的一环。
函数原型与参数说明
SetDilation的接口声明如下(与 SetDilation API 参考文档 一致):
void SetDilation(int64_t dilationD, int64_t dilationH, int64_t dilationW)各参数含义如下表所示:
| 参数名 | 输入/输出 | 描述 |
|---|---|---|
| dilationD | 输入 | 卷积核 Weight 的 Depth 方向扩张大小。 |
| dilationH | 输入 | 卷积核 Weight 的 Height 方向扩张大小。 |
| dilationW | 输入 | 卷积核 Weight 的 Width 方向扩张大小。 |
返回值:无(void)。
三个参数均为int64_t有符号整型,语义上对应正向三维卷积的 depth/height/width 三个方向的空洞间隔。例如dilationH = 2表示 Height 方向上每两个采样点之间插入一个空洞,等效卷积核高度从kh变为(kh - 1) * 2 + 1。
约束说明与参数取值范围
API 参考文档对SetDilation本身的约束写为"无",但这并不意味着可以随意传值。从仓库源码看,dilation 的合法性校验发生在 Tiling 计算入口CheckInputParam()的CheckInputAttr()阶段,见 conv3d_bp_input_tiling_base.cpp:
if (this->attrInfo.dilationH <= 0 || this->attrInfo.dilationW <= 0 || this->attrInfo.dilationD <= 0) { TILING_LOG_ERROR( "Illegal attrs have set: dilationH=%ld, dilationW=%ld, dilationD=%ld, which must > 0.", this->attrInfo.dilationH, this->attrInfo.dilationW, this->attrInfo.dilationD); return false; }即实际生效的硬性约束是:dilationD / dilationH / dilationW 必须为正整数(> 0)。这一约束在单元测试 test_conv3d_backprop_input_api_tiling_func.cpp 中有直接验证:
// dilation not positive conv3dDx_empty_params.attrInfo.dilationH = 0; EXPECT_EQ(false, conv3dDx_empty_params.CheckInputAttr()); conv3dDx_empty_params.attrInfo.dilationH = 1;另外,在Conv3DTranspose场景中,SetOutputPadding传入的 outputPadding 不能同时大于等于同一维度的 dilation 与 stride,参见 conv3d_bp_input_tiling.cpp 的约束检查逻辑。
源码实现剖析:参数如何被存储与传递
底层存储:Conv3DBpAttr 结构体
SetDilation的实现位于 conv3d_bp_input_tiling_base.cpp:
void Conv3DBpInputTilingBase::SetDilation(int64_t dilationD, int64_t dilationH, int64_t dilationW) { this->attrInfo.dilationH = dilationH; this->attrInfo.dilationW = dilationW; this->attrInfo.dilationD = dilationD; }三个值被分别写入attrInfo的dilationD/dilationH/dilationW成员。attrInfo的类型为Conv3DBpAttr,定义在 conv3d_bp_tiling_base.h,其默认值为:
int64_t dilationD = 1; int64_t dilationH = 1; int64_t dilationW = 1;也就是说,即使不调用SetDilation,dilation 默认也为 1(即普通卷积,无膨胀)。这也是文档调用示例中普遍以SetDilation(1, 1, 1)出现的原因——显式声明"无膨胀",便于与真正使用膨胀卷积的场景区分。
从 attrInfo 到最终 Tiling 数据
Tiling 计算成功后,SetFinalTiling会把 dilation 写入输出结构体conv3DDxTiling,见 conv3d_bp_input_tiling_base.cpp:
tiling.conv3DDxTiling.set_dilationH(this->attrInfo.dilationH); tiling.conv3DDxTiling.set_dilationW(this->attrInfo.dilationW); tiling.conv3DDxTiling.set_dilationD(this->attrInfo.dilationD);这样,Kernel 侧(设备端)即可从TConv3DBackpropInputTiling结构体中直接读取dilationD/dilationH/dilationW,用于数据搬运与计算循环的控制。
Dilation 在 Tiling 计算中的实际用途
除了存储与透传,dilation 还深度参与 Tiling 侧的多个推导与校验环节,理解这些有助于排查反卷积算子形状不匹配类问题。
1. 校验正向卷积输出 shape 的一致性(CheckCalPads)
CheckCalPads 利用 dilation 计算等效卷积核尺寸,并反推"期望的 GradOutput 尺寸",与用户通过SetGradOutputShape传入的 Do/Ho/Wo 比对:
int64_t doExpect = (shapeInfo.orgDi + attrInfo.padFront + attrInfo.padBack - filterDDilation) / attrInfo.strideD + 1; int64_t hoExpect = (shapeInfo.orgHi + attrInfo.padUp + attrInfo.padDown - filterHDilation) / attrInfo.strideH + 1; int64_t woExpect = (shapeInfo.orgWi + attrInfo.padLeft + attrInfo.padRight - filterWDilation) / attrInfo.strideW + 1; OP_TILING_CHECK( doExpect != shapeInfo.orgDo || hoExpect != shapeInfo.orgHo || woExpect != shapeInfo.orgWo, ... return false);这里filterDDilation/filterHDilation/filterWDilation正是(k-1) * dilation + 1。如果 dilation 设置错误,直接表现为 GetTiling 返回 -1 且报错 "out_backprop's shape is not equal with inferred shape"。因此,在使用膨胀卷积的反传场景中,SetDilation的取值必须与正向卷积算子中的 dilation 属性完全一致。
2. 计算 backprop padding(SetBackpropPadInfo / CalBackpropPadBefore)
反卷积需要把正向卷积的 padding 换算为反传过程中的 padding。SetBackpropPadInfo 中,backprop 各方向尾部 padding 的计算公式同样包含 dilation:
int64_t bpPadTail = shapeInfo.orgDi - (static_cast<int64_t>(shapeInfo.orgDo - 1) * attrInfo.strideD + 1) + (shapeInfo.orgkD - 1) * attrInfo.dilationD - attrInfo.backpropPadHead;而前侧 padding 由 CalBackpropPadBefore 计算:
static int32_t CalBackpropPadBefore(int32_t filter, int32_t dilation, int32_t pad) { return (filter - 1) * dilation - pad; }可见 dilation 直接决定了反卷积前/后两侧需要裁剪或补零的范围,设置不当将导致反卷积输出(dx)的尺寸错误。
3. 决定输出是否需要初始化(SetInitOutput)
SetInitOutput 中有一个专门针对 dilation 的判断:
if (doModulo > attrInfo.padBack || hoModulo > attrInfo.padDown || attrInfo.strideH > shapeInfo.orgkH || (opType_ == OpType::kConv3DTranspose && (attrInfo.backpropPadDown > 0 || attrInfo.backpropPadHead > 0)) || attrInfo.dilationD > 1) { // 1 is init output with l0C, 2 is init output with l1, default is 0 means not init output initOutputFlag = 1; }即当dilationD > 1(Depth 方向存在膨胀)时,反卷积输出必须被预先初始化为 0(使用 L0C 或 L1 初始化),否则叠加计算结果会出错。这也解释了为何大多数测试用例中 dilation 都取 1:普通卷积场景可以跳过输出初始化以提升性能。
完整调用示例与使用流程
SetDilation必须配合其他 Tiling 设置接口一起使用,完整流程(取自 Conv3DBackpropInput Tiling 使用说明)为:
- 创建一个单核 Tiling 对象(基于
platform_ascendc::PlatformAscendCManager::GetInstance()获取的平台信息)。 - 通过
SetWeightType、SetGradOutputType、SetInputType设置各张量的 Position、Format、DType。 - 通过
SetInputShape、SetGradOutputShape、SetWeightShape设置 shape 信息。 - 如有 Padding、Stride 参数,调用 SetPadding、SetStride 设置。
- 调用
SetDilation设置膨胀参数。 - 调用 GetTiling 获取 Tiling 信息(返回 -1 表示计算失败)。
完整样例如下:
#include "tiling/conv_backprop/conv3d_bp_input_tiling.h" optiling::Conv3DBackpropInputTilingData tilingData; auto ascendcPlatform = platform_ascendc::PlatformAscendCManager::GetInstance(); ConvBackpropApi::Conv3DBpInputTiling conv3DBpDxTiling(*ascendcPlatform); conv3DBpDxTiling.SetWeightType( Convolution3DBackprop::TPosition::GM, Convolution3DBackprop::ConvFormat::FRACTAL_Z_3D, Convolution3DBackprop::ConvDtype::FLOAT32); conv3DBpDxTiling.SetGradOutputType( Convolution3DBackprop::TPosition::GM, Convolution3DBackprop::ConvFormat::NDC1HWC0, Convolution3DBackprop::ConvDtype::FLOAT16); conv3DBpDxTiling.SetInputType( Convolution3DBackprop::TPosition::CO1, Convolution3DBackprop::ConvFormat::NDC1HWC0, Convolution3DBackprop::ConvDtype::FLOAT16); conv3DBpDxTiling.SetInputShape(orgN, orgCi, orgDi, orgHi, orgWi); conv3DBpDxTiling.SetGradOutputShape(orgCo, orgDo, orgHo, orgWo); conv3DBpDxTiling.SetWeightShape(orgKd, orgKh, orgKw); conv3DBpDxTiling.SetPadding(padFront, padBack, padUp, padDown, padLeft, padRight); conv3DBpDxTiling.SetStride(strideD, strideH, strideW); conv3DBpDxTiling.SetDilation(dilationD, dilationH, dilationW); int ret = conv3DBpDxTiling.GetTiling(tilingData); // if ret = -1, get tiling failed需要包含的头文件:
#include "lib/conv_backprop/conv3d_bp_input_tiling.h"仓库中该头文件的实体位于 conv3d_bp_input_tiling.h,其公开类Conv3DBpInputTiling继承自 conv3d_bp_input_tiling_base.h 中定义的Conv3DBpInputTilingBase,SetDilation即声明并实现在基类中,派生类可直接使用。
与 Conv3DTranspose 的等价用法
同一 Tiling 类还可用于构建 Conv3DTranspose 算子的 Tiling(见 GetTiling 文档示例):此时不要调用SetInputShape(调用后 opType 会被置为kConv3DBackpropInput,与SetOutputPadding冲突,参见 conv3d_bp_input_tiling_base.cpp 的错误提示),而改用SetOutputPadding对输出 Y 进行 padding,SetDilation的用法不变:
auto ascendcPlatform = platform_ascendc::PlatformAscendC(context->GetPlatformInfo()); ConvBackpropApi::Conv3DBpInputTiling tiling(ascendcPlatform); tiling.SetWeightShape(256, 128, 3, 3, 3); tiling.SetGradOutputShape(256, 9, 128, 128); // 等价于 Conv3dTranspose 的输入 X tiling.SetPadding(0, 0, 1, 1, 1, 1); tiling.SetDilation(1, 1, 1); tiling.SetStride(1, 1, 1); tiling.SetOutputPadding(0, 0, 0); // 对 Conv3dTranspose 的输出 Y 进行 padding optiling::Conv3DBackpropInputTilingData tilingData; int ret = tiling.GetTiling(tilingData); // 获取 Tiling 参数测试验证与常用取值参考
仓库的单元测试 test_conv3d_backprop_input_api_tiling_network.cpp 覆盖了大量SetDilation(1, 1, 1)的常规反卷积场景(WeightShape 覆盖3×3×3、1×1×1、3×1×1等多种卷积核),可作为默认取值与组合搭配的参考;test_conv3d_backprop_input_api_tiling_func.cpp 则从参数校验维度验证了 dilation 必须为正数的约束。
使用建议速查:
- 普通反卷积:显式调用
SetDilation(1, 1, 1),与默认值一致,行为最稳妥。 - 膨胀反卷积:
dilationD/dilationH/dilationW必须与正向卷积属性一致,且均为正整数;设置后注意CheckCalPads会严格校验 GradOutput shape,若GetTiling返回 -1 且日志提示 shape 不匹配,优先检查 dilation、stride、padding 三者与输入/输出 shape 的换算关系。 - Conv3DTranspose:
SetOutputPadding的值需小于同维度 stride 或 dilation,否则 Tiling 计算会失败。
小结
SetDilation是Conv3DBackpropInput Tiling系列接口中负责配置卷积核三方向膨胀参数的入口,虽然接口本身极简(三个int64_t参数、无返回值),但它通过attrInfo深度影响等效卷积核尺寸推导、GradOutput shape 校验、backprop padding 计算以及输出初始化策略。正确使用它的关键在于:dilation 取值为正整数,且与正向卷积算子属性保持一致;在构造 Tiling 流程中按"创建对象 → 设置 Type → 设置 Shape → 设置 Padding/Stride → 设置 Dilation → GetTiling"的顺序调用,即可为 Conv3DBackpropInput(含 Conv3DTranspose)算子生成正确的 Tiling 参数。
- 人工智能
- 深度学习
- 算子库
- CANN
- Ascend
【免费下载链接】asc-devkit
本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C++标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。
相关推荐
Ascend C Conv3DBackpropFilter Tiling 接口精讲:SetDilation 设置卷积核扩张参数
Ascend C Conv3DBackpropFilter Tiling 接口精讲:SetDilation 设置卷积核扩张参数 本文围绕 Ascend C(CA
人工智能深度学习算子库CANNAscendasc-devkit 中 Conv3D Tiling 的 SetDilation 接口详解:膨胀卷积参数设置、校验规则与完整调用链
asc devkit 中 Conv3D Tiling 的 SetDilation 接口详解:膨胀卷积参数设置、校验规则与完整调用链 导读 SetDilation
人工智能深度学习算子库CANNAscendasc-devkit 中 Conv3DBackpropInput Tiling 的 SetPadding 接口:反卷积 Padding 参数设置详解
asc devkit 中 Conv3DBackpropInput Tiling 的 SetPadding 接口:反卷积 Padding 参数设置详解 导读 :本
人工智能深度学习算子库CANNAscend
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考