Im2col算子开发设计文档
【免费下载链接】cann-ops-competitions本仓库用于 CANN 开源社区各类竞赛、开源课题、社区任务等课题发布、开发者作品提交和展示。项目地址: https://gitcode.com/cann/cann-ops-competitions
需求背景
需求来源
本需求来源于 CANN 社区任务 2026 年 5 月发放的Im2col算子开发任务。任务要求参考 CANN 内置aclnnIm2col的 TBE 实现,使用 Ascend C 实现功能一致的算子,并新增bool数据类型支持。
适配硬件为 Atlas A2 训练系列产品和 Atlas A3 系列产品。交付内容包括算子代码、README、 aclnn 调用测试、自验证报告和通过评审的设计文档。
背景介绍
Im2col算子实现优化
Im2col将输入图像的滑动窗口展开为列矩阵,常用于将卷积转换为矩阵乘法。该算子只进行 数据重排和越界补零,不改变有效输入元素的数值。
本任务需要保持aclnnIm2col的接口语义,覆盖原有浮点类型,并为bool增加一条 Ascend C 实现路径。
Im2col算子(TBE)实现路径和相关API路径
以下路径基于 CANN 8.5.2 安装环境、ascend910b算子信息库和ops-math接口源码核验。安装路径中的{ASCEND_OPP_PATH}在本次调查环境中为/home/developer/Ascend/cann-8.5.2/opp。
| 层级 | 文件路径 | 作用 |
|---|---|---|
| aclnn接口 | ops-math/conversion/im2col/op_api/aclnn_im2col.cpp | 参数校验、连续化、3维输入补batch维、NCHW格式规整和输出恢复 |
| l0op封装 | ops-math/conversion/im2col/op_api/im2col.cpp | 推导输出shape,将属性映射到内部Im2col并加入AICore launcher |
| ascend910b算子信息库 | ${ASCEND_OPP_PATH}/built-in/op_impl/ai_core/tbe/kernel/config/ascend910b/ops_legacy/im2col.json | 注册9个NCHW动态二进制条目 |
| TBE动态入口 | ${ASCEND_OPP_PATH}/built-in/op_impl/ai_core/tbe/impl/ops_legacy/dynamic/im2col.py | 校验NCHW和dtype,展开属性并创建ExtractImagePatchesNCHW |
| TBE动态实现 | ${ASCEND_OPP_PATH}/built-in/op_impl/ai_core/tbe/impl/ops_legacy/dynamic/extract_image_patches_nchw.py | 构造padding、滑窗提取和布局变换计算图,并执行auto schedule和build |
| TBE legacy参考 | ${ASCEND_OPP_PATH}/built-in/op_impl/ai_core/tbe/impl/ops_legacy/im2col.py | 静态shape的NC1HWC0、L1/UB和无Cbuf实现,仅作为辅助参考 |
| TBE legacy公共函数 | ${ASCEND_OPP_PATH}/built-in/op_impl/ai_core/tbe/impl/ops_legacy/im2col_common_func.py | legacy路径的im2col_compute和im2col_schedule |
| 算子原型 | ${ASCEND_OPP_PATH}/built-in/op_proto/inc/transformation_ops.h | REG_OP(Im2col)原型定义 |
接口层完成以下映射:
self为3维(C,H,W)时,在第0维补batch维,统一为4维NCHW输入。- 非连续输入先执行
Contiguous。 padding=[paddingH,paddingW]扩展为pads=[paddingH,paddingH,paddingW,paddingW]。- l0op将
kernelSize、stride、dilation、"CALCULATED"、pads下发给内部Im2col。 - 3维输入计算完成后去除batch维,恢复为2维输出。
Im2col算子TBE实现现状分析
TBE支持的数据类型和数据格式
910B 的内置 Im2col TBE 配置覆盖 FP16/FP32/BF16 和CALCULATED/SAME/VALID三种 padding 模式,总共 9 个动态 NCHW 条目;当前公开aclnnIm2colAPI 使用显式padding参数,并固定映射到CALCULATED模式。本文以 ascend910b 注册的动态 NCHW TBE 路径作为基线;legacy 静态实现用于补充说明历史调度结构。
| 层级 | 数据类型 | 数据格式 | 说明 |
|---|---|---|---|
| ascend910b算子信息库 | float16、float32、bfloat16 | NCHW | 注册为动态Im2col,覆盖CALCULATED/SAME/VALID三种padding模式 |
dynamic/im2col.py | float16、float32、bfloat16 | NCHW | 910B动态入口,完成参数校验和属性规整 |
dynamic/extract_image_patches_nchw.py | float16、float32、bfloat16 | 逻辑输入NCHW | 动态NCHW主实现,构造padding、滑窗提取、布局变换和build流程 |
| legacy静态实现 | 以浮点路径为主,部分分支涉及整数类型 | NCHW/NHWC转内部NC1HWC0 | 静态shape和旧调度路径,仅作为实现参考 |
本任务新增(Ascend CIm2colCustom) | NCHW | float16、float32、bfloat16、bool | 对齐内置浮点语义,新增bool支持,由自定义 Ascend C Kernel 实现 |
动态TBE实现描述
1.dynamic/im2col.py入口
@register_operator("Im2col", pattern="ExtractImagePatches")注册动态入口。- 校验输入format必须为
NCHW,dtype必须为float16/float32/bfloat16。 - 通过
None in (ksizes, strides, dilations, pads)判断属性是否为binary形式。 - 属性已知时,
prepare_params将长度1或2的ksizes/strides/dilations扩展为4维形式,并将pads扩展为四向。 - 创建
ExtractImagePatchesNCHW对象并调用build(kernel_name)。
2.ExtractImagePatchesNCHW初始化
- 归一化dtype;其中bfloat16在TVM内部按16位承载类型处理。
- 根据shape中是否包含
-1/-2区分常量shape和动态shape。 - 解析
kh/kw、sh/sw、rh/rw、pt/pb/pl/pr。 CALCULATED使用显式公式计算Ho/Wo;SAME/VALID通过_calc_output_size_and_pad计算输出尺寸和padding。- 常量shape调用
op_tiling.do_op_tiling获取tiling key及n/c/kh/kw/ho/wo/ub七个factor;动态shape使用TVM变量表示。
3._compute()计算图
- 创建输入placeholder,并通过
x_ub=identity(x)标记UB计算节点。 - 将逻辑索引从
NCHW转换为NHWC。 - 非
VALID模式调用_padding(),通过四向tvm.select生成补零张量。 - 生成6维滑窗结果:
y_nhwc[n,kh,kw,oh,ow,c] = x[n,oh*sh+kh*rh,ow*sw+kw*rw,c]。 - 将索引顺序转换为
(N,C,KH,KW,Ho,Wo)。 - 生成输出tensor;其flatten语义为
(N,C*KH*KW,Ho*Wo)。
4.build()构建过程
build()依次执行tbe.compute()、_compute()、注册compile info、tbe.auto_schedule(y)和tbe.build(...),最终生成CCE内核二进制。
动态TBE源码构建流程图
Im2col算子功能分析
设输入为(N,C,H,W),属性为(kernelH,kernelW)、(dilationH,dilationW)、(paddingH,paddingW)和(strideH,strideW):
outH = floor((H + 2*paddingH - dilationH*(kernelH-1) - 1) / strideH + 1) outW = floor((W + 2*paddingW - dilationW*(kernelW-1) - 1) / strideW + 1) L = outH * outW输出shape为:
4维输入: (N, C*kernelH*kernelW, L) 3维输入: (C*kernelH*kernelW, L)输出元素映射为:
row = c*kernelH*kernelW + kh*kernelW + kw col = oh*outW + ow ih = oh*strideH - paddingH + kh*dilationH iw = ow*strideW - paddingW + kw*dilationW(ih,iw)有效时复制输入值,否则写0;bool的越界填充值为false。当outH<=0或outW<=0时按非法参数报错。
需求分析
需求描述
使用 Ascend C 实现aclnnIm2col,对齐原 TBE 的功能和公开接口语义,支持float16、float32、bfloat16、bool,并满足泛化、精度和性能要求。
需求拆解
- 支持3维
(C,H,W)和4维(N,C,H,W)输入。 - 支持
float16、float32、bfloat16、bool,输入输出dtype一致。 - 支持长度为2的
kernelSize、dilation、padding、stride及其合法组合。 - 支持非连续输入、非32B对齐尾块、小shape和大shape。
- 有效位置保持二进制一致,padding区域写0或
false。 - 大shape使用多核并行;bool性能按任务书与TBE float16基线比较。
详细设计
算子分析
算子原型、支持数据类型和形状
| 项目 | 原型设计 |
|---|---|
| 内部算子名 | Im2colCustom |
| 输入 | x,必选,ND;支持3维(C,H,W)或4维(N,C,H,W) |
| 输入dtype | float16、float32、bfloat16、bool |
| 输出 | y,必选,ND;输入为3维时输出shape为(C*kernelH*kernelW,L),输入为4维时输出shape为(N,C*kernelH*kernelW,L) |
| 输出dtype | 与输入dtype一致 |
| 属性 | ksizes: ListInt、strides: ListInt、dilations: ListInt、padding_mode: String、pads: ListInt |
| SoC配置 | ascend910b、ascend910_93 |
| 动态能力 | 支持dynamic shape,不支持dynamic rank和dynamic format |
aclnnIm2col接口层接收self、kernelSize、dilation、padding、stride、out。其中padding在接口层扩展为四边pads,padding_mode固定为CALCULATED后下发给Im2colCustom。Im2col不执行数值运算,浮点类型直接搬运原始元素;bool按1字节类型搬运。
算子实现
实现方案
对外接口保持aclnnIm2col,内部AICore算子注册为Im2colCustom,与系统内置Im2col区分;aclnn层将参数规整后加入该算子的AICore launcher。实现采用以下分层:
- aclnn层校验参数、扩展四向padding、连续化输入,并通过view将3维输入统一为4维。
- Host tiling按64B cache line对输出线性区间分核,填充统一的
Im2colCustomTilingData,使用一个固定tiling key。 - Kernel入口按
sizeof(DTYPE_X)分派:1字节类型进入bool专用实现,2/4字节类型进入Im2colCustomGeneric<T>。 - 两类Kernel均在
Process()内根据实际shape选择连续拷贝、特化3x3/stride=2/padding=1或通用按行处理路径。
Ascend C实现流程图
host侧设计
参数处理
- 校验非空指针、输入维度、属性长度和属性取值。
- 校验输入输出dtype一致,输出shape与公式一致。
- 非连续输入执行
Contiguous。 - 3维输入补batch维;padding从两元素扩展为四边。
outH/outW<1时返回参数错误,不启动kernel。
分核和tiling
- 根据dtype计算元素字节数:bool为1B,float16/bfloat16为2B,float32为4B。
- 将总输出元素数换算为64B cache line数量,按平台AIV核数均分cache line。
elementsPerCore按cache line元素数对齐,使每个核写回独立的cache line区间。。- 实际核数不超过平台AIV核数和输出cache line数量。
- tiling数据记录输入shape、卷积属性、输出shape、总输出元素数和
elementsPerCore。 - 当前Host只设置
IM2COL_CUSTOM_TILING_KEY,具体优化路径由Kernel根据dtype和shape判断。
kernel侧设计
连续拷贝快路径
输入输出元素数量和线性顺序一致。每个核处理连续区间,以对齐tile执行DataCopyPad或 等价DMA搬运;尾tile按真实长度写回。
特化3x3 stride2路径
当kernel=3x3、stride=2、dilation=1、padding=1,且输入输出宽度、plane大小和 tile容量满足对齐条件时,Kernel按(n,c)plane分配任务,将输入plane搬入UB后完成 stride2抽取和9个kernel位置的输出组织。
通用按行路径
固定(n,c,kh,kw,oh),计算:
ih = oh*strideH - paddingH + kh*dilationHKernel由输出线性区间得到flatOutputRow和outputWStart。当从完整输出行开始时:
strideW=1尝试批量处理连续输出行。strideW!=1尝试批量处理strided输出行。- 无法批量处理时,按当前行剩余元素和tile容量生成segment。
- 每个segment计算有效W区间;有效位置读取输入,无效位置写0。
浮点类型使用Im2colCustomGeneric<T>,bool使用1字节专用实现。两者共享相同输出索引语义,但UB组织和可用指令不同。
bool和尾块
bool使用uint8_t等1字节承载类型,值0表示false。- 输出优先在UB形成连续块后DMA写回。
- 非32B对齐尾块使用按真实长度的安全搬运方式,避免越界覆盖。
Ascend C实现与TBE动态路径的差异点和原因
| 差异点 | TBE动态实现 | 当前Ascend C实现 | 原因 |
|---|---|---|---|
| 编程模型 | TVM DSL声明计算图并auto schedule | 手写Ascend C Kernel和Host tiling | 任务目标是原生Ascend C实现 |
| 内部布局 | 逻辑上执行NCHW→NHWC→滑窗提取→NCHW | 直接按NCHW线性地址计算输入位置 | 减少中间layout tensor和索引变换开销 |
| padding | _padding()生成四向补零compute | Kernel按行计算有效区间并写0 | 直接结合数据搬运处理边界 |
| tiling | op_tiling产生7个factor并由auto schedule组织多核 | Host按64B cache line线性分核,Kernel内部选择优化路径 | 保证多核写回互不共享cache line |
| dtype分派 | FP16/FP32/BF16动态TBE二进制 | 1B bool专用Kernel,2/4B进入泛型Kernel | 新增bool且不同字节宽度可用指令不同 |
| 专项优化 | 由auto schedule和TBE模板生成 | 显式1x1拷贝与3x3 stride2特化 | 针对当前验收shape降低地址计算和搬运开销 |
| BOOL | 不支持 | 按uint8_t承载并写0表示false | 本任务新增能力 |
支持硬件
| 支持的芯片版本 | 涉及勾选 |
|---|---|
| Atlas A2 训练系列产品 | √ |
| Atlas A3 系列产品 | √ |
算子约束限制
- 输入维度为3或4。
kernelSize、dilation、padding、stride长度均为2。kernelSize、dilation、stride各元素大于0,padding各元素大于等于0。- 输入输出dtype一致。
- 推导的
outH/outW必须大于0。 - 非连续输入在aclnn层转连续后进入kernel。
可维可测分析
精度标准/性能标准
| 验收标准 | 描述 | 标准来源 |
|---|---|---|
| 精度标准 | 与参考实现功能一致;重排数据和bool结果按二进制一致校验 | 任务书 |
| 性能标准 | 全核场景下bool不低于TBE float16,其他类型不低于对应TBE实现 | 任务书 |
小shape的TBE耗时低于10us且差距不超过3us时,按任务书补充流水图和瓶颈分析。
自验证用例设计
| 类别 | 覆盖场景 |
|---|---|
| 输入维度 | 3维、4维 |
| dtype | float16、float32、bfloat16、bool |
| kernel | 1x1、3x3、1x3等非方形kernel |
| 属性 | 无padding、大padding、stride 1/2、dilation 1/2、H/W非对称属性 |
| shape | 小shape、大shape、32B对齐、非32B对齐尾块 |
| 输入布局 | 连续输入、非连续输入 |
| 异常 | 属性长度错误、非正kernel/stride/dilation、负padding、输出尺寸非法 |
| 性能 | 1x1连续拷贝、3x3/stride2/pad1特化、strideW=1与strideW!=1通用行路径,以及BOOL/FP16/BF16/FP32分派 |
正确性测试使用CPU参考实现生成golden。浮点按任务书精度标准验收,并对数据重排场景增加严格相等检查;bool逐元素严格相等,padding区域单独检查0值。性能使用msprof的内核Task Duration(us),每个shape独立运行多次并保留原始日志。
兼容性分析
- 继承
aclnnIm2col的函数签名、3维/4维输入语义和输出shape。 - 在原有浮点类型行为基础上扩展
bool数据类型。 - 对外保持ND Tensor语义,3维输入view变换和内部tiling封装在实现内部。
- aclnn层完成非连续输入规整,kernel接收连续NCHW数据。
参考资料
04_tasks/01_community-task-2026/docs/202605/im2col_task_doc.md04_tasks/01_community-task-2026/resources/design_template.mdops-math/conversion/im2col- CANN 8.5.2 内置 TBE
Im2col源码、Proto和ascend910b信息库 aclnnIm2colAPI文档: https://www.hiascend.com/document/detail/zh/canncommercial/850/API/aolapi/context/ops-math/aclnnIm2col.md
【免费下载链接】cann-ops-competitions本仓库用于 CANN 开源社区各类竞赛、开源课题、社区任务等课题发布、开发者作品提交和展示。项目地址: https://gitcode.com/cann/cann-ops-competitions
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考