Closed
[Bug-Report|缺陷反馈]: IndexByTensor融合pass三参Replace强引用致低版本undefined symbol,Index算子编译期InferShape失败 #6168
xuejinghuiAdd on  Sep 23Closed at  Sep 23
xuejinghuiCollaborators
Sep 23 Create

[Bug-Report|缺陷反馈]: IndexByTensor融合pass三参Replace强引用致低版本undefined symbol,Index算子编译期InferShape失败

Describe the current behavior / 问题描述 (Mandatory / 必填)

ops-nn 仓 index/index 算子相关代码存在两个缺陷:

缺陷1:IndexByTensorStaticFusionPass 跨版本符号强引用

index/index/op_graph/fusion_pass/indexbytensor_static_fusion_pass.cpp 中通过编译期宏选择 SubgraphRewriter::Replace 的重载版本:

#if GE_COMPILER_VERSION_NUM >= 90200000
    if (SubgraphRewriter::Replace(*boundary, *replacement, passContext) != SUCCESS) {
#else
    if (SubgraphRewriter::Replace(*boundary, *replacement) != SUCCESS) {
#endif

三参重载 ge::fusion::SubgraphRewriter::Replace(const SubgraphBoundary&, const Graph&, CustomPassContext&) 是 GE 9.1+ 才引入的符号。当用 9.2 头文件编译出 libopgraph_nn.so、放到 9.0.0 运行时环境加载时,该符号为强引用未定义符号,导致 so 加载失败:

undefined symbol: _ZN2ge6fusion16SubgraphRewriter7ReplaceERKNS0_16SubgraphBoundaryERKNS_5GraphERNS_17CustomPassContextE

即"编译期头文件版本"与"运行时库版本"不一致时产物不可用,编译期宏无法解决该跨版本场景。

缺陷2:Index 算子 InferShape 编译期被 nullptr 校验卡住

index/index/op_host/index_infershape.cpp 的 InferShape4Index 中:

const int64_t* indexed_sizes = sizes_tensor->GetData<int64_t>();
OP_CHECK_NULL_WITH_CONTEXT(context, indexed_sizes);   // 编译期必失败

Index 算子 InferShape 必须读取 indexed_sizes 的值才能推导输出 shape,且该输入已声明 ValueDepend(OPTIONAL)、已注册 InputsDataDependency({IDX_SIZES})。但 InferShape 在编译期和执行期都会执行,编译期 const 数据未就绪时 GetData 必然为 nullptr,被 OP_CHECK_NULL 校验住导致 InferShape 返回 FAILED,进而使融合 pass 替换失败、整图编译失败。

另外,当 indexed_sizes 全 0(无任何索引维)时,indicesShapeList 为空,原代码 broadShapeList[0] 存在空 vector 越界访问的 UB 风险。

Environment Information / 环境信息 (Mandatory / 必填)

  • 硬件:与芯片型号无关(host 侧图编译问题,x86_64/aarch64 均存在)
  • CANN 版本:编译环境 CANN 9.2.0,运行时环境 CANN 9.0.0(缺陷1的触发组合);缺陷2任意版本可复现
  • OS:Linux

Steps to reproduce the issue / 重现步骤 (Mandatory / 必填)

缺陷1:

  1. source CANN 9.2.0 环境,编译 ops-nn opgraph:bash build.sh --opgraph -j16
  2. 对产物 build/opp/built-in/op_proto/libopgraph_nn.so,用 9.0.0 的运行时库做符号解析检查:
LD_LIBRARY_PATH=<cann-9.0.0>/x86_64-linux/lib64 ldd -r libopgraph_nn.so
  1. 观察到 SubgraphRewriter::Replace 三参符号 undefined。9.0.0 的 libge_compiler.so 中该符号不存在(nm -D 仅有两个两参重载),9.1/9.2/9.3 的库中存在。

缺陷2:

编译期对 Index 算子执行 InferShape,indexed_sizes 输入无 const 数据(GetData<int64_t>() == nullptr),InferShape 返回 GRAPH_FAILED;在 IndexByTensorStaticFusionPass 中表现为 GeUtils::InferShape 替换子图失败 → Replacement 返回 nullptr → pass 失败 → 整图编译失败。

Describe the expected behavior / 预期结果 (Mandatory / 必填)

  1. libopgraph_nn.so 在任意"编译头文件版本 × 运行时库版本"组合下均能正常加载,无 undefined symbol;运行库支持三参 Replace 时走三参,不支持时自动回退到各版本都有的两参版本。
  2. Index 算子编译期 InferShape 在 indexed_sizes 数据未就绪时不应失败,应输出 unknown rank 并返回成功,待执行期数据就绪后由 GE 依据 InputsDataDependency 重新推导真实 shape;mask 全 0 场景不越界、输出与 x 相同。

9.2 头文件编译产物 + 9.0.0 运行时库解析:

$ readelf --dyn-syms -W libopgraph_nn.so | grep SubgraphRewriter7Replace
   27: 0000000000000000  0 NOTYPE  GLOBAL DEFAULT  UND _ZN2ge6fusion16SubgraphRewriter7ReplaceERKNS0_16SubgraphBoundaryERKNS_5GraphERNS_17CustomPassContextE

$ LD_LIBRARY_PATH=<cann-9.0.0>/x86_64-linux/lib64 ldd -r libopgraph_nn.so
undefined symbol: _ZN2ge6fusion16SubgraphRewriter7ReplaceERKNS0_16SubgraphBoundaryERKNS_5GraphERNS_17CustomPassContextE

各版本 libge_compiler.so 符号确认:

9.0.0: 无三参符号(仅2个两参Replace)
9.1.0/9.2.0/9.3.0: 存在 _ZN2ge6fusion16SubgraphRewriter7ReplaceERKNS0_16SubgraphBoundaryERKNS_5GraphERNS_17CustomPassContextE

Special notes for this issue / 备注 (Optional / 选填)

修复方案(已提PR,commit 6cc5d7eb7,分支 index_fusion):

  1. 缺陷1:不删 graph_rewriter.h(两参 Replace 与 SubgraphBoundary 仍依赖它,且同类在同一编译单元无法重定义加 weak 成员),改用 __asm__ label 对三参符号做弱镜像声明 + 调用点 != nullptr 判空回退两参,与 batch_matmul_transpose_fusion_pass.cpp 中 GraphFuseInspectorUtils::ReportFuse 的弱符号思路等价。已实测:9.0 运行时弱符号解析为 NULL 走回退,9.1/9.2/9.3 运行时正确绑定真实现;若未来 GE 变更该符号签名,弱符号静默回退两参,功能良性退化不崩溃。

  2. 缺陷2:编译期 GetData 为 nullptr 时置 unknown rank(-2) 返回成功(参照 repeat_interleave 等 data-dependency 算子的标准写法);同时修复 mask 全 0 时 broadShapeList[0] 空 vector 越界问题。补充 UT 用例 2 个,op_host UT 15/15、op_graph 融合 pass UT 7/7 全部通过。

likedislike
XxuejinghuiCollaborators
Sep 23 Added label: bug-report
xuejinghuiCollaborators
Sep 23 Comments:

/assign

likedislike
CANN-robotCANN-robotCollaborators
Sep 23 Assign xuejinghui as responsible person
XxuejinghuiCollaborators
Sep 23 Change title to "[Bug-Report|缺陷反馈]: IndexByTensor融合pass三参Replace强引用致低版本undefined symbol,Index算子编译期InferShape失败", originally titled "[Bug-Report|缺陷反馈]: 11".
XxuejinghuiCollaborators
Sep 23 Modify description of issue
CANN-robotCANN-robotCollaborators
Sep 23 Close issue
CANN-robotCANN-robotCollaborators
Sep 23 Added label: resolved