Closed
[Documentation|文档反馈]: [aclnnRoundDecimals] 参数表 decimals 未声明取值范围(使用说明列为「-」),实测值域受 int32 截断与大值 NaN 约束 #4164
liuhanwen8Add on  13 days agoClosed at  3 days ago
liuhanwen8
liuhanwen8
13 days ago Create

一、文档链接

  • 仓库:cann/ops-math
  • 文件:math/round/docs/aclnnRoundDecimals&aclnnInplaceRoundDecimals.md
  • 非原地接口段参数表:L107-115(aclnnRoundDecimalsGetWorkspaceSize)
  • 原地接口段参数表:L280-288(aclnnInplaceRoundDecimalsGetWorkspaceSize,同样问题)

二、问题文档片段

L107-115 逐字原文:

      <td>decimals(int64_t)</td>
      <td>输入</td>
      <td>指定需要四舍五入的位数。</td>
      <td>-</td>
      <td>-</td>
      <td>-</td>
      <td>-</td>
      <td>-</td>

「约束说明」(L241、L394)逐字原文:

针对decimals不为0的场景:
输入数据超过(-347000, 347000)范围,精度可能会有影响。

三、存在的问题

1)decimals 的取值约束应有而缺。 参数表给这一行留了「使用说明 / 数据类型 / 数据格式 / 维度 / 非连续Tensor」五个字段,全部填的是 -。也就是说:合法取值范围没写、默认值没写、负值是否允许没写。而「约束说明」约束的是输入数据的绝对值(|x| > 347000),不是 decimals 本身,两件事不能互相顶替。

2)实测该参数的值域确实受约束(A2 910B2 / CANN 9.2.0,aclnn 两段式直调,两次调用均返回 0):

输入 decimals 实测输出 说明
fp32 0.5 / 1.5 40 NaN / NaN 10^40 在 fp32 溢出,x*10^d 与 /10^d 都失效
fp32 0.5 / 1.5 38 0.5 / 1.5 同 dtype 下仍正常,边界在 38/39 之间
fp64 0.5 / 1.5 300 0.5 / 1.5 正常
fp64 0.5 / 1.5 309 NaN / NaN 同上,边界在 308/309 之间
fp16 / bf16 0.5 / 1.5 5 0.5 / 1.5 走 AiCore 路径,未观察到 NaN
fp32 1234.5678 INT64_MAX 1230 与 decimals=-1 逐位相同(按 int32 截断)
fp32 1234.5678 INT64_MIN 1235 与 decimals=0 逐位相同
fp32 1234.5678 INT64_MIN+1 1234.6 与 decimals=+1 逐位相同(低 32 位 = 1)

用户按现在的资料无法预判「传 40 会得到全 NaN」「传 INT64_MAX 会被当成 -1」。这类输入目前既不报错也不提示。

3)接口层同样不校验。 math/round/op_api/aclnn_round.cpp 的 CheckParamsRound 只校验空指针、dtype、shape 与 format,校验区内不出现 decimals,值域完全靠调用方自觉。

4)建议补法。 在参数表 decimals 行的「使用说明」列补一句取值范围,并在「约束说明」补边界行为,例如:

decimals 建议取值 [-38, 38](FLOAT)/ [-308, 308](DOUBLE);超出该区间时实现返回 NaN,不额外报错。FLOAT16/BFLOAT16 实测到 decimals=5 仍正常(走另一条执行路径),如无已知上限可写明"建议不超过 4"。

原地与非原地两段参数表内容一致,建议同步修改。

四、复现方式

  1. 在仓库根目录保存下面脚本为 check.py。
  2. 执行 python3 check.py。
  3. 期望输出末行为 [DEFECT]、退出码为 1;若资料已补取值范围,脚本会打印 [OK] 并返回 0。
import pathlib
import re
import sys

