CANN ops-math Invert 算子深度解析:按位取反的架构实现、Tiling 调度与图模式调用实战

发布时间:2026/9/20 19:26:42

CANN ops-math Invert 算子深度解析:按位取反的架构实现、Tiling 调度与图模式调用实战 算子库人工智能CANN【免费下载链接】ops-math本项目是CANN提供的数学类基础计算算子库实现网络在NPU上加速计算。项目地址https://gitcode.com/cann/ops-math点击查看免费下载导读Invert 是 CANN ops-math 数学算子库中的按位取反算子对输入张量的每一个元素执行按位取反bitwise NOT运算等价于out_i ~input_i。本文以 math/invert/README.md 为核心骨架结合算子注册、构图、Tiling、Kernel 与单测等源码完整梳理 Invert 算子在 Ascend NPU 上的支持范围、参数语义、底层实现原理与图模式调用方法。读完本文你将掌握Invert 算子的数据类型/产品支持矩阵、逐元素算子的标准实现范式Proto → Def → Infershape → Tiling → Kernel、以及如何用算子 IR 构图方式在 GE 会话中跑通单算子图。一、算子功能与数学定义Invert 是典型的逐元素elementwise / elewise一元算子功能定义非常简洁算子功能对输入张量x的每一个元素执行按位取反bitwise invert得到输出张量y。计算公式$$ out_i\sim input_i $$即每个输出元素是输入元素按位取反后的结果。以 INT8 为例输入0b000000011经 invert 后输出0b11111110-2输入0b11110000则输出0b00001111。由于是按位运算invert(invert(x)) x恒成立因此该算子在符号/掩码翻转、编码反转等场景中常被用作基础原语。需要特别说明的是这里的取反是按位取反bitwise NOT不是算术取负negation-x。算术取负在 CANN 中由独立的 neg 算子承担见 math/neg/README.md两者语义不同~x在补码表示下等价于-x - 1。二、产品支持情况Invert 算子在各产品形态上的支持情况如下表取自 math/invert/README.md产品是否支持Ascend 950PR / Ascend 950DT√Atlas A3 训练系列产品 / Atlas A3 推理系列产品√Atlas A2 训练系列产品 / Atlas A2 推理系列产品√Atlas 200I/500 A2 推理产品×Atlas 推理系列产品√Atlas 训练系列产品√从源码可以交叉印证该支持矩阵。在 op_host/invert_def.cpp 中算子定义通过this-AICore().AddConfig(ascend950, aicoreConfig)显式注册了 ascend950 架构对应 Ascend 950 系列的 AICore 配置在 op_api/invert.cpp 中算子运行时会根据当前 NPU 架构动态选择执行路径// math/invert/op_api/invert.cpp static inline bool IsAiCoreSupport(const aclTensor* self) { auto npuArch op::GetCurrentPlatformInfo().GetCurNpuArch(); if (IsRegBase(npuArch)) { return CheckType(self-GetDataType(), REGBASE_DTYPE_SUPPORT_LIST); } return CheckType(self-GetDataType(), AICORE_DTYPE_SUPPORT_LIST); }即RegBase 类架构如 A2/A3 等通用寄存器基架构支持 8 种整数类型全部走 AICore其余架构仅 INT16、UINT16 两种类型走 AICore其余类型回退到 AICpu 执行。这也解释了为什么 README 中标注 Atlas 200I/500 A2 推理产品不支持——该形态无对应的 AICore/AICpu 内核路径。注意README 中不支持 BFLOAT16的结论在参数表中已明确体现Invert 仅接受 8 种整数类型浮点与 BF16 均不在支持范围内。三、参数说明Invert 算子只有一对输入输出参数取自 math/invert/README.md参数名输入/输出/属性描述数据类型数据格式x输入待进行 invert 计算的入参公式中的 input_iINT8、INT16、INT32、INT64、UINT8、UINT16、UINT32、UINT64NDy输出待进行 invert 计算的出参公式中的 out_iINT8、INT16、INT32、INT64、UINT8、UINT16、UINT32、UINT64ND附加约束Atlas 训练系列产品、Atlas 推理系列产品不支持 BFLOAT16。约束说明无除数据类型约束外Invert 不引入其他 shape、format 层面的限制。3.1 参数语义在算子定义中的落地参数声明与 README 完全对应见 op_host/invert_def.cppthis-Input(x) .ParamType(REQUIRED) .DataType({ge::DT_INT8, ge::DT_INT16, ge::DT_INT32, ge::DT_INT64, ge::DT_UINT8, ge::DT_UINT16, ge::DT_UINT32, ge::DT_UINT64}) .Format({ge::FORMAT_ND, ...}); this-Output(y) .ParamType(REQUIRED) .DataType({...}) // 与 x 完全一致 .Format({ge::FORMAT_ND, ...});该定义同时设置了 AICore 配置项DynamicCompileStaticFlag(true)支持动态编译静态化DynamicFormatFlag(false)不启用动态格式DynamicRankSupportFlag(true)支持动态 rank任意维度数DynamicShapeSupportFlag(true)支持动态 shapeNeedCheckSupportFlag(false)ExtendCfgInfo(opFile.value, invert_apt)指定 kernel 实现文件为 op_kernel/invert_apt.cpp。3.2 输入输出类型一致性校验Tiling 阶段会对输入输出 dtype 做一致性检查见 op_host/arch35/invert_tiling_arch35.cppge::graphStatus InvertTiling::CheckAndGetOutputDtype(ge::DataType outputDtype) { ... OP_CHECK_IF((inputDtype ! outputDtype), ..., return ge::GRAPH_FAILED); ... }若y的 dtype 与x不一致或者落入{DT_INT8, DT_INT16, DT_INT32, DT_INT64, DT_UINT8, DT_UINT16, DT_UINT32, DT_UINT64}之外如浮点、BF16Tiling 会直接报错返回GRAPH_FAILED从而保证算子只按位运算语义合法。四、算子实现架构与调用链路Invert 算子遵循 CANN 算子标准的五段式实现结构目录见 math/invert目录职责关键文件op_graph算子 IRProto定义与图推理invert_proto.h、invert_graph_infer.cppop_host算子定义注册、Infershape、Tilinginvert_def.cpp、invert_infershape.cpp、arch35/invert_tiling_arch35.cppop_kernelNPU 内核实现invert_apt.cpp、arch35/invert_dag.hop_apiL0 API 层aclnn 执行入口invert.cpp、invert.hframework第三方框架TensorFlow算子映射invert_tf_plugin.cpp4.1 算子 IR 定义op_graphinvert_proto.h 使用 GE 的REG_OP宏声明算子接口输入输出类型统一使用TensorType::IntegerDataType()注释中明确其与 TensorFlow 的 Invert 算子兼容REG_OP(Invert) .INPUT(x, TensorType::IntegerDataType()) .OUTPUT(y, TensorType::IntegerDataType()) .OP_END_FACTORY_REG(Invert)同时图推理graph infer逻辑由 invert_graph_infer.cpp 承载用于在构图阶段推导输出 shape。4.2 Infershape复用逐元素通用推理op_host/invert_infershape.cpp 直接复用了逐元素算子的通用 shape 推理IMPL_OP_INFERSHAPE(Invert).InferShape(Ops::Base::InferShape4Elewise);InferShape4Elewise是 CANN 为逐元素算子提供的通用推理工具来源于infershape_elewise_util.hInvert 作为标准 elewise 算子无需单独编写推理逻辑。4.3 Tiling按 dtype 分发到不同 DAG 模板Tiling 是 Ascend 算子在 Host 侧完成的分块调度计算决定 NPU 上如何切分数据、配置核数。Invert 的 Tiling 逻辑arch35/invert_tiling_arch35.cpp要点如下先做输入输出 dtype 一致性检查见 3.2 节根据输出 dtype 分发到对应类型的InvertDagT::OpDag模板调用通用的DoTiling完成 elewise 分块计算SetTilingData()中设置TilingKey 101INVERT_TILING_KEYkernel 侧用TILING_KEY_IS(101UL)匹配workspace 预留 16MBINVERT_WORKSPACE_RESERVE_BYTE 16777216blockNum核数通过context_-SetBlockDim(td_-blockNum)下发。4.4 KernelDAG 描述的 Vector Not 计算Kernel 侧使用DAG 描述 ElementwiseSch 调度器的现代写法。计算核心在 arch35/invert_dag.htemplate typename U struct InvertDag { using OpCopyIn BindVec::CopyInU, Placeholder::In0U; using OpResult BindVec::NotU, OpCopyIn; // 按位取反核心运算 using OpCopyOut BindVec::CopyOutU, Placeholder::Out0U, OpResult; using Outputs ElemsOpCopyOut; using MemCfg MemOptCfgMemLevel::LEVEL_2; // L2 缓存优化 using OpDag DAGSchOutputs, void, MemCfg; };即CopyIn搬运输入→Vec::Not向量按位取反→CopyOut搬出结果并启用 L2 内存级优化。Kernel 入口 op_kernel/invert_apt.cpp 通过if constexpr对 8 种整数类型分别实例化ElementwiseSch使用KERNEL_TASK_TYPE_DEFAULT(KERNEL_TYPE_AIV_ONLY)指定 AIV 向量核执行extern C __global__ __aicore__ void invert(GM_ADDR x, GM_ADDR y, GM_ADDR workspace, GM_ADDR tiling) { KERNEL_TASK_TYPE_DEFAULT(KERNEL_TYPE_AIV_ONLY); REGISTER_TILING_DEFAULT(EleBaseTilingData); ... if (TILING_KEY_IS(101UL)) { if constexpr (std::is_sameDTYPE_X, int8_t::value) { ElementwiseSch0UL, InvertDagint8_t::OpDag sch(tilingData, pipe); sch.Init(x, y); sch.Process(); } // ... 其余 7 种整数类型同理 } }4.5 L0 API 层AICore / AICpu 双路径路由op_api/invert.cpp 是算子对外的高层执行入口实现双路径路由const aclTensor* Invert(const aclTensor* self, aclOpExecutor* executor) { auto out executor-AllocTensor(self-GetViewShape(), self-GetDataType()); if (IsAiCoreSupport(self)) { return InvertAiCore(self, out, executor); // 走 AICore 向量核 } else { return InvertAiCpu(self, out, executor); // 回退 AICputf_kernel } }InvertAiCore通过ADD_TO_LAUNCHER_LIST_AICORE(Invert, OP_INPUT(self), OP_OUTPUT(out))把算子加入 AICore 任务队列InvertAiCpu通过ADD_TO_LAUNCHER_LIST_AICPU(Invert, OP_ATTR_NAMES(), OP_INPUT(self), OP_OUTPUT(out))走 AICputf_kernel执行。RegBase 架构A2/A3 等下 8 种整数类型全部命中 AICore其余架构仅 INT16/UINT16 命中 AICore其余类型回退 AICpu。4.6 TensorFlow 框架适配framework/invert_tf_plugin.cpp 注册了 TF 框架的自定义算子映射REGISTER_CUSTOM_OP(Invert) .FrameworkType(TENSORFLOW) .OriginOpType(Invert) .ParseParamsByOperatorFn(AutoMappingByOpFn) .ImplyType(ImplyType::TVM);这与 invert_proto.h 注释中Compatible with the TensorFlow operator Invert的声明互为印证说明 CANN 的 Invert 与 TensorFlowtf.bitwise.invert语义对齐。五、调用说明与图模式实战README 给出的调用方式如下调用方式调用样例说明图模式调用test_geir_invert.cpp通过算子 IR 构图方式调用 invert 算子5.1 图模式调用完整流程以 examples/test_geir_invert.cpp 为样板图模式调用的完整流程为初始化 GE设置全局选项deviceId、graphRunMode并调用ge::GEInitializestd::mapAscendString, AscendString global_options {{ge.exec.deviceId, 0}, {ge.graphRunMode, 1}}; Status ret ge::GEInitialize(global_options);构造单算子图通过op::Invert(invert1)创建算子节点用ADD_INPUT/ADD_OUTPUT宏绑定输入输出 TensorDescauto invert1 op::Invert(invert1); std::vectorint64_t xShape {4, 2}; ADD_INPUT(1, x, inDtype, xShape); // 生成 placeholder 输入填充值 2 ADD_OUTPUT(1, y, inDtype, xShape); // 声明输出 shape/dtype outputs.push_back(invert1);其中ADD_INPUT宏内部会调用GenOnesData生成 shape 为{4, 2}、元素值为 2 的输入张量示例默认使用DT_INT32值为 2 的 INT32 输入经按位取反后输出 -3。构建并提交图graph.SetInputs(inputs).SetOutputs(outputs)创建Sessionsession-AddGraph(graph_id, graph, graph_options)。Dump 并运行aclgrphDumpGraph(graph, file_path, len)可把构图 dump 到本地默认./dump随后session-RunGraph(graph_id, input, output)执行。回读结果将输入输出数据写为二进制文件命名形如tc_ge_irrun_test_0008_npu_input_0.bin/_output_0.bin并逐元素打印结果验证for (int64_t j 0; j output_shape; j) { LOG_PRINT(result[%ld] is: %d\n, j, result[j]); }收尾ge::GEGetErrorMsgV2()/GEGetWarningMsgV2()获取错误与告警信息最后GEFinalize()释放 GE 会话。5.2 单测覆盖UT 测试 tests/ut/op_api/test_aclnn_invert.cpp 覆盖了多类型用例Invert_int16、Invert_uint16AICore 路径、Invert_int8、Invert_int32等。测试通过aclCreateTensor构造 ND 格式 tensor调用l0op::Invert后断言输出 shape 与输入一致EXPECT_EQ(ToShapeVector(result-GetViewShape()), expectShape)验证了算子输出 shape 继承输入 shape 的逐元素语义。六、总结Invert 是 ops-math 中最典型的逐元素整数算子之一语义单一out ~input支持 8 种整数类型、ND 格式输出与输入 shape、dtype 完全一致实现范式标准Protoinvert_proto.h→ Def/Infershapeinvert_def.cpp、invert_infershape.cpp→ Tilinginvert_tiling_arch35.cpp→ DAG Kernelinvert_dag.h invert_apt.cpp→ L0 APIinvert.cpp架构兼容AICore 向量核Vec::NotElementwiseSch L2 优化为主路径AICpu 兜底RegBase 架构下 8 种整数类型全覆盖调用灵活既可通过图模式GEIR 构图见 test_geir_invert.cpp调用也可通过 L0 API 单算子执行并支持 TensorFlow 框架算子映射。如需在自定义模型中复用 Invert 进行掩码翻转或编码取反可直接参照本文的参数表与图模式样例构造算子图若需在昇腾上做性能优化可进一步阅读 Tiling 与 DAG 源码理解其 L2 缓存与向量化调度策略。赞分享算子库人工智能CANN【免费下载链接】ops-math本项目是CANN提供的数学类基础计算算子库实现网络在NPU上加速计算。项目地址https://gitcode.com/cann/ops-math点击查看免费下载相关推荐CANN ops-math BroadcastTo 算子深度解析NPU 广播实现、图模式调用与源码架构CANN ops math BroadcastTo 算子深度解析NPU 广播实现、图模式调用与源码架构 本文以 CANN ops math 开源算子库中 Br算子库人工智能CANNCANN ops-math 算子深度解析ConcatDV2 多 Tensor 拼接算子的 Tiling 实现与 aclnnCat 调用指南CANN ops math 算子深度解析ConcatDV2 多 Tensor 拼接算子的 Tiling 实现与 aclnnCat 调用指南 ConcatDV2算子库人工智能CANNRightShift 算子深度解析CANN ops-math 按位右移实现与 aclnn 两段式调用指南RightShift 算子深度解析CANN ops math 按位右移实现与 aclnn 两段式调用指南 导读 本文以 CANN ops math 仓库中 R算子库人工智能CANN创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/20 19:26:42

