已关闭
[Requirement|需求建议]: ViewCopy算子AscendC实现贡献 #2183
Andy Zhang创建于  7月8日关闭于  7月9日
Andy Zhang
Andy Zhang
7月8日 创建

Thanks for sending an requirement! Please fill in the following template to help quickly solve your problem.

ViewCopy AscendC 重构适配

一、背景信息(必填)

使用 AscendC 对 TBE 实现的 ViewCopy 算子进行重构,实现 AscendC 版本 ViewCopy 算子对 Atlas A2 训练系列产品的适配。

二、价值/作用(必填)

ViewCopy 用于支持基于 size / stride / storage_offset 描述的 view 拷贝场景,可覆盖连续 Tensor、非连续 Tensor、带 storage offset 的切片、转置、置换以及 dst overlap 等数据搬运需求。

本需求通过 AscendC 重构 ViewCopy 算子,提升算子在 Atlas A2 训练系列产品上的可维护性和适配能力,并支持 ACLNN 直调方式使用。相比原 TBE 实现,AscendC 实现便于后续针对不同 shape、stride、overlap 场景进行精细化优化,同时可支撑训练框架中 view copy、非连续 Tensor 写回等常见场景。

三、设计方案(必填)

3.1 使能方式(涉及哪些框架:如 Aclnn 直调、Pytorch 训练等)

当前通过 ACLNN 直调方式使能,提供如下接口:

阶段 接口
workspace 查询 aclnnViewCopyGetWorkspaceSize
算子执行 aclnnViewCopy

算子输入输出如下:

类型 名称 说明
输入 dst 原始目标 storage
输入 dst_size 目标 view shape
输入 dst_stride 目标 view stride
输入 dst_storage_offset 目标 view storage offset
输入 src 源 storage
输入 src_size 源 view shape
输入 src_stride 源 view stride
输入 src_storage_offset 源 view storage offset
输出 dst 更新后的目标 storage

3.2 总体设计

ViewCopy 的总体语义为:先保留 dst 原始 storage 内容,再根据 dst_size / dst_stride / dst_storage_offsetsrc_size / src_stride / src_storage_offset 描述的 view 映射,将 src view 中的数据拷贝到 dst 对应 view 位置,最终输出更新后的 dst

3.2.1 算子支持的数据类型

数据 Tensor 支持:

类型类别 支持类型
浮点 float16, float32, bfloat16
有符号整数 int8, int16, int32, int64
无符号整数 uint8, uint16, uint32
布尔 bool

元数据 Tensor 支持:

元数据 支持类型
size / stride / storage_offset int32, int64

3.2.2 host 侧设计

Host 侧主要完成参数检查、metadata 读取和 tiling 计算。

模块 设计说明
参数检查 检查 dst / src / output 数据类型一致
metadata 检查 检查 dst_size / dst_stride / dst_storage_offset / src_size / src_stride / src_storage_offset 类型一致,且为 int32int64
rank 检查 支持 rank 范围 [1, 8]
shape 检查 size/stride 元素个数为 rank,storage offset 元素个数为 1
metadata 读取 metadata 可 host 侧读取时,提前计算 viewNumdstSpandstOverlap
并行切分 根据 dtype 字节数、shape、stride、overlap 情况选择 blockDim
overlap 处理 dst 可能 overlap 时,按 dst 物理地址范围切分,避免多核写同一物理地址导致不确定结果

Host 侧设计流程图:

flowchart TD
    A["进入 ViewCopy tiling"] --> B["获取输入/输出描述信息"]
    B --> C{"dtype 是否合法且一致"}
    C -- 否 --> C1["返回参数错误"]
    C -- 是 --> D{"metadata dtype 是否为 int32/int64 且一致"}
    D -- 否 --> D1["返回参数错误"]
    D -- 是 --> E["校验 rank 与 metadata shape"]
    E --> F{"metadata 是否可 host 侧读取"}
    F -- 否 --> G["metadataReady = 0<br/>运行时由 kernel 读取 metadata"]
    F -- 是 --> H["读取 size/stride/storage_offset"]
    H --> I["计算 viewNum / dstSpan"]
    I --> J["判断 dst 是否可能 overlap"]
    G --> K["按保守策略设置 tiling"]
    J --> L{"是否 dst overlap"}
    L -- 是 --> M["按 dst 物理地址 block 切分"]
    L -- 否 --> N{"是否命中特殊连续/转置模式"}
    N -- 是 --> O["选择连续片段或特殊模式切分"]
    N -- 否 --> P["按 view 线性元素切分"]
    K --> Q["设置 blockDim / tilingKey / tilingData"]
    M --> Q
    O --> Q
    P --> Q
    Q --> R["返回 tiling 成功"]

