
人工智能算子库深度学习CANNAscend【免费下载链接】ops-nn本项目是CANN提供的神经网络类计算算子库实现网络在NPU上加速计算。项目地址https://gitcode.com/cann/ops-nn点击查看免费下载导读ThresholdV2 是 CANN ops-nn 神经网络算子库中用于元素级阈值过滤的激活类算子对输入张量逐元素判断大于阈值的元素保持原值小于等于阈值的元素替换为指定值。本文以仓库中 ThresholdV2 README 为骨架完整继承其功能公式、参数表、约束与调用说明并深入 op_host、op_kernel 与 aclnn 示例 源码讲解从 aclnn L2/L0 API 到算子注册、shape 推导、tiling 切分直至 AICore 内核Compare Select的完整调用链帮助你掌握在 Ascend 950 系列产品上使用与理解该算子的完整方法。算子功能概述ThresholdV2 是一个典型的逐元素element-wise条件过滤算子语义与 PyTorchtorch.nn.functional.threshold一致输入中大于阈值的元素原样保留不大于阈值的元素统一替换为 value。其核心计算公式为$$ y_i \begin{cases} x_i, x_i \text{threshold} \ \text{value}, x_i \leq \text{threshold} \end{cases} $$其中x为输入张量算子的self输入threshold为判断阈值value为替换值y为输出张量。注意判断条件是严格大于等于阈值时元素同样会被替换。README 给出的计算示例为设 $\text{Input} [1.0, 2.0, 0.5, 3.0, -1.0, 4.0]$取 $\text{threshold}1.5$、$\text{value}0.0$则输出为$$ \text{Output} [0.0, 2.0, 0.0, 3.0, 0.0, 4.0] $$即只有2.0、3.0、4.0三个大于 1.5 的元素被保留其余三个元素含等于条件的边界情形均被替换为0.0。产品支持情况与平台约束根据 README 的“产品支持情况”与“约束说明”该算子当前支持的产品与硬性约束如下产品是否支持Ascend 950PR / Ascend 950DT√相关约束包括输入张量self与输出张量out的 shape 必须一致。threshold和value为编译期/运行期常量通过算子属性Attr传入而非张量输入。仅支持 Ascend 950 系列芯片。这一平台约束在源码中有明确佐证L0 层入口 threshold_v2.cpp 中的IsAiCoreSupport检查了当前 NPU 架构必须为NpuArch::DAV_3510即 Ascend 950否则直接返回ACLNN_ERR_PARAM_INVALID并打印 “Only DAV_3510 (Ascend950) is supported.” 的日志算子定义 threshold_v2_def.cpp 中也只注册了ascend950一个 AICore 配置。因此该算子在其他平台上调用会直接失败这是阅读代码或移植到其他产品前必须注意的前提。参数说明README 中给出了完整的参数定义整理如下参数名输入/输出/属性描述数据类型数据格式self输入输入张量公式中的 x。FLOAT、FLOAT16、BFLOAT16NDthreshold属性阈值用于判断条件 x threshold。FLOAT-value属性替换值当 x threshold 时输出为 value。FLOAT-out输出输出张量公式中的 y与 self 的 shape 和数据类型一致。FLOAT、FLOAT16、BFLOAT16ND从源码可进一步确认这些参数的具体形态输入/输出 dtype 与格式算子定义 threshold_v2_def.cpp 为self与out均声明了{ge::DT_FLOAT, ge::DT_FLOAT16, ge::DT_BF16}三种数据类型与FORMAT_ND数据格式三者一一对应且都标记了AutoContiguous()。L2 层的AICORE_DTYPE_SUPPORT_LIST见 aclnn_threshold_v2.cpp同样限定为 DT_FLOAT / DT_FLOAT16 / DT_BF16。属性类型threshold与value均为AttrType(REQUIRED).Float()的必选浮点属性见 threshold_v2_def.cpp以 FLOAT单精度 float保存与 README 参数表一致。shape 关系shape 推导函数 threshold_v2_infershape.cpp 将输出 shape 直接赋值为输入 shape*out_shape *self_shape并且 L2 参数校验要求二者 shape 完全相同见 aclnn_threshold_v2.cpp同时限定最大 rank 为 8ACLNN_MAX_SHAPE_RANK。调用说明aclnn 方式README 的“调用说明”指出该算子通过 aclnn 方式调用即使用aclnnThresholdV2GetWorkspaceSize与aclnnThresholdV2两个接口参考样例为 test_aclnn_threshold_v2.cpp。接口原型两个核心接口的声明位于 aclnn_threshold_v2.hACLNN_API aclnnStatus aclnnThresholdV2GetWorkspaceSize( const aclTensor* self, const aclScalar* threshold, const aclScalar* value, aclTensor* out, uint64_t* workspaceSize, aclOpExecutor** executor); ACLNN_API aclnnStatus aclnnThresholdV2( void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, aclrtStream stream);调用模式遵循 aclnn 系列算子的标准“两步式”流程准备工作空间调用aclnnThresholdV2GetWorkspaceSize传入输入张量、两个标量属性、输出张量返回所需的 workspace 大小与aclnnOpExecutor执行器对象。若 workspaceSize 为 0 则无需申请空间。执行算子在指定aclrtStream流上调用aclnnThresholdV2(workspace, workspaceSize, executor, stream)真正下发执行。值得注意的是属性threshold与value在 aclnn 接口层以aclScalar形式传入。示例代码中使用aclCreateScalar(threshold, ACL_FLOAT)创建浮点标量见 test_aclnn_threshold_v2.cppL2 实现中再通过threshold-ToFloat()转成 float 并塞入算子属性见 aclnn_threshold_v2.cpp。完整可运行的调用示例仓库 examples/arch35/test_aclnn_threshold_v2.cpp 提供了一个端到端可编译运行的样例其核心流程可概括为以下步骤完整代码请直接查看该文件#include acl/acl.h #include aclnnop/aclnn_ops_nn_custom.h // 1. 初始化 ACL 运行时并设置设备 aclInit(nullptr); aclrtSetDevice(0); // 2. 准备输入数据shape{6}与 README 计算示例一致 std::vectorint64_t shape {6}; std::vectorfloat selfData {1.0f, 2.0f, 0.5f, 3.0f, -1.0f, 4.0f}; float threshold 1.5f; float value 0.0f; // 3. 申请设备内存并创建 aclTensor / aclScalar // selfDeviceAddr / outDeviceAddr 通过 aclrtMalloc 申请 // aclCreateTensor(shape, rank, ACL_FLOAT, strides, 0, ACL_FORMAT_ND, ...) // aclCreateScalar(threshold, ACL_FLOAT); aclCreateScalar(value, ACL_FLOAT); // 4. 查询 workspace 并执行 uint64_t workspaceSize 0; aclOpExecutor* executor nullptr; aclnnThresholdV2GetWorkspaceSize(self, thresholdScalar, valueScalar, out, workspaceSize, executor); if (workspaceSize 0) { aclrtMalloc(workspace, workspaceSize, ACL_MEM_MALLOC_NORMAL_ONLY); } aclrtCreateStream(stream); aclnnThresholdV2(workspace, workspaceSize, executor, stream); aclrtSynchronizeStream(stream); // 5. 将结果拷回 host 并打印 // aclrtMemcpy(outData.data(), ..., outDeviceAddr, ..., ACL_MEMCPY_DEVICE_TO_HOST); // Expected: (x 1.5) ? x : 0.0 0.0 2.0 0.0 3.0 0.0 4.0 // 6. 释放资源workspace / 设备内存 / tensor / scalar / stream并 aclrtResetDevice(0); aclFinalize();示例中还包含了aclInit/aclrtSetDevice初始化、aclrtMemcpy的 H2D/D2H 拷贝、aclrtSynchronizeStream同步以及完整的内存释放与aclFinalize收尾可直接作为基于 aclnn 编写 NPU 算子单测的模板。程序运行成功后会在终端打印run test_aclnn_threshold_v2, execute samples success。源码级实现剖析从 aclnn 到 AICore 内核ThresholdV2 的完整调用链跨越了 CANN 算子开发的多个层级从源码结构可以梳理出如下链路aclnn L2 API (aclnn_threshold_v2.cpp) → l0op::ThresholdV2 (threshold_v2.cpp, op_api) → 算子定义/注册 (threshold_v2_def.cpp) → InferShape (threshold_v2_infershape.cpp) → Host Tiling (threshold_v2_tiling.cpp) → AICore Kernel (threshold_v2.h / threshold_v2.cpp)L2 层参数校验与自动 contiguousaclnn_threshold_v2.cpp 中的aclnnThresholdV2GetWorkspaceSize依次完成空指针校验CheckNotNull对self、threshold、value、out四个参数做非空检查失败返回ACLNN_ERR_PARAM_NULLPTR。dtype 校验CheckDtypeValid检查self必须是 FLOAT/FLOAT16/BFLOAT16且out与self的 dtype 必须一致OP_CHECK_DTYPE_NOT_MATCH。shape 校验CheckShape限制最大 rank 为 8并要求self与out的 view shape 完全相等与 README 约束对应。空张量短路self-IsEmpty()时直接返回 workspaceSize0无需下发计算。构图将self经过l0op::Contiguous转成连续内存布局再调用l0op::ThresholdV2构建计算图最后ViewCopy写回out。l0op::Contiguous的存在保证了即使输入是切片视图等非连续张量也能正确参与计算。L0 层与算子定义l0op::ThresholdV2 首先通过IsAiCoreSupport校验平台架构必须为 Ascend 950 的DAV_3510与 dtype然后按输入 view shape 分配输出张量再通过ADD_TO_LAUNCHER_LIST_AICORE携带OP_ATTR(thresholdF, valueF)下发 AICore 启动器。算子定义 threshold_v2_def.cpp 中的OpAICoreConfig明确声明了该算子的运行特性支持动态编译DynamicCompileStaticFlag(true)、动态 rankDynamicRankSupportFlag(true)、动态 shapeDynamicShapeSupportFlag(true)关闭动态格式DynamicFormatFlag(false)开启精度压缩PrecisionReduceFlag(true)并指定内核文件为threshold_v2。这些标志决定了算子在昇腾图引擎中的调度与编译行为。Host Tiling多核切分与双缓冲决策threshold_v2_tiling.cpp 在 Host 侧完成数据切分策略是理解算子性能的关键获取平台信息通过GetPlatformInfo读取可用 AIV 核数coreNum与 UBUnified Buffer容量ubSize。核间切分按总元素数totalIdx与核数计算blockFactor CeilAlign(CeilDiv(totalIdx, coreNum), ubBlockSize)即每个核处理的数据块大小按 UB block size 对齐实际使用核数为CeilDiv(totalIdx, blockFactor)。UB 内切分ubFactor为单次搬运进 UB 处理的元素数由可用 UB 容量除以缓冲份数得到并按 256 字节向量对齐vectorAlign 256 / typeSize。UB 容量预留了 4096 字节的 mask 保留区。双缓冲决策当总元素数超过MIN_SPLIT_THRESHOLD 1024时启用双缓冲useDoubleBuffer1缓冲份数从 2 份提升到 4 份否则使用单缓冲模式。该开关通过ASCENDC_TPL_SEL_PARAM(context, useDoubleBuffer, dtypeSelf)作为模板参数传给内核。属性透传从context-GetAttrs()中读取threshold、value两个 float 属性写入 ThresholdV2TilingData 结构体totalNum/blockFactor/ubFactor/thresholdVal/valueVal供内核侧使用。workspaceGetWorkspaceSize将 workspace 大小置为 0WS_SYS_SIZE 0即该算子运行不需要额外 workspace与示例中可能打印workspaceSize 0的现象吻合。AICore 内核Compare Select 两指令完成计算内核入口 threshold_v2.cpp 按模板参数DTYPE_SELF, BUFFER_MODE实例化 NsThresholdV2::ThresholdV2模板参数由 threshold_v2_tiling_key.h 声明BUFFER_MODE取值 0/1单/双缓冲DTYPE_SELF取值 DT_FLOAT/DT_FLOAT16/DT_BF16。内核主体采用经典的Vector 流水线三段式CopyIn → Compute → CopyOut配合 TPipe 队列CopyInDataCopyPad按ubFactor分块将 Global Memory 数据搬运进 VECIN 队列的 LocalTensorblockLen currentNum * sizeof(T)精确控制尾块长度。Computethreshold_v2.h仅用两条向量指令完成全部计算逻辑AscendC::Compares(maskLocal, inputLocal, thresholdT_, CMPMODE::GT, alignNum)逐元素比较x threshold生成掩码比较指令输出按 256 字节对齐的重复次数alignNumAscendC::Select(outputLocal, maskLocal, inputLocal, valueT_, SELMODE::VSEL_TENSOR_SCALAR_MODE, alignNum)依据掩码从输入张量与标量value中选择即x threshold ? x : value这正是公式的指令级实现。CopyOutDataCopyPad将结果从 VECOUT 队列写回 Global Memory。其中模板属性threshold、value通过FloatToTT从 float 转换到目标类型FLOAT16/BFLOAT16 有专门的位截断实现见 threshold_v2.h 中 bfloat16 特化版本取 float 的高 16 位。ELEMS_PER_REPEAT 256 / sizeof(T)体现了向量指令按 256 字节处理的硬件特性。从源码结构看maskBuf按(ubLength_ 255) / 256 * 32字节分配专门用于存放 Compares 产生的掩码中间结果。小结ThresholdV2 是 CANN ops-nn 中实现“阈值过滤”语义的精简元素算子其价值在于接口标准遵循 aclnn 统一的GetWorkspaceSize 执行两步调用范式样例代码可直接复用语义清晰Compares(GT) Select两条向量指令即可完整表达y (x threshold) ? x : value实现直观针对 Ascend 950 优化通过 Host Tiling 实现核间均分、UB 分块、超大数据量自动启用双缓冲内核侧以对齐长度执行向量指令兼顾正确性与性能。如需进一步了解算子注册机制、Tiling 模板参数化或 aclnn 调用规范可继续阅读仓库内的 算子定义、Tiling 实现 与 内核实现 等源码文件。赞分享人工智能算子库深度学习CANNAscend【免费下载链接】ops-nn本项目是CANN提供的神经网络类计算算子库实现网络在NPU上加速计算。项目地址https://gitcode.com/cann/ops-nn点击查看免费下载相关推荐InsGallery与PictureSelector深度整合如何借助开源力量实现产品级媒体选择功能InsGallery与PictureSelector深度整合如何借助开源力量实现产品级媒体选择功能 在移动应用开发中媒体选择功能是用户交互的核心环节之一。I人工智能算子库深度学习CANNAscendCANN ops-math Eltwise 算子深度解析三种逐元素计算模式、Ascend 950 源码实现与 ACLNN 调用实战CANN ops math Eltwise 算子深度解析三种逐元素计算模式、Ascend 950 源码实现与 ACLNN 调用实战 Eltwise 是 CAN算子库人工智能CANNCANN ops-nn 算子深度解析ReluGradV3 多核 ReLU 反向梯度算子实现与 aclnn 调用实战CANN ops nn 算子深度解析ReluGradV3 多核 ReLU 反向梯度算子实现与 aclnn 调用实战 导读 ReluGradV3 是 CANN人工智能算子库深度学习CANNAscend上一篇ELLA扩散模型在广告设计中的应用提升创意效率的新工具下一篇RuoYi-Vue-fast分布式部署方案多服务器集群配置创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考