已关闭
[Requirement|需求建议]: 【社区任务】upsample_nearest算子开发交付(任务编号 05-29) #561
_PeterXing_创建于 6月25日关闭于 8月1日
_PeterXing_
6月25日 评论:
6月25日 评论:
/assign


6月25日 将 kxingaa 设为负责人
6月25日 关联了pull request:[社区任务] UpsampleNearestExact1d2d 算子开发
7月1日 关联了pull request:[社区任务]upsample_nearest算子开发(任务编号05-29、master版本)
liu-wei
7月14日 评论:
7月14日 评论:
你好,这个issue是什么进展了?


liu-wei
7月16日 评论:
7月16日 评论:
您好,我们计划关闭这个 issue,如果您还有其他问题,可以随时提 issue 或者参与 SIG 会议一起参与讨论。
- SIG 会议时间:meeting.osinfra.cn/cann
- 所属 SIG 组:sig-ops-basic
- 往期会议记录:etherpad-cann.meeting.osinfra.cn/p/sig-ops-basic


_PeterXing_
7月21日 评论:
7月21日 评论:
你好,这个issue是什么进展了?
@liu-wei
https://gitcode.com/cann/ops-cv/pull/1070 pr还没有合入。
https://gitcode.com/cann/ops-cv/issues/631 precommit有问题,麻烦老师看一下


liu-wei
7月22日 评论:
7月22日 评论:
precommit的问题本地就可以直接解决,用库上precommit对应版本解决一下格式问题。


liu-wei
7月22日 评论:
7月22日 评论:
liu-wei
7月25日 评论:
7月25日 评论:
你好,这个issue现在是什么进展了?


liu-wei
7月27日 评论:
7月27日 评论:
您好,麻烦尽快处理关联PR里的检视意见上库哈。


liu-wei
7月30日 评论:
7月30日 评论:
您好,现在这个issue是什么进展了,遇到什么问题了吗?


liu-wei
7月31日 评论:
7月31日 评论:
您好,这个issue对应的PR已经合入了,问题是否可以关闭了?


liu-wei
8月1日 评论:
8月1日 评论:
您好,我们计划关闭这个 issue,如果您还有其他问题,可以随时提 issue 或者参与 SIG 会议一起参与讨论。
- SIG 会议时间:meeting.osinfra.cn/cann
- 所属 SIG 组:sig-ops-basic
- 往期会议记录:etherpad-cann.meeting.osinfra.cn/p/sig-ops-basic


