Skip to content

Commit

Permalink
Avoid subnormals in expression validation for quantizing types (in no…
Browse files Browse the repository at this point in the history
…rmalize and refract) (#3938)

* Avoid test cases involving subnormals

* Update refract as well

* Miinor lint fixing

---------

Co-authored-by: Peter McNeeley <[email protected]>
  • Loading branch information
petermcneeleychromium and Peter McNeeley authored Sep 6, 2024
1 parent 6c236a3 commit 7568697
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@ import {
scalarTypeOf,
ScalarType,
} from '../../../../../util/conversion.js';
import { QuantizeFunc, quantizeToF16, quantizeToF32 } from '../../../../../util/math.js';
import {
QuantizeFunc,
quantizeToF16,
quantizeToF32,
isSubnormalNumberF16,
isSubnormalNumberF32,
} from '../../../../../util/math.js';
import { ShaderValidationTest } from '../../../shader_validation_test.js';

import {
Expand All @@ -37,6 +43,17 @@ function quantizeFunctionForScalarType(type: ScalarType): QuantizeFunc<number> {
}
}

function isSubnormalFunctionForScalarType(type: ScalarType): (v: number) => boolean {
switch (type) {
case Type.f32:
return isSubnormalNumberF32;
case Type.f16:
return isSubnormalNumberF16;
default:
return (v: number) => false;
}
}

g.test('values')
.desc(
`
Expand Down Expand Up @@ -73,6 +90,11 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec
expectedResult = false;
}

// We skip tests with values that would involve subnormal computations in
// order to avoid defining a specific behavior (flush to zero).
const isSubnormalFn = isSubnormalFunctionForScalarType(scalarType);
t.skipIf(isSubnormalFn(vv) || isSubnormalFn(dp) || isSubnormalFn(len));

validateConstOrOverrideBuiltinEval(
t,
builtin,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,21 @@ const builtin = 'refract';
export const description = `
Validation tests for the ${builtin}() builtin.
`;

import { makeTestGroup } from '../../../../../../common/framework/test_group.js';
import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js';
import { Type, kConvertableToFloatVectors, scalarTypeOf } from '../../../../../util/conversion.js';
import {
Type,
kConvertableToFloatVectors,
scalarTypeOf,
ScalarType,
} from '../../../../../util/conversion.js';
import {
QuantizeFunc,
quantizeToF16,
quantizeToF32,
isSubnormalNumberF16,
isSubnormalNumberF32,
} from '../../../../../util/math.js';
import { ShaderValidationTest } from '../../../shader_validation_test.js';

import {
Expand All @@ -20,6 +31,28 @@ export const g = makeTestGroup(ShaderValidationTest);

const kValidArgumentTypes = objectsToRecord(kConvertableToFloatVectors);

function quantizeFunctionForScalarType(type: ScalarType): QuantizeFunc<number> {
switch (type) {
case Type.f32:
return quantizeToF32;
case Type.f16:
return quantizeToF16;
default:
return (v: number) => v;
}
}

function isSubnormalFunctionForScalarType(type: ScalarType): (v: number) => boolean {
switch (type) {
case Type.f32:
return isSubnormalNumberF32;
case Type.f16:
return isSubnormalNumberF16;
default:
return (v: number) => false;
}
}

g.test('values')
.desc(
`
Expand Down Expand Up @@ -64,6 +97,17 @@ where a the calculations result in a non-representable value for the given type.
const c2_one_minus_b_dot_a_2 = vCheck.checkedResult(c2 * one_minus_b_dot_a_2);
const k = vCheck.checkedResult(1.0 - c2_one_minus_b_dot_a_2);

const quantizeFn = quantizeFunctionForScalarType(scalarType);
const isSubnormalFn = isSubnormalFunctionForScalarType(scalarType);
// We skip tests with values that would involve subnormal computations in
// order to avoid defining a specific behavior (flush to zero).
t.skipIf(
isSubnormalFn(quantizeFn(b_dot_a)) ||
isSubnormalFn(quantizeFn(b_dot_a_2)) ||
isSubnormalFn(quantizeFn(c2)) ||
isSubnormalFn(quantizeFn(k))
);

if (k >= 0) {
// If the k is near zero it may fail on some implementations which implement sqrt as
// 1/inversesqrt, so skip the test.
Expand Down

0 comments on commit 7568697

Please sign in to comment.