已关闭
[Bug-Report|缺陷反馈]: ops-nn 30 个算子 GE IR 原型头缺少 OPS_PROTO_DEF 隔离宏 #5170
TangPC创建于  13 天前关闭于  13 天前
TangPC
TangPC成员
13 天前 创建

Describe the current behavior / 问题描述

ops-nn 仓中 30 个算子的 GE IR 原型头 <算子>/op_graph/*_proto.h,其 REG_OP 外层缺少 OPS_PROTO_DEF_<OPTYPE> 条件编译隔离宏。

这些原型会被 scripts/util/merge_proto.py 合并成 ops_proto_nn.h/.cppcmake/gen_ops_info.cmakemerge_graph_headers),再由 cmake/symbol.cmakegen_opgraph_symbol 编成内置 op_proto 库并安装到 ${OPP_PREFIX}/built-in/op_graph/inc。当同名算子在 canndev 侧的遗留原型头(nn_norm_ops.hreduce_ops.hnn_batch_norm_ops.hops_proto_legacy.h 等)也有 REG_OP 注册时,两份定义进入同一编译单元即构成重复定义。

本仓已有 activation/relu6_doptim/sgdnorm/in_training_reduce_v2vfusion/normalize_bbox 等算子按此范式加了隔离宏,发布包 opp/built-in/op_graph/inc 中也已有 967 个同类隔离宏,但下列 30 个算子的原型头遗漏了该保护:

ApplyAdagrad、BatchNormExt2、BN3DTrainingUpdate、BNInfer、BNTrainingUpdateV2、BNTrainingUpdateV3、ChamferDistance、ClippedSwiglu、CosineEmbeddingLoss、DeepNorm、DeepNormGrad、DynamicQuantUpdateScatter、DynamicQuantUpdateScatterV2、GemmaRmsNorm、GroupNormSiluQuant、HardSigmoid、HardSwishGradV2、INInferV2、InplaceApplyRMSProp、InplaceSub、InstanceNormGrad、INTrainingUpdateGrad、L2NormalizeGrad、MultiAddRmsNormDynamicQuant、MultilabelMarginLoss、NonZeroWithValue、PoissonNllLoss、Relu6Grad、SoftmaxFocalLoss、SoftmaxFocalLossGrad

另有 5 个原型头(deep_normdeep_norm_gradgemma_rms_normmulti_add_rms_norm_dynamic_quantdynamic_quant_update_scatter_v2)文件末尾缺换行,pre-commitend-of-file-fixer 钩子只扫改动文件,一旦改动这些文件即会被门禁拦截。

Environment / 环境信息

本问题属于头文件与构建期问题,与运行硬件型号无关,在任意昇腾产品形态下构建均可复现。

  • 仓库/分支:cann/ops-nn master(复现基线 commit e7257e707
  • CANN 版本:9.2.0
  • 构建工具:CMake + Python3,scripts/util/merge_proto.py
  • 校验工具:clang-format 18.1.8、pre-commit(仓内 .pre-commit-config.yaml
  • OS/架构:Linux x86_64

Steps to reproduce the issue / 重现步骤

以 DeepNorm 为例:

git clone https://gitcode.com/cann/ops-nn.git && cd ops-nn

# 1) 确认原型头没有隔离宏
grep -c "OPS_PROTO_DEF" norm/deep_norm/op_graph/deep_norm_proto.h
# 输出:0

# 2) 跑合并脚本,观察合并产物
python3 scripts/util/merge_proto.py D norm/deep_norm/op_graph/deep_norm_proto.h \
        --output-file /tmp/merged.h
grep -c "REG_OP("               /tmp/merged.h   # 1,原型已并入
grep -c "#ifndef OPS_PROTO_DEF_" /tmp/merged.h   # 0,无隔离宏

# 3) 对照 canndev 侧同名注册源
grep -n "REG_OP(DeepNorm)" <CANN安装路径>/opp/built-in/op_graph/inc/nn_norm_ops.h

合并产物 ops_proto_nn.hnn_norm_ops.h 同时被包含时,REG_OP(DeepNorm) 展开出的类定义出现两次,构成重复定义。

文件末尾缺换行的复现:

tail -c1 norm/deep_norm/op_graph/deep_norm_proto.h | xxd
# 末字节非 0a,end-of-file-fixer 钩子会改写该文件并使门禁失败

Describe the expected behavior / 预期结果

  1. 每个算子的 op_graph/*_proto.h 中,REG_OP 外层带 #ifndef/#define OPS_PROTO_DEF_<OPTYPE>#endif,且宏名与发布包中同名算子的既有隔离宏逐字节一致。
  2. 隔离宏能被 merge_proto.py 正确带入合并产物(该正则要求 guard 与 REG_OP 严格相邻,位置写偏宏会被丢弃)。
  3. 原型头满足仓内 .pre-commit-config.yaml 的全部钩子。

merge_proto.py 合并产物对比(以 deep_norm_proto.h 为例):

master 合并产物: REG_OP=1  隔离宏=0     ← 原型进去了,但没有隔离保护
修复后合并产物: REG_OP=1  隔离宏=1     ← 隔离宏正确带出

修复后全量校验:

ops-nn: 改动文件=30  合并产物隔离宏=30/30  宏名与发布包不一致项=0
        跨文件重名宏=0  每文件 OPS_PROTO_DEF 宏数=1(无嵌套/重复保护)
        clang-format(整文件)=30/30 通过   OAT 许可头=30/30 合规
        trailing-whitespace / end-of-file-fixer / check-merge-conflict /
        detect-private-key / check-added-large-files 全部通过

Special notes for this issue/备注

  • 仅补条件编译指令与文件末尾换行,不改动任何 IR 的输入/输出/属性/dtype 定义,无功能与支持面变化。
  • 未改动 common/inc/op_graph/op_nn_proto_extend.hmerge_proto.py 会按算子名把聚合头中与各算子原型头重复的条目去重,改它不会进入合并产物。
  • 核对时发现,上述算子中有一部分在发布包的遗留原型头里同名 REG_OP 也没有隔离宏。彻底闭环还需遗留侧同步补同名宏(发布包中已有 967 个算子是成对做的)。该部分不在本 Issue 的修改范围内,供后续跟踪。

关联 PR:https://gitcode.com/cann/ops-nn/pull/9218

likedislike
TangPCTangPC成员
13 天前 添加了label:bug-report
CANN-robotCANN-robot成员
13 天前 关闭了 issue
CANN-robotCANN-robot成员
13 天前 添加了label:resolved