summaryrefslogtreecommitdiffstats
path: root/dom/webgpu/tests/cts/checkout/src/webgpu/shader/execution/expression/binary/f16_division.spec.ts
diff options
context:
space:
mode:
Diffstat (limited to 'dom/webgpu/tests/cts/checkout/src/webgpu/shader/execution/expression/binary/f16_division.spec.ts')
-rw-r--r--dom/webgpu/tests/cts/checkout/src/webgpu/shader/execution/expression/binary/f16_division.spec.ts212
1 files changed, 212 insertions, 0 deletions
diff --git a/dom/webgpu/tests/cts/checkout/src/webgpu/shader/execution/expression/binary/f16_division.spec.ts b/dom/webgpu/tests/cts/checkout/src/webgpu/shader/execution/expression/binary/f16_division.spec.ts
new file mode 100644
index 0000000000..c3b8fc04db
--- /dev/null
+++ b/dom/webgpu/tests/cts/checkout/src/webgpu/shader/execution/expression/binary/f16_division.spec.ts
@@ -0,0 +1,212 @@
+export const description = `
+Execution Tests for non-matrix f16 division expression
+`;
+
+import { makeTestGroup } from '../../../../../common/framework/test_group.js';
+import { GPUTest } from '../../../../gpu_test.js';
+import { TypeF16, TypeVec } from '../../../../util/conversion.js';
+import { FP, FPVector } from '../../../../util/floating_point.js';
+import { sparseF16Range, sparseVectorF16Range } from '../../../../util/math.js';
+import { makeCaseCache } from '../case_cache.js';
+import { allInputSources, run } from '../expression.js';
+
+import { binary, compoundBinary } from './binary.js';
+
+const divisionVectorScalarInterval = (v: readonly number[], s: number): FPVector => {
+ return FP.f16.toVector(v.map(e => FP.f16.divisionInterval(e, s)));
+};
+
+const divisionScalarVectorInterval = (s: number, v: readonly number[]): FPVector => {
+ return FP.f16.toVector(v.map(e => FP.f16.divisionInterval(s, e)));
+};
+
+export const g = makeTestGroup(GPUTest);
+
+const scalar_cases = ([true, false] as const)
+ .map(nonConst => ({
+ [`scalar_${nonConst ? 'non_const' : 'const'}`]: () => {
+ return FP.f16.generateScalarPairToIntervalCases(
+ sparseF16Range(),
+ sparseF16Range(),
+ nonConst ? 'unfiltered' : 'finite',
+ FP.f16.divisionInterval
+ );
+ },
+ }))
+ .reduce((a, b) => ({ ...a, ...b }), {});
+
+const vector_scalar_cases = ([2, 3, 4] as const)
+ .flatMap(dim =>
+ ([true, false] as const).map(nonConst => ({
+ [`vec${dim}_scalar_${nonConst ? 'non_const' : 'const'}`]: () => {
+ return FP.f16.generateVectorScalarToVectorCases(
+ sparseVectorF16Range(dim),
+ sparseF16Range(),
+ nonConst ? 'unfiltered' : 'finite',
+ divisionVectorScalarInterval
+ );
+ },
+ }))
+ )
+ .reduce((a, b) => ({ ...a, ...b }), {});
+
+const scalar_vector_cases = ([2, 3, 4] as const)
+ .flatMap(dim =>
+ ([true, false] as const).map(nonConst => ({
+ [`scalar_vec${dim}_${nonConst ? 'non_const' : 'const'}`]: () => {
+ return FP.f16.generateScalarVectorToVectorCases(
+ sparseF16Range(),
+ sparseVectorF16Range(dim),
+ nonConst ? 'unfiltered' : 'finite',
+ divisionScalarVectorInterval
+ );
+ },
+ }))
+ )
+ .reduce((a, b) => ({ ...a, ...b }), {});
+
+export const d = makeCaseCache('binary/f16_division', {
+ ...scalar_cases,
+ ...vector_scalar_cases,
+ ...scalar_vector_cases,
+});
+
+g.test('scalar')
+ .specURL('https://www.w3.org/TR/WGSL/#floating-point-evaluation')
+ .desc(
+ `
+Expression: x / y, where x and y are scalars
+Accuracy: 2.5 ULP for |y| in the range [2^-126, 2^126]
+`
+ )
+ .params(u => u.combine('inputSource', allInputSources))
+ .beforeAllSubcases(t => {
+ t.selectDeviceOrSkipTestCase({ requiredFeatures: ['shader-f16'] });
+ })
+ .fn(async t => {
+ const cases = await d.get(
+ t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const'
+ );
+ await run(t, binary('/'), [TypeF16, TypeF16], TypeF16, t.params, cases);
+ });
+
+g.test('vector')
+ .specURL('https://www.w3.org/TR/WGSL/#floating-point-evaluation')
+ .desc(
+ `
+Expression: x / y, where x and y are vectors
+Accuracy: 2.5 ULP for |y| in the range [2^-126, 2^126]
+`
+ )
+ .params(u => u.combine('inputSource', allInputSources).combine('vectorize', [2, 3, 4] as const))
+ .beforeAllSubcases(t => {
+ t.selectDeviceOrSkipTestCase({ requiredFeatures: ['shader-f16'] });
+ })
+ .fn(async t => {
+ const cases = await d.get(
+ t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' // Using vectorize to generate vector cases based on scalar cases
+ );
+ await run(t, binary('/'), [TypeF16, TypeF16], TypeF16, t.params, cases);
+ });
+
+g.test('scalar_compound')
+ .specURL('https://www.w3.org/TR/WGSL/#floating-point-evaluation')
+ .desc(
+ `
+Expression: x /= y
+Accuracy: 2.5 ULP for |y| in the range [2^-126, 2^126]
+`
+ )
+ .params(u =>
+ u.combine('inputSource', allInputSources).combine('vectorize', [undefined, 2, 3, 4] as const)
+ )
+ .beforeAllSubcases(t => {
+ t.selectDeviceOrSkipTestCase({ requiredFeatures: ['shader-f16'] });
+ })
+ .fn(async t => {
+ const cases = await d.get(
+ t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const'
+ );
+ await run(t, compoundBinary('/='), [TypeF16, TypeF16], TypeF16, t.params, cases);
+ });
+
+g.test('vector_scalar')
+ .specURL('https://www.w3.org/TR/WGSL/#floating-point-evaluation')
+ .desc(
+ `
+Expression: x / y, where x is a vector and y is a scalar
+Accuracy: Correctly rounded
+`
+ )
+ .params(u => u.combine('inputSource', allInputSources).combine('dim', [2, 3, 4] as const))
+ .beforeAllSubcases(t => {
+ t.selectDeviceOrSkipTestCase({ requiredFeatures: ['shader-f16'] });
+ })
+ .fn(async t => {
+ const dim = t.params.dim;
+ const cases = await d.get(
+ t.params.inputSource === 'const' ? `vec${dim}_scalar_const` : `vec${dim}_scalar_non_const`
+ );
+ await run(
+ t,
+ binary('/'),
+ [TypeVec(dim, TypeF16), TypeF16],
+ TypeVec(dim, TypeF16),
+ t.params,
+ cases
+ );
+ });
+
+g.test('vector_scalar_compound')
+ .specURL('https://www.w3.org/TR/WGSL/#floating-point-evaluation')
+ .desc(
+ `
+Expression: x /= y, where x is a vector and y is a scalar
+Accuracy: Correctly rounded
+`
+ )
+ .params(u => u.combine('inputSource', allInputSources).combine('dim', [2, 3, 4] as const))
+ .beforeAllSubcases(t => {
+ t.selectDeviceOrSkipTestCase({ requiredFeatures: ['shader-f16'] });
+ })
+ .fn(async t => {
+ const dim = t.params.dim;
+ const cases = await d.get(
+ t.params.inputSource === 'const' ? `vec${dim}_scalar_const` : `vec${dim}_scalar_non_const`
+ );
+ await run(
+ t,
+ compoundBinary('/='),
+ [TypeVec(dim, TypeF16), TypeF16],
+ TypeVec(dim, TypeF16),
+ t.params,
+ cases
+ );
+ });
+
+g.test('scalar_vector')
+ .specURL('https://www.w3.org/TR/WGSL/#floating-point-evaluation')
+ .desc(
+ `
+Expression: x / y, where x is a scalar and y is a vector
+Accuracy: Correctly rounded
+`
+ )
+ .params(u => u.combine('inputSource', allInputSources).combine('dim', [2, 3, 4] as const))
+ .beforeAllSubcases(t => {
+ t.selectDeviceOrSkipTestCase({ requiredFeatures: ['shader-f16'] });
+ })
+ .fn(async t => {
+ const dim = t.params.dim;
+ const cases = await d.get(
+ t.params.inputSource === 'const' ? `scalar_vec${dim}_const` : `scalar_vec${dim}_non_const`
+ );
+ await run(
+ t,
+ binary('/'),
+ [TypeF16, TypeVec(dim, TypeF16)],
+ TypeVec(dim, TypeF16),
+ t.params,
+ cases
+ );
+ });