CANN ops-math 中 AddV2 算子深度解析:功能、参数、产品差异与 GE 图模式调用指南
2026/9/21 15:25:50 网站建设 项目流程
  • 算子库
  • 人工智能
  • CANN

【免费下载链接】ops-math

本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。

项目地址:https://gitcode.com/cann/ops-math
点击查看免费下载

AddV2 是 CANN ops-math 数学算子库中用于执行逐元素加法的基础算子,兼容 TensorFlow AddV2 语义,支持广播与动态 shape。本文以 math/add_v2/README.md 为主体,结合仓库内算子原型(proto)、宿主侧定义(OpDef)、InferShape、Tiling 与 Kernel 源码,完整梳理 AddV2 的功能说明、参数规格、产品差异、广播规则,并给出基于算子 IR(GE 图模式)的可运行调用示例,帮助开发者在 Ascend 系列产品上正确使用与验证该算子。

一、算子功能与语义说明

1.1 功能概述

AddV2 对输入张量x1x2执行逐元素加法,并将结果写入输出张量y,支持 NumPy 风格的广播(broadcast)语义,兼容 TensorFlow AddV2 图节点行为。

1.2 版本说明(V2 的含义)

名称中的 "V2" 仅用于对应 TensorFlow 的AddV2图节点,并不表示加法运算或广播规则发生了变化。在 AddV2 与 Add 共同支持的数据类型范围内,两者的数学语义一致;AddV2 的数据类型与调用通路以本文为准。

1.3 计算公式

$$ y_i = x_{1,i} + x_{2,i} $$

其中 $i$ 遍历广播结果的全部元素,$x_{1,i}$ 与 $x_{2,i}$ 表示广播后对应位置的元素。该逐元素语义在 Kernel 层由Vec::Add实现(见 math/add_v2/op_kernel/arch35/add_v2_dag.h),所有元素按同一规则并行计算。

1.4 广播规则与示例

广播时从末尾维度向前对齐,每组对应维度的长度必须相等,或至少有一路的维度长度为 1。仓库文档给出的典型示例:

x1 shape (3, 4), x2 shape (1, 4) -> y shape (3, 4) x1 shape (3, 1), x2 shape (1, 4) -> y shape (3, 4)

从源码看,广播的 shape 推导由宿主侧 InferShape 统一完成。在 math/add_v2/op_host/add_v2_infershape.cpp 中,InferShapeAddV2直接调用Ops::Base::InferShape4Broadcast(context),即输出 shape 完全由通用广播推导工具计算,确保输出 shape 等于x1x2按广播规则对齐后的 shape。单元测试 math/add_v2/tests/ut/op_host/test_add_v2_infershape.cpp 验证了(8, 8)(1)广播得到(8, 8)的场景。

二、产品支持情况

根据仓库 README,AddV2 在以下产品上均获得支持:

产品是否支持
Ascend 950PR / Ascend 950DT
Atlas A3 训练系列产品 / Atlas A3 推理系列产品
Atlas A2 训练系列产品 / Atlas A2 推理系列产品
Atlas 200I/500 A2 推理产品
Atlas 推理系列产品
Atlas 训练系列产品

其中 Ascend 950 平台(架构代号 arch35)的宿主与 Kernel 实现均落在 math/add_v2/op_host/arch35/ 与 math/add_v2/op_kernel/arch35/ 目录下,并通过 math/add_v2/op_host/config/ascend950/add_v2_binary.json 配置每种数据类型的算子二进制文件(bin)。

三、参数说明

AddV2 共包含两个输入张量与一个输出张量,均为必选(REQUIRED),数据格式统一为 ND:

参数名输入/输出/属性描述数据类型数据格式
x1输入加法运算的第一个输入张量,对应公式中的 x1BFLOAT16、FLOAT16、FLOAT、INT32、INT16、UINT8、INT8、INT64、COMPLEX64ND
x2输入加法运算的第二个输入张量,对应公式中的 x2。数据类型与 x1 一致BFLOAT16、FLOAT16、FLOAT、INT32、INT16、UINT8、INT8、INT64、COMPLEX64ND
y输出加法运算的输出张量,对应公式中的 y。数据类型与 x1 一致,shape 为 x1 与 x2 的广播结果BFLOAT16、FLOAT16、FLOAT、INT32、INT16、UINT8、INT8、INT64、COMPLEX64ND

