已关闭
[Requirement|需求建议]: 【社区任务】Cross算子AscendC实现贡献 #1199
hth810创建于  4月9日关闭于  5月9日
hth810
hth810
4月9日 创建

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

一、背景信息 (必填)

使用AscendC对TBE实现的Cross算子进行重构,实现了AscendC实现的Cross算子对Atlas 200/500 A2推理产品和Atlas 800I/T A2硬件的适配。

二、价值/作用 (必填)

Cross算子的主要功能是计算两个输入张量在指定维度上的向量叉乘:依据右手定则对长度为 3 的向量进行正交积运算,得到垂直于原向量所在平面的新向量,并生成结果张量 out。在数学、计算机图形学与物理仿真领域,Cross 运算是一种基础而关键的几何向量操作,被广泛应用于 3D 渲染、姿态估计、力矩计算、法向量生成等场景,可高效处理批量向量的叉乘计算。实现了Cross算子的AscendC实现,替代原有TBE算子在昇腾硬件上的适配。

三、设计方案 (必填)

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

Aclnn直调

3.2 总体设计
3.2.1 算子支持的数据类型

float16、float32、int32、int8、uint8、int16

3.2.2 host侧设计

由于输入 self 和 other 形状相同,当前实现不支持广播场景下的 kernel 侧特殊排布处理,算子计算过程依赖输入 shape 和 dim 信息。Host 侧首先根据输入 shape 和 dim 计算:

intervalNum:cross 维度之后的连续元素个数
loopTimes:cross 三元组的组数
算子本质上是对长度为 3 的向量做叉积计算。当前实现将输入展平后,按照 dim 对应的 cross 轴进行分组:

当 intervalNum > 1 时,按 stride=intervalNum 访问同一组三个分量
当 intervalNum == 1 时,说明每组三个分量在内存中天然连续,可切换为 group mode 处理
任务划分采用 tile 化方式。Host 侧根据 UB 大小、数据类型长度、kernel 临时 buffer 数量等信息计算 tileDataNum,表示单次搬运/计算的数据量。随后根据 totalTileCount 和可用 coreNum 设置 blockDim,并将 tile 尽量均匀分配到各个 core。尾块不单独拆出复杂调度信息,而是统一交由 kernel 侧通过 DataCopyPad 处理,以减少 host 侧切分复杂度。

(1)分核策略
当前实现遵循“优先使用满核、尽量均分”的原则。
首先通过平台信息获取:
AIV 核数 coreNum
UB 大小 ubSize
然后根据输入 shape、dtype 和 dim 计算总工作量。对不同模式分别处理:
normal mode:总 tile 数为 loopTimes * ceil(intervalNum / tileDataNum)
group mode:总 tile 数为 ceil(loopTimes / tileDataNum)
最终分核策略为:
blockDim = min(coreNum, totalTileCount)
每个 core 处理的 tile 数尽量均分
若不能整除,前面的若干 core 多分配 1 个 tile
这种方式可以避免某些 core 空跑,同时保持 host 逻辑简单稳定。当前实现没有单独维护“大核/小核数据量”字段,而是直接基于 tile 数均分。
(2)数据切分和内存优化策略
遵循“尽量使用 UB、同时保证 kernel 中间 buffer 可容纳”的原则。
Host 侧通过平台接口获取 UB 大小后,结合 block size 和不同 dtype 所需的 buffer 数量,估算单次 tile 能处理的数据规模。不同 dtype 的 UB 预算不同:
float / int32 / int16:除输入输出外,还需一个临时 buffer
float16:由于计算过程中需要先转 fp32 再计算,因此需要更多 fp32 临时 buffer
group mode:只需要连续搬运两路输入和一路输出,buffer 数相对更少
切分策略如下:
normal mode 下,tileDataNum 表示单次处理多少个 interval 元素
group mode 下,tileDataNum 表示单次处理多少组三元组,实际搬运大小为 tileDataNum * 3
为避免 UB 超限,tileDataNum 会受以下因素约束:
UB 总大小
block 对齐大小
dtype 字节数
kernel 临时 buffer 数量
当前模式下的最大可处理 work unit 数
尾块场景下,若单次 tile 不能整除 block 对齐大小,kernel 使用 DataCopyPad 对尾部不足整块的数据进行补齐搬运和写回,从而保证计算流程统一,不额外增加 host 侧复杂的尾块调度逻辑。

3.2.3 kernel侧设计

进行Init和Process两个阶段,其中Process包括数据搬入(CopyIn)、计算(Compute)、搬出(CopyOut)三个阶段。
对于float16数据类型,转换为float32进行计算,计算完成后再转换回float16;
对于int8、uint8数据类型,先转换为int32,计算完成后再转回int8、uint8;
对于float32和整数类型(int32、int16),直接计算。
无广播填充需求,直接在Compute阶段执行元素级运算。
根据tilingkey(固定)执行核函数。

3.3 支持硬件

Atlas A2 训练系列产品/Atlas A2 推理系列产品,Atlas A3 训练系列产品/Atlas A3 推理系列产品

3.4 算子约束限制

💡 备注(选填)

likedislike
hth810hth810
4月9日 修改了issue 的描述
hth810
hth810
4月9日 评论:

/assign

likedislike
CANN-robotCANN-robot成员
4月9日 将 hth810 设为负责人
hth810hth810
4月9日 关联了pull request:【社区任务】AscendC实现Cross算子贡献
CANN-robotCANN-robot成员
5月9日 关闭了 issue
CANN-robotCANN-robot成员
5月9日 添加了label:resolved