From d5ce9402de2658fab0777900affbd3cfc2ecde4f Mon Sep 17 00:00:00 2001 From: Ryan Harrison Date: Mon, 11 Mar 2024 11:30:57 -0400 Subject: [PATCH] wgsl: Implement AbstractInt bitwise-and execution tests (#3436) Issue #1631 --- .../expression/binary/bitwise.spec.ts | 158 +++++++++++++----- 1 file changed, 119 insertions(+), 39 deletions(-) diff --git a/src/webgpu/shader/execution/expression/binary/bitwise.spec.ts b/src/webgpu/shader/execution/expression/binary/bitwise.spec.ts index 71744b45959b..b6e9a45e9de8 100644 --- a/src/webgpu/shader/execution/expression/binary/bitwise.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/bitwise.spec.ts @@ -7,11 +7,9 @@ import { assert } from '../../../../../common/util/util.js'; import { GPUTest } from '../../../../gpu_test.js'; import { abstractIntBits, - i32, i32Bits, ScalarValue, scalarType, - u32, u32Bits, } from '../../../../util/conversion.js'; import { allInputSources, onlyConstInputSource, run } from '../expression.js'; @@ -221,59 +219,137 @@ Bitwise-or. Component-wise when T is a vector. await run(t, compoundBinary('|='), [type, type], type, t.params, cases); }); -function makeBitwiseAndCases(inputType: string) { - const V = inputType === 'i32' ? i32 : u32; - const cases = [ - // Static patterns +/** Manually calculated bitwise-and cases used a check that the CTS test is correct */ +const kBitwiseAndStaticPatterns = { + 32: [ { - input: [V(0b00000000000000000000000000000000), V(0b00000000000000000000000000000000)], - expected: V(0b00000000000000000000000000000000), + input: [0b00000000000000000000000000000000, 0b00000000000000000000000000000000], + expected: 0b00000000000000000000000000000000, }, { - input: [V(0b11111111111111111111111111111111), V(0b00000000000000000000000000000000)], - expected: V(0b00000000000000000000000000000000), + input: [0b11111111111111111111111111111111, 0b00000000000000000000000000000000], + expected: 0b00000000000000000000000000000000, }, { - input: [V(0b00000000000000000000000000000000), V(0b11111111111111111111111111111111)], - expected: V(0b00000000000000000000000000000000), + input: [0b00000000000000000000000000000000, 0b11111111111111111111111111111111], + expected: 0b00000000000000000000000000000000, }, { - input: [V(0b11111111111111111111111111111111), V(0b11111111111111111111111111111111)], - expected: V(0b11111111111111111111111111111111), + input: [0b11111111111111111111111111111111, 0b11111111111111111111111111111111], + expected: 0b11111111111111111111111111111111, }, { - input: [V(0b10100100010010100100010010100100), V(0b00000000000000000000000000000000)], - expected: V(0b00000000000000000000000000000000), + input: [0b10100100010010100100010010100100, 0b00000000000000000000000000000000], + expected: 0b00000000000000000000000000000000, }, { - input: [V(0b10100100010010100100010010100100), V(0b11111111111111111111111111111111)], - expected: V(0b10100100010010100100010010100100), + input: [0b10100100010010100100010010100100, 0b11111111111111111111111111111111], + expected: 0b10100100010010100100010010100100, }, { - input: [V(0b00000000000000000000000000000000), V(0b10100100010010100100010010100100)], - expected: V(0b00000000000000000000000000000000), + input: [0b00000000000000000000000000000000, 0b10100100010010100100010010100100], + expected: 0b00000000000000000000000000000000, }, { - input: [V(0b11111111111111111111111111111111), V(0b10100100010010100100010010100100)], - expected: V(0b10100100010010100100010010100100), + input: [0b11111111111111111111111111111111, 0b10100100010010100100010010100100], + expected: 0b10100100010010100100010010100100, }, { - input: [V(0b01010010001001010010001001010010), V(0b01011011101101011011101101011011)], - expected: V(0b01010010001001010010001001010010), + input: [0b01010010001001010010001001010010, 0b01011011101101011011101101011011], + expected: 0b01010010001001010010001001010010, }, - ]; - // Permute all combinations of a single bit being set for the LHS and all but one bit set for the RHS - for (let i = 0; i < 32; i++) { - const lhs = 1 << i; - for (let j = 0; j < 32; j++) { - const rhs = 0xffffffff ^ (1 << j); - cases.push({ - input: [V(lhs), V(rhs)], - expected: V(lhs & rhs), + ], + 64: [ + { + input: [ + 0b0000000000000000000000000000000000000000000000000000000000000000n, + 0b0000000000000000000000000000000000000000000000000000000000000000n, + ], + expected: 0b0000000000000000000000000000000000000000000000000000000000000000n, + }, + { + input: [ + 0b1111111111111111111111111111111111111111111111111111111111111111n, + 0b0000000000000000000000000000000000000000000000000000000000000000n, + ], + expected: 0b0000000000000000000000000000000000000000000000000000000000000000n, + }, + { + input: [ + 0b0000000000000000000000000000000000000000000000000000000000000000n, + 0b1111111111111111111111111111111111111111111111111111111111111111n, + ], + expected: 0b0000000000000000000000000000000000000000000000000000000000000000n, + }, + { + input: [ + 0b1111111111111111111111111111111111111111111111111111111111111111n, + 0b1111111111111111111111111111111111111111111111111111111111111111n, + ], + expected: 0b1111111111111111111111111111111111111111111111111111111111111111n, + }, + { + input: [ + 0b1010010001001010010001001010010010100100010010100100010010100100n, + 0b0000000000000000000000000000000000000000000000000000000000000000n, + ], + expected: 0b0000000000000000000000000000000000000000000000000000000000000000n, + }, + { + input: [ + 0b1010010001001010010001001010010010100100010010100100010010100100n, + 0b1111111111111111111111111111111111111111111111111111111111111111n, + ], + expected: 0b1010010001001010010001001010010010100100010010100100010010100100n, + }, + { + input: [ + 0b0000000000000000000000000000000000000000000000000000000000000000n, + 0b1010010001001010010001001010010010100100010010100100010010100100n, + ], + expected: 0b0000000000000000000000000000000000000000000000000000000000000000n, + }, + { + input: [ + 0b1111111111111111111111111111111111111111111111111111111111111111n, + 0b1010010001001010010001001010010010100100010010100100010010100100n, + ], + expected: 0b1010010001001010010001001010010010100100010010100100010010100100n, + }, + { + input: [ + 0b0101001000100101001000100101001001010010001001010010001001010010n, + 0b0101101110110101101110110101101101011011101101011011101101011011n, + ], + expected: 0b0101001000100101001000100101001001010010001001010010001001010010n, + }, + ], +}; + +/** @returns a set of bitwise-or cases for the specific input type */ +function makeBitwiseAndCases(inputType: string) { + const impl = scalarImplForInputType(inputType); + const indices = + impl.size === 64 ? [...Array(impl.size).keys()].map(BigInt) : [...Array(impl.size).keys()]; + + return [ + ...kBitwiseAndStaticPatterns[impl.size].map(c => { + return { + input: c.input.map(impl.builder), + expected: impl.builder(c.expected), + }; + }), + // Permute all combinations of a single bit being set for the LHS and all but one bit set for the RHS + ...indices.flatMap(i => { + const lhs = typeof i === 'bigint' ? 1n << i : 1 << i; + return indices.map(j => { + const rhs = typeof j === 'bigint' ? 0xffffffffffffffffn ^ (1n << j) : 0xffffffff ^ (1 << j); + assert(typeof lhs === typeof rhs); + const result = typeof lhs === 'bigint' ? lhs & (rhs as bigint) : lhs & (rhs as number); + return { input: [impl.builder(lhs), impl.builder(rhs)], expected: impl.builder(result) }; }); - } - } - return cases; + }), + ]; } g.test('bitwise_and') @@ -281,21 +357,25 @@ g.test('bitwise_and') .desc( ` e1 & e2: T -T is i32, u32, vecN, or vecN +T is i32, u32, AbstractInt, vecN, vecN, or vecN Bitwise-and. Component-wise when T is a vector. ` ) .params(u => u - .combine('type', ['i32', 'u32'] as const) + .combine('type', ['i32', 'u32', 'abstract-int'] as const) .combine('inputSource', allInputSources) .combine('vectorize', [undefined, 2, 3, 4] as const) ) .fn(async t => { + t.skipIf( + t.params.type === 'abstract-int' && !onlyConstInputSource.includes(t.params.inputSource) + ); const type = scalarType(t.params.type); const cases = makeBitwiseAndCases(t.params.type); - await run(t, binary('&'), [type, type], type, t.params, cases); + const builder = t.params.type === 'abstract-int' ? abstractIntBinary('&') : binary('&'); + await run(t, builder, [type, type], type, t.params, cases); }); g.test('bitwise_and_compound')