Skip to content

Commit

Permalink
Add executions tests for unary indirection (#3304)
Browse files Browse the repository at this point in the history
Also tests deref followed by index/member access, including
pointer_composite_access syntax if supported.
  • Loading branch information
amaiorano authored Jan 25, 2024
1 parent 482b442 commit 2f6a77f
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/webgpu/listing_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -1536,6 +1536,9 @@
"webgpu:shader,execution,expression,unary,bool_conversion:i32:*": { "subcaseMS": 8.219 },
"webgpu:shader,execution,expression,unary,bool_conversion:u32:*": { "subcaseMS": 7.401 },
"webgpu:shader,execution,expression,unary,bool_logical:negation:*": { "subcaseMS": 6.413 },
"webgpu:shader,execution,expression,unary,indirection:deref:*": { "subcaseMS": 0.0 },
"webgpu:shader,execution,expression,unary,indirection:deref_index:*": { "subcaseMS": 0.0 },
"webgpu:shader,execution,expression,unary,indirection:deref_member:*": { "subcaseMS": 0.0 },
"webgpu:shader,execution,expression,unary,f16_arithmetic:negation:*": { "subcaseMS": 117.604 },
"webgpu:shader,execution,expression,unary,f16_conversion:bool:*": { "subcaseMS": 34.694 },
"webgpu:shader,execution,expression,unary,f16_conversion:f16:*": { "subcaseMS": 36.013 },
Expand Down
2 changes: 2 additions & 0 deletions src/webgpu/shader/execution/expression/expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ export const allInputSources: InputSource[] = ['const', 'uniform', 'storage_r',
/** Just constant input source */
export const onlyConstInputSource: InputSource[] = ['const'];

export const allButConstInputSource: InputSource[] = ['uniform', 'storage_r', 'storage_rw'];

/** Configuration for running a expression test */
export type Config = {
// Where the input values are read from
Expand Down
156 changes: 156 additions & 0 deletions src/webgpu/shader/execution/expression/unary/indirection.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
export const description = `
Execution Tests for unary indirection (dereference)
`;

import { makeTestGroup } from '../../../../../common/framework/test_group.js';
import { keysOf } from '../../../../../common/util/data_tables.js';
import { GPUTest } from '../../../../gpu_test.js';
import { ScalarKind, scalarType } from '../../../../util/conversion.js';
import { sparseScalarF32Range } from '../../../../util/math.js';
import {
allButConstInputSource,
basicExpressionWithPredeclarationBuilder,
run,
} from '../expression.js';

export const g = makeTestGroup(GPUTest);

// All the ways to deref an expression
const kDerefCases = {
deref_address_of_identifier: {
wgsl: '(*(&a))',
requires_pointer_composite_access: false,
},
deref_pointer: {
wgsl: '(*p)',
requires_pointer_composite_access: false,
},
address_of_identifier: {
wgsl: '(&a)',
requires_pointer_composite_access: true,
},
pointer: {
wgsl: 'p',
requires_pointer_composite_access: true,
},
};

g.test('deref')
.specURL('https://www.w3.org/TR/WGSL/#indirection')
.desc(
`
Expression: *e
Pointer expression dereference.
`
)
.params(u =>
u
.combine('inputSource', allButConstInputSource)
.combine('vectorize', [undefined, 2, 3, 4] as const)
.combine('scalarType', ['u32', 'i32', 'f32'] as ScalarKind[])
.combine('derefType', keysOf(kDerefCases))
.filter(p => !kDerefCases[p.derefType].requires_pointer_composite_access)
)
.fn(async t => {
const ty = scalarType(t.params.scalarType);
const cases = sparseScalarF32Range().map(e => {
return { input: ty.create(e), expected: ty.create(e) };
});
const elemType = ty.kind;
const type = t.params.vectorize ? `vec${t.params.vectorize}<${elemType}>` : elemType;
const shaderBuilder = basicExpressionWithPredeclarationBuilder(
value => `get_dereferenced_value(${value})`,
`fn get_dereferenced_value(value: ${type}) -> ${type} {
var a = value;
let p = &a;
return ${kDerefCases[t.params.derefType].wgsl};
}`
);
await run(t, shaderBuilder, [ty], ty, t.params, cases);
});

g.test('deref_index')
.specURL('https://www.w3.org/TR/WGSL/#logical-expr')
.desc(
`
Expression: (*e)[index]
Pointer expression dereference as lhs of index accessor expression
`
)
.params(u =>
u
.combine('inputSource', allButConstInputSource)
.combine('vectorize', [undefined, 2, 3, 4] as const)
.combine('scalarType', ['i32', 'f32'] as ScalarKind[])
.combine('derefType', keysOf(kDerefCases))
)
.fn(async t => {
if (
kDerefCases[t.params.derefType].requires_pointer_composite_access &&
!t.hasLanguageFeature('pointer_composite_access')
) {
return;
}

const ty = scalarType(t.params.scalarType);
const cases = sparseScalarF32Range().map(e => {
return { input: ty.create(e), expected: ty.create(e) };
});
const elemType = ty.kind;
const type = t.params.vectorize ? `vec${t.params.vectorize}<${elemType}>` : elemType;
const shaderBuilder = basicExpressionWithPredeclarationBuilder(
value => `get_dereferenced_value(${value})`,
`fn get_dereferenced_value(value: ${type}) -> ${type} {
var a = array<${type}, 1>(value);
let p = &a;
return ${kDerefCases[t.params.derefType].wgsl}[0];
}`
);
await run(t, shaderBuilder, [ty], ty, t.params, cases);
});

g.test('deref_member')
.specURL('https://www.w3.org/TR/WGSL/#logical-expr')
.desc(
`
Expression: (*e).member
Pointer expression dereference as lhs of member accessor expression
`
)
.params(u =>
u
.combine('inputSource', allButConstInputSource)
.combine('vectorize', [undefined, 2, 3, 4] as const)
.combine('scalarType', ['i32', 'f32'] as ScalarKind[])
.combine('derefType', keysOf(kDerefCases))
)
.fn(async t => {
if (
kDerefCases[t.params.derefType].requires_pointer_composite_access &&
!t.hasLanguageFeature('pointer_composite_access')
) {
return;
}

const ty = scalarType(t.params.scalarType);
const cases = sparseScalarF32Range().map(e => {
return { input: ty.create(e), expected: ty.create(e) };
});
const elemType = ty.kind;
const type = t.params.vectorize ? `vec${t.params.vectorize}<${elemType}>` : elemType;
const shaderBuilder = basicExpressionWithPredeclarationBuilder(
value => `get_dereferenced_value(${value})`,
`struct S {
m : ${type}
}
fn get_dereferenced_value(value: ${type}) -> ${type} {
var a = S(value);
let p = &a;
return ${kDerefCases[t.params.derefType].wgsl}.m;
}`
);
await run(t, shaderBuilder, [ty], ty, t.params, cases);
});

0 comments on commit 2f6a77f

Please sign in to comment.