From 1eb1455568e2a23971f2c1b7be1077a8c1494685 Mon Sep 17 00:00:00 2001 From: Jeremy Johnson Date: Thu, 11 Apr 2024 16:21:54 +0100 Subject: Update compliance verify checks Cope with large error bounds with small reference values. Change how error bounds of NaN are avoided for ABS_ERRORs. Update SIN/COS compliance to latest spec and use input value as magnitude. Signed-off-by: Jeremy Johnson Change-Id: I55aca59e0255e1cfd255b08edb845c3e33ca7eff --- reference_model/src/ops/ewise_unary.cc | 8 ++++---- reference_model/src/verify/verify_abs_error.cc | 22 ++++++++++++++++++---- reference_model/src/verify/verify_utils.cc | 17 ++++++++++++++--- reference_model/src/verify/verify_utils.h | 2 ++ .../schemavalidation/compliance-config.schema.json | 8 ++++++++ verif/generator/tosa_test_gen.py | 21 ++++++++++++++++----- 6 files changed, 62 insertions(+), 16 deletions(-) diff --git a/reference_model/src/ops/ewise_unary.cc b/reference_model/src/ops/ewise_unary.cc index 310a174..6818f8c 100644 --- a/reference_model/src/ops/ewise_unary.cc +++ b/reference_model/src/ops/ewise_unary.cc @@ -181,8 +181,8 @@ int OpCos::register_fcn() case TOSA_REF_TYPE_FP64: if (g_func_config.abs_mode) { - // ABS_ERROR bounds return 1.0 - this->fcn = [](InEigenType a) -> OutEigenType { return 1.0; }; + // ABS_ERROR bounds return + this->fcn = [](InEigenType a) -> OutEigenType { return a; }; } else { @@ -414,8 +414,8 @@ int OpSin::register_fcn() case TOSA_REF_TYPE_FP64: if (g_func_config.abs_mode) { - // ABS_ERROR bounds return 1.0 - this->fcn = [](InEigenType a) -> OutEigenType { return 1.0; }; + // ABS_ERROR bounds return + this->fcn = [](InEigenType a) -> OutEigenType { return a; }; } else { diff --git a/reference_model/src/verify/verify_abs_error.cc b/reference_model/src/verify/verify_abs_error.cc index 64f86a3..b49ce48 100644 --- a/reference_model/src/verify/verify_abs_error.cc +++ b/reference_model/src/verify/verify_abs_error.cc @@ -30,15 +30,29 @@ double calcErrorBound(double referenceValue, double boundsValue, const void* cfg { const auto cfg = reinterpret_cast(cfgPtr); + double boundsMagnitude; + if (cfg->boundAsMagnitude) + { + // Special case for SIN/COS + // use the input value (stored in the bounds tensor) as the magnitude and value + boundsMagnitude = boundsValue; + boundsValue = std::abs(boundsValue); + } + else + { + // Use the referenceValue as the magnitude + boundsMagnitude = referenceValue; + } + double errorBound = 0.0; - if (std::isfinite(referenceValue) && std::abs(referenceValue) != 0.0) + if (std::isfinite(boundsValue) || std::abs(boundsMagnitude) != 0.0) { - double valBound = std::abs(referenceValue) * boundsValue; + double valueBound = std::abs(boundsMagnitude) * (boundsValue + cfg->boundAddition); if (cfg->lowerBound > 0) { - valBound = std::max(cfg->lowerBound, valBound); + valueBound = std::max(cfg->lowerBound, valueBound); } - errorBound = exp2(-AccPrecision::normal_frac / cfg->normalDivisor) * valBound; + errorBound = exp2(-AccPrecision::normal_frac / cfg->normalDivisor) * valueBound; } return errorBound; } diff --git a/reference_model/src/verify/verify_utils.cc b/reference_model/src/verify/verify_utils.cc index d4657b3..594158c 100644 --- a/reference_model/src/verify/verify_utils.cc +++ b/reference_model/src/verify/verify_utils.cc @@ -84,6 +84,14 @@ void from_json(const nlohmann::json& j, AbsErrorVerifyInfo& absErrorInfo) { j.at("normal_divisor").get_to(absErrorInfo.normalDivisor); } + if (j.contains("bound_as_magnitude")) + { + j.at("bound_as_magnitude").get_to(absErrorInfo.boundAsMagnitude); + } + if (j.contains("bound_addition")) + { + j.at("bound_addition").get_to(absErrorInfo.boundAddition); + } } void from_json(const nlohmann::json& j, RelativeVerifyInfo& rInfo) @@ -112,8 +120,10 @@ void from_json(const nlohmann::json& j, VerifyConfig& cfg) { j.at("reduce_product_info").get_to(cfg.reduceProductInfo); } - cfg.absErrorInfo.lowerBound = 0; - cfg.absErrorInfo.normalDivisor = 1; + cfg.absErrorInfo.lowerBound = 0; + cfg.absErrorInfo.normalDivisor = 1; + cfg.absErrorInfo.boundAsMagnitude = false; + cfg.absErrorInfo.boundAddition = 0; if (j.contains("abs_error_info")) { j.at("abs_error_info").get_to(cfg.absErrorInfo); @@ -317,7 +327,8 @@ bool tosaCheckFloatBound( if (referenceMin < AccPrecision::normal_min) { - referenceMin = 0.0; + // Large error bounds could mean referenceMin is negative + referenceMin = std::min(0.0, referenceMin); } } diff --git a/reference_model/src/verify/verify_utils.h b/reference_model/src/verify/verify_utils.h index 9144317..33491e0 100644 --- a/reference_model/src/verify/verify_utils.h +++ b/reference_model/src/verify/verify_utils.h @@ -83,6 +83,8 @@ struct AbsErrorVerifyInfo double lowerBound; double normalDivisor; + bool boundAsMagnitude; + double boundAddition; }; /// \brief relative verification meta-data diff --git a/scripts/schemavalidation/compliance-config.schema.json b/scripts/schemavalidation/compliance-config.schema.json index f4a310c..517dd99 100644 --- a/scripts/schemavalidation/compliance-config.schema.json +++ b/scripts/schemavalidation/compliance-config.schema.json @@ -74,6 +74,14 @@ "normal_divisor": { "description": "normal_divisor for error bounds", "type": "number" + }, + "bound_as_magnitude": { + "description": "when the bound magnitude is passed in the bound value", + "type": "boolean" + }, + "bound_addition": { + "description": "addition to the bounds value", + "type": "number" } }, "additionalProperties": false diff --git a/verif/generator/tosa_test_gen.py b/verif/generator/tosa_test_gen.py index 40788a2..b85dd03 100644 --- a/verif/generator/tosa_test_gen.py +++ b/verif/generator/tosa_test_gen.py @@ -290,10 +290,18 @@ class TosaTestGen: } elif op["op"] in (Op.SIN, Op.COS): mode = gtu.ComplianceMode.ABS_ERROR - if "compliance" in op and "abs_error_normal_divisor" in op["compliance"]: - compliance_tens["abs_error_info"] = { - "normal_divisor": op["compliance"]["abs_error_normal_divisor"] - } + if "compliance" in op: + normal_divisor = op["compliance"].get("abs_error_normal_divisor", 1) + bound_addition = op["compliance"].get("abs_error_bound_addition", 0) + else: + normal_divisor = 1 + bound_addition = 0 + + compliance_tens["abs_error_info"] = { + "normal_divisor": normal_divisor, + "bound_as_magnitude": True, + "bound_addition": bound_addition, + } else: mode = gtu.ComplianceMode.EXACT compliance_tens["mode"] = gtu.ComplianceMode(mode).name @@ -4139,7 +4147,10 @@ class TosaTestGen: TosaErrorValidator.evWrongOutputList, ), "data_gen": PSEUDO_RANDOM_DATAGEN, - "compliance": {"abs_error_normal_divisor": 2}, + "compliance": { + "abs_error_normal_divisor": 2, + "abs_error_bound_addition": 1, + }, }, "exp": { "op": Op.EXP, -- cgit v1.2.1