为什么 OpenClaw Gateway 一直离线?TaoToken 这样修模型通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/20 19:26:42

5分钟上手ComfyUI:ZHO工作流合集完整指南

5分钟上手ComfyUI:ZHO工作流合集完整指南 【免费下载链接】ComfyUI-Workflows-ZHO 我的 ComfyUI 工作流合集 | My ComfyUI workflows collection 项目地址: https://gitcode.com/GitHub_Trending/co/ComfyUI-Workflows-ZHO ComfyUI-Workflows-ZHO 是一位创作…

2026/9/20 19:21:42

Build Tools for Visual Studio 2022:下载安装、静默部署与排障指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/20 21:16:50

Pandoc 3.6.4实战:Markdown与Word/PDF高效转换指南

简介:Pandoc 是广为使用的开源文档转换利器,支持 Markdown、HTML、LaTeX、Word DOCX、EPUB 等数十种标记格式之间的相互转换,在写作、出版、学术排版与技术文档维护中非常实用,尤其适合需要批量处理文档格式的开发者、技术写作者和…

2026/9/20 21:16:50

Sails 应用内省指南:深入解析 `sails.getActions()` 方法

Sails 应用内省指南:深入解析 sails.getActions() 方法 【免费下载链接】sails Realtime MVC Framework for Node.js 项目地址: https://gitcode.com/gh_mirrors/sa/sails 导读 sails.getActions() 是 Sails(Realtime MVC Framework for Node.js…

2026/9/20 21:16:50

ZooKeeper客户端编程实战:从数据模型到分布式锁的避坑指南

分布式系统里,协调这件事听起来很虚,但落到代码上往往就是几个具体问题:多个进程怎么选出一个主节点、配置改了怎么让所有机器同时生效、某个节点挂了怎么让其他人立刻知道。ZooKeeper 就是为解决这类问题而生的。它对外暴露的接口非常朴素—…

2026/9/20 21:11:49

miniblink49 网页打印与 PDF 导出实战:从参数配置到故障排查

miniblink49 网页打印与 PDF 导出实战:从参数配置到故障排查 【免费下载链接】miniblink49 a lighter, faster browser kernel of blink to integrate HTML UI in your app. 一个小巧、轻量的浏览器内核,用来取代wke和libcef 项目地址: https://gitcod…

2026/9/20 0:04:49

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/20 0:04:49

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/20 0:04:49

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/20 0:04:49

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/20 4:54:47

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/20 5:01:23

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/20 5:09:33

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码