3.1 参数约束的源码印证

  • 数据类型一致性:算子原型 math/add_v2/op_graph/add_v2_proto.h 通过REG_OP(AddV2)声明x1x2y三个端口,并限制为同 dtype 集合;同时宿主侧定义 math/add_v2/op_host/add_v2_def.cpp 为三个端口注册了完全相同的 9 组同 dtype 组合。
  • 运行期校验:图推断阶段 math/add_v2/op_graph/add_v2_graph_infer.cpp 的InferDataTypeAddV2会显式检查x1x2dtype 是否相同,若不同则报错x1 and x2 must have the same dtype并返回失败;输出 dtype 直接继承x1。该算子不注册异类型组合,因此不做类型提升(type promotion)。
  • 数据格式:所有端口统一声明为FORMAT_ND,并标记AutoContiguous(),表示输入为连续排布的 ND 张量。

四、产品差异说明(重点)

不同产品在数据类型、动态 shape 能力与空 Tensor 支持上存在差异,使用时须严格对照下表:

产品数据类型静态 shape 能力动态 shape 能力shape/rank 及空 Tensor 限制
Ascend 950PR / Ascend 950DTBFLOAT16、FLOAT16、FLOAT、INT32、INT16、UINT8、INT8、INT64、COMPLEX64输入 ND → 输出 ND输入 ND → 输出 ND;支持固定 rank 动态 shape 和 dynamic rankrank 取值范围为 [1, 8];支持空 Tensor,输出 y 的 shape 仍必须是两路输入的广播结果
Atlas A3 训练系列 / A3 推理系列、Atlas A2 训练系列 / A2 推理系列BFLOAT16、FLOAT16、FLOAT、INT32、INT64输入 ND → 输出 ND输入 ND → 输出 ND;支持固定 rank 动态 shape,不支持 dynamic rankrank 取值范围为 [0, 8],rank 为 0 时表示标量;空 Tensor 仅支持两路输入 shape 相同,或其中一路输入为单元素张量的广播场景
Atlas 200I/500 A2 推理产品、Atlas 推理系列、Atlas 训练系列FLOAT16、FLOAT、INT32、INT64输入 ND → 输出 ND输入 ND → 输出 ND;支持固定 rank 动态 shape,不支持 dynamic rankrank 取值范围为 [0, 8],rank 为 0 时表示标量;空 Tensor 仅支持两路输入 shape 相同,或其中一路输入为单元素张量的广播场景

4.1 差异的源码依据

  • 数据类型注册差异:完整的 9 种 dtype(含 COMPLEX64、INT16、UINT8、INT8)注册在算子定义中,但不同产品实际支持范围不同。Tiling 侧的IsSupportedDtype(见 math/add_v2/op_host/arch35/add_v2_tiling_arch35.cpp)对 arch35 平台校验DT_FLOAT16/DT_BF16/DT_FLOAT/DT_INT64/DT_COMPLEX64/DT_UINT8/DT_INT8/DT_INT32/DT_INT16,与 README 中 Ascend 950 的数据类型列一致;而其他产品按产品能力裁剪。
  • rank 范围与 dynamic rank:Ascend 950 平台在 Tiling 中通过CheckRank强制 rank 落在 [1, 8](见 math/add_v2/op_host/arch35/add_v2_tiling_arch35.cpp),且add_v2_def.cppaicoreConfig.DynamicRankSupportFlag(true)DynamicShapeSupportFlag(true)分别开启 dynamic rank 与动态 shape 支持;而 Atlas A2/A3 等系列不支持 dynamic rank,仅支持固定 rank 动态 shape。
  • 空 Tensor 支持:Ascend 950 平台专门为空 Tensor 设计了独立处理通路(详见下文第六节),因此支持范围更宽;其他产品仅允许两路输入 shape 相同或单元素广播这两种空 Tensor 场景。