3.2.3 kernel 侧设计

Kernel 侧基于 AscendC 实现数据搬运逻辑。

场景 kernel 处理方式
连续拷贝 使用连续片段搬运
普通非连续拷贝 根据线性 view index 计算 src/dst offset 后搬运
连续 slice 场景 按 slice/chunk 切分,提高连续搬运比例
特殊转置场景 针对规则 3D transpose 类模式做专门处理
dst overlap 场景 按最终 dst 物理地址反推对应最后一次 src 写入,保证最终写入语义

dst overlap 反推优化:

优化点 作用
suffix max 剪枝 快速过滤不可能命中的 dst 地址
suffix gcd 剪枝 跳过 stride 组合无法表示的 dst 地址
最后 1 维快速求解 避免继续 DFS
最后 2 维模逆求解 将二维搜索转为有界求解
按 dst 物理地址切分 避免多核对同一 dst 地址重复写导致结果不确定

Kernel 侧设计流程图:

flowchart TD
    A["进入 ViewCopy kernel"] --> B["根据 tilingKey 选择模板实例<br/>1B/2B/4B/8B"]
    B --> C{"metadataReady 是否为 1"}
    C -- 否 --> D["从 GM 读取 size/stride/storage_offset"]
    C -- 是 --> E["使用 tiling 中 metadata"]
    D --> F["计算 viewNum / dstSpan / dstOverlap"]
    E --> F
    F --> G{"viewNum 是否为 0"}
    G -- 是 --> G1["直接返回"]
    G -- 否 --> H{"dst 是否 overlap"}
    H -- 是 --> I["按 dst 物理地址范围处理"]
    I --> J["构造 TensorIterator 写入顺序"]
    J --> K["构造 suffix max / suffix gcd"]
    K --> L["遍历当前 core 负责的 dst 地址"]
    L --> M{"dst 地址是否可由 stride 表示"}
    M -- 否 --> L
    M -- 是 --> N["反推最后一次写入该 dst 的 src offset"]
    N --> O["写入 output dst"]
    O --> L

    H -- 否 --> P{"是否为特殊 3D transpose 模式"}
    P -- 是 --> P1["执行 transpose 专用搬运"]
    P -- 否 --> Q{"是否为连续 slice 模式"}
    Q -- 是 --> Q1["按 slice/chunk 连续搬运"]
    Q -- 否 --> R["按线性 view index 计算 offset 搬运"]

    P1 --> S["必要时清理 cache"]
    Q1 --> S
    R --> S
    L --> S
    S --> T["kernel 结束"]

Overlap 场景伪代码如下:

for each dst physical address assigned to current core:
    if dst address cannot be represented by dst strides:
        continue

    reverse solve logical coord that writes this dst address last
    if coord exists:
        src_offset = src_storage_offset + sum(coord[i] * src_stride[i])
        dst_offset = dst_storage_offset + dst_physical_offset
        dst_out[dst_offset] = src[src_offset]

3.3 支持硬件

硬件系列 支持情况
Atlas A2 训练系列产品 支持

3.4 算子约束限制

约束项 说明
format 仅支持 ND 格式
rank 支持 [1, 8]
数据类型 dst / src / output 数据类型必须一致
metadata 类型 metadata Tensor 类型必须一致,且仅支持 int32int64
shape dst_sizesrc_size 需要一致
广播 不支持广播
stride 当前仅支持正 stride,不支持负 stride
scalar 当前不覆盖 rank 0/scalar Tensor 场景
地址合法性 storage offset、size、stride 组合需保证访问地址在对应 storage 范围内

备注(选填)

已使用覆盖多 dtype、多 rank、多 shape、连续/非连续、稀疏 stride、storage offset、dst/src storage size 不等以及 dst overlap 的测试用例进行验证,并通过自定义 AscendC 算子性能测试。

likedislike
Andy ZhangAndy Zhang
7月8日 关联了pull request:西工大智能感知交互实验室-AscendC实现ViewCopy算子贡献
Andy Zhang
Andy Zhang
7月8日 评论:

/assign @hehe7758511

likedislike
CANN-robotCANN-robot成员
7月8日 将 hehe7758511 设为负责人
陈思陈思成员
7月9日 移除了负责人 hehe7758511
陈思陈思成员
7月9日 将 hehe7758511 设为负责人
陈思陈思成员
7月9日 移除了负责人 hehe7758511
CANN-robotCANN-robot成员
7月9日 关闭了 issue
CANN-robotCANN-robot成员
7月10日 添加了label:resolved