From 5f049af73f5a90ae9db1b6ac0c2d9611e670bc9e Mon Sep 17 00:00:00 2001 From: Brandon Jones <bajones@chromium.org> Date: Wed, 13 Mar 2024 15:01:33 -0700 Subject: [PATCH 1/4] Add validation test for min/max builtin functions --- src/webgpu/listing_meta.json | 6 ++ .../expression/call/builtin/max.spec.ts | 85 +++++++++++++++++++ .../expression/call/builtin/min.spec.ts | 85 +++++++++++++++++++ 3 files changed, 176 insertions(+) create mode 100644 src/webgpu/shader/validation/expression/call/builtin/max.spec.ts create mode 100644 src/webgpu/shader/validation/expression/call/builtin/min.spec.ts diff --git a/src/webgpu/listing_meta.json b/src/webgpu/listing_meta.json index e6bf7b75b652..8305c360c7f5 100644 --- a/src/webgpu/listing_meta.json +++ b/src/webgpu/listing_meta.json @@ -1909,6 +1909,12 @@ "webgpu:shader,validation,expression,call,builtin,log:integer_argument:*": { "subcaseMS": 1.134 }, "webgpu:shader,validation,expression,call,builtin,log:must_use:*": { "subcaseMS": 1597.590 }, "webgpu:shader,validation,expression,call,builtin,log:values:*": { "subcaseMS": 0.291 }, + "webgpu:shader,validation,expression,call,builtin,max:bad_args:*": { "subcaseMS": 79.423 }, + "webgpu:shader,validation,expression,call,builtin,max:must_use:*": { "subcaseMS": 8.286 }, + "webgpu:shader,validation,expression,call,builtin,max:values:*": { "subcaseMS": 260241.074 }, + "webgpu:shader,validation,expression,call,builtin,min:bad_args:*": { "subcaseMS": 40.137 }, + "webgpu:shader,validation,expression,call,builtin,min:must_use:*": { "subcaseMS": 3.899 }, + "webgpu:shader,validation,expression,call,builtin,min:values:*": { "subcaseMS": 246733.594 }, "webgpu:shader,validation,expression,call,builtin,modf:integer_argument:*": { "subcaseMS": 1.089 }, "webgpu:shader,validation,expression,call,builtin,modf:values:*": { "subcaseMS": 1.866 }, "webgpu:shader,validation,expression,call,builtin,pack4xI8:args:*": { "subcaseMS": 36.226 }, diff --git a/src/webgpu/shader/validation/expression/call/builtin/max.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/max.spec.ts new file mode 100644 index 000000000000..a1cfabeb00c0 --- /dev/null +++ b/src/webgpu/shader/validation/expression/call/builtin/max.spec.ts @@ -0,0 +1,85 @@ +const builtin = 'max'; +export const description = ` +Validation tests for the ${builtin}() builtin. +`; + +import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; +import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; +import { + Type, + kAllNumericScalarsAndVectors, + scalarTypeOf, +} from '../../../../../util/conversion.js'; +import { ShaderValidationTest } from '../../../shader_validation_test.js'; + +import { + fullRangeForType, + kConstantAndOverrideStages, + stageSupportsType, + validateConstOrOverrideBuiltinEval, +} from './const_override_validation.js'; + +export const g = makeTestGroup(ShaderValidationTest); + +const kValuesTypes = objectsToRecord(kAllNumericScalarsAndVectors); + +g.test('values') + .desc( + ` +Validates that constant evaluation and override evaluation of ${builtin}() never errors +` + ) + .params(u => + u + .combine('stage', kConstantAndOverrideStages) + .combine('type', keysOf(kValuesTypes)) + .filter(u => stageSupportsType(u.stage, kValuesTypes[u.type])) + .beginSubcases() + .expand('a', u => fullRangeForType(kValuesTypes[u.type])) + .expand('b', u => fullRangeForType(kValuesTypes[u.type])) + ) + .beforeAllSubcases(t => { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { + t.selectDeviceOrSkipTestCase('shader-f16'); + } + }) + .fn(t => { + const type = kValuesTypes[t.params.type]; + const expectedResult = true; // should never error + validateConstOrOverrideBuiltinEval( + t, + builtin, + expectedResult, + [type.create(t.params.a), type.create(t.params.b)], + t.params.stage + ); + }); + +const kGoodArgs = '(1.1, 2.2)'; +const kBadArgs = { + no_parens: '', + // Bad number of args + '0args': '()', + '1arg': '(1.0)', + // Bad value for arg 0 + '0bool': '(false, 1.0)', + '0array': '(array(1.1,2.2), 1.0)', + '0struct': '(modf(2.2), 1.0)', + // Bad value for arg 1 + '1bool': '(1.0, true)', + '1array': '(1.0, array(1.1,2.2))', + '1struct': '(1.0, modf(2.2))', +}; + +g.test('bad_args') + .desc(`Test compilation failure of ${builtin} with bad arguments`) + .params(u => u.combine('arg', keysOf(kBadArgs))) + .fn(t => { + t.expectCompileResult(false, `const c = ${builtin}${kBadArgs[t.params.arg]};`); + }); + +g.test('must_use') + .desc(`Result of ${builtin} must be used`) + .fn(t => { + t.expectCompileResult(false, `fn f() { ${builtin}${kGoodArgs}; }`); + }); diff --git a/src/webgpu/shader/validation/expression/call/builtin/min.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/min.spec.ts new file mode 100644 index 000000000000..f31d8971e133 --- /dev/null +++ b/src/webgpu/shader/validation/expression/call/builtin/min.spec.ts @@ -0,0 +1,85 @@ +const builtin = 'min'; +export const description = ` +Validation tests for the ${builtin}() builtin. +`; + +import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; +import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; +import { + Type, + kAllNumericScalarsAndVectors, + scalarTypeOf, +} from '../../../../../util/conversion.js'; +import { ShaderValidationTest } from '../../../shader_validation_test.js'; + +import { + fullRangeForType, + kConstantAndOverrideStages, + stageSupportsType, + validateConstOrOverrideBuiltinEval, +} from './const_override_validation.js'; + +export const g = makeTestGroup(ShaderValidationTest); + +const kValuesTypes = objectsToRecord(kAllNumericScalarsAndVectors); + +g.test('values') + .desc( + ` +Validates that constant evaluation and override evaluation of ${builtin}() never errors +` + ) + .params(u => + u + .combine('stage', kConstantAndOverrideStages) + .combine('type', keysOf(kValuesTypes)) + .filter(u => stageSupportsType(u.stage, kValuesTypes[u.type])) + .beginSubcases() + .expand('a', u => fullRangeForType(kValuesTypes[u.type])) + .expand('b', u => fullRangeForType(kValuesTypes[u.type])) + ) + .beforeAllSubcases(t => { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { + t.selectDeviceOrSkipTestCase('shader-f16'); + } + }) + .fn(t => { + const type = kValuesTypes[t.params.type]; + const expectedResult = true; // should never error + validateConstOrOverrideBuiltinEval( + t, + builtin, + expectedResult, + [type.create(t.params.a), type.create(t.params.b)], + t.params.stage + ); + }); + +const kGoodArgs = '(1.1, 2.2)'; +const kBadArgs = { + no_parens: '', + // Bad number of args + '0args': '()', + '1arg': '(1.0)', + // Bad value for arg 0 + '0bool': '(false, 1.0)', + '0array': '(array(1.1,2.2), 1.0)', + '0struct': '(modf(2.2), 1.0)', + // Bad value for arg 1 + '1bool': '(1.0, true)', + '1array': '(1.0, array(1.1,2.2))', + '1struct': '(1.0, modf(2.2))', +}; + +g.test('bad_args') + .desc(`Test compilation failure of ${builtin} with bad arguments`) + .params(u => u.combine('arg', keysOf(kBadArgs))) + .fn(t => { + t.expectCompileResult(false, `const c = ${builtin}${kBadArgs[t.params.arg]};`); + }); + +g.test('must_use') + .desc(`Result of ${builtin} must be used`) + .fn(t => { + t.expectCompileResult(false, `fn f() { ${builtin}${kGoodArgs}; }`); + }); From fcb464a3964abaeca1a920e5d72283c7bf6a9cbf Mon Sep 17 00:00:00 2001 From: Brandon Jones <bajones@chromium.org> Date: Thu, 14 Mar 2024 15:23:51 -0700 Subject: [PATCH 2/4] Address feedback from @dneto --- src/webgpu/listing_meta.json | 2 + .../expression/call/builtin/max.spec.ts | 40 +++++++++++-------- .../expression/call/builtin/min.spec.ts | 40 +++++++++++-------- 3 files changed, 48 insertions(+), 34 deletions(-) diff --git a/src/webgpu/listing_meta.json b/src/webgpu/listing_meta.json index 8305c360c7f5..c1466abd0087 100644 --- a/src/webgpu/listing_meta.json +++ b/src/webgpu/listing_meta.json @@ -1909,9 +1909,11 @@ "webgpu:shader,validation,expression,call,builtin,log:integer_argument:*": { "subcaseMS": 1.134 }, "webgpu:shader,validation,expression,call,builtin,log:must_use:*": { "subcaseMS": 1597.590 }, "webgpu:shader,validation,expression,call,builtin,log:values:*": { "subcaseMS": 0.291 }, + "webgpu:shader,validation,expression,call,builtin,max:args:*": { "subcaseMS": 77.529 }, "webgpu:shader,validation,expression,call,builtin,max:bad_args:*": { "subcaseMS": 79.423 }, "webgpu:shader,validation,expression,call,builtin,max:must_use:*": { "subcaseMS": 8.286 }, "webgpu:shader,validation,expression,call,builtin,max:values:*": { "subcaseMS": 260241.074 }, + "webgpu:shader,validation,expression,call,builtin,min:args:*": { "subcaseMS": 67.260 }, "webgpu:shader,validation,expression,call,builtin,min:bad_args:*": { "subcaseMS": 40.137 }, "webgpu:shader,validation,expression,call,builtin,min:must_use:*": { "subcaseMS": 3.899 }, "webgpu:shader,validation,expression,call,builtin,min:values:*": { "subcaseMS": 246733.594 }, diff --git a/src/webgpu/shader/validation/expression/call/builtin/max.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/max.spec.ts index a1cfabeb00c0..7a1df57e5795 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/max.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/max.spec.ts @@ -55,31 +55,37 @@ Validates that constant evaluation and override evaluation of ${builtin}() never ); }); -const kGoodArgs = '(1.1, 2.2)'; -const kBadArgs = { - no_parens: '', +const kArgCases = { + 'good': '(1.1, 2.2)', + bad_no_parens: '', // Bad number of args - '0args': '()', - '1arg': '(1.0)', + 'bad_0args': '()', + 'bad_1arg': '(1.0)', + 'bad_3arg': '(1.0, 2.0, 3.0)', // Bad value for arg 0 - '0bool': '(false, 1.0)', - '0array': '(array(1.1,2.2), 1.0)', - '0struct': '(modf(2.2), 1.0)', - // Bad value for arg 1 - '1bool': '(1.0, true)', - '1array': '(1.0, array(1.1,2.2))', - '1struct': '(1.0, modf(2.2))', + 'bad_0bool': '(false, 1.0)', + 'bad_0array': '(array(1.1,2.2), 1.0)', + 'bad_0struct': '(modf(2.2), 1.0)', + // Bad value type for arg 1 + 'bad_1bool': '(1.0, true)', + 'bad_1array': '(1.0, array(1.1,2.2))', + 'bad_1struct': '(1.0, modf(2.2))', }; -g.test('bad_args') - .desc(`Test compilation failure of ${builtin} with bad arguments`) - .params(u => u.combine('arg', keysOf(kBadArgs))) +g.test('args') + .desc(`Test compilation failure of ${builtin} with variously shaped and typed arguments`) + .params(u => u.combine('arg', keysOf(kArgCases))) .fn(t => { - t.expectCompileResult(false, `const c = ${builtin}${kBadArgs[t.params.arg]};`); + t.expectCompileResult( + t.params.arg === 'good', + `const c = ${builtin}${kArgCases[t.params.arg]};` + ); }); g.test('must_use') .desc(`Result of ${builtin} must be used`) + .params(u => u.combine('use', [true, false])) .fn(t => { - t.expectCompileResult(false, `fn f() { ${builtin}${kGoodArgs}; }`); + const use_it = t.params.use ? '_ = ' : ''; + t.expectCompileResult(t.params.use, `fn f() { ${use_it}${builtin}${kArgCases['good']}; }`); }); diff --git a/src/webgpu/shader/validation/expression/call/builtin/min.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/min.spec.ts index f31d8971e133..d4b3673b7d0e 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/min.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/min.spec.ts @@ -55,31 +55,37 @@ Validates that constant evaluation and override evaluation of ${builtin}() never ); }); -const kGoodArgs = '(1.1, 2.2)'; -const kBadArgs = { - no_parens: '', +const kArgCases = { + 'good': '(1.1, 2.2)', + bad_no_parens: '', // Bad number of args - '0args': '()', - '1arg': '(1.0)', + 'bad_0args': '()', + 'bad_1arg': '(1.0)', + 'bad_3arg': '(1.0, 2.0, 3.0)', // Bad value for arg 0 - '0bool': '(false, 1.0)', - '0array': '(array(1.1,2.2), 1.0)', - '0struct': '(modf(2.2), 1.0)', - // Bad value for arg 1 - '1bool': '(1.0, true)', - '1array': '(1.0, array(1.1,2.2))', - '1struct': '(1.0, modf(2.2))', + 'bad_0bool': '(false, 1.0)', + 'bad_0array': '(array(1.1,2.2), 1.0)', + 'bad_0struct': '(modf(2.2), 1.0)', + // Bad value type for arg 1 + 'bad_1bool': '(1.0, true)', + 'bad_1array': '(1.0, array(1.1,2.2))', + 'bad_1struct': '(1.0, modf(2.2))', }; -g.test('bad_args') - .desc(`Test compilation failure of ${builtin} with bad arguments`) - .params(u => u.combine('arg', keysOf(kBadArgs))) +g.test('args') + .desc(`Test compilation failure of ${builtin} with variously shaped and typed arguments`) + .params(u => u.combine('arg', keysOf(kArgCases))) .fn(t => { - t.expectCompileResult(false, `const c = ${builtin}${kBadArgs[t.params.arg]};`); + t.expectCompileResult( + t.params.arg === 'good', + `const c = ${builtin}${kArgCases[t.params.arg]};` + ); }); g.test('must_use') .desc(`Result of ${builtin} must be used`) + .params(u => u.combine('use', [true, false])) .fn(t => { - t.expectCompileResult(false, `fn f() { ${builtin}${kGoodArgs}; }`); + const use_it = t.params.use ? '_ = ' : ''; + t.expectCompileResult(t.params.use, `fn f() { ${use_it}${builtin}${kArgCases['good']}; }`); }); From 0e90becc854a38c80d1c84419a11df4516c7dfee Mon Sep 17 00:00:00 2001 From: Brandon Jones <tojiro@gmail.com> Date: Fri, 15 Mar 2024 13:34:05 -0700 Subject: [PATCH 3/4] Reduce number of values tested (was timing out in browser) --- .../expression/call/builtin/max.spec.ts | 24 +++++++++---------- .../expression/call/builtin/min.spec.ts | 24 +++++++++---------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/webgpu/shader/validation/expression/call/builtin/max.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/max.spec.ts index 7a1df57e5795..f32589fcf673 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/max.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/max.spec.ts @@ -35,8 +35,8 @@ Validates that constant evaluation and override evaluation of ${builtin}() never .combine('type', keysOf(kValuesTypes)) .filter(u => stageSupportsType(u.stage, kValuesTypes[u.type])) .beginSubcases() - .expand('a', u => fullRangeForType(kValuesTypes[u.type])) - .expand('b', u => fullRangeForType(kValuesTypes[u.type])) + .expand('a', u => fullRangeForType(kValuesTypes[u.type], 5)) + .expand('b', u => fullRangeForType(kValuesTypes[u.type], 5)) ) .beforeAllSubcases(t => { if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { @@ -56,20 +56,20 @@ Validates that constant evaluation and override evaluation of ${builtin}() never }); const kArgCases = { - 'good': '(1.1, 2.2)', + good: '(1.1, 2.2)', bad_no_parens: '', // Bad number of args - 'bad_0args': '()', - 'bad_1arg': '(1.0)', - 'bad_3arg': '(1.0, 2.0, 3.0)', + bad_0args: '()', + bad_1arg: '(1.0)', + bad_3arg: '(1.0, 2.0, 3.0)', // Bad value for arg 0 - 'bad_0bool': '(false, 1.0)', - 'bad_0array': '(array(1.1,2.2), 1.0)', - 'bad_0struct': '(modf(2.2), 1.0)', + bad_0bool: '(false, 1.0)', + bad_0array: '(array(1.1,2.2), 1.0)', + bad_0struct: '(modf(2.2), 1.0)', // Bad value type for arg 1 - 'bad_1bool': '(1.0, true)', - 'bad_1array': '(1.0, array(1.1,2.2))', - 'bad_1struct': '(1.0, modf(2.2))', + bad_1bool: '(1.0, true)', + bad_1array: '(1.0, array(1.1,2.2))', + bad_1struct: '(1.0, modf(2.2))', }; g.test('args') diff --git a/src/webgpu/shader/validation/expression/call/builtin/min.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/min.spec.ts index d4b3673b7d0e..2222c44e9228 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/min.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/min.spec.ts @@ -35,8 +35,8 @@ Validates that constant evaluation and override evaluation of ${builtin}() never .combine('type', keysOf(kValuesTypes)) .filter(u => stageSupportsType(u.stage, kValuesTypes[u.type])) .beginSubcases() - .expand('a', u => fullRangeForType(kValuesTypes[u.type])) - .expand('b', u => fullRangeForType(kValuesTypes[u.type])) + .expand('a', u => fullRangeForType(kValuesTypes[u.type], 5)) + .expand('b', u => fullRangeForType(kValuesTypes[u.type], 5)) ) .beforeAllSubcases(t => { if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { @@ -56,20 +56,20 @@ Validates that constant evaluation and override evaluation of ${builtin}() never }); const kArgCases = { - 'good': '(1.1, 2.2)', + good: '(1.1, 2.2)', bad_no_parens: '', // Bad number of args - 'bad_0args': '()', - 'bad_1arg': '(1.0)', - 'bad_3arg': '(1.0, 2.0, 3.0)', + bad_0args: '()', + bad_1arg: '(1.0)', + bad_3arg: '(1.0, 2.0, 3.0)', // Bad value for arg 0 - 'bad_0bool': '(false, 1.0)', - 'bad_0array': '(array(1.1,2.2), 1.0)', - 'bad_0struct': '(modf(2.2), 1.0)', + bad_0bool: '(false, 1.0)', + bad_0array: '(array(1.1,2.2), 1.0)', + bad_0struct: '(modf(2.2), 1.0)', // Bad value type for arg 1 - 'bad_1bool': '(1.0, true)', - 'bad_1array': '(1.0, array(1.1,2.2))', - 'bad_1struct': '(1.0, modf(2.2))', + bad_1bool: '(1.0, true)', + bad_1array: '(1.0, array(1.1,2.2))', + bad_1struct: '(1.0, modf(2.2))', }; g.test('args') From fee7357bebd67e19c5cbb3cf5df3314f6143a8a6 Mon Sep 17 00:00:00 2001 From: Brandon Jones <tojiro@gmail.com> Date: Fri, 15 Mar 2024 13:45:33 -0700 Subject: [PATCH 4/4] Removing non-existent tests from listing_meta.json --- src/webgpu/listing_meta.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/webgpu/listing_meta.json b/src/webgpu/listing_meta.json index c1466abd0087..591636e87af9 100644 --- a/src/webgpu/listing_meta.json +++ b/src/webgpu/listing_meta.json @@ -1910,11 +1910,9 @@ "webgpu:shader,validation,expression,call,builtin,log:must_use:*": { "subcaseMS": 1597.590 }, "webgpu:shader,validation,expression,call,builtin,log:values:*": { "subcaseMS": 0.291 }, "webgpu:shader,validation,expression,call,builtin,max:args:*": { "subcaseMS": 77.529 }, - "webgpu:shader,validation,expression,call,builtin,max:bad_args:*": { "subcaseMS": 79.423 }, "webgpu:shader,validation,expression,call,builtin,max:must_use:*": { "subcaseMS": 8.286 }, "webgpu:shader,validation,expression,call,builtin,max:values:*": { "subcaseMS": 260241.074 }, "webgpu:shader,validation,expression,call,builtin,min:args:*": { "subcaseMS": 67.260 }, - "webgpu:shader,validation,expression,call,builtin,min:bad_args:*": { "subcaseMS": 40.137 }, "webgpu:shader,validation,expression,call,builtin,min:must_use:*": { "subcaseMS": 3.899 }, "webgpu:shader,validation,expression,call,builtin,min:values:*": { "subcaseMS": 246733.594 }, "webgpu:shader,validation,expression,call,builtin,modf:integer_argument:*": { "subcaseMS": 1.089 },