五、调用说明:GE 图模式

AddV2 的调用方式如下表:

调用方式调用样例说明
GE 图模式test_geir_add_v2.cpp通过算子 IR(add_v2_proto.h)构图方式调用 AddV2 算子

注意:本算子不提供同名 aclnn 接口,仅支持上表的 GE 图模式调用。这意味着用户无法通过aclnnAddV2这类接口直接调用,必须经由 GE(Graph Engine)构图后在图上运行。

5.1 构图与运行流程

仓库示例 math/add_v2/examples/test_geir_add_v2.cpp 完整演示了 GE 图模式的调用步骤,核心流程为:

  1. 初始化 GE:通过ge::GEInitialize(global_options)初始化 GE 全局环境,示例中使用{"ge.exec.deviceId", "0"}指定设备、{"ge.graphRunMode", "1"}指定图运行模式。
  2. 创建图与算子节点ge::Graph graph(graph_name)创建图,op::AddV2("add1")创建 AddV2 算子节点。
  3. 构造输入数据节点:使用op::Data(...)构造占位输入节点,并通过ADD_INPUT宏为每个输入创建TensorDesc(shape、FORMAT_ND、dtype),调用GenOnesDataFloat32生成全 2 的浮点测试数据,最后通过add1.set_input_x1(...)/add1.set_input_x2(...)将输入节点接入 AddV2 算子。
  4. 设置图输入输出graph.SetInputs(inputs).SetOutputs(outputs)声明图的输入输出。
  5. 创建会话并建图new Session(build_options)创建会话,session->AddGraph(graph_id, graph, graph_options)将计算图加入会话。
  6. 运行图session->RunGraph(graph_id, input, output)执行计算。
  7. 保存结果SaveInputOutput将输入/输出张量以 bin 文件落盘,并逐元素打印输出结果。
  8. 资源清理:删除会话并调用ge::GEFinalize()结束 GE 环境。

其中示例默认使用{4, 2}的输入 shape(std::vector<int64_t> xShape = {4, 2};),即两路4x2张量相加,输出同样为4x2。关键代码片段:

auto add1 = op::AddV2("add1"); std::vector<int64_t> xShape = {4, 2}; ADD_INPUT(1, x1, inDtype, xShape); ADD_INPUT(2, x2, inDtype, xShape); outputs.push_back(add1);

ADD_INPUT宏内部会完成占位节点、TensorDescFORMAT_ND+ dtype)、测试数据生成、set_input_xN接线等全部工作,是理解 GE 图模式入参构造的关键入口。

5.2 图模式下的算子端口与校验链路

在 GE 图模式下,AddV2 的端口契约由算子 IR 原型 math/add_v2/op_graph/add_v2_proto.h 声明,构图后经过以下链路完成推导与校验:

  • InferDataType(add_v2_graph_infer.cpp):校验x1x2同 dtype,并将y的 dtype 置为x1的 dtype。
  • InferShape(add_v2_infershape.cpp):调用InferShape4Broadcast计算广播后的输出 shape。
  • OpDef 定义(add_v2_def.cpp):声明端口 dtype/format 集合与 AICore 配置(开启动态 shape、dynamic rank、精度降低标志等)。
  • Tiling(add_v2_tiling_arch35.cpp):根据实际 shape、dtype 与编译信息生成切分策略。

六、源码级实现原理(以 Ascend 950 / arch35 为例)

6.1 Kernel 入口与模板分派

Kernel 入口位于 math/add_v2/op_kernel/arch35/add_v2.cpp,采用模板参数schMode(调度模式)与userDef(用户自定义分支开关)做编译期分派:

  • userDef == 1:空 Tensor 通路。由于输出元素个数为 0,无任何数据需要搬运,Kernel 直接返回;Tiling 侧已把blockDim设为 1。
  • 否则按 dtype 选择计算 DAG:浮点类 dtype(half/bfloat16_t/float)走AddWithCastCompute,其余类型走AddWithoutCastCompute,再统一交给BroadcastSch<schMode, OpDag> sch(tiling)完成广播调度。

