diff options
Diffstat (limited to 'dom/webgpu/tests/cts/checkout/src/webgpu/shader/execution/memory_model/barrier.spec.ts')
-rw-r--r-- | dom/webgpu/tests/cts/checkout/src/webgpu/shader/execution/memory_model/barrier.spec.ts | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/dom/webgpu/tests/cts/checkout/src/webgpu/shader/execution/memory_model/barrier.spec.ts b/dom/webgpu/tests/cts/checkout/src/webgpu/shader/execution/memory_model/barrier.spec.ts new file mode 100644 index 0000000000..6cda6c3e19 --- /dev/null +++ b/dom/webgpu/tests/cts/checkout/src/webgpu/shader/execution/memory_model/barrier.spec.ts @@ -0,0 +1,211 @@ +export const description = ` +Tests for non-atomic memory synchronization within a workgroup in the presence of a WebGPU barrier`; + +import { makeTestGroup } from '../../../../common/framework/test_group.js'; +import { GPUTest } from '../../../gpu_test.js'; + +import { + MemoryModelTestParams, + MemoryModelTester, + buildTestShader, + MemoryType, + TestType, + buildResultShader, + ResultType, +} from './memory_model_setup.js'; + +export const g = makeTestGroup(GPUTest); + +// A reasonable parameter set, determined heuristically. +const memoryModelTestParams: MemoryModelTestParams = { + workgroupSize: 256, + testingWorkgroups: 512, + maxWorkgroups: 1024, + shufflePct: 100, + barrierPct: 100, + memStressPct: 100, + memStressIterations: 1024, + memStressStoreFirstPct: 50, + memStressStoreSecondPct: 50, + preStressPct: 100, + preStressIterations: 1024, + preStressStoreFirstPct: 50, + preStressStoreSecondPct: 50, + scratchMemorySize: 2048, + stressLineSize: 64, + stressTargetLines: 2, + stressStrategyBalancePct: 50, + permuteFirst: 109, + permuteSecond: 419, + memStride: 4, + aliasedMemory: false, + numBehaviors: 2, +}; + +const storageMemoryBarrierStoreLoadTestCode = ` + test_locations.value[x_0] = 1u; + workgroupBarrier(); + let r0 = test_locations.value[x_1]; + atomicStore(&results.value[shuffled_workgroup * workgroupXSize + id_1].r0, r0); +`; + +const workgroupMemoryBarrierStoreLoadTestCode = ` + wg_test_locations[x_0] = 1u; + workgroupBarrier(); + let r0 = wg_test_locations[x_1]; + atomicStore(&results.value[shuffled_workgroup * workgroupXSize + id_1].r0, r0); +`; + +g.test('workgroup_barrier_store_load') + .desc( + `Checks whether the workgroup barrier properly synchronizes a non-atomic write and read on + separate threads in the same workgroup. Within a workgroup, the barrier should force an invocation + after the barrier to read a write from an invocation before the barrier. + ` + ) + .paramsSimple([ + { memType: MemoryType.NonAtomicStorageClass, _testCode: storageMemoryBarrierStoreLoadTestCode }, + { + memType: MemoryType.NonAtomicWorkgroupClass, + _testCode: workgroupMemoryBarrierStoreLoadTestCode, + }, + ]) + .fn(async t => { + const resultCode = ` + if (r0 == 1u) { + atomicAdd(&test_results.seq, 1u); + } else if (r0 == 0u) { + atomicAdd(&test_results.weak, 1u); + } + `; + const testShader = buildTestShader( + t.params._testCode, + t.params.memType, + TestType.IntraWorkgroup + ); + const resultShader = buildResultShader( + resultCode, + TestType.IntraWorkgroup, + ResultType.TwoBehavior + ); + const memModelTester = new MemoryModelTester( + t, + memoryModelTestParams, + testShader, + resultShader + ); + await memModelTester.run(15, 1); + }); + +const storageMemoryBarrierLoadStoreTestCode = ` + let r0 = test_locations.value[x_0]; + workgroupBarrier(); + test_locations.value[x_1] = 1u; + atomicStore(&results.value[shuffled_workgroup * workgroupXSize + id_0].r0, r0); +`; + +const workgroupMemoryBarrierLoadStoreTestCode = ` + let r0 = wg_test_locations[x_0]; + workgroupBarrier(); + wg_test_locations[x_1] = 1u; + atomicStore(&results.value[shuffled_workgroup * workgroupXSize + id_0].r0, r0); +`; + +g.test('workgroup_barrier_load_store') + .desc( + `Checks whether the workgroup barrier properly synchronizes a non-atomic write and read on + separate threads in the same workgroup. Within a workgroup, the barrier should force an invocation + before the barrier to not read the write from an invocation after the barrier. + ` + ) + .paramsSimple([ + { memType: MemoryType.NonAtomicStorageClass, _testCode: storageMemoryBarrierLoadStoreTestCode }, + { + memType: MemoryType.NonAtomicWorkgroupClass, + _testCode: workgroupMemoryBarrierLoadStoreTestCode, + }, + ]) + .fn(async t => { + const resultCode = ` + if (r0 == 0u) { + atomicAdd(&test_results.seq, 1u); + } else if (r0 == 1u) { + atomicAdd(&test_results.weak, 1u); + } + `; + const testShader = buildTestShader( + t.params._testCode, + t.params.memType, + TestType.IntraWorkgroup + ); + const resultShader = buildResultShader( + resultCode, + TestType.IntraWorkgroup, + ResultType.TwoBehavior + ); + const memModelTester = new MemoryModelTester( + t, + memoryModelTestParams, + testShader, + resultShader + ); + await memModelTester.run(12, 1); + }); + +const storageMemoryBarrierStoreStoreTestCode = ` + test_locations.value[x_0] = 1u; + storageBarrier(); + test_locations.value[x_1] = 2u; +`; + +const workgroupMemoryBarrierStoreStoreTestCode = ` + wg_test_locations[x_0] = 1u; + workgroupBarrier(); + wg_test_locations[x_1] = 2u; + workgroupBarrier(); + test_locations.value[shuffled_workgroup * workgroupXSize * stress_params.mem_stride * 2u + x_1] = wg_test_locations[x_1]; +`; + +g.test('workgroup_barrier_store_store') + .desc( + `Checks whether the workgroup barrier properly synchronizes non-atomic writes on + separate threads in the same workgroup. Within a workgroup, the barrier should force the value in memory + to be the result of the write after the barrier, not the write before. + ` + ) + .paramsSimple([ + { + memType: MemoryType.NonAtomicStorageClass, + _testCode: storageMemoryBarrierStoreStoreTestCode, + }, + { + memType: MemoryType.NonAtomicWorkgroupClass, + _testCode: workgroupMemoryBarrierStoreStoreTestCode, + }, + ]) + .fn(async t => { + const resultCode = ` + if (mem_x_0 == 2u) { + atomicAdd(&test_results.seq, 1u); + } else if (mem_x_0 == 1u) { + atomicAdd(&test_results.weak, 1u); + } + `; + const testShader = buildTestShader( + t.params._testCode, + t.params.memType, + TestType.IntraWorkgroup + ); + const resultShader = buildResultShader( + resultCode, + TestType.IntraWorkgroup, + ResultType.TwoBehavior + ); + const memModelTester = new MemoryModelTester( + t, + memoryModelTestParams, + testShader, + resultShader + ); + await memModelTester.run(10, 1); + }); |