Skip to content

Commit

Permalink
Merge branch 'main' into test-create-pl-null-bgl
Browse files Browse the repository at this point in the history
  • Loading branch information
Jiawei-Shao committed Dec 6, 2024
2 parents 8823381 + 9223c26 commit 9c54a1b
Show file tree
Hide file tree
Showing 14 changed files with 103 additions and 170 deletions.
51 changes: 51 additions & 0 deletions src/webgpu/api/operation/adapter/info.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { makeTestGroup } from '../../../../common/framework/test_group.js';
import { keysOf } from '../../../../common/util/data_tables.js';
import { getGPU } from '../../../../common/util/navigator_gpu.js';
import { assert, objectEquals } from '../../../../common/util/util.js';
import { isPowerOfTwo } from '../../../util/math.js';

export const g = makeTestGroup(Fixture);

Expand Down Expand Up @@ -136,3 +137,53 @@ different orders to make sure that they are consistent regardless of the access
t.expect(objectEquals(deviceInfo, adapterInfo));
}
});

// This can be removed once 'subgroups' lands.
// See https://github.com/gpuweb/gpuweb/pull/4963
interface SubgroupProperties extends GPUAdapterInfo {
subgroupMinSize?: number;
subgroupMaxSize?: number;
}

const kSubgroupMinSizeBound = 4;
const kSubgroupMaxSizeBound = 128;

g.test('subgroup_sizes')
.desc(
`
Verify GPUAdapterInfo.subgroupMinSize, GPUAdapterInfo.subgroupMaxSize.
If the subgroups feature is supported, they must both exist.
If they exist, they must both exist and be powers of two, and
4 <= subgroupMinSize <= subgroupMaxSize <= 128.
`
)
.fn(async t => {
const gpu = getGPU(t.rec);
const adapter = await gpu.requestAdapter();
assert(adapter !== null);
const { subgroupMinSize, subgroupMaxSize } = adapter.info as SubgroupProperties;
// Once 'subgroups' lands, the properties should be defined with default values 4 and 128
// when adapter does not support the feature.
// https://github.com/gpuweb/gpuweb/pull/4963
if (adapter.features.has('subgroups')) {
t.expect(
subgroupMinSize !== undefined,
'GPUAdapterInfo.subgroupMinSize must exist when subgroups supported'
);
t.expect(
subgroupMaxSize !== undefined,
'GPUAdapterInfo.subgroupMaxSize must exist when subgroups supported'
);
}
t.expect(
(subgroupMinSize === undefined) === (subgroupMinSize === undefined),
'GPUAdapterInfo.subgropuMinSize and GPUAdapterInfo.subgroupMaxSize must both be defined, or neither should be'
);
if (subgroupMinSize !== undefined && subgroupMaxSize !== undefined) {
t.expect(isPowerOfTwo(subgroupMinSize));
t.expect(isPowerOfTwo(subgroupMaxSize));
t.expect(kSubgroupMinSizeBound <= subgroupMinSize);
t.expect(subgroupMinSize <= subgroupMaxSize);
t.expect(subgroupMaxSize <= kSubgroupMaxSizeBound);
}
});
17 changes: 17 additions & 0 deletions src/webgpu/api/operation/adapter/requestAdapter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Tests for GPU.requestAdapter.
Test all possible options to requestAdapter.
default, low-power, and high performance should all always return adapters.
forceFallbackAdapter may or may not return an adapter.
invalid featureLevel values should not return an adapter.
GPU.requestAdapter can technically return null for any reason
but we need test functionality so the test requires an adapter except
Expand All @@ -26,6 +27,8 @@ const powerPreferenceModes: Array<GPUPowerPreference | undefined> = [
'high-performance',
];
const forceFallbackOptions: Array<boolean | undefined> = [undefined, false, true];
const validFeatureLevels: Array<string | undefined> = [undefined, 'core', 'compatibility'];
const invalidFeatureLevels: Array<string> = ['cor', 'Core', 'compatability', '', ' '];

async function testAdapter(t: Fixture, adapter: GPUAdapter | null) {
assert(adapter !== null, 'Failed to get adapter.');
Expand Down Expand Up @@ -120,6 +123,20 @@ g.test('requestAdapter')
await testAdapter(t, adapter);
});

