Pull Request已成功合入, 合并人@CANN-robot
(感谢 liyuewei 的贡献)变更摘要
本 PR 主要针对 PowScalar 的幂运算性能问题进行优化。核心思路是在 Pow 接口的 float/bfloat16_t 分支中,当指数为 uint32 范围内的整数时,改用基于平方求幂(快速幂)的快速路径(先 Duplicate 结果并循环 Mul),替代原先直接调用通用 Power 的实现;同时在 autofuse/ascendc/api/utils.h 中新增位运算工具函数 IsIntegerWithinUint32Magnitude 用于判断浮点值是否为 uint32 量级内的精确整数,并补充了对应单元测试。
主要改动
- 新增整数判断工具函数:在
autofuse/ascendc/api/utils.h中新增IsIntegerWithinUint32Magnitude,通过解析浮点的指数位与尾数位(kExponentMask/kFractionMask等掩码)判断值是否为 uint32 量级内的整数,并显式排除 NaN、Infinity 及超范围值。 Pow快速路径优化:在autofuse/v35/ascendc/api_regbase/pow.h的Pow函数中,对float/bfloat16_t类型先判断IsIntegerWithinUint32Magnitude(src2),若成立则取指数绝对值并转uint32_t,用平方求幂循环(按位右移 + 条件Mul)计算,否则回退到原Power调用,从而降低标量幂运算开销。- 补充单元测试:在
autofuse/tests/ut/ascendc/api/test_utils.cpp中新增两个测试用例,覆盖零值、正负整数、边界值(如4294967040.0f)以及 NaN、Infinity 等非整数/非法输入场景。


代码审查
审查总结
已逐一审查全部 3 个变更文件:
1. autofuse/ascendc/api/utils.h
新增的 IsIntegerWithinUint32Magnitude 逐位分解逻辑经校验正确(NaN/Inf 拦截、2^32 边界(exponent≥159)、次正规数、(1U << (23-integer_bits)) 移位范围 [1,22] 无未定义行为、≥2^23 直接判整)。本文件无问题。
2. autofuse/tests/ut/ascendc/api/test_utils.cpp
新增用例调用了全仓库均未定义的 IsInteger(diff 实际新增的函数名是 IsIntegerWithinUint32Magnitude)→ 测试目标编译失败,P0。
3. autofuse/v35/ascendc/api_regbase/pow.h
新增的整数指数快速幂分支存在两个独立缺陷:负整数指数计算出 x^|n| 而非 1/x^|n|(is_negative 计算后从未使用,P1);Mul(src1, src1, src1) 原地改写 const 输入张量并多做一次无用平方,破坏只读契约与 dst==src1 原地场景(P2)。此外该高风险路径缺少关键测试(P2)。
发现统计: P0 × 1,P1 × 1,P2 × 2,共 4 项。
整体风险判断: 本次 PR 的优化思路(整数指数走快速幂)本身可行,但当前实现存在构建失败(测试引用未定义符号)与静默数值错误(负指数)两类阻断性问题,且输入张量被原地改写属于行为回归,建议修复后再合入。
| 类型 | 数量 |
|---|---|
| 🔴 阻塞 | 3 |
| 🟡 建议 | 1 |
⛔ 需要修改


Thanks for your pull-request.
The full list of commands accepted by me can be found at here.
You can get sig-info at here.
You can self-configure the PR merge rules for this repository. For more details, please refer to Here.
For more, you also can visit HICANN.
PR Approval Progress
✅ Congratulations! All modules have met the lgtm and approve requirements.
Module Approval Details
| module | lgtm status | approve status |
|---|---|---|
| repo-cann/graph-autofusion | ✅ xchu42, 张德鹏, xuyafei (3/2) | ✅ 张德鹏 (1/1) |
💡 Tip:
- Committer can comment
/approveor/lgtm- Commenting
/approveimplies both code review (lgtm) and intent to merge (approve)
CLA Signature Pass
liyuewei, thanks for your pull request. All authors of the commits have signed the CLA. 👍


