from dataclasses import dataclass, field
from typing import List, Optional
@dataclass
class ResolvedStandard:
token: str
params: dict = field(default_factory=dict)
THRESHOLDS = {
"float16": 2**-10,
"bfloat16": 2**-7,
"float32": 2**-13,
"float8_e4m3fn": 2**-3,
"float8_e5m2": 2**-2,
}
DEFAULT_THRESHOLD = 2**-13
LEVEL_PRESETS = {
"L0": {"mare_ratio": 10.0, "mere_ratio": 2.0, "rmse_ratio": 2.0},
"L1": {"mare_ratio": 5.0, "mere_ratio": 1.5, "rmse_ratio": 1.5},
"L2": {"mare_ratio": 2.0, "mere_ratio": 1.2, "rmse_ratio": 1.2},
}
SMALL_VALUE = {
"float16": {"small_value": 2**-11, "small_value_atol": 2**-16},
"bfloat16": {"small_value": 2**-8, "small_value_atol": 2**-16},
"float32": {"small_value": 2**-14, "small_value_atol": 2**-30},
}
_REQUANT_DTYPES = {"float8_e5m2", "float8_e4m3fn", "hifloat8"}
_BIN_DTYPES = {"float4_e2m1", "float4_e1m2", "float8_e8m0"}
def _dtype_str(dtype) -> str:
return str(dtype).split(".")[-1]
def _is_int_or_bool(s: str) -> bool:
return s == "bool" or s.startswith("int") or s.startswith("uint")
def _is_complex(s: str) -> bool:
return "complex" in s
def _float_choice(tolerance: Optional[dict], dtype_str: str,
compare_method: Optional[str]) -> str:
"""普通浮点族的三级优先级:CLI > Spec.tolerance > stat_rel_err。"""
if compare_method:
return compare_method.lower()
if tolerance and dtype_str in tolerance:
std = tolerance[dtype_str].get("standard")
if std:
return std.lower()
return "stat_rel_err"
def _resolve_params(standard, tolerance, dtype_str) -> dict:
cfg = (tolerance or {}).get(dtype_str, {})
extra = {k: v for k, v in cfg.items() if k != "standard"}
if standard == "stat_rel_err":
th = extra.pop("threshold", None) or THRESHOLDS.get(dtype_str, DEFAULT_THRESHOLD)
return {"threshold": th}
elif standard == "cross_check":
if dtype_str not in SMALL_VALUE:
raise ValueError(f"[{dtype_str}] cross_check unsupported dtype; supported: {sorted(SMALL_VALUE)}")
level = extra.get("level")
if level is not None:
if level not in LEVEL_PRESETS:
raise ValueError(f"[{dtype_str}] cross_check unknown level: {level!r}; expected {sorted(LEVEL_PRESETS)}")
limits = dict(LEVEL_PRESETS[level])
else:
level = "L1"
limits = dict(LEVEL_PRESETS[level])
for k in ("mare_ratio", "mere_ratio", "rmse_ratio"):
if k in extra:
limits[k] = extra[k]
missing = [k for k in ("mare_ratio", "mere_ratio", "rmse_ratio") if k not in limits]
if missing:
raise ValueError(f"[{dtype_str}] cross_check missing ratios: {missing}; specify level or all 3 ratios")
resolved_level = level or "L1"
sv_default = SMALL_VALUE[dtype_str]
return {"level": resolved_level, **limits,
"small_value": extra.get("small_value", sv_default["small_value"]),
"small_value_atol": extra.get("small_value_atol", sv_default["small_value_atol"])}
else:
return {}
def resolve_tolerance(tolerance, precision_tolerances, absolute_precision,
output_dtypes, compare_method):
standards = []
for idx, dtype in enumerate(output_dtypes):
s = _dtype_str(dtype)
if dtype is None:
token = "binary_equal"
elif _is_int_or_bool(s):
token = "binary_equal"
elif _is_complex(s):
choice = _float_choice(tolerance, s, compare_method)
token = "binary_equal" if choice in ("bin", "binary") else "isclose"
elif s in _REQUANT_DTYPES:
choice = _float_choice(tolerance, s, compare_method)
token = choice if choice in ("bin", "binary", "requant") else "requant"
elif s in _BIN_DTYPES:
token = "bin"
else:
token = _float_choice(tolerance, s, compare_method)
params = _resolve_params(token, tolerance, s)
params["legacy"] = {
"rtol": precision_tolerances[idx][0] if precision_tolerances and idx < len(precision_tolerances) else None,
"ptol": precision_tolerances[idx][1] if precision_tolerances and idx < len(precision_tolerances) else None,
"atol": absolute_precision[idx] if isinstance(absolute_precision, (tuple, list)) and idx < len(absolute_precision) else (absolute_precision if not isinstance(absolute_precision, (tuple, list)) else None),
}
standards.append(ResolvedStandard(token, params))
return standards