g.test('requestAdapter_invalid_featureLevel')
.desc(`request adapter with invalid featureLevel string values return null`)
.params(u => u.combine('featureLevel', [...validFeatureLevels, ...invalidFeatureLevels]))
.fn(async t => {
const { featureLevel } = t.params;
const adapter = await getGPU(t.rec).requestAdapter({ featureLevel });

if (!validFeatureLevels.includes(featureLevel)) {
assert(adapter === null);
} else {
await testAdapter(t, adapter);
}
});

g.test('requestAdapter_no_parameters')
.desc(`request adapter with no parameters`)
.fn(async t => {
Expand Down
9 changes: 3 additions & 6 deletions src/webgpu/listing_meta.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"_comment": "SEMI AUTO-GENERATED. This list is NOT exhaustive. Please read docs/adding_timing_metadata.md.",
"webgpu:api,operation,adapter,info:adapter_info:*": { "subcaseMS": 32.901 },
"webgpu:api,operation,adapter,info:device_matches_adapter:*": { "subcaseMS": 14.708 },
"webgpu:api,operation,adapter,info:same_object:*": { "subcaseMS": 25.153 },
"webgpu:api,operation,adapter,info:subgroup_sizes:*": { "subcaseMS": 18.831 },
"webgpu:api,operation,adapter,requestAdapter:requestAdapter:*": { "subcaseMS": 152.083 },
"webgpu:api,operation,adapter,requestAdapter:requestAdapter_no_parameters:*": { "subcaseMS": 384.601 },
"webgpu:api,operation,adapter,requestDevice:always_returns_device:*": { "subcaseMS": 19.450 },
Expand Down Expand Up @@ -2284,14 +2287,12 @@
"webgpu:shader,validation,expression,call,builtin,quadBroadcast:id_values:*": { "subcaseMS": 7.315 },
"webgpu:shader,validation,expression,call,builtin,quadBroadcast:must_use:*": { "subcaseMS": 41.658 },
"webgpu:shader,validation,expression,call,builtin,quadBroadcast:requires_subgroups:*": { "subcaseMS": 42.565 },
"webgpu:shader,validation,expression,call,builtin,quadBroadcast:requires_subgroups_f16:*": { "subcaseMS": 44.998 },
"webgpu:shader,validation,expression,call,builtin,quadBroadcast:return_type:*": { "subcaseMS": 363.607 },
"webgpu:shader,validation,expression,call,builtin,quadBroadcast:stage:*": { "subcaseMS": 3.050 },
"webgpu:shader,validation,expression,call,builtin,quadSwap:data_type:*": { "subcaseMS": 89.379 },
"webgpu:shader,validation,expression,call,builtin,quadSwap:early_eval:*": { "subcaseMS": 108.243 },
"webgpu:shader,validation,expression,call,builtin,quadSwap:must_use:*": { "subcaseMS": 5.557 },
"webgpu:shader,validation,expression,call,builtin,quadSwap:requires_subgroups:*": { "subcaseMS": 113.624 },
"webgpu:shader,validation,expression,call,builtin,quadSwap:requires_subgroups_f16:*": { "subcaseMS": 12.712 },
"webgpu:shader,validation,expression,call,builtin,quadSwap:return_type:*": { "subcaseMS": 1424.551 },
"webgpu:shader,validation,expression,call,builtin,quadSwap:stage:*": { "subcaseMS": 7.664 },
"webgpu:shader,validation,expression,call,builtin,quantizeToF16:args:*": { "subcaseMS": 1.000 },
Expand Down Expand Up @@ -2377,14 +2378,12 @@
"webgpu:shader,validation,expression,call,builtin,subgroupBroadcast:id_values:*": { "subcaseMS": 7.763 },
"webgpu:shader,validation,expression,call,builtin,subgroupBroadcast:must_use:*": { "subcaseMS": 232.030 },
"webgpu:shader,validation,expression,call,builtin,subgroupBroadcast:requires_subgroups:*": { "subcaseMS": 47.231 },
"webgpu:shader,validation,expression,call,builtin,subgroupBroadcast:requires_subgroups_f16:*": { "subcaseMS": 38.503 },
"webgpu:shader,validation,expression,call,builtin,subgroupBroadcast:return_type:*": { "subcaseMS": 496.031 },
"webgpu:shader,validation,expression,call,builtin,subgroupBroadcast:stage:*": { "subcaseMS": 3.715 },
"webgpu:shader,validation,expression,call,builtin,subgroupBroadcastFirst:data_type:*": { "subcaseMS": 32.168 },
"webgpu:shader,validation,expression,call,builtin,subgroupBroadcastFirst:early_eval:*": { "subcaseMS": 57.922 },
"webgpu:shader,validation,expression,call,builtin,subgroupBroadcastFirst:must_use:*": { "subcaseMS": 36.296 },
"webgpu:shader,validation,expression,call,builtin,subgroupBroadcastFirst:requires_subgroups:*": { "subcaseMS": 42.522 },
"webgpu:shader,validation,expression,call,builtin,subgroupBroadcastFirst:requires_subgroups_f16:*": { "subcaseMS": 47.111 },
"webgpu:shader,validation,expression,call,builtin,subgroupBroadcastFirst:return_type:*": { "subcaseMS": 402.558 },
"webgpu:shader,validation,expression,call,builtin,subgroupBroadcastFirst:stage:*": { "subcaseMS": 2.869 },
"webgpu:shader,validation,expression,call,builtin,subgroupElect:data_type:*": { "subcaseMS": 72.441 },
Expand All @@ -2397,7 +2396,6 @@
"webgpu:shader,validation,expression,call,builtin,subgroupMinMax:early_eval:*": { "subcaseMS": 551.671 },
"webgpu:shader,validation,expression,call,builtin,subgroupMinMax:must_use:*": { "subcaseMS": 4.403 },
"webgpu:shader,validation,expression,call,builtin,subgroupMinMax:requires_subgroups:*": { "subcaseMS": 87.208 },
"webgpu:shader,validation,expression,call,builtin,subgroupMinMax:requires_subgroups_f16:*": { "subcaseMS": 25.190 },
"webgpu:shader,validation,expression,call,builtin,subgroupMinMax:return_type:*": { "subcaseMS": 911.454 },
"webgpu:shader,validation,expression,call,builtin,subgroupMinMax:stage:*": { "subcaseMS": 6.395 },
"webgpu:shader,validation,expression,call,builtin,subgroupMul:data_type:*": { "subcaseMS": 45.396 },
Expand All @@ -2412,7 +2410,6 @@
"webgpu:shader,validation,expression,call,builtin,subgroupShuffle:param2_early_eval:*": { "subcaseMS": 133.389 },
"webgpu:shader,validation,expression,call,builtin,subgroupShuffle:param2_type:*": { "subcaseMS": 88.305 },
"webgpu:shader,validation,expression,call,builtin,subgroupShuffle:requires_subgroups:*": { "subcaseMS": 102.779 },
"webgpu:shader,validation,expression,call,builtin,subgroupShuffle:requires_subgroups_f16:*": { "subcaseMS": 13.121 },
"webgpu:shader,validation,expression,call,builtin,subgroupShuffle:return_type:*": { "subcaseMS": 1930.309 },
"webgpu:shader,validation,expression,call,builtin,subgroupShuffle:stage:*": { "subcaseMS": 9.527 },
"webgpu:shader,validation,expression,call,builtin,tan:args:*": { "subcaseMS": 43.560 },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -547,12 +547,12 @@ g.test('fragment,all_active')
.fn(async t => {
const numInputs = t.params.size[0] * t.params.size[1];

interface SubgroupLimits extends GPUSupportedLimits {
minSubgroupSize: number;
interface SubgroupProperties extends GPUAdapterInfo {
subgroupMinSize: number;
}
const { minSubgroupSize } = t.device.limits as SubgroupLimits;
const { subgroupMinSize } = t.device.adapterInfo as SubgroupProperties;
const innerTexels = (t.params.size[0] - 1) * (t.params.size[1] - 1);
t.skipIf(innerTexels < minSubgroupSize, 'Too few texels to be reliable');
t.skipIf(innerTexels < subgroupMinSize, 'Too few texels to be reliable');

const inputData = generateInputData(t.params.case, numInputs, identity(t.params.op));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -444,12 +444,12 @@ g.test('compute,split')
const testcase = kPredicateCases[t.params.predicate];
const wgThreads = t.params.wgSize[0] * t.params.wgSize[1] * t.params.wgSize[2];

interface SubgroupLimits extends GPUSupportedLimits {
minSubgroupSize: number;
maxSubgroupSize: number;
interface SubgroupProperties extends GPUAdapterInfo {
subgroupMinSize: number;
subgroupMaxSize: number;
}
const { minSubgroupSize, maxSubgroupSize } = t.device.limits as SubgroupLimits;
for (let size = minSubgroupSize; size <= maxSubgroupSize; size *= 2) {
const { subgroupMinSize, subgroupMaxSize } = t.device.adapterInfo as SubgroupProperties;
for (let size = subgroupMinSize; size <= subgroupMaxSize; size *= 2) {
t.skipIf(!testcase.filter(t.params.id, size), 'Skipping potential undefined behavior');
}

Expand Down Expand Up @@ -669,11 +669,11 @@ g.test('fragment')
})
.fn(async t => {
const innerTexels = (t.params.size[0] - 1) * (t.params.size[1] - 1);
interface SubgroupLimits extends GPUSupportedLimits {
maxSubgroupSize: number;
interface SubgroupProperties extends GPUAdapterInfo {
subgroupMaxSize: number;
}
const { maxSubgroupSize } = t.device.limits as SubgroupLimits;
t.skipIf(innerTexels < maxSubgroupSize, 'Too few texels to be reliable');
const { subgroupMaxSize } = t.device.adapterInfo as SubgroupProperties;
t.skipIf(innerTexels < subgroupMaxSize, 'Too few texels to be reliable');

const broadcast =
t.params.id === 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ export async function queryMipLevelMixWeightsForDevice(t: GPUTest, stage: Shader
pass.setBindGroup(0, createBindGroup(pipeline));
pass.dispatchWorkgroups(kMipLevelWeightSteps + 1);
pass.end();
encoder.copyBufferToBuffer(storageBuffer, 0, resultBuffer, 0, resultBuffer.size);
encoder.copyBufferToBuffer(storageBuffer, 0, resultBuffer, 0, storageBuffer.size);
break;
}
case 'fragment': {
Expand Down
12 changes: 6 additions & 6 deletions src/webgpu/shader/execution/shader_io/compute_builtins.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -398,11 +398,11 @@ g.test('subgroup_size')
t.selectDeviceOrSkipTestCase('subgroups' as GPUFeatureName);
})
.fn(async t => {
interface SubgroupLimits extends GPUSupportedLimits {
minSubgroupSize: number;
maxSubgroupSize: number;
interface SubgroupProperties extends GPUAdapterInfo {
subgroupMinSize: number;
subgroupMaxSize: number;
}
const { minSubgroupSize, maxSubgroupSize } = t.device.limits as SubgroupLimits;
const { subgroupMinSize, subgroupMaxSize } = t.device.adapterInfo as SubgroupProperties;

const wgx = t.params.sizes[0];
const wgy = t.params.sizes[1];
Expand Down Expand Up @@ -518,8 +518,8 @@ fn main(@builtin(subgroup_size) size : u32,
checkSubgroupSizeConsistency(
sizesData,
compareData,
minSubgroupSize,
maxSubgroupSize,
subgroupMinSize,
subgroupMaxSize,
wgThreads
)
);
Expand Down
24 changes: 12 additions & 12 deletions src/webgpu/shader/execution/shader_io/fragment_builtins.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1655,16 +1655,16 @@ g.test('subgroup_size')
t.selectDeviceOrSkipTestCase('subgroups' as GPUFeatureName);
})
.fn(async t => {
interface SubgroupLimits extends GPUSupportedLimits {
minSubgroupSize: number;
maxSubgroupSize: number;
interface SubgroupProperties extends GPUAdapterInfo {
subgroupMinSize: number;
subgroupMaxSize: number;
}
const { minSubgroupSize, maxSubgroupSize } = t.device.limits as SubgroupLimits;
const { subgroupMinSize, subgroupMaxSize } = t.device.adapterInfo as SubgroupProperties;

const fsShader = `
enable subgroups;
const maxSubgroupSize = ${kMaximiumSubgroupSize}u;
const subgroupMaxSize = ${kMaximiumSubgroupSize}u;
const noError = ${kSubgroupShaderNoError}u;
const width = ${t.params.size[0]};
Expand All @@ -1686,7 +1686,7 @@ fn fsMain(
var subgroupSizeBallotedInvocations: u32 = 0u;
var ballotedSubgroupSize: u32 = 0u;
for (var i: u32 = 0; i <= maxSubgroupSize; i++) {
for (var i: u32 = 0; i <= subgroupMaxSize; i++) {
let ballotSubgroupSizeEqualI = countOneBits(subgroupBallot(sg_size == i));
let countSubgroupSizeEqualI = ballotSubgroupSizeEqualI.x + ballotSubgroupSizeEqualI.y + ballotSubgroupSizeEqualI.z + ballotSubgroupSizeEqualI.w;
subgroupSizeBallotedInvocations += countSubgroupSizeEqualI;
Expand Down Expand Up @@ -1716,8 +1716,8 @@ fn fsMain(
return checkSubgroupSizeConsistency(
data,
t.params.format,
minSubgroupSize,
maxSubgroupSize,
subgroupMinSize,
subgroupMaxSize,
t.params.size[0],
t.params.size[1]
);
Expand Down Expand Up @@ -1816,7 +1816,7 @@ enable subgroups;
const width = ${t.params.size[0]};
const height = ${t.params.size[1]};
const maxSubgroupSize = ${kMaximiumSubgroupSize}u;
const subgroupMaxSize = ${kMaximiumSubgroupSize}u;
// A non-zero magic number indicating no expectation error, in order to prevent the
// false no-error result from zero-initialization.
const noError = ${kSubgroupShaderNoError}u;
Expand All @@ -1830,8 +1830,8 @@ fn fsMain(
var error: u32 = noError;
// Validate that reported subgroup size is no larger than maxSubgroupSize
if (sg_size > maxSubgroupSize) {
// Validate that reported subgroup size is no larger than subgroupMaxSize
if (sg_size > subgroupMaxSize) {
error++;
}
Expand All @@ -1843,7 +1843,7 @@ fn fsMain(
// Validate that each subgroup id is assigned to at most one active invocation
// in the subgroup
var countAssignedId: u32 = 0u;
for (var i: u32 = 0; i < maxSubgroupSize; i++) {
for (var i: u32 = 0; i < subgroupMaxSize; i++) {
let ballotIdEqualsI = countOneBits(subgroupBallot(id == i));
let countInvocationIdEqualsI = ballotIdEqualsI.x + ballotIdEqualsI.y + ballotIdEqualsI.z + ballotIdEqualsI.w;
// Validate an id assigned at most once
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,28 +30,6 @@ fn foo() {
t.expectCompileResult(t.params.enable, wgsl);
});

g.test('requires_subgroups_f16')
.desc('Validates that the subgroups feature is required')
.params(u => u.combine('enable', [false, true] as const))
.beforeAllSubcases(t => {
const features: GPUFeatureName[] = ['shader-f16', 'subgroups' as GPUFeatureName];
if (t.params.enable) {
features.push('subgroups-f16' as GPUFeatureName);
}
t.selectDeviceOrSkipTestCase(features);
})
.fn(t => {
const wgsl = `
enable f16;
enable subgroups;
${t.params.enable ? 'enable subgroups_f16;' : ''}
fn foo() {
_ = quadBroadcast(0h, 0);
}`;

t.expectCompileResult(t.params.enable, wgsl);
});

const kArgumentTypes = objectsToRecord(kAllScalarsAndVectors);

const kStages: Record<string, string> = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,28 +32,6 @@ fn foo() {
t.expectCompileResult(t.params.enable, wgsl);
});

g.test('requires_subgroups_f16')
.desc('Validates that the subgroups feature is required')
.params(u => u.combine('enable', [false, true] as const).combine('op', kOps))
.beforeAllSubcases(t => {
const features: GPUFeatureName[] = ['shader-f16', 'subgroups' as GPUFeatureName];
if (t.params.enable) {
features.push('subgroups-f16' as GPUFeatureName);
}
t.selectDeviceOrSkipTestCase(features);
})
.fn(t => {
const wgsl = `
enable f16;
enable subgroups;
${t.params.enable ? 'enable subgroups_f16;' : ''}
fn foo() {
_ = ${t.params.op}(0h);
}`;

t.expectCompileResult(t.params.enable, wgsl);
});

const kStages: Record<string, (op: string) => string> = {
constant: (op: string) => {
return `
Expand Down
Loading

0 comments on commit 9c54a1b

Please sign in to comment.