Pull Request已成功合入, 合并人@CANN-robot
(感谢 xuyiyang 的贡献)变更摘要
此 PR 主要对 impl/simt_api/math_functions_impl.h 中的 expf、logf、sqrtf 和 fdividef 四个数学函数进行改造,通过引入编译宏 __ASC_FTZ__ 和 __ASC_PREC_SQRT__ 控制不同代码分支,以支持 subnormal 浮点数场景以及高精度平方根计算,同时将 fdividef 改为内建 intrinsic 实现。
主要改动
-
expf增加 subnormal 处理分支:当未定义__ASC_FTZ__时,检测结果是否落在 subnormal 边界(1.17549435e-38f)以下,若是则通过expf(x*0.5f)平方的方式重新计算以避免精度丢失;定义__ASC_FTZ__时保持原直接调用__expf(x)的行为。 -
logf改为受__ASC_FTZ__宏控制:将原有的 subnormal 缩放补偿逻辑(乘以2^23并用-ln(2^23)补偿)移入#ifndef __ASC_FTZ__分支中,同时将先前硬编码的expf(23.0f)和-23.0f替换为更精确的常量8388608.0f和-15.9423851528787421f,使代码在不需要 subnormal 支持时直接走__logf(x)。 -
sqrtf新增三路分支与高精度实现:新增静态内联函数__asc_sqrtf_precise_impl,使用 Newton-Raphson 迭代(内含fmaf进行误差修正)实现高精度平方根;sqrtf根据__ASC_FTZ__和__ASC_PREC_SQRT__的组合选择直接调用__sqrtf(x)、高精度实现或 subnormal 缩放路径。 -
fdividef改为 intrinsic 实现:将fdividef的实现从普通的x / y改为调用内建函数__fdividef(x, y),以获得更优的除法性能或精度。


代码审查
审查总结
已审查文件:impl/simt_api/math_functions_impl.h
| 优先级 | 数量 | 说明 |
|---|---|---|
| P0 | 1 | fdividef 缺少分号,直接导致编译失败 |
| P2 | 1 | FTZ+PREC_SQRT 路径下负 subnormal 的 sqrtf 返回 0.0f 而非 NaN |
| P1 | 0 | — |
| P3 | 0 | — |
整体风险评估: 本次变更整体质量较好——expf / logf 的 subnormal 处理逻辑正确,__asc_sqrtf_precise_impl 的 Newton 迭代实现无误,四种编译宏组合的 sqrtf 分发路径覆盖完整。但 P0 的 fdividef 缺分号是阻塞性问题,必须在合入前修复;P2 的负 subnormal 行为偏差在 FTZ 模式下影响有限,可视情况处理。
| 类型 | 数量 |
|---|---|
| 🔴 阻塞 | 1 |
| 🟡 建议 | 0 |
⛔ 需要修改


The MR can not be merged, because of CodeReview discussion not resolved
If you want to solve this problem, you can click here to do it in the FAQs.


描述
expf和sqrtf接口支持subnormal:
在impl/simt_api/math_functions_impl.h中,将expf和sqrtf接口实现修改,根据编译宏状态来控制代码逻辑走不同的分支,实现支持subnormal场景和sqrt高精度场景。
关联的Issue
https://gitcode.com/cann/asc-devkit/issues/1487
测试
编写测试用例测试精度
文档更新
在impl/simt_api/math_functions_impl.h中,将expf和sqrtf接口实现修改。
类型标签