8月1日 issue状态由 进行中 改变为 已完成
8月1日 关闭了 issue
8月1日 添加了label:Accepted
需求背景(required)
需求来源
aclnnUpsampleNearestExact1d/aclnnUpsampleNearestExact2d算子不支持uint8数据类型,需要在原来的代码上进行再开发,使其支持uint8数据类型。
image/upsample_nearest背景介绍
算子现状分析
当前
aclnnUpsampleNearestExact1d/aclnnUpsampleNearestExact2d基于 Ascend C 实现,底层为同一个UpsampleNearest算子(op_kernel/upsample_nearest.cpp),通过 aclnn 层的视图变换(NCL→NCHW、NCHW↔NHWC、转置)复用同一套 kernel/tiling 逻辑。当前已支持的数据类型如下:
output_size(必选,ListInt)、scales_h/scales_w(可选,float)、exact_mode(可选,bool)。算子整体调用链路:本次方案不改变 aclnn 层、L0 包装层、Tiling 层与各链路分发,仅在底层
UpsampleNearestkernel 的 MODE=1/3 路径上对 UINT8 接入 Cast 桥接。下图一是 1d 接口的完整调用路径,下图二是 2d 接口的完整调用路径,两张图都向下延伸到了 kernel 内部的 MODE 分发。
*图一:aclnnUpsampleNearestExact1d 流程图
flowchart TD A[aclnnUpsampleNearestExact1d<br/>用户入口] --> B[CheckParams<br/>dtype/shape/null 校验] B --> C[Contiguous self/out<br/>非连续张量物化为连续] C --> D[realScales = 1.0 / scales<br/>scale 方向翻转] D --> E{IsRegBase} E -->|是 + NCL/ND| F[View3dAs4d<br/>3D → 4D] F --> F2[l0op::ResizeNearestNeighborV2<br/>复用 v2 算子] F2 --> F3[View4dAs3d<br/>4D → 3D] F3 --> Z[ViewCopy 写回 out] E -->|否 + NCL/ND| G[Transpose<br/>N,C,L → N,L,C] E -->|否 + NLC| G2[直接进入 L0] G --> G2 G2 --> H[l0op::UpsampleNearestExact2d<br/>分配 out, ADD_TO_LAUNCHER_LIST_AICORE] H --> I[host Tiling<br/>dim=3 NLC 分支<br/>归一化为 NHWC, H=1] I --> J{GetTilingKey<br/>outputH=1 不命中 1001<br/>format 非 NCHW 不命中 1003} J -->|inputC<8K<br/>outputW<8K<br/>realScaleW<2| K1[TilingKey = 1002<br/>SMALL_C] J -->|其他| K2[TilingKey = 1000<br/>COMMON] K1 --> L1[UpsampleNearestND<T, 2><br/>MODE=2<br/>ProcessOutputSmallC] K2 --> L2[UpsampleNearestND<T, 0><br/>MODE=0<br/>NearestComputeBase] L1 --> M1[CopyInBatch 一段 W×C<br/>逐 W 调 CopyOutBase] L2 --> M2[逐 H,W 切片<br/>CopyIn → CopyOut] M1 --> N[Transpose 回 NCL] M2 --> N N --> Z图二:aclnnUpsampleNearestExact2d 流程图
flowchart TD A[aclnnUpsampleNearestExact2d<br/>用户入口] --> B[CheckParams<br/>dtype/format/shape/N,C 一致校验] B --> C[Contiguous self/out] C --> D{IsRegBase} D -->|是 + 常规| E1[l0op::ResizeNearestNeighborV2<br/>主路径] D -->|是 + 大shape<br/>IsCaseNearestExact3d| E2[4D → 5D<br/>l0op::UpsampleNearestExact3dNcdhw<br/>5D → 4D] D -->|否 + NCHW/ND| F[Transpose+ReFormat<br/>NCHW → NHWC] D -->|否 + NHWC| G[直接进 L0] F --> G G --> H[l0op::UpsampleNearestExact2d<br/>ADD_TO_LAUNCHER_LIST_AICORE] H --> I[host Tiling<br/>dim=4 NHWC 分支] I --> J{GetTilingKey<br/>inputFormat = NHWC<br/>不命中 1003} J -->|inputC*W<8K<br/>inputC*outW<8K<br/>outputH>1| K1[TilingKey = 1001<br/>SMALL_CW] J -->|inputC<8K<br/>outputW<8K<br/>realScaleW<2| K2[TilingKey = 1002<br/>SMALL_C] J -->|其他| K3[TilingKey = 1000<br/>COMMON] K1 --> L1[UpsampleNearestND<T, 1><br/>MODE=1 SMALL_CW] K2 --> L2[UpsampleNearestND<T, 2><br/>MODE=2 SMALL_C] K3 --> L3[UpsampleNearestND<T, 0><br/>MODE=0 COMMON] L1 --> M1[NearestComputeSmallCW<br/>Gather 行内重排<br/>一次 CopyIn + 一次 Gather + 一次 CopyOut] L2 --> M2[ProcessOutputSmallC<br/>批量 CopyInBatch + 逐 W 输出] L3 --> M3[NearestComputeBase<br/>逐 H,W,batch 通用搬运] M1 --> N[Transpose 回 NCHW/ND<br/>如有] M2 --> N M3 --> N E1 --> Z[ViewCopy 写回 out] E2 --> Z N --> Z现状问题
aclnnUpsampleNearestExact1d/aclnnUpsampleNearestExact2d不支持 UINT8 数据类型。在图像类业务(如分割掩码、调色板图、量化前的 8bit 图像)中,UINT8 上采样是常见诉求,缺失该类型会导致业务侧需先 Cast 到 FP16/FP32 再上采样,增加额外的搬运与转换开销。需求分析(required)
需求描述
在不破坏既有 FLOAT32/FLOAT16/BFLOAT16 功能与性能的前提下,使用 Ascend C 在
image/upsample_nearest目录新增对 UINT8 数据类型的支持,覆盖aclnnUpsampleNearestExact1d与aclnnUpsampleNearestExact2d两个接口,并同步更新算子文档(README、aclnn 接口文档)。需求拆解
op_def中为 Atlas A2/A3(ascend910b / ascend910_93)增加 UINT8 的输入/输出 DataType 与 Format 组合。GetDataTypeVal()能识别 UINT8(按 1 字节返回),分核/切分逻辑自然适配 1 字节元素。Gather在 A2/A3 不支持 b8 的硬件约束。本方案采用 Cast 桥接:UINT8 → half → Gather → half → UINT8。*_binary.json中新增 UINT8 编译条目。详细设计(required)
算子分析
数学公式
最近邻插值(与既有类型完全一致,仅元素 dtype 不同):
hsrc=min(floor((hdst+0.5)⋅scalesH), H−1)
wsrc=min(floor((wdst+0.5)⋅scalesW), W−1)
hsrc=min(floor(hdst⋅scalesH), H−1),wsrc=min(floor(wdst⋅scalesW), W−1)
out(N,C,hdst,wdst)=self(N,C,hsrc,wsrc)
1d 接口将 L 维视作 W 维(H=1)处理,公式同上。
支持数据类型
FLOAT32、FLOAT16、BFLOAT16、UINT8。
支持形状
算子实现
实现方案
UINT8 的最近邻上采样与现有浮点类型走相同的算法主链,本方案采用 MODE=1/3 的 Gather 路径上对 UINT8 采用 half 桥接,即在 Gather 前后插入一对 Cast。
核心原理:
GatherAPI 在 Atlas A2/A3 不支持 b8(uint8_t),但支持 half。uint8 → half → uint8是比特级无损变换。Cast(uint8→half)与Cast(half→uint8),把 b8 的 Gather 转换为 half 的 Gather,硬件即可正确执行。host 侧设计
1. 算子原型(upsample_nearest_def.cpp)
为主 AICore 配置(ascend910b、ascend910_93)的输入
x、输出y的 dtype 列表中追加ge::DT_UINT8,并相应追加ge::FORMAT_ND。config310p(ascend310p / kirinx90 / kirin9030)保持{FLOAT16, FLOAT}不变。2. Tiling(upsample_nearest_tiling.cpp)
tilingData.dataType字段语义为"元素字节数"(FLOAT=4、FLOAT16/BF16=2)。在GetDataTypeVal()的 switch 中新增case ge::DT_UINT8分支,返回 1。3. 二进制配置
在
op_host/config/ascend910b/upsample_nearest_binary.json、.../ascend910_93/upsample_nearest_binary.json中各新增一条 UINT8(dtype: "uint8",format: "ND")编译条目。kernel 侧设计
1. 模板实例化(upsample_nearest.cpp)
非 310P 分支(910b/910_93 走
upsample_nearest.h)下,为 4 个 TilingKey(1000/1001/1002/1003)的 if/else 分发块中各新增dataType == 1的实例化分支,构造UpsampleNearestND<uint8_t, MODE>并调用Init/Process,与原half/float分支并列。2. Cast 桥接核心(upsample_nearest.h)
新增模板成员函数
GatherWithBridge(dst, src, offset, count),函数体内用if constexpr (std::is_same_v<T, uint8_t>)做编译期分发。ProcessOutputSmallCW(MODE=1)和NearestComputeSmallNCH(MODE=3)中原本对Gather(...)的调用统一替换为GatherWithBridge(...),其余流水线保持不变。算子实现流程图(UINT8 修改点)
下两张图把"图一/图二"的链路结构精简到与 UINT8 改动相关的关键节点上,并把新增/修改位置用橙色高亮(深橙为本次新增逻辑,浅橙为本次扩展点)。
图三:aclnnUpsampleNearestExact1d UINT8 增加流程图
flowchart TD A[aclnnUpsampleNearestExact1d] --> B[CheckParams<br/>UINT8 加入 dtype 白名单] B --> C[非 RegBase: Transpose + 2d L0] C --> D[host Tiling<br/>GetDataTypeVal 增加<br/>case DT_UINT8 → 1] D --> E[Kernel 模板分发<br/>新增 dataType==1 分支<br/>UpsampleNearestND<uint8_t, MODE>] E --> F{1d 实际 MODE} F -->|MODE=0 COMMON| G1[NearestComputeBase<br/>无 Gather, 无桥接] F -->|MODE=2 SMALL_C| G2[ProcessOutputSmallC<br/>无 Gather, 无桥接] G1 --> H[ViewCopy → out] G2 --> H图四:aclnnUpsampleNearestExact2d UINT8 增加流程图
flowchart TD A[aclnnUpsampleNearestExact2d] --> B[CheckParams + 视图变换<br/>UINT8 加入 dtype 白名单] B --> C[Tiling + Kernel 模板分发<br/>dataType=1, T=uint8_t] C --> D{2d 实际 MODE} D -->|MODE=0/2| E[无 Gather, 无桥接] D -->|MODE=1 SMALL_CW| F[ProcessOutputSmallCW<br/>调用 GatherWithBridge] F --> G[Cast u8→half<br/>Gather half<br/>Cast half→u8] E --> H[ViewCopy → out] G --> H支持硬件
算子约束限制
upsample_nearest_310p.h,其ComputeNearest使用Duplicate/Add/SetAtomicAdd<T>等算术与原子累加指令完成清零累加,这些指令不支持 b8(UINT8) 类型;且本任务适配硬件为 Atlas A2/A3,故 310P/Kirin 保持原{FLOAT16, FLOAT}不变。兼容性分析
GatherWithBridge中if constexpr (std::is_same_v<T, uint8_t>)分支在 fp16/fp32 编译期消除,直接降为原Gather调用,无任何运行时开销GatherElemSize<T>()对 fp16/fp32 返回sizeof(T),offset 计算与原代码完全一致T == uint8_t时编译期才把桥接分支编译进 kernel精度标准/性能标准