CANN ops-math 数学算子 IsNan 详解:源码实现、图模式调用与工程验证

发布时间:2026/9/20 23:50:49
CANN ops-math 数学算子 IsNan 详解:源码实现、图模式调用与工程验证 算子库人工智能CANN【免费下载链接】ops-math本项目是CANN提供的数学类基础计算算子库实现网络在NPU上加速计算。项目地址https://gitcode.com/cann/ops-math点击查看免费下载导读IsNan 是 CANN ops-math 数学算子库math/ 目录中一个典型的逐元素elementwise判断算子用于检测张量中哪些元素是 NaNNot a Number。本文以 math/is_nan/README.md 为骨架结合该算子完整的 op_def、tiling、kernel 实现 与 测试用例 源码系统讲解 IsNan 的功能语义、参数约束、产品支持范围、图模式构图调用方式以及底层 AIV 核上的 DAG 实现原理帮助读者在 NPU 上正确使用并深入理解这一算子。功能说明IsNan 算子的功能是判断输入张量中哪些元素是 NaN输出与输入形状相同的 BOOL 张量元素为true表示对应输入位置是 NaN。计算公式如下$$ out_i(input_i ! input_i) $$该公式利用了 IEEE 754 浮点标准中 NaN 不等于任何值包括自身 的特性是判断 NaN 的标准手法。官方 README 给出两组示例若x[9, 6, 3]计算结果为[False, False, False]三个元素均为正常数值。若x[[-3.14, inf], [2.7183, nan]]计算结果为[[False, False], [False, True]]inf不是 NaN因此对应位置为False只有nan所在位置为True。从算子原型 is_nan_proto.h 的注释可以看到该算子与 TensorFlow 的IsNan算子兼容Compatible with tensorflow IsNan operator输入支持 1D ~ 8D 张量。对于正常数值包括正负无穷返回False这是 NaN 判断与无穷判断的关键区别。产品支持情况README 明确给出了 IsNan 算子的软硬件支持矩阵产品是否支持Ascend 950PR/Ascend 950DT√Atlas A3 训练系列产品/Atlas A3 推理系列产品√Atlas A2 训练系列产品/Atlas A2 推理系列产品√Atlas 200I/500 A2 推理产品×Atlas 推理系列产品×Atlas 训练系列产品×与支持矩阵相对应is_nan_def.cpp 中通过this-AICore().AddConfig(ascend950, aicoreConfig)和this-AICore().AddConfig(ascend350, aicoreConfig)注册了两个 AICore 平台配置op_host/config/ 目录下也分别提供了ascend950/含 is_nan_binary.json 与is_nan_simplified_key.ini和ascend350/含 is_nan_binary.json的平台专属配置。由此可见当前仓库中的 IsNan 算子实现面向 950/350即 A2/A3 系列架构使用前应先确认目标设备落在支持矩阵内。参数说明IsNan 算子只有 1 个输入和 1 个输出均为必选REQUIRED参数参数名输入/输出/属性描述数据类型数据格式x输入公式中的输入 input_iFLOAT、FLOAT16、BFLOAT16NDy输出公式中的输出 out_iBOOLND补充说明依据源码输入x支持 3 种浮点类型FLOATFP32、FLOAT16FP16、BFLOAT16BF16数据格式限定为ND这与 is_nan_def.cpp 中Input(x).DataType({ge::DT_BF16, ge::DT_FLOAT16, ge::DT_FLOAT}).Format({ge::FORMAT_ND, ...})的注册一致。注意不接收整数、双精度等其它类型若传入不支持的数据类型tiling 阶段会直接报错返回GRAPH_FAILED见下文约束小节。输出y的数据类型固定为BOOL。即便图模式下未显式指定输出类型is_nan_graph_infer.cpp 中的InferDataType4SingleOutBool也会在推理阶段将输出数据类型强制置为DT_BOOL。输出形状与输入形状完全一致。由 is_nan_infershape.cpp 中的InferShape4IsNan实现*out_shape *in_shape;。约束说明README 中标注 IsNan 算子的约束为「无」。但从源码层面看存在如下由实现施加的隐含约束使用时应予以注意数据类型约束输入必须是FLOAT16/BFLOAT16/FLOAT之一。在 tiling 阶段is_nan_tiling_arch35.cpp 的CalcInputDtype()会对输入类型做校验非上述类型时记录OP_LOGE_FOR_INVALID_DTYPE错误并返回GRAPH_FAILED。形状一致性约束tiling 的CheckShape()会校验输入x与输出y的存储形状完全一致inputXShape ! outputYShape时报错这也与 infershape 阶段输出形状等于输入形状的规则互为印证。输出类型约束CalcOutputDtype()要求输出必须是BOOL否则同样报错返回。设备约束仅支持支持矩阵中列出的产品例如 Atlas 200I/500 A2 推理产品等不在支持列表内。调用说明图模式调用算子 IR 构图README 给出的官方调用方式是图模式调用即通过算子 IR 构建计算图后在 GEGraph Engine会话中运行。核心代码是 test_geir_is_nan.cpp使用 is_nan_proto.h 中REG_OP(IsNan)注册的算子原型构图。整个调用流程分为四步初始化 GE通过ge::GEInitialize(global_options)初始化图引擎其中ge.exec.deviceId指定设备号示例为0ge.graphRunMode设为1图模式运行。构建计算图创建Graph对象在CreateOppInGraph()中通过auto isnan op::IsNan(isnan)创建 IsNan 算子节点用ADD_INPUT宏创建Data占位节点并生成全 2.0 的 FP32 输入数据形状{4, 4}用ADD_OUTPUT宏声明DT_BOOL、形状同为{4, 4}的输出最后graph.SetInputs(inputs).SetOutputs(outputs)绑定图输入输出。会话运行创建ge::Sessionsession-AddGraph(graph_id, graph)添加计算图session-RunGraph(graph_id, input, output)执行。运行结束后将输入/输出张量分别落盘为tc_ge_irrun_test_0008_npu_input_0.bin与tc_ge_irrun_test_0008_npu_output_0.bin并逐元素打印输出结果。资源回收调用ge::GEFinalize()结束会话。构图的关键代码片段如下auto isnan op::IsNan(isnan); std::vectorint64_t xShape {4, 4}; // 输入 xFP32形状 {4,4} ADD_INPUT(1, x, inDtype, xShape); // 输出 yBOOL形状与输入一致 ADD_OUTPUT(1, y, DT_BOOL, xShape); outputs.push_back(isnan);其中宏ADD_INPUT内部调用isnan.set_input_x(placeholder)、ADD_OUTPUT调用isnan.update_output_desc_y(...)与算子原型 is_nan_proto.h 中定义的INPUT(x, ...)/OUTPUT(y, ...)一一对应。其它调用方式从仓库结构看IsNan 与 ops-math 中其它算子一样最终由 GE 统一调度执行。图模式之外用户也可参照 examples/ 目录下的 add_example 等示例通过框架层如 op_api 模式间接触发该算子执行具体以 examples/README.md 的构建运行说明为准。源码级实现原理算子定义op_defis_nan_def.cpp 通过OP_ADD(IsNan)完成算子注册关键配置项如下OpAICoreConfig aicoreConfig; aicoreConfig.DynamicCompileStaticFlag(true) // 动态编译静态化 .DynamicFormatFlag(false) // 不支持动态格式 .DynamicRankSupportFlag(true) // 支持动态 rank .DynamicShapeSupportFlag(true) // 支持动态 shape .NeedCheckSupportFlag(false) .PrecisionReduceFlag(true) .ExtendCfgInfo(opFile.value, is_nan_apt); // 指定 kernel 文件 this-AICore().AddConfig(ascend950, aicoreConfig); this-AICore().AddConfig(ascend350, aicoreConfig);其中ExtendCfgInfo(opFile.value, is_nan_apt)将算子的 kernel 实现指向 is_nan_apt.cppDynamicShapeSupportFlag(true)表明算子支持动态 shape这也是 is_nan_binary.json 中 shape 字段使用-2动态 shape 标记的原因——三份 binary 配置分别对应bfloat16、float16、float32三种输入类型输出均为bool、格式均为ND。形状与数据类型推导is_nan_infershape.cppInferShape4IsNan直接将输入形状拷贝给输出*out_shape *in_shape保证逐元素一一对应。is_nan_graph_infer.cppInferDataType4SingleOutBool把输出数据类型固定为DT_BOOL。Tiling 与 Kernel 实现IsNan 的 tiling 逻辑位于 is_nan_tiling_arch35.cpp整体流程为读取平台信息GetCoreNumAiv()、GetCoreMemSize(UB)校验核数与 UB 内存有效CalcInputDtype()/CalcOutputDtype()/CheckShape()完成类型与形状校验按输入类型选择 tiling keyFP16 →101UL、BF16 →102UL、FP32 →103UL调用elewiseBaseTiling.DoTilingIsNanOp::IsNanDAGT::OpDag()生成基础切分baseTilingSetTilingData()写入 workspace为 0即不需要额外 workspace并设置SetBlockDim。Kernel 端 is_nan_apt.cpp 声明为KERNEL_TASK_TYPE_DEFAULT(KERNEL_TYPE_AIV_ONLY)即仅在 AIVAI Vector核上执行运行时通过TILING_KEY_IS(101UL/102UL/103UL)将不同输入类型分发到对应的ElementwiseSch0UL, IsNanOp::IsNanDAGhalf/bfloat16_t/float::OpDag复用通用的 elementwise 调度框架atvoss/elewise/elewise_sch.h。真正的计算 DAG 定义在 is_nan_dag.h 中其核心思路是把 判断 NaN 拆解为比较 选择两步// 输入拷贝 using OpCopyIn BindVec::CopyInU, Placeholder::In0U; // 比较x ! xCMP_MODE 2NaN 自比较为真 using CompareMask BindVec::Compareuint8_t, U, CMP_MODE, OpCopyIn, OpCopyIn; // 选择为真时输出 1为假时输出 0 using SelectRes BindVec::Selectuint8_t, uint8_t, SELECT_MODE, CompareMask, DataZero, ConstOne; // 输出拷贝 using OpCopyOut BindVec::CopyOutuint8_t, Placeholder::Out0uint8_t, SelectRes;CompareMask对同一个输入执行两次拷贝后做CMP_MODE2不等于比较得到掩码——只有 NaN 元素x ! x为真SelectRes根据掩码在常量1与0之间选择产出true/false掩码MemOptCfgMemLevel::LEVEL_2将中间数据优化到 L2 级内存ElemsOpCopyOut声明 DAG 的输出节点最终组成DAGSchOutputs, void, MemCfg交由调度器执行。测试与验证仓库为 IsNan 提供了三层测试验证单测UTtest_is_nan_infershape.cpp验证 infershape 阶段输出形状与输入一致test_is_nan_tiling_arch35.cpp验证 arch35 平台的 tiling 逻辑tiling key、blockDim、workspace 等。系统测试STttk_kernel_is_nan_st.csv 定义了在 arch35 上执行的 kernel 级 ST 用例矩阵。Golden 数据golden.py 提供参考实现用于生成与 NPU 输出对拍的期望结果。开发者在修改或移植该算子后可按 scripts/build_ut.sh 与 cmake/ut.cmake 描述的 UT 框架运行上述单测并用 ST 用例回归验证 950/350 平台行为。小结IsNan 是 ops-math 中一个结构清晰、可直接作为 elementwise 算子范式的样例功能语义单一x ! x即 NaN输入输出形状一致、类型固定FP16/BF16/FP32 → BOOL通过 op_def 注册、infershape 推导、arch35 tiling 切分与 AIV 核上「比较 选择」DAG 完成计算并配有完整的 UT/ST/golden 验证链路。对于需要在 NPU 上进行 NaN 检测或数值健康性检查如梯度、loss 监控的场景可以直接在支持矩阵内的设备上按本文介绍的方式构图调用。赞分享算子库人工智能CANN【免费下载链接】ops-math本项目是CANN提供的数学类基础计算算子库实现网络在NPU上加速计算。项目地址https://gitcode.com/cann/ops-math点击查看免费下载相关推荐CANN ops-math 算子详解Expint 指数积分算子原理、实现与图模式调用实践CANN ops math 算子详解Expint 指数积分算子原理、实现与图模式调用实践 导读 Expint 是 CANN ops math 数学算子库中用于算子库人工智能CANNCANN ops-math AxpyV2 算子全面解析功能、参数、源码实现与图模式调用实战CANN ops math AxpyV2 算子全面解析功能、参数、源码实现与图模式调用实战 AxpyV2 是 CANN ops math 算子库中实现标量乘算子库人工智能CANNCANN ops-math ClipByValue 算子深度解析功能、参数、GE IR 图模式调用与源码实现CANN ops math ClipByValue 算子深度解析功能、参数、GE IR 图模式调用与源码实现 ClipByValue裁剪取值是 CANN算子库人工智能CANN创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考