Skip to content

Commit

Permalink
wgsl: Implement AbstractInt bitwise-and execution tests (#3436)
Browse files Browse the repository at this point in the history
Issue #1631
  • Loading branch information
zoddicus authored Mar 11, 2024
1 parent 11d3770 commit d5ce940
Showing 1 changed file with 119 additions and 39 deletions.
158 changes: 119 additions & 39 deletions src/webgpu/shader/execution/expression/binary/bitwise.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -221,81 +219,163 @@ 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')
.specURL('https://www.w3.org/TR/WGSL/#bit-expr')
.desc(
`
e1 & e2: T
T is i32, u32, vecN<i32>, or vecN<u32>
T is i32, u32, AbstractInt, vecN<i32>, vecN<u32>, or vecN<AbstractInt>
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')
Expand Down

0 comments on commit d5ce940

Please sign in to comment.