-
Notifications
You must be signed in to change notification settings - Fork 89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add executions tests for unary indirection #3304
Add executions tests for unary indirection #3304
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests look good. Some suggestions to reduce the verbosity / improve readability.
|
||
// All the ways to deref an expression | ||
const kDerefTypes = [ | ||
'DerefAddressOfIdentifier', // *(&a) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: The WGSL spec uses the term indirection
. Maybe Indir
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I kept trying to rename things, but in the end, I think I'm going to keep "deref" because this is the name of the operation: we "dereference" pointers, we don't "indirect" them.
|
||
// All the ways to deref an expression | ||
const kDerefTypes = [ | ||
'DerefAddressOfIdentifier', // *(&a) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: most strings that end up in case parameters are snake_case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
} | ||
|
||
// Returns deref expression for identifier 'a' or pointer 'p' based on deref type | ||
function deref(derefType: DerefType): string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Turn kDerefTypes
into a map? The values can hold these helpers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure how to do that, and to define a type like:
type DerefType = (typeof kDerefTypes)[number];
Also, I somewhat prefer keeping is as an enum-like.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I meant:
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);
});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like that! Done.
); | ||
} | ||
|
||
function derefIndexBuilder( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These guys are only used once. Suggest inlining into the place of usage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
b4e4e28
to
de84b48
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
Also tests deref followed by index/member access, including pointer_composite_access syntax if supported.
dec78de
to
6fcf053
Compare
Also tests deref followed by index/member access, including pointer_composite_access syntax if supported.
Issue: #3225
Requirements for PR author:
.unimplemented()
./** documented */
and new helper files are found inhelper_index.txt
.Requirements for reviewer sign-off:
When landing this PR, be sure to make any necessary issue status updates.