🔴 Critical
变更行:test_utils.cpp 新增的 TEST(TestUtilsApi, IsInteger_ShouldCheckExactFloatValue)(50-64 行)与 TEST(TestUtilsApi, IsInteger_ShouldRejectNanAndInfinity)(66-69 行)调用了 IsInteger(...)。
影响/契约:本 diff 只在 autofuse/ascendc/api/utils.h 中新增了 IsIntegerWithinUint32Magnitude(283-316 行);对 autofuse 全目录的检索显示 IsInteger 仅出现在本测试文件中,从未被定义。test_utils.cpp 第 17 行 #include "utils.h" 引入的正是这个 utils.h,其中并不存在 IsInteger。
失败模式:测试编译时报 “IsInteger was not declared in this scope”,UT 目标构建失败(P0 构建/编译错误)。测试的断言语义(0/±2/16777216/±4294967040 为真,0.5/±2.25/±4294967296/NaN/Inf 为假)与 IsIntegerWithinUint32Magnitude 的实现完全吻合,显然是笔误把函数名写错了。
修复:将测试中所有 IsInteger( 调用改为 IsIntegerWithinUint32Magnitude((或在 utils.h 中为 IsInteger 提供别名/包装),保证测试可编译。
建议:将测试中对 IsInteger 的调用统一改为 IsIntegerWithinUint32Magnitude(该函数的语义与测试断言完全一致),或在不改名的情况下于 utils.h 中补充 IsInteger 的定义/别名。


🟠 High Priority
变更行:pow.h 62-73 行新增的整数指数快速幂分支。
影响/契约:第 63 行 const bool is_negative = src2 < 0.0f; 计算了符号,但该变量从未被使用;第 64-73 行直接用 |n|(abs_src2 → src_u32)做平方累乘,循环结果为 x^|n|。
失败模式:当 src2 为负数且幅值在 uint32 范围内(如 -2.0f、-3.0f、-4.0f 等;-1.0f/-0.5f 已被前面的分支拦截)时,IsIntegerWithinUint32Magnitude(-2.0f) 返回 true 进入快速路径,输出 x² 而非数学上正确的 1/x²,与基线 Power(exp2/log2 路径)语义不一致,静默产生错误数值。该问题对 T=float 与 T=bfloat16_t 均存在。
修复:仅对非负整数指数启用快速路径,其余(含所有负指数)回退到 Power<T, false, pow_config>。最小改动:把进入条件改为 IsIntegerWithinUint32Magnitude(src2) && !(src2 < 0.0f),并删除未使用的 is_negative/abs_src2。
建议:快速路径只应处理非负整数指数:将条件改为 if (IsIntegerWithinUint32Magnitude(src2) && !(src2 < 0.0f)),删除 is_negative/abs_src2 两行,直接 uint32_t src_u32 = static_cast<uint32_t>(src2);;负指数统一走 Power 基线路径。
|
73 | + if (IsIntegerWithinUint32Magnitude(src2) && !(src2 < 0.0f)) { |
| 73
| - |
|
74 | + uint32_t src_u32 = static_cast<uint32_t>(src2); |
|
75 | + Duplicate(dst, static_cast<float>(1.0), calCount); |


🟠 High Priority
changed line → affected behavior/contract → failure mode → suggested fix
本 PR 在 autofuse/v35/ascendc/api_regbase/pow.h 的标量指数 Pow 重载中新增了整数指数的快速路径(第 62-73 行)。第 63 行计算了 is_negative = src2 < 0.0f,第 64-65 行取绝对值 abs_src2 并转为 uint32_t src_u32,随后第 67-73 行循环只用 src_u32 做快速幂累乘,is_negative 变量被算出后从未使用,循环结束后直接 return(第 77 行),没有任何求倒数/回退逻辑。
新增的 IsIntegerWithinUint32Magnitude 明确忽略符号位(utils.h 第 299-302 行注释 "Ignore the sign bit"),因此负整数指数(如 -2.0f、-3.0f,对 bfloat16_t 还包括 -1.0f、-0.5f 因第 35/50 行特殊分支仅覆盖 float/half)会命中该快速路径。例如 Pow(dst, src1, -2.0f, ...) 应得 x^(-2)=1/x²,实际得到 x²;-1.0f 的 bfloat16 场景应得 1/x,实际得到 x。
失败模式:任何调用方传入负整数标量指数时,kernel 静默产出错误数值,无任何告警,属本次变更引入的回归(改动前该分支直接走 Power 通用实现,结果正确)。指数为 0.5/-0.5 等非整数不会命中此路径(IsIntegerWithinUint32Magnitude(±0.5) 返回 false),故该错误仅影响负整数指数,触发条件明确。
建议:在进入快速路径前增加非负判断,负指数回退到 Power 通用路径,例如将第 62 行改为 if (src2 >= 0.0f && IsIntegerWithinUint32Magnitude(src2)),并删除未使用的 is_negative/abs_src2 逻辑(或改为循环后对 dst 求倒数)。


🟡 Medium Priority
变更行:pow.h 62-73 行新增的整数指数快速路径(本次 PR 的核心变更)。
影响/契约:本次改动触及 Pow 的核心计算路径——新增按位快速幂分支(改变计算结果来源)、原地改写输入张量 src1、并对负指数引入了语义变更;但同目录的 test_pow.cpp(UT 中唯一调用该 Pow 重载的用例文件)未做任何修改,新增测试只覆盖了 utils.h 的 IsInteger 函数。
失败模式:上述两个真实缺陷(负整数指数输出 x^|n| 而非 1/x^|n|;src1 被原地平方污染、dst==src1 时结果恒为 1.0)没有任何用例覆盖——只要新增一个 Pow(x, -2.0f) 或 Pow 原地调用用例即可暴露,当前改动即便存在这些回归也能通过 UT。这是高风险路径(复杂分支、数值语义、输入张量副作用)缺少关键测试。
修复:在 test_pow.cpp 中为 float/bfloat16 补充快速路径用例,至少覆盖:(1) 正整数指数(如 4、5、大指数)与数学期望/基线 Power 对比;(2) 负整数指数(如 -2、-3)验证 1/x^|n|;(3) 调用后复用 src1 以及 dst==src1 别名场景,防止输入张量被污染。
建议:在 test_pow.cpp 中补充对新增快速路径的用例:正/负整数指数结果验证、调用后 src1 复用与 dst==src1 别名场景,覆盖负数指数与输入污染这两类回归。


compile


流水线任务触发成功
任务链接 [7561884c8e594cb3b92c667a6b11874b][流水线指导]
| 任务名称 | 状态 | 日志 | 下载链接 |
|---|---|---|---|
| UT_Test_Python_superkernel | ✅ SUCCESS | >>>>> | |
| ST_Test_Python_superkernel | ✅ SUCCESS | >>>>> | |
| UT_Test_superkernel | ✅ SUCCESS | >>>>> | |
| UT_Test_autofuse_framework | ✅ SUCCESS | >>>>> | |
| ST_Test_autofuse_framework | ✅ SUCCESS | >>>>> | |
| UT_Test_autofuse_ascendc_api | ✅ SUCCESS | >>>>> | |
| ST_Test_autofuse_ascendc_api | ✅ SUCCESS | >>>>> | |
| ST_Test_autofuse_e2e | ✅ SUCCESS | >>>>> | |
| pre_comment | ✅ SUCCESS | >>>>> | |
| UT_Test_Report | ✅ SUCCESS | >>>>> | |
| ST_Test_Report | ✅ SUCCESS | >>>>> |
[2026-08-24 18:43:44] CI执行结束


流水线任务触发成功
任务链接 [6701b83f438c4fb29a4ee5ba145497c5][流水线指导]
| 任务名称 | 状态 | 日志 | 下载链接 |
|---|---|---|---|
| codecheck | ✅ SUCCESS | >>>>> | |
| SCA | ✅ SUCCESS | >>>>> | |
| antipoison | ✅ SUCCESS | >>>>> | |
| codecheck_checkpr | ✅ SUCCESS | ||
| pre_comment | ✅ SUCCESS | >>>>> | |
| codecheck_codestyle | ⚠️ WARNING | >>>>> | |
| codecheck_precommit | ✅ SUCCESS | >>>>> |
[2026-08-24 19:23:06] CI执行结束


/lgtm


Pull Request
描述
PowScalar性能问题优化。
变更类型
请选择本次引入的变更类型:
关联的Issue
如何测试
描述测试此变更的步骤和前提条件:
NA
核对清单
其他信息
在此添加任何其他关于本次 PR 的说明。