Closed
[Requirement|需求建议]: AsStrided算子AscendC实现贡献 #2180
Mars_Cheng_cysAdd on Jul 8Closed at Jul 30
Mars_Cheng_cys
Jul 8 Comments:
Jul 8 Comments:
/assign @Mars_Cheng_cys


Jul 8 Assign Mars_Cheng_cys as responsible person
Jul 8 Modify description of issue
Jul 8 Associated pull request
Jul 8 Associated pull request
Thanks for sending an requirement! Please fill in the following template to help quickly solve your problem.
一、背景信息 (必填)
使用 AscendC对TBE实现的 AsStrided 算子进行 AICore 实现重构,适配 Atlas A2 训练系列产品。AsStrided 根据 size、stride 和 storage_offset 从输入 Tensor 的底层存储中按步长取数,生成指定 shape 的输出 Tensor,语义对齐 torch.as_strided 的取数规则。
二、价值/作用 (必填)
AsStrided 是张量视图、切片、滑窗、非连续内存布局访问等场景的基础算子能力。该算子本身不进行数值计算,仅进行按 stride 的数据读取与输出写回,可为 ACLNN 直调及后续上层框架接入提供 NPU 侧实现,减少相关场景回退或低效通用搬运路径。
三、设计方案 (必填)
3.1 使能方式(涉及哪些框架:如Aclnn直调、Pytorch训练等)
当前支持 ACLNN 直调,提供以下接口:
aclnnAsStridedGetWorkspaceSize:根据 x、size、stride、storageOffset、out 生成执行器并返回 workspace 大小。
aclnnAsStrided:提交 AICore 算子执行。
Level 0 接口将 aclIntArray 类型的 size、stride、storageOffset 转换为 INT64 Tensor,执行 shape 推导后进入 AICore 路径;当当前 dtype 或平台不满足 AICore 支持条件时,使用 ViewCopy 作为兜底路径。
3.2 总体设计
AsStrided 的输出 shape 由 size 决定,输出每个元素的输入偏移计算公式为:
input_offset = storage_offset + sum(output_coord[i] * stride[i])
即:
y[coord] = x[input_offset]
算子只进行数据搬运和布局重排,不涉及数值计算,因此不涉及 FP16/BF16 升精度。
3.2.1 算子支持的数据类型
3.2.2 host侧设计
Host 侧完成以下工作:
主要 Tiling 策略包括:
Kernel 总体流程如下:
flowchart TD A["as_strided Kernel 入口"] --> B["读取 TilingData"] B --> C["创建 TPipe 与 AsStridedKernel"] C --> D["Init 初始化"] D --> D1["加载 tilingKey、shape、stride、storage_offset、UB 与多核切分参数"] D1 --> D2["按 tilingKey 确定 splitElements"] D2 --> D3["根据 blockIdx 计算 coreBaseIndex 与 currentCoreElements"] D3 --> D4["绑定输入 / 输出 GM Buffer"] D4 --> D5["按路径申请 UB Buffer"] D5 --> E{"currentCoreElements > 0 且 ubElements > 0?"} E -- "否" --> Z["当前核无任务,直接返回"] E -- "是" --> F{"按 tilingKey 分发"} F -- "CONTIGUOUS" --> P0["连续视图:DataCopyPad 双缓冲块搬运"] F -- "CONTIGUOUS_SMALL_ALIGNED" --> P9["小对齐连续视图:单 UB DataCopy / DataCopyPad"] F -- "COMPACT_SPAN" --> P10["整段输入进 UB:生成 mask / Gather 打包输出"] F -- "COMPACT_SUFFIX" --> P11["复用 suffix mask:按 suffix block Gather 打包输出"] F -- "STRIDE_1" --> P1["最后一维连续:按行分块搬运"] F -- "STRIDE1_ROW_BATCH" --> P6["小行批量:二维 DataCopyPad 后打包输出"] F -- "GENERAL_STRIDE" --> P2["通用 stride:DataCopy srcStride 搬运即重排"] F -- "GENERAL_SMALL_SPAN" --> P7["小跨度:加载覆盖 span 后按 stride 打包"] F -- "RANK1_STRIDE" --> P5["Rank-1 stride:按输出元素多核切分,srcStride 搬运"] F -- "RANK1_STRIDE_SPAN" --> P8["Rank-1 小跨度:加载连续 span 后打包"] F -- "BROADCAST" --> P3["stride 为 0:读取单元素并在 UB 内复制"] F -- "其他 / SCALAR" --> P4["标量兜底:逐元素 ComputeInputOffset 后读写"] P0 --> G["写回连续输出 GM"] P9 --> G P10 --> G P11 --> G P1 --> G P6 --> G P2 --> G P7 --> G P5 --> G P8 --> G P3 --> G P4 --> G G --> H["当前核处理完成"]3.2.3 kernel侧设计
Kernel 根据 Tiling Key 分发到不同处理路径。核心逻辑包括:
3.3 支持硬件
3.4 算子约束限制
💡 备注(选填)
AsStrided 为访存密集型算子。当前设计通过连续搬运、srcStride 搬运、compact span/suffix gather、小 shape 专用路径、DataCopyPad 尾块处理和多核任务切分提升不同 stride 模式下的有效带宽。后续验证建议覆盖 ACLNN 直调样例、msopst 精度对比(golden 使用 torch.as_strided)、多 dtype / 多 rank / 多 Tiling Key 用例,以及与内置实现的性能对比。