doc = pathlib.Path("math/round/docs/aclnnRoundDecimals&aclnnInplaceRoundDecimals.md").read_text("utf-8")
row = re.search(r"<td>decimals(int64_t)</td>(.*?)</tr>", doc, re.S).group(1)
cells = re.findall(r"<td>(.*?)</td>", row)
rng = re.search(r"decimals[^。;\n]{0,40}?[-+]?\d+\s*[~至到]\s*[-+]?\d+", doc)
api = pathlib.Path("math/round/op_api/aclnn_round.cpp").read_text("utf-8")
guarded = "decimals" in api.split("aclnnRoundGetWorkspaceSize")[0]
print("使用说明列 =", repr(cells[2].strip()))
print("全文存在 decimals 区间声明 =", bool(rng))
print("接口层校验 decimals =", guarded)
if cells[2].strip() == "-" and not rng and not guarded:
    print("[DEFECT] decimals 既无取值范围说明,接口层也不校验值域")
    sys.exit(1)
print("[OK] 资料已声明 decimals 的取值范围")

实测输出(当前 master):

使用说明列 = '-'
全文存在 decimals 区间声明 = False
接口层校验 decimals = False
[DEFECT] decimals 既无取值范围说明,接口层也不校验值域

以上脚本只读仓内文件,不依赖 NPU 与网络;第 2 点表格中的上板数据来自 aclnnRoundDecimals 两段式直调,环境为 Ascend 910B2 + CANN 9.2.0。

likedislike
liuhanwen8liuhanwen8
13 days ago Added label: documentation
xujiachen8Collaborators
13 days ago Comments:

您好,感谢反馈和各类型的边界实测!

问题分析

核对 cann/ops-math master b08e885e7fac370203a51904fd0680523b9a9205,两个接口的 decimals 使用说明确实均为“-”,未说明负值及极端值的行为;现有 (-347000, 347000) 提示约束的是输入数据,不能替代参数本身的说明。这部分资料缺口可以确认。参数与约束、原地接口参数

对于您报告的 INT64_MAX/MIN 等表现,当前可见的 API 与 L0 接口均以 int64_t 传递 decimals,CheckParamsRound 没有该参数的范围校验,也未发现浮点调用链在这里将其转为 int32_t。因此,这几组输出与低 32 位取值相符是现有实测线索,具体截断位置还不能据此定在 API 层;需要结合 A2 / CANN 9.2.0 安装库对应实现确认。API 传参、L0 派发

大 decimals 的行为也依赖后端和计算类型。该基线的 DOUBLE 走 AICPU,先计算 10^|decimals| 并转为输入类型,再执行缩放、舍入和反向缩放,因而会受到幂、乘积及结果的表示范围影响。仓库公开的 arch35 浮点分支另有 |decimals| > 38 的特殊值处理,正常缩放使用 FP32 中间量;这些 arch35 分支不能直接作为 A2 安装库 kernel 的实现证据。AICPU 缩放、arch35 边界处理

[-38,38]、[-308,308] 不能仅凭幂的表示范围写成全输入安全范围:即使 10^d 有限,x × 10^d 仍可能溢出,负位数及最终输出类型也有各自边界。同样,FLOAT16/BFLOAT16 在两个小值、d=5 下正常,不能推出统一上限,当前也没有足够依据把“FLOAT16 建议不超过 4”作为通用限制。

处理方向

可行方向是同步补充两个参数表及约束说明,按产品、输入类型和实际计算路径说明正负位数语义、支持条件与越界行为;decimals 是 C 接口需要显式传入的参数,图算子的默认属性不宜直接当作此接口的默认实参。

实现侧可评估在求绝对值、取反或生成十进制幂之前检查极值,特别是 INT64_MIN,再明确不支持组合应报错还是保留已有数值行为。具体范围与返回策略需兼顾中间量溢出和已有调用兼容性,不能只增加一个统一常量区间。我们会继续核对安装库的参数传递路径及适用边界。

likedislike
Xxujiachen8Collaborators
13 days ago Assign jiaoyiming as responsible person
Xxujiachen8Collaborators
13 days ago Added label: pending-confirmation
陈思陈思Collaborators
13 days ago Removed label: pending-confirmation
CANN-robotCANN-robotCollaborators
3 days ago Close issue
CANN-robotCANN-robotCollaborators
3 days ago changed custom state from 进行中 to 已完成
CANN-robotCANN-robotCollaborators
3 days ago Added label: resolved