6.2 计算 DAG 设计

在 math/add_v2/op_kernel/arch35/add_v2_dag.h 中定义了两种计算图(DAG):

  • AddWithoutCastCompute(免精度转换通路):CopyInBrc(广播搬入)→Vec::Add<T>(逐元素加)→CopyOut(写回),适用于整型等可直接相加的 dtype。
  • AddWithCastCompute(精度转换通路):先将输入Castfloat做加法,再把结果Cast回原 dtype(CAST_RINT_MODE使用就近取整),适用于half/bfloat16_t/float类型,对应PrecisionReduceFlag(true)的配置。

两个 DAG 均使用MemOptCfg<MemLevel::LEVEL_2>进行二级内存(L2)级的访存优化,并由DAGSch统一调度。

6.3 空 Tensor 专用通路

空 Tensor 场景在 math/add_v2/op_kernel/arch35/add_v2_struct_arch35.h 中被专门处理:常规广播通路使用 schMode 取值表(1、2、101…999 等)中的普通模式,而空 Tensor 走自定义schMode = 999+userDef = 1的模板分支。原因在于 ATVOSS 的BroadcastBaseTiling在合轴后会显式拒绝 0 元素("tensor check is empty"),因此空 Tensor 必须复用该自定义分支;Tiling 侧对应定义ADD_V2_SCH_MODE_EMPTY = 999ADD_V2_USER_DEF_EMPTY = 1(见 add_v2_tiling_arch35.cpp)。

单元测试 math/add_v2/tests/ut/op_host/arch35/test_add_v2_tiling.cpp 对该分支给出了精确注释:空 Tensor 分支的 tiling key 为65550 = 0x1000E,其低 16 位0x000E = 14是 schMode 999 在取值表中的序号,第 16 位userDef = 1;常规通路userDef = 0,key 仍为 8,不受影响。

七、约束说明与使用建议

  • 仓库 README 明确 AddV2 的约束说明为("约束说明:无"),但这仅指算子层面的通用约束;实际使用时仍需遵守上文第四节产品差异表中的产品级限制(数据类型范围、rank 范围、dynamic rank 支持度、空 Tensor 场景等)。
  • 输入x1x2必须同 dtype,输出y的 dtype 与x1一致,shape 为广播结果。
  • 由于本算子不提供 aclnn 接口,涉及动态 shape 或 dynamic rank 的图模式调用,建议在 test_add_v2_tiling.cpp 与 test_add_v2_infershape.cpp 中选取对应的 shape 组合先做宿主侧单测验证,再上板运行。

八、验证与测试参考

仓库为 AddV2 提供了完整的宿主侧单元测试,可用于验证 shape 推导与 tiling 逻辑:

  • InferShape 单测:math/add_v2/tests/ut/op_host/test_add_v2_infershape.cpp 覆盖了同 shape 相加((8,8)+(8,8)->(8,8))、广播相加((8,8)+(1)->(8,8))以及动态 shape 等场景。
  • Tiling 单测:math/add_v2/tests/ut/op_host/arch35/test_add_v2_tiling.cpp 使用TilingContextFaker/TilingCaseExecutor构造DT_FLOAT等 dtype、8x8等 shape 的 tiling 上下文,并验证空 Tensor 分支的 tiling key(65550)等关键数值。

结合这些测试与上文的源码链路,开发者可以在修改 shape、dtype 或产品形态后快速回归验证 AddV2 的广播推导与切分策略是否符合预期。

  • 算子库
  • 人工智能
  • CANN

【免费下载链接】ops-math

本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。

项目地址:https://gitcode.com/cann/ops-math
点击查看免费下载
上一篇:rack-mini-profiler 与单页应用集成:React、Vue、Angular 完美适配方案
下一篇:OneBot消息系统完全指南:文本、图片、语音、视频等12种消息段的灵活应用

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询