diff options
Diffstat (limited to '')
-rw-r--r-- | dom/webgpu/tests/cts/checkout/src/webgpu/shader/execution/expression/binary/f32_logical.spec.ts | 260 |
1 files changed, 260 insertions, 0 deletions
diff --git a/dom/webgpu/tests/cts/checkout/src/webgpu/shader/execution/expression/binary/f32_logical.spec.ts b/dom/webgpu/tests/cts/checkout/src/webgpu/shader/execution/expression/binary/f32_logical.spec.ts new file mode 100644 index 0000000000..21f2810d01 --- /dev/null +++ b/dom/webgpu/tests/cts/checkout/src/webgpu/shader/execution/expression/binary/f32_logical.spec.ts @@ -0,0 +1,260 @@ +export const description = ` +Execution Tests for the f32 logical binary expression operations +`; + +import { makeTestGroup } from '../../../../../common/framework/test_group.js'; +import { GPUTest } from '../../../../gpu_test.js'; +import { anyOf } from '../../../../util/compare.js'; +import { bool, f32, Scalar, TypeBool, TypeF32 } from '../../../../util/conversion.js'; +import { flushSubnormalScalarF32, vectorF32Range } from '../../../../util/math.js'; +import { makeCaseCache } from '../case_cache.js'; +import { allInputSources, Case, run } from '../expression.js'; + +import { binary } from './binary.js'; + +export const g = makeTestGroup(GPUTest); + +/** + * @returns a test case for the provided left hand & right hand values and truth function. + * Handles quantization and subnormals. + */ +function makeCase( + lhs: number, + rhs: number, + truthFunc: (lhs: Scalar, rhs: Scalar) => boolean +): Case { + const f32_lhs = f32(lhs); + const f32_rhs = f32(rhs); + const lhs_options = new Set([f32_lhs, flushSubnormalScalarF32(f32_lhs)]); + const rhs_options = new Set([f32_rhs, flushSubnormalScalarF32(f32_rhs)]); + const expected: Array<Scalar> = []; + lhs_options.forEach(l => { + rhs_options.forEach(r => { + const result = bool(truthFunc(l, r)); + if (!expected.includes(result)) { + expected.push(result); + } + }); + }); + + return { input: [f32_lhs, f32_rhs], expected: anyOf(...expected) }; +} + +export const d = makeCaseCache('binary/f32_logical', { + equals_non_const: () => { + const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + return (lhs.value as number) === (rhs.value as number); + }; + + return vectorF32Range(2).map(v => { + return makeCase(v[0], v[1], truthFunc); + }); + }, + equals_const: () => { + const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + return (lhs.value as number) === (rhs.value as number); + }; + + return vectorF32Range(2).map(v => { + return makeCase(v[0], v[1], truthFunc); + }); + }, + not_equals_non_const: () => { + const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + return (lhs.value as number) !== (rhs.value as number); + }; + + return vectorF32Range(2).map(v => { + return makeCase(v[0], v[1], truthFunc); + }); + }, + not_equals_const: () => { + const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + return (lhs.value as number) !== (rhs.value as number); + }; + + return vectorF32Range(2).map(v => { + return makeCase(v[0], v[1], truthFunc); + }); + }, + less_than_non_const: () => { + const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + return (lhs.value as number) < (rhs.value as number); + }; + + return vectorF32Range(2).map(v => { + return makeCase(v[0], v[1], truthFunc); + }); + }, + less_than_const: () => { + const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + return (lhs.value as number) < (rhs.value as number); + }; + + return vectorF32Range(2).map(v => { + return makeCase(v[0], v[1], truthFunc); + }); + }, + less_equals_non_const: () => { + const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + return (lhs.value as number) <= (rhs.value as number); + }; + + return vectorF32Range(2).map(v => { + return makeCase(v[0], v[1], truthFunc); + }); + }, + less_equals_const: () => { + const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + return (lhs.value as number) <= (rhs.value as number); + }; + + return vectorF32Range(2).map(v => { + return makeCase(v[0], v[1], truthFunc); + }); + }, + greater_than_non_const: () => { + const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + return (lhs.value as number) > (rhs.value as number); + }; + + return vectorF32Range(2).map(v => { + return makeCase(v[0], v[1], truthFunc); + }); + }, + greater_than_const: () => { + const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + return (lhs.value as number) > (rhs.value as number); + }; + + return vectorF32Range(2).map(v => { + return makeCase(v[0], v[1], truthFunc); + }); + }, + greater_equals_non_const: () => { + const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + return (lhs.value as number) >= (rhs.value as number); + }; + + return vectorF32Range(2).map(v => { + return makeCase(v[0], v[1], truthFunc); + }); + }, + greater_equals_const: () => { + const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + return (lhs.value as number) >= (rhs.value as number); + }; + + return vectorF32Range(2).map(v => { + return makeCase(v[0], v[1], truthFunc); + }); + }, +}); + +g.test('equals') + .specURL('https://www.w3.org/TR/WGSL/#floating-point-evaluation') + .desc( + ` +Expression: x == y +Accuracy: Correct result +` + ) + .params(u => + u.combine('inputSource', allInputSources).combine('vectorize', [undefined, 2, 3, 4] as const) + ) + .fn(async t => { + const cases = await d.get( + t.params.inputSource === 'const' ? 'equals_const' : 'equals_non_const' + ); + await run(t, binary('=='), [TypeF32, TypeF32], TypeBool, t.params, cases); + }); + +g.test('not_equals') + .specURL('https://www.w3.org/TR/WGSL/#floating-point-evaluation') + .desc( + ` +Expression: x != y +Accuracy: Correct result +` + ) + .params(u => + u.combine('inputSource', allInputSources).combine('vectorize', [undefined, 2, 3, 4] as const) + ) + .fn(async t => { + const cases = await d.get( + t.params.inputSource === 'const' ? 'not_equals_const' : 'not_equals_non_const' + ); + await run(t, binary('!='), [TypeF32, TypeF32], TypeBool, t.params, cases); + }); + +g.test('less_than') + .specURL('https://www.w3.org/TR/WGSL/#floating-point-evaluation') + .desc( + ` +Expression: x < y +Accuracy: Correct result +` + ) + .params(u => + u.combine('inputSource', allInputSources).combine('vectorize', [undefined, 2, 3, 4] as const) + ) + .fn(async t => { + const cases = await d.get( + t.params.inputSource === 'const' ? 'less_than_const' : 'less_than_non_const' + ); + await run(t, binary('<'), [TypeF32, TypeF32], TypeBool, t.params, cases); + }); + +g.test('less_equals') + .specURL('https://www.w3.org/TR/WGSL/#floating-point-evaluation') + .desc( + ` +Expression: x <= y +Accuracy: Correct result +` + ) + .params(u => + u.combine('inputSource', allInputSources).combine('vectorize', [undefined, 2, 3, 4] as const) + ) + .fn(async t => { + const cases = await d.get( + t.params.inputSource === 'const' ? 'less_equals_const' : 'less_equals_non_const' + ); + await run(t, binary('<='), [TypeF32, TypeF32], TypeBool, t.params, cases); + }); + +g.test('greater_than') + .specURL('https://www.w3.org/TR/WGSL/#floating-point-evaluation') + .desc( + ` +Expression: x > y +Accuracy: Correct result +` + ) + .params(u => + u.combine('inputSource', allInputSources).combine('vectorize', [undefined, 2, 3, 4] as const) + ) + .fn(async t => { + const cases = await d.get( + t.params.inputSource === 'const' ? 'greater_than_const' : 'greater_than_non_const' + ); + await run(t, binary('>'), [TypeF32, TypeF32], TypeBool, t.params, cases); + }); + +g.test('greater_equals') + .specURL('https://www.w3.org/TR/WGSL/#floating-point-evaluation') + .desc( + ` +Expression: x >= y +Accuracy: Correct result +` + ) + .params(u => + u.combine('inputSource', allInputSources).combine('vectorize', [undefined, 2, 3, 4] as const) + ) + .fn(async t => { + const cases = await d.get( + t.params.inputSource === 'const' ? 'greater_equals_const' : 'greater_equals_non_const' + ); + await run(t, binary('>='), [TypeF32, TypeF32], TypeBool, t.params, cases); + }); |