Browse Source

[#2273][bulknormdot] fixing spurious invalid flag in bulk_norm_dot_no_mult

Bulk normalized dot product is expected to raise the invalid flag if two products with infinite values and opposite signs are added.
Spike function failed to consider the second operand of a product when determining whether the product had infinite value or not, and missed the exclusion of NaN and zero from this case.

The zero case is quiet, because it happens for inf * zero which is expected to raise the invalid flag. The qNaN case is not quiet and can cause the apparition of a spurious invalid flag when none were expected.
pull/2275/head
Nicolas Brunie 1 month ago
parent
commit
41c31ce427
  1. 13
      riscv/bulknormdot.h

13
riscv/bulknormdot.h

@ -203,13 +203,18 @@ template<typename ValueTypeLHS, typename ValueTypeRHS, typename SigProdType> bul
a[i].isZero() || b[i].isZero() ? (f32_exp_bias - (lhs_bias + rhs_bias)) : // minimalize exp of zero product a[i].isZero() || b[i].isZero() ? (f32_exp_bias - (lhs_bias + rhs_bias)) : // minimalize exp of zero product
a[i].expSubFixed() + b[i].expSubFixed() + (f32_exp_bias - (lhs_bias + rhs_bias)); a[i].expSubFixed() + b[i].expSubFixed() + (f32_exp_bias - (lhs_bias + rhs_bias));
bool a_is_zero = (a[i].subOrZero() && cfg.flushSub) || a[i].isZero();
bool b_is_zero = (b[i].subOrZero() && cfg.flushSub) || b[i].isZero();
bool either_inf = a[i].inf() || b[i].inf(); bool either_inf = a[i].inf() || b[i].inf();
any_pos_inf |= either_inf && a[i].sign() == b[i].sign(); bool either_nan = a[i].nan() || b[i].nan();
any_neg_inf |= either_inf && a[i].sign() != b[i].sign(); bool either_zero = a_is_zero || b_is_zero;
any_pos_inf |= either_inf && !either_nan && !either_zero && a[i].sign() == b[i].sign();
any_neg_inf |= either_inf && !either_nan && !either_zero && a[i].sign() != b[i].sign();
any_invalid_nan |= any_invalid_nan |=
(a[i].inf() && ((b[i].subOrZero() && cfg.flushSub) || b[i].isZero())) || (a[i].inf() && b_is_zero) ||
(b[i].inf() && ((a[i].subOrZero() && cfg.flushSub) || a[i].isZero())); (b[i].inf() && a_is_zero);
any_nan |= any_invalid_nan || a[i].nan() || b[i].nan(); any_nan |= any_invalid_nan || a[i].nan() || b[i].nan();

Loading…
Cancel
Save