diff --git a/src/resources/cache/hashes.json b/src/resources/cache/hashes.json index ea368705c448..e0459422560f 100644 --- a/src/resources/cache/hashes.json +++ b/src/resources/cache/hashes.json @@ -97,7 +97,7 @@ "webgpu/shader/execution/unary/f16_arithmetic.bin": "4a20db6d", "webgpu/shader/execution/unary/f16_conversion.bin": "31f72f5a", "webgpu/shader/execution/unary/f32_arithmetic.bin": "f1c311cb", - "webgpu/shader/execution/unary/f32_conversion.bin": "57dc324c", + "webgpu/shader/execution/unary/f32_conversion.bin": "7539cdb3", "webgpu/shader/execution/unary/i32_arithmetic.bin": "de945eec", "webgpu/shader/execution/unary/i32_conversion.bin": "1728a03e", "webgpu/shader/execution/unary/u32_conversion.bin": "9e6ca0ce", diff --git a/src/resources/cache/webgpu/shader/execution/unary/f32_conversion.bin b/src/resources/cache/webgpu/shader/execution/unary/f32_conversion.bin index bdcc0c72988e..66b2bc73f889 100644 Binary files a/src/resources/cache/webgpu/shader/execution/unary/f32_conversion.bin and b/src/resources/cache/webgpu/shader/execution/unary/f32_conversion.bin differ diff --git a/src/webgpu/listing_meta.json b/src/webgpu/listing_meta.json index 878a7155697e..2360a199e3e4 100644 --- a/src/webgpu/listing_meta.json +++ b/src/webgpu/listing_meta.json @@ -1681,6 +1681,9 @@ "webgpu:shader,execution,expression,unary,f16_conversion:i32:*": { "subcaseMS": 24.557 }, "webgpu:shader,execution,expression,unary,f16_conversion:u32:*": { "subcaseMS": 84.500 }, "webgpu:shader,execution,expression,unary,f32_arithmetic:negation:*": { "subcaseMS": 16.400 }, + "webgpu:shader,execution,expression,unary,f32_conversion:abstract_float:*": { "subcaseMS": 688.718 }, + "webgpu:shader,execution,expression,unary,f32_conversion:abstract_float_mat:*": { "subcaseMS": 1409.951 }, + "webgpu:shader,execution,expression,unary,f32_conversion:abstract_int:*": { "subcaseMS": 506.131 }, "webgpu:shader,execution,expression,unary,f32_conversion:bool:*": { "subcaseMS": 7.182 }, "webgpu:shader,execution,expression,unary,f32_conversion:f16:*": { "subcaseMS": 107.463 }, "webgpu:shader,execution,expression,unary,f32_conversion:f16_mat:*": { "subcaseMS": 60.170 }, diff --git a/src/webgpu/shader/execution/expression/unary/f32_conversion.cache.ts b/src/webgpu/shader/execution/expression/unary/f32_conversion.cache.ts index f61435f07ce4..8ce39eccfd1b 100644 --- a/src/webgpu/shader/execution/expression/unary/f32_conversion.cache.ts +++ b/src/webgpu/shader/execution/expression/unary/f32_conversion.cache.ts @@ -1,7 +1,8 @@ -import { bool, f16, f32, i32, u32 } from '../../../../util/conversion.js'; -import { FP } from '../../../../util/floating_point.js'; +import { abstractInt, bool, f16, f32, i32, u32 } from '../../../../util/conversion.js'; +import { FP, FPInterval } from '../../../../util/floating_point.js'; import { fullI32Range, + fullI64Range, fullU32Range, scalarF16Range, scalarF32Range, @@ -10,6 +11,12 @@ import { } from '../../../../util/math.js'; import { makeCaseCache } from '../case_cache.js'; +const f32FiniteRangeInterval = new FPInterval( + 'f32', + FP.f32.constants().negative.min, + FP.f32.constants().positive.max +); + // Cases: f32_matCxR_[non_]const const f32_mat_cases = ([2, 3, 4] as const) .flatMap(cols => @@ -46,6 +53,23 @@ const f16_mat_cases = ([2, 3, 4] as const) ) .reduce((a, b) => ({ ...a, ...b }), {}); +// Cases: abstract_float_matCxR +// Note that abstract float values may be not exactly representable in f32 +// and/or out of range. +const abstract_float_mat_cases = ([2, 3, 4] as const) + .flatMap(cols => + ([2, 3, 4] as const).map(rows => ({ + [`abstract_float_mat${cols}x${rows}`]: () => { + return FP.abstract.generateMatrixToMatrixCases( + FP.abstract.sparseMatrixRange(cols, rows), + 'finite', + FP.f32.correctlyRoundedMatrix + ); + }, + })) + ) + .reduce((a, b) => ({ ...a, ...b }), {}); + export const d = makeCaseCache('unary/f32_conversion', { bool: () => { return [ @@ -63,6 +87,13 @@ export const d = makeCaseCache('unary/f32_conversion', { return { input: i32(i), expected: FP.f32.correctlyRoundedInterval(i) }; }); }, + abstract_int: () => { + return [...fullI64Range()] + .filter(v => f32FiniteRangeInterval.contains(Number(v))) + .map(i => { + return { input: abstractInt(i), expected: FP.f32.correctlyRoundedInterval(Number(i)) }; + }); + }, f32: () => { return scalarF32Range().map(f => { return { input: f32(f), expected: FP.f32.correctlyRoundedInterval(f) }; @@ -74,6 +105,15 @@ export const d = makeCaseCache('unary/f32_conversion', { return { input: f16(f), expected: FP.f32.correctlyRoundedInterval(f) }; }); }, + // Note that abstract float values may be not exactly representable in f32. + abstract_float: () => { + return FP.abstract.generateScalarToIntervalCases( + [...FP.abstract.scalarRange()], + 'finite', + FP.f32.correctlyRoundedInterval + ); + }, ...f32_mat_cases, ...f16_mat_cases, + ...abstract_float_mat_cases, }); diff --git a/src/webgpu/shader/execution/expression/unary/f32_conversion.spec.ts b/src/webgpu/shader/execution/expression/unary/f32_conversion.spec.ts index 464fdee44e79..7a42334cb860 100644 --- a/src/webgpu/shader/execution/expression/unary/f32_conversion.spec.ts +++ b/src/webgpu/shader/execution/expression/unary/f32_conversion.spec.ts @@ -5,7 +5,7 @@ Execution Tests for the f32 conversion operations import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; import { Type } from '../../../../util/conversion.js'; -import { ShaderBuilder, allInputSources, run } from '../expression.js'; +import { ShaderBuilder, allInputSources, run, onlyConstInputSource } from '../expression.js'; import { d } from './f32_conversion.cache.js'; import { unary } from './unary.js'; @@ -73,6 +73,32 @@ Converted to f32 await run(t, vectorizeToExpression(t.params.vectorize), [Type.i32], Type.f32, t.params, cases); }); +g.test('abstract_int') + .specURL('https://www.w3.org/TR/WGSL/#value-constructor-builtin-function') + .desc( + ` +f32(e), where e is an AbstractInt + +Converted to f32, +/-Inf if out of range +` + ) + .params(u => + u + .combine('inputSource', onlyConstInputSource) + .combine('vectorize', [undefined, 2, 3, 4] as const) + ) + .fn(async t => { + const cases = await d.get('abstract_int'); + await run( + t, + vectorizeToExpression(t.params.vectorize), + [Type.abstractInt], + Type.f32, + t.params, + cases + ); + }); + g.test('f32') .specURL('https://www.w3.org/TR/WGSL/#value-constructor-builtin-function') .desc( @@ -166,3 +192,52 @@ g.test('f16_mat') cases ); }); + +g.test('abstract_float') + .specURL('https://www.w3.org/TR/WGSL/#value-constructor-builtin-function') + .desc( + ` +f32(e), where e is an AbstractFloat + +Correctly rounded to f32 +` + ) + .params(u => + u + .combine('inputSource', onlyConstInputSource) + .combine('vectorize', [undefined, 2, 3, 4] as const) + ) + .fn(async t => { + const cases = await d.get('abstract_float'); + await run( + t, + vectorizeToExpression(t.params.vectorize), + [Type.abstractFloat], + Type.f32, + t.params, + cases + ); + }); + +g.test('abstract_float_mat') + .specURL('https://www.w3.org/TR/WGSL/#matrix-builtin-functions') + .desc(`AbstractFloat matrix to f32 matrix tests`) + .params(u => + u + .combine('inputSource', onlyConstInputSource) + .combine('cols', [2, 3, 4] as const) + .combine('rows', [2, 3, 4] as const) + ) + .fn(async t => { + const cols = t.params.cols; + const rows = t.params.rows; + const cases = await d.get(`abstract_float_mat${cols}x${rows}`); + await run( + t, + matrixExperession(cols, rows), + [Type.mat(cols, rows, Type.abstractFloat)], + Type.mat(cols, rows, Type.f32), + t.params, + cases + ); + });