blob: 00d9250480122619d46dd33263884321e4f0bb6c [file] [log] [blame]
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]));
});