| export const description = ` |
| Execution Tests for float parsing cases |
| `; |
| |
| import { makeTestGroup } from '../../../common/framework/test_group.js'; |
| import { keysOf } from '../../../common/util/data_tables.js'; |
| import { iterRange } from '../../../common/util/util.js'; |
| import { AllFeaturesMaxLimitsGPUTest, GPUTest } from '../../gpu_test.js'; |
| |
| export const g = makeTestGroup(AllFeaturesMaxLimitsGPUTest); |
| |
| /** |
| * Run a shader and check that the buffer output matches expectations. |
| * |
| * @param t The test object |
| * @param wgsl The shader source |
| * @param expected The array of expected values after running the shader |
| */ |
| function runShaderTest(t: GPUTest, wgsl: string, expected: Float32Array): void { |
| const pipeline = t.device.createComputePipeline({ |
| layout: 'auto', |
| compute: { |
| module: t.device.createShaderModule({ code: wgsl }), |
| entryPoint: 'main', |
| }, |
| }); |
| |
| // Allocate a buffer and fill it with 0xdeadbeef words. |
| const outputBuffer = t.makeBufferWithContents( |
| new Float32Array([...iterRange(expected.length, _i => 0xdeadbeef)]), |
| GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC |
| ); |
| const bindGroup = t.device.createBindGroup({ |
| layout: pipeline.getBindGroupLayout(0), |
| entries: [{ binding: 0, resource: { buffer: outputBuffer } }], |
| }); |
| |
| // Run the shader. |
| const encoder = t.device.createCommandEncoder(); |
| const pass = encoder.beginComputePass(); |
| pass.setPipeline(pipeline); |
| pass.setBindGroup(0, bindGroup); |
| pass.dispatchWorkgroups(1); |
| pass.end(); |
| t.queue.submit([encoder.finish()]); |
| |
| // Check that only the non-padding bytes were modified. |
| t.expectGPUBufferValuesEqual(outputBuffer, expected); |
| } |
| |
| const kTestFloats = { |
| small_pos_zero_exp: { |
| src: |
| '0.' + |
| '00000000000000000000000000000000000000000000000000' + // 50 |
| '00000000000000000000000000000000000000000000000000' + // 100 |
| '00000000000000000000000000000000000000000000000000' + // 150 |
| '00000000000000000000000000000000000000000000000000' + // 200 |
| '00000000000000000000000000000000000000000000000000' + // 250 |
| '00000000000000000000000000000000000000000000000000' + // 300 |
| '00000000000000000000000000000000000000000000000000' + // 350 |
| '1e+0', |
| result: 0.0, |
| }, |
| small_pos_non_zero_exp: { |
| src: |
| '0.' + |
| '00000000000000000000000000000000000000000000000000' + // 50 |
| '00000000000000000000000000000000000000000000000000' + // 100 |
| '00000000000000000000000000000000000000000000000000' + // 150 |
| '00000000000000000000000000000000000000000000000000' + // 200 |
| '00000000000000000000000000000000000000000000000000' + // 250 |
| '00000000000000000000000000000000000000000000000000' + // 300 |
| '00000000000000000000000000000000000000000000000000' + // 350 |
| '1e+10', |
| result: 0.0, |
| }, |
| pos_exp_neg_result: { |
| src: |
| '0.' + |
| '00000000000000000000000000000000000000000000000000' + // 50 |
| '00000000000000000000000000000000000000000000000000' + // 100 |
| '00000000000000000000000000000000000000000000000000' + // 150 |
| '00000000000000000000000000000000000000000000000000' + // 200 |
| '00000000000000000000000000000000000000000000000000' + // 250 |
| '00000000000000000000000000000000000000000000000000' + // 300 |
| '00000000000000000000000000000000000000000000000000' + // 350 |
| '1e+300', |
| result: 1e-51, |
| }, |
| no_exp: { |
| src: |
| '0.' + |
| '00000000000000000000000000000000000000000000000000' + // 50 |
| '00000000000000000000000000000000000000000000000000' + // 100 |
| '00000000000000000000000000000000000000000000000000' + // 150 |
| '00000000000000000000000000000000000000000000000000' + // 200 |
| '00000000000000000000000000000000000000000000000000' + // 250 |
| '00000000000000000000000000000000000000000000000000' + // 300 |
| '00000000000000000000000000000000000000000000000000' + // 350 |
| '1', |
| result: 0.0, |
| }, |
| large_number_small_exp: { |
| src: |
| '1' + |
| '00000000000000000000000000000000000000000000000000' + // 50 |
| '00000000000000000000000000000000000000000000000000' + // 100 |
| '.0e-350', |
| result: 1e-251, |
| }, |
| }; |
| |
| g.test('valid') |
| .desc(`Test that floats are parsed correctly`) |
| .params(u => u.combine('value', keysOf(kTestFloats))) |
| .fn(t => { |
| const data = kTestFloats[t.params.value]; |
| const wgsl = ` |
| struct S { |
| val: f32, |
| } |
| @group(0) @binding(0) var<storage, read_write> buffer : S; |
| |
| @compute @workgroup_size(1) |
| fn main() { |
| buffer = S(${data.src}); |
| } |
| `; |
| runShaderTest(t, wgsl, new Float32Array([data.result])); |
| }); |