diff --git a/src/resources/cache/hashes.json b/src/resources/cache/hashes.json index 80b8cd524cc5..88a4ab4478b9 100644 --- a/src/resources/cache/hashes.json +++ b/src/resources/cache/hashes.json @@ -1,103 +1,103 @@ { - "webgpu/shader/execution/binary/af_addition.bin": "a9c5cce6", + "webgpu/shader/execution/binary/af_addition.bin": "9ff4c694", "webgpu/shader/execution/binary/af_logical.bin": "9ec85311", - "webgpu/shader/execution/binary/af_division.bin": "8d23c845", - "webgpu/shader/execution/binary/af_matrix_addition.bin": "63a6a1ac", - "webgpu/shader/execution/binary/af_matrix_subtraction.bin": "120cfedf", - "webgpu/shader/execution/binary/af_multiplication.bin": "94eed575", - "webgpu/shader/execution/binary/af_remainder.bin": "7d4767a5", - "webgpu/shader/execution/binary/af_subtraction.bin": "5a18e960", - "webgpu/shader/execution/binary/f16_addition.bin": "7a67e7b1", + "webgpu/shader/execution/binary/af_division.bin": "573bcb2", + "webgpu/shader/execution/binary/af_matrix_addition.bin": "b82c13e3", + "webgpu/shader/execution/binary/af_matrix_subtraction.bin": "54653771", + "webgpu/shader/execution/binary/af_multiplication.bin": "6c680224", + "webgpu/shader/execution/binary/af_remainder.bin": "e780a0c8", + "webgpu/shader/execution/binary/af_subtraction.bin": "315b6080", + "webgpu/shader/execution/binary/f16_addition.bin": "9e6f8c87", "webgpu/shader/execution/binary/f16_logical.bin": "1edd08ec", - "webgpu/shader/execution/binary/f16_division.bin": "127a1260", - "webgpu/shader/execution/binary/f16_matrix_addition.bin": "f3a630df", - "webgpu/shader/execution/binary/f16_matrix_matrix_multiplication.bin": "e396f4b8", - "webgpu/shader/execution/binary/f16_matrix_scalar_multiplication.bin": "bfbed0d7", - "webgpu/shader/execution/binary/f16_matrix_subtraction.bin": "50d9bac9", - "webgpu/shader/execution/binary/f16_matrix_vector_multiplication.bin": "9b0ddaa2", - "webgpu/shader/execution/binary/f16_multiplication.bin": "6b29214d", - "webgpu/shader/execution/binary/f16_remainder.bin": "c45c8326", - "webgpu/shader/execution/binary/f16_subtraction.bin": "44437355", - "webgpu/shader/execution/binary/f32_addition.bin": "ef227af", + "webgpu/shader/execution/binary/f16_division.bin": "99dcc71b", + "webgpu/shader/execution/binary/f16_matrix_addition.bin": "3aa70dc8", + "webgpu/shader/execution/binary/f16_matrix_matrix_multiplication.bin": "2301ffc4", + "webgpu/shader/execution/binary/f16_matrix_scalar_multiplication.bin": "e97285fb", + "webgpu/shader/execution/binary/f16_matrix_subtraction.bin": "8e17ece5", + "webgpu/shader/execution/binary/f16_matrix_vector_multiplication.bin": "abc984c1", + "webgpu/shader/execution/binary/f16_multiplication.bin": "f8c1e34c", + "webgpu/shader/execution/binary/f16_remainder.bin": "6bbb566f", + "webgpu/shader/execution/binary/f16_subtraction.bin": "f8acc55b", + "webgpu/shader/execution/binary/f32_addition.bin": "b9dfd280", "webgpu/shader/execution/binary/f32_logical.bin": "fab7cfc5", - "webgpu/shader/execution/binary/f32_division.bin": "c2df73c9", - "webgpu/shader/execution/binary/f32_matrix_addition.bin": "18502449", - "webgpu/shader/execution/binary/f32_matrix_matrix_multiplication.bin": "96cda4b2", - "webgpu/shader/execution/binary/f32_matrix_scalar_multiplication.bin": "5570ca6f", - "webgpu/shader/execution/binary/f32_matrix_subtraction.bin": "a0d7e8d1", - "webgpu/shader/execution/binary/f32_matrix_vector_multiplication.bin": "90b6aeb9", - "webgpu/shader/execution/binary/f32_multiplication.bin": "f6dff4c7", - "webgpu/shader/execution/binary/f32_remainder.bin": "1d5f3a8", - "webgpu/shader/execution/binary/f32_subtraction.bin": "b9a951e9", + "webgpu/shader/execution/binary/f32_division.bin": "5bb9f335", + "webgpu/shader/execution/binary/f32_matrix_addition.bin": "e35631d2", + "webgpu/shader/execution/binary/f32_matrix_matrix_multiplication.bin": "b306d17", + "webgpu/shader/execution/binary/f32_matrix_scalar_multiplication.bin": "a62498ea", + "webgpu/shader/execution/binary/f32_matrix_subtraction.bin": "ae6edc24", + "webgpu/shader/execution/binary/f32_matrix_vector_multiplication.bin": "3c64a590", + "webgpu/shader/execution/binary/f32_multiplication.bin": "2ede2dcd", + "webgpu/shader/execution/binary/f32_remainder.bin": "99df37d5", + "webgpu/shader/execution/binary/f32_subtraction.bin": "dce728b3", "webgpu/shader/execution/binary/i32_arithmetic.bin": "de93ee2a", "webgpu/shader/execution/binary/i32_comparison.bin": "aaa1f21b", "webgpu/shader/execution/binary/u32_arithmetic.bin": "d79a1011", "webgpu/shader/execution/binary/u32_comparison.bin": "31764c75", - "webgpu/shader/execution/abs.bin": "9e12d146", - "webgpu/shader/execution/acos.bin": "d72227bc", - "webgpu/shader/execution/acosh.bin": "b3008340", - "webgpu/shader/execution/asin.bin": "2348666b", - "webgpu/shader/execution/asinh.bin": "1fcc0429", - "webgpu/shader/execution/atan.bin": "34f29ec8", - "webgpu/shader/execution/atan2.bin": "33c3196c", - "webgpu/shader/execution/atanh.bin": "79cffc5a", - "webgpu/shader/execution/bitcast.bin": "c6e7405c", - "webgpu/shader/execution/ceil.bin": "4cabf37c", - "webgpu/shader/execution/clamp.bin": "8b4c84c7", - "webgpu/shader/execution/cos.bin": "dd4f0d54", - "webgpu/shader/execution/cosh.bin": "cf2303ea", - "webgpu/shader/execution/cross.bin": "f231a725", - "webgpu/shader/execution/degrees.bin": "216634ac", - "webgpu/shader/execution/determinant.bin": "3a4c5761", - "webgpu/shader/execution/distance.bin": "45c1bcee", - "webgpu/shader/execution/dot.bin": "553f268b", - "webgpu/shader/execution/exp.bin": "13f273d5", - "webgpu/shader/execution/exp2.bin": "215379e7", - "webgpu/shader/execution/faceForward.bin": "dfcee405", - "webgpu/shader/execution/floor.bin": "422b808a", - "webgpu/shader/execution/fma.bin": "df385cdd", - "webgpu/shader/execution/fract.bin": "416f144f", - "webgpu/shader/execution/frexp.bin": "48323de7", - "webgpu/shader/execution/inverseSqrt.bin": "b5d88ed0", - "webgpu/shader/execution/ldexp.bin": "82257924", - "webgpu/shader/execution/length.bin": "eef942e5", - "webgpu/shader/execution/log.bin": "6889843e", - "webgpu/shader/execution/log2.bin": "97bae6ee", - "webgpu/shader/execution/max.bin": "9369c070", - "webgpu/shader/execution/min.bin": "85cd40d4", - "webgpu/shader/execution/mix.bin": "f24ecba4", - "webgpu/shader/execution/modf.bin": "6914406e", - "webgpu/shader/execution/normalize.bin": "56db74b3", + "webgpu/shader/execution/abs.bin": "b4140bc8", + "webgpu/shader/execution/acos.bin": "82621bf", + "webgpu/shader/execution/acosh.bin": "4166d51", + "webgpu/shader/execution/asin.bin": "3db84c59", + "webgpu/shader/execution/asinh.bin": "5aa1e7a2", + "webgpu/shader/execution/atan.bin": "de8094d", + "webgpu/shader/execution/atan2.bin": "9b5938b4", + "webgpu/shader/execution/atanh.bin": "3fa65838", + "webgpu/shader/execution/bitcast.bin": "e4e06164", + "webgpu/shader/execution/ceil.bin": "4746da0e", + "webgpu/shader/execution/clamp.bin": "56745472", + "webgpu/shader/execution/cos.bin": "e1ed11", + "webgpu/shader/execution/cosh.bin": "fbd92f9", + "webgpu/shader/execution/cross.bin": "3ade16cf", + "webgpu/shader/execution/degrees.bin": "1392cbd6", + "webgpu/shader/execution/determinant.bin": "5b562124", + "webgpu/shader/execution/distance.bin": "48c26875", + "webgpu/shader/execution/dot.bin": "784b83f1", + "webgpu/shader/execution/exp.bin": "bf0dcc36", + "webgpu/shader/execution/exp2.bin": "2a7bbe9e", + "webgpu/shader/execution/faceForward.bin": "e14093b7", + "webgpu/shader/execution/floor.bin": "7ac9dae9", + "webgpu/shader/execution/fma.bin": "172e6a74", + "webgpu/shader/execution/fract.bin": "cbe80708", + "webgpu/shader/execution/frexp.bin": "d3ce34ce", + "webgpu/shader/execution/inverseSqrt.bin": "a65b3762", + "webgpu/shader/execution/ldexp.bin": "aa39225f", + "webgpu/shader/execution/length.bin": "67457bbf", + "webgpu/shader/execution/log.bin": "1ffe589b", + "webgpu/shader/execution/log2.bin": "451a8eb8", + "webgpu/shader/execution/max.bin": "e96b1472", + "webgpu/shader/execution/min.bin": "2f429b46", + "webgpu/shader/execution/mix.bin": "2a438cc0", + "webgpu/shader/execution/modf.bin": "94a8dad4", + "webgpu/shader/execution/normalize.bin": "9deeb24e", "webgpu/shader/execution/pack2x16float.bin": "b2cb12ea", - "webgpu/shader/execution/pow.bin": "4559fe54", - "webgpu/shader/execution/quantizeToF16.bin": "6e7140c0", - "webgpu/shader/execution/radians.bin": "3d20d9af", - "webgpu/shader/execution/reflect.bin": "83096c2a", - "webgpu/shader/execution/refract.bin": "5ff885dc", - "webgpu/shader/execution/round.bin": "f8bdb72b", - "webgpu/shader/execution/saturate.bin": "fd71272f", - "webgpu/shader/execution/sign.bin": "5ac3fcf8", - "webgpu/shader/execution/sin.bin": "8eb2a6be", - "webgpu/shader/execution/sinh.bin": "33fffc1d", - "webgpu/shader/execution/smoothstep.bin": "33df4b5f", - "webgpu/shader/execution/sqrt.bin": "f0e8fd1", - "webgpu/shader/execution/step.bin": "eef87c59", - "webgpu/shader/execution/tan.bin": "4904b8c0", - "webgpu/shader/execution/tanh.bin": "b1afeda", - "webgpu/shader/execution/transpose.bin": "697e34a5", - "webgpu/shader/execution/trunc.bin": "4474ec0", - "webgpu/shader/execution/unpack2x16float.bin": "be34edc2", - "webgpu/shader/execution/unpack2x16snorm.bin": "68115c4", - "webgpu/shader/execution/unpack2x16unorm.bin": "b0a3bc8d", - "webgpu/shader/execution/unpack4x8snorm.bin": "778671b5", - "webgpu/shader/execution/unpack4x8unorm.bin": "686ea0d", - "webgpu/shader/execution/unary/af_arithmetic.bin": "b1492312", - "webgpu/shader/execution/unary/af_assignment.bin": "86ca08b5", + "webgpu/shader/execution/pow.bin": "861845e1", + "webgpu/shader/execution/quantizeToF16.bin": "cdec1b52", + "webgpu/shader/execution/radians.bin": "ff93c962", + "webgpu/shader/execution/reflect.bin": "da8f8021", + "webgpu/shader/execution/refract.bin": "918d854e", + "webgpu/shader/execution/round.bin": "314d28fe", + "webgpu/shader/execution/saturate.bin": "3eff93e8", + "webgpu/shader/execution/sign.bin": "fcc68d98", + "webgpu/shader/execution/sin.bin": "cc92b580", + "webgpu/shader/execution/sinh.bin": "751d3edb", + "webgpu/shader/execution/smoothstep.bin": "2604a849", + "webgpu/shader/execution/sqrt.bin": "100a05ab", + "webgpu/shader/execution/step.bin": "9463ab1b", + "webgpu/shader/execution/tan.bin": "8c924dc6", + "webgpu/shader/execution/tanh.bin": "c73a178", + "webgpu/shader/execution/transpose.bin": "21358779", + "webgpu/shader/execution/trunc.bin": "38d0c22e", + "webgpu/shader/execution/unpack2x16float.bin": "8138f397", + "webgpu/shader/execution/unpack2x16snorm.bin": "23d2c366", + "webgpu/shader/execution/unpack2x16unorm.bin": "ffed85bc", + "webgpu/shader/execution/unpack4x8snorm.bin": "6ac8cab7", + "webgpu/shader/execution/unpack4x8unorm.bin": "3cebb66b", + "webgpu/shader/execution/unary/af_arithmetic.bin": "e4193a8f", + "webgpu/shader/execution/unary/af_assignment.bin": "c841e6c6", "webgpu/shader/execution/unary/bool_conversion.bin": "cb53bf65", - "webgpu/shader/execution/unary/f16_arithmetic.bin": "69914092", - "webgpu/shader/execution/unary/f16_conversion.bin": "8a3ffbbb", - "webgpu/shader/execution/unary/f32_arithmetic.bin": "61e25fb6", - "webgpu/shader/execution/unary/f32_conversion.bin": "c47c9b05", + "webgpu/shader/execution/unary/f16_arithmetic.bin": "59fe7c00", + "webgpu/shader/execution/unary/f16_conversion.bin": "428ba8c1", + "webgpu/shader/execution/unary/f32_arithmetic.bin": "ba5faac0", + "webgpu/shader/execution/unary/f32_conversion.bin": "dd493eea", "webgpu/shader/execution/unary/i32_arithmetic.bin": "d322b73d", "webgpu/shader/execution/unary/i32_complement.bin": "c4e6cbb", "webgpu/shader/execution/unary/i32_conversion.bin": "d6905a0f", diff --git a/src/resources/cache/webgpu/shader/execution/mix.bin b/src/resources/cache/webgpu/shader/execution/mix.bin index 4cf9083aed69..e6d92fc898d5 100644 Binary files a/src/resources/cache/webgpu/shader/execution/mix.bin and b/src/resources/cache/webgpu/shader/execution/mix.bin differ diff --git a/src/unittests/floating_point.spec.ts b/src/unittests/floating_point.spec.ts index f4aaf3e78841..d3bc0cee99c8 100644 --- a/src/unittests/floating_point.spec.ts +++ b/src/unittests/floating_point.spec.ts @@ -5327,62 +5327,97 @@ g.test('fmaInterval') // prettier-ignore const kMixImpreciseIntervalCases = { f32: [ - // [0.0, 1.0] cases - { input: [0.0, 1.0, 0.1], expected: [reinterpretU64AsF64(0x3fb9_9999_8000_0000n), reinterpretU64AsF64(0x3fb9_9999_a000_0000n)] }, // ~0.1 - { input: [0.0, 1.0, 0.9], expected: [reinterpretU64AsF64(0x3fec_cccc_c000_0000n), reinterpretU64AsF64(0x3fec_cccc_e000_0000n)] }, // ~0.9 - // [1.0, 0.0] cases - { input: [1.0, 0.0, 0.1], expected: [reinterpretU64AsF64(0x3fec_cccc_c000_0000n), reinterpretU64AsF64(0x3fec_cccc_e000_0000n)] }, // ~0.9 - { input: [1.0, 0.0, 0.9], expected: [reinterpretU64AsF64(0x3fb9_9999_0000_0000n), reinterpretU64AsF64(0x3fb9_999a_0000_0000n)] }, // ~0.1 - // [0.0, 10.0] cases - { input: [0.0, 10.0, 0.1], expected: [reinterpretU64AsF64(0x3fef_ffff_e000_0000n), reinterpretU64AsF64(0x3ff0_0000_2000_0000n)] }, // ~1 - { input: [0.0, 10.0, 0.9], expected: [reinterpretU64AsF64(0x4021_ffff_e000_0000n), reinterpretU64AsF64(0x4022_0000_2000_0000n)] }, // ~9 - // [2.0, 10.0] cases - { input: [2.0, 10.0, 0.1], expected: [reinterpretU64AsF64(0x4006_6666_6000_0000n), reinterpretU64AsF64(0x4006_6666_8000_0000n)] }, // ~2.8 - { input: [2.0, 10.0, 0.9], expected: [reinterpretU64AsF64(0x4022_6666_6000_0000n), reinterpretU64AsF64(0x4022_6666_8000_0000n)] }, // ~9.2 - // [-1.0, 1.0] cases - { input: [-1.0, 1.0, 0.1], expected: [reinterpretU64AsF64(0xbfe9_9999_a000_0000n), reinterpretU64AsF64(0xbfe9_9999_8000_0000n)] }, // ~-0.8 - { input: [-1.0, 1.0, 0.9], expected: [reinterpretU64AsF64(0x3fe9_9999_8000_0000n), reinterpretU64AsF64(0x3fe9_9999_c000_0000n)] }, // ~0.8 - - // Showing how precise and imprecise versions diff - // Note that this expectation is 0 only in f32 as 10.0 is much smaller that f32.negative.min, - // So that 10 - f32.negative.min == f32.negative.min even in f64. But for f16, there is not - // a exactly-represenatble f16 value v that make v - f16.negative.min == f16.negative.min - // in f64, in fact that require v being smaller than 2**-37. - { input: [kValue.f32.negative.min, 10.0, 1.0], expected: 0.0 }, - // -10.0 is the same, much smaller than f32.negative.min - { input: [kValue.f32.negative.min, -10.0, 1.0], expected: 0.0 }, + // [0.0, 1.0] cases + { input: [0.0, 1.0, 0.1], expected: [reinterpretU64AsF64(0x3fb9_9999_8000_0000n), reinterpretU64AsF64(0x3fb9_9999_a000_0000n)] }, // ~0.1 + { input: [0.0, 1.0, 0.9], expected: [reinterpretU64AsF64(0x3fec_cccc_c000_0000n), reinterpretU64AsF64(0x3fec_cccc_e000_0000n)] }, // ~0.9 + // [1.0, 0.0] cases + { input: [1.0, 0.0, 0.1], expected: [reinterpretU64AsF64(0x3fec_cccc_c000_0000n), reinterpretU64AsF64(0x3fec_cccc_e000_0000n)] }, // ~0.9 + { input: [1.0, 0.0, 0.9], expected: [reinterpretU64AsF64(0x3fb9_9999_0000_0000n), reinterpretU64AsF64(0x3fb9_999a_0000_0000n)] }, // ~0.1 + // [0.0, 10.0] cases + { input: [0.0, 10.0, 0.1], expected: [reinterpretU64AsF64(0x3fef_ffff_e000_0000n), reinterpretU64AsF64(0x3ff0_0000_2000_0000n)] }, // ~1 + { input: [0.0, 10.0, 0.9], expected: [reinterpretU64AsF64(0x4021_ffff_e000_0000n), reinterpretU64AsF64(0x4022_0000_2000_0000n)] }, // ~9 + // [2.0, 10.0] cases + { input: [2.0, 10.0, 0.1], expected: [reinterpretU64AsF64(0x4006_6666_6000_0000n), reinterpretU64AsF64(0x4006_6666_8000_0000n)] }, // ~2.8 + { input: [2.0, 10.0, 0.9], expected: [reinterpretU64AsF64(0x4022_6666_6000_0000n), reinterpretU64AsF64(0x4022_6666_8000_0000n)] }, // ~9.2 + // [-1.0, 1.0] cases + { input: [-1.0, 1.0, 0.1], expected: [reinterpretU64AsF64(0xbfe9_9999_a000_0000n), reinterpretU64AsF64(0xbfe9_9999_8000_0000n)] }, // ~-0.8 + { input: [-1.0, 1.0, 0.9], expected: [reinterpretU64AsF64(0x3fe9_9999_8000_0000n), reinterpretU64AsF64(0x3fe9_9999_c000_0000n)] }, // ~0.8 + + // Showing how precise and imprecise versions diff + // Note that this expectation is 0 in f32 as 10.0 is much smaller that + // f32.negative.min. + // So that 10 - f32.negative.min == -f32.negative.min even in f64. + { input: [kValue.f32.negative.min, 10.0, 1.0], expected: 0.0 }, + // -10.0 is the same, much smaller than f32.negative.min + { input: [kValue.f32.negative.min, -10.0, 1.0], expected: 0.0 }, + { input: [kValue.f32.negative.min, 10.0, 5.0], expected: kUnboundedEndpoints }, + { input: [kValue.f32.negative.min, -10.0, 5.0], expected: kUnboundedEndpoints }, + { input: [kValue.f32.negative.min, 10.0, 0.5], expected: reinterpretU32AsF32(0xfeffffff) }, + { input: [kValue.f32.negative.min, -10.0, 0.5], expected: reinterpretU32AsF32(0xfeffffff) }, ] as ScalarTripleToIntervalCase[], f16: [ - // [0.0, 1.0] cases - { input: [0.0, 1.0, 0.1], expected: [reinterpretU64AsF64(0x3fb9_9800_0000_0000n), reinterpretU64AsF64(0x3fb9_9c00_0000_0000n)] }, // ~0.1 - { input: [0.0, 1.0, 0.9], expected: [reinterpretU64AsF64(0x3fec_cc00_0000_0000n), reinterpretU64AsF64(0x3fec_d000_0000_0000n)] }, // ~0.9 - // [1.0, 0.0] cases - { input: [1.0, 0.0, 0.1], expected: [reinterpretU64AsF64(0x3fec_cc00_0000_0000n), reinterpretU64AsF64(0x3fec_d000_0000_0000n)] }, // ~0.9 - { input: [1.0, 0.0, 0.9], expected: [reinterpretU64AsF64(0x3fb9_8000_0000_0000n), reinterpretU64AsF64(0x3fb9_a000_0000_0000n)] }, // ~0.1 - // [0.0, 10.0] cases - { input: [0.0, 10.0, 0.1], expected: [reinterpretU64AsF64(0x3fef_fc00_0000_0000n), reinterpretU64AsF64(0x3ff0_0400_0000_0000n)] }, // ~1 - { input: [0.0, 10.0, 0.9], expected: [reinterpretU64AsF64(0x4021_fc00_0000_0000n), reinterpretU64AsF64(0x4022_0400_0000_0000n)] }, // ~9 - // [2.0, 10.0] cases - { input: [2.0, 10.0, 0.1], expected: [reinterpretU64AsF64(0x4006_6400_0000_0000n), reinterpretU64AsF64(0x4006_6800_0000_0000n)] }, // ~2.8 - { input: [2.0, 10.0, 0.9], expected: [reinterpretU64AsF64(0x4022_6400_0000_0000n), reinterpretU64AsF64(0x4022_6800_0000_0000n)] }, // ~9.2 - // [-1.0, 1.0] cases - { input: [-1.0, 1.0, 0.1], expected: [reinterpretU64AsF64(0xbfe9_9c00_0000_0000n), reinterpretU64AsF64(0xbfe9_9800_0000_0000n)] }, // ~-0.8 - { input: [-1.0, 1.0, 0.9], expected: [reinterpretU64AsF64(0x3fe9_9800_0000_0000n), reinterpretU64AsF64(0x3fe9_a000_0000_0000n)] }, // ~0.8 - - // Showing how precise and imprecise versions diff - // In imprecise version, we compute (y - x), where y = 10 and x = -65504, the result is 65514 - // and cause an overflow in f16. - { input: [kValue.f16.negative.min, 10.0, 1.0], expected: kUnboundedEndpoints }, - // (y - x) * 1.0, where y = -10 and x = -65504, the result is 65494 rounded to 65472 or 65504. - // The result is -65504 + 65472 = -32 or -65504 + 65504 = 0. - { input: [kValue.f16.negative.min, -10.0, 1.0], expected: [-32, 0] }, + // [0.0, 1.0] cases + { input: [0.0, 1.0, 0.1], expected: [reinterpretU64AsF64(0x3fb9_9800_0000_0000n), reinterpretU64AsF64(0x3fb9_9c00_0000_0000n)] }, // ~0.1 + { input: [0.0, 1.0, 0.9], expected: [reinterpretU64AsF64(0x3fec_cc00_0000_0000n), reinterpretU64AsF64(0x3fec_d000_0000_0000n)] }, // ~0.9 + // [1.0, 0.0] cases + { input: [1.0, 0.0, 0.1], expected: [reinterpretU64AsF64(0x3fec_cc00_0000_0000n), reinterpretU64AsF64(0x3fec_d000_0000_0000n)] }, // ~0.9 + { input: [1.0, 0.0, 0.9], expected: [reinterpretU64AsF64(0x3fb9_8000_0000_0000n), reinterpretU64AsF64(0x3fb9_a000_0000_0000n)] }, // ~0.1 + // [0.0, 10.0] cases + { input: [0.0, 10.0, 0.1], expected: [reinterpretU64AsF64(0x3fef_fc00_0000_0000n), reinterpretU64AsF64(0x3ff0_0400_0000_0000n)] }, // ~1 + { input: [0.0, 10.0, 0.9], expected: [reinterpretU64AsF64(0x4021_fc00_0000_0000n), reinterpretU64AsF64(0x4022_0400_0000_0000n)] }, // ~9 + // [2.0, 10.0] cases + { input: [2.0, 10.0, 0.1], expected: [reinterpretU64AsF64(0x4006_6400_0000_0000n), reinterpretU64AsF64(0x4006_6800_0000_0000n)] }, // ~2.8 + { input: [2.0, 10.0, 0.9], expected: [reinterpretU64AsF64(0x4022_6400_0000_0000n), reinterpretU64AsF64(0x4022_6800_0000_0000n)] }, // ~9.2 + // [-1.0, 1.0] cases + { input: [-1.0, 1.0, 0.1], expected: [reinterpretU64AsF64(0xbfe9_9c00_0000_0000n), reinterpretU64AsF64(0xbfe9_9800_0000_0000n)] }, // ~-0.8 + { input: [-1.0, 1.0, 0.9], expected: [reinterpretU64AsF64(0x3fe9_9800_0000_0000n), reinterpretU64AsF64(0x3fe9_a000_0000_0000n)] }, // ~0.8 + + // Showing how precise and imprecise versions diff + // In imprecise version, we compute (y - x), where y = 10 and x = -65504, the result is 65514 + // and cause an overflow in f16. + { input: [kValue.f16.negative.min, 10.0, 1.0], expected: kUnboundedEndpoints }, + // (y - x) * 1.0, where y = -10 and x = -65504, the result is 65494 rounded to 65472 or 65504. + // The result is -65504 + 65472 = -32 or -65504 + 65504 = 0. + { input: [kValue.f16.negative.min, -10.0, 1.0], expected: [-32, 0] }, + { input: [kValue.f16.negative.min, 10.0, 5.0], expected: kUnboundedEndpoints }, + { input: [kValue.f16.negative.min, -10.0, 5.0], expected: kUnboundedEndpoints }, + { input: [kValue.f16.negative.min, 10.0, 0.5], expected: kUnboundedEndpoints }, + { input: [kValue.f16.negative.min, -10.0, 0.5], expected: [-32768.0, -32752.0] }, + ] as ScalarTripleToIntervalCase[], + abstract: [ + // [0.0, 1.0] cases + { input: [0.0, 1.0, 0.1], expected: 0.1 }, + { input: [0.0, 1.0, 0.9], expected: 0.9 }, + // [1.0, 0.0] cases + { input: [1.0, 0.0, 0.1], expected: 0.9 }, + { input: [1.0, 0.0, 0.9], expected: kMinusNULPFunctions['abstract'](0.1, 2) }, // This not being 0.1 is related to https://github.com/gpuweb/cts/issues/2993 + // [0.0, 10.0] cases + { input: [0.0, 10.0, 0.1], expected: 1 }, + { input: [0.0, 10.0, 0.9], expected: 9 }, + // [2.0, 10.0] cases + { input: [2.0, 10.0, 0.1], expected: 2.8 }, + { input: [2.0, 10.0, 0.9], expected: 9.2 }, + // [-1.0, 1.0] cases + { input: [-1.0, 1.0, 0.1], expected: -0.8 }, + { input: [-1.0, 1.0, 0.9], expected: 0.8 }, + + // Showing how precise and imprecise versions diff + // Note that this expectation is 0 in f64 as 10.0 is much smaller that + // f64.negative.min, so that 10 - f64.negative.min == -f64.negative.min + { input: [kValue.f64.negative.min, 10.0, 1.0], expected: 0 }, + // -10.0 is the same, much smaller than f64.negative.min + { input: [kValue.f64.negative.min, -10.0, 1.0], expected: 0 }, + { input: [kValue.f64.negative.min, 10.0, 5.0], expected: kUnboundedEndpoints }, + { input: [kValue.f64.negative.min, -10.0, 5.0], expected: kUnboundedEndpoints }, + { input: [kValue.f64.negative.min, 10.0, 0.5], expected: reinterpretU64AsF64(0xffdf_ffff_ffff_ffffn) }, + { input: [kValue.f64.negative.min, -10.0, 0.5], expected: reinterpretU64AsF64(0xffdf_ffff_ffff_ffffn) }, ] as ScalarTripleToIntervalCase[], } as const; g.test('mixImpreciseInterval') .params(u => u - .combine('trait', ['f32', 'f16'] as const) + .combine('trait', ['f32', 'f16', 'abstract'] as const) .beginSubcases() .expandWithParams(p => { const trait = FP[p.trait]; @@ -5437,9 +5472,6 @@ g.test('mixImpreciseInterval') { input: [1.0, 0.0, constants.negative.infinity], expected: kUnboundedEndpoints }, { input: [0.0, 1.0, constants.positive.infinity], expected: kUnboundedEndpoints }, { input: [1.0, 0.0, constants.positive.infinity], expected: kUnboundedEndpoints }, - - // The [negative.min, +/-10.0, 1.0] cases has different result for different trait on - // imprecise version. ]; }) ) @@ -5474,6 +5506,17 @@ const kMixPreciseIntervalCases = { // [-1.0, 1.0] cases { input: [-1.0, 1.0, 0.1], expected: [reinterpretU64AsF64(0xbfe9_9999_c000_0000n), reinterpretU64AsF64(0xbfe9_9999_8000_0000n)] }, // ~-0.8 { input: [-1.0, 1.0, 0.9], expected: [reinterpretU64AsF64(0x3fe9_9999_8000_0000n), reinterpretU64AsF64(0x3fe9_9999_c000_0000n)] }, // ~0.8 + + // Showing how precise and imprecise versions diff + { input: [kValue.f32.negative.min, 10.0, 1.0], expected: 10 }, + { input: [kValue.f32.negative.min, -10.0, 1.0], expected: -10 }, + { input: [kValue.f32.negative.min, 10.0, 5.0], expected: kUnboundedEndpoints }, + { input: [kValue.f32.negative.min, -10.0, 5.0], expected: kUnboundedEndpoints }, + { input: [kValue.f32.negative.min, 10.0, 0.5], expected: reinterpretU32AsF32(0xfeffffff) }, + { input: [kValue.f32.negative.min, -10.0, 0.5], expected: reinterpretU32AsF32(0xfeffffff) }, + + // Intermediate OOB + { input: [1.0, 2.0, kPlusOneULPFunctions['f32'](kValue.f32.positive.max / 2)], expected: kUnboundedEndpoints }, ] as ScalarTripleToIntervalCase[], f16: [ // [0.0, 1.0] cases @@ -5491,13 +5534,52 @@ const kMixPreciseIntervalCases = { // [-1.0, 1.0] cases { input: [-1.0, 1.0, 0.1], expected: [reinterpretU64AsF64(0xbfe9_a000_0000_0000n), reinterpretU64AsF64(0xbfe9_9800_0000_0000n)] }, // ~-0.8 { input: [-1.0, 1.0, 0.9], expected: [reinterpretU64AsF64(0x3fe9_9800_0000_0000n), reinterpretU64AsF64(0x3fe9_a000_0000_0000n)] }, // ~0.8 + + // Showing how precise and imprecise versions diff + { input: [kValue.f64.negative.min, 10.0, 1.0], expected: kUnboundedEndpoints }, + { input: [kValue.f64.negative.min, -10.0, 1.0], expected: kUnboundedEndpoints }, + { input: [kValue.f64.negative.min, 10.0, 5.0], expected: kUnboundedEndpoints }, + { input: [kValue.f64.negative.min, -10.0, 5.0], expected: kUnboundedEndpoints }, + { input: [kValue.f64.negative.min, 10.0, 0.5], expected: kUnboundedEndpoints }, + { input: [kValue.f64.negative.min, -10.0, 0.5], expected: kUnboundedEndpoints }, + + // Intermediate OOB + { input: [1.0, 2.0, kPlusOneULPFunctions['f16'](kValue.f16.positive.max / 2)], expected: kUnboundedEndpoints }, + ] as ScalarTripleToIntervalCase[], + abstract: [ + // [0.0, 1.0] cases + { input: [0.0, 1.0, 0.1], expected: 0.1 }, + { input: [0.0, 1.0, 0.9], expected: 0.9 }, + // [1.0, 0.0] cases + { input: [1.0, 0.0, 0.1], expected: 0.9 }, + { input: [1.0, 0.0, 0.9], expected: kMinusNULPFunctions['abstract'](0.1, 2) }, // This not being 0.1 is related to https://github.com/gpuweb/cts/issues/2993 + // [0.0, 10.0] cases + { input: [0.0, 10.0, 0.1], expected: 1 }, + { input: [0.0, 10.0, 0.9], expected: 9 }, + // [2.0, 10.0] cases + { input: [2.0, 10.0, 0.1], expected: 2.8 }, + { input: [2.0, 10.0, 0.9], expected: 9.2 }, + // [-1.0, 1.0] cases + { input: [-1.0, 1.0, 0.1], expected: -0.8 }, + { input: [-1.0, 1.0, 0.9], expected: 0.8 }, + + // Showing how precise and imprecise versions diff + { input: [kValue.f64.negative.min, 10.0, 1.0], expected: 10.0 }, + { input: [kValue.f64.negative.min, -10.0, 1.0], expected: -10.0 }, + { input: [kValue.f64.negative.min, 10.0, 5.0], expected: kUnboundedEndpoints }, + { input: [kValue.f64.negative.min, -10.0, 5.0], expected: kUnboundedEndpoints }, + { input: [kValue.f64.negative.min, 10.0, 0.5], expected: reinterpretU64AsF64(0xffdf_ffff_ffff_ffffn) }, + { input: [kValue.f64.negative.min, -10.0, 0.5], expected: reinterpretU64AsF64(0xffdf_ffff_ffff_ffffn) }, + + // Intermediate OOB + { input: [1.0, 2.0, kPlusOneULPFunctions['abstract'](kValue.f64.positive.max / 2)], expected: kUnboundedEndpoints }, ] as ScalarTripleToIntervalCase[], } as const; g.test('mixPreciseInterval') .params(u => u - .combine('trait', ['f32', 'f16'] as const) + .combine('trait', ['f32', 'f16', 'abstract'] as const) .beginSubcases() .expandWithParams(p => { const trait = FP[p.trait]; @@ -5552,10 +5634,6 @@ g.test('mixPreciseInterval') { input: [1.0, 0.0, constants.negative.infinity], expected: kUnboundedEndpoints }, { input: [0.0, 1.0, constants.positive.infinity], expected: kUnboundedEndpoints }, { input: [1.0, 0.0, constants.positive.infinity], expected: kUnboundedEndpoints }, - - // Showing how precise and imprecise versions diff - { input: [constants.negative.min, 10.0, 1.0], expected: 10.0 }, - { input: [constants.negative.min, -10.0, 1.0], expected: -10.0 }, ]; }) ) diff --git a/src/webgpu/shader/execution/expression/call/builtin/mix.cache.ts b/src/webgpu/shader/execution/expression/call/builtin/mix.cache.ts index 12176f87d4cf..3f1de937b159 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/mix.cache.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/mix.cache.ts @@ -1,11 +1,15 @@ import { FP } from '../../../../../util/floating_point.js'; import { makeCaseCache } from '../../case_cache.js'; -// Cases: [f32|f16]_[non_]const -const scalar_cases = (['f32', 'f16'] as const) +// Cases: [f32|f16|abstract]_[non_]const +// abstract_non_const is empty and unused +const scalar_cases = (['f32', 'f16', 'abstract'] as const) .flatMap(trait => ([true, false] as const).map(nonConst => ({ [`${trait}_${nonConst ? 'non_const' : 'const'}`]: () => { + if (trait === 'abstract' && nonConst) { + return []; + } return FP[trait].generateScalarTripleToIntervalCases( FP[trait].sparseScalarRange(), FP[trait].sparseScalarRange(), @@ -19,11 +23,15 @@ const scalar_cases = (['f32', 'f16'] as const) .reduce((a, b) => ({ ...a, ...b }), {}); // Cases: [f32|f16]_vecN_scalar_[non_]const -const vec_scalar_cases = (['f32', 'f16'] as const) +// abstract_vecN_non_const is empty and unused +const vec_scalar_cases = (['f32', 'f16', 'abstract'] as const) .flatMap(trait => ([2, 3, 4] as const).flatMap(dim => ([true, false] as const).map(nonConst => ({ [`${trait}_vec${dim}_scalar_${nonConst ? 'non_const' : 'const'}`]: () => { + if (trait === 'abstract' && nonConst) { + return []; + } return FP[trait].generateVectorPairScalarToVectorComponentWiseCase( FP[trait].sparseVectorRange(dim), FP[trait].sparseVectorRange(dim), diff --git a/src/webgpu/shader/execution/expression/call/builtin/mix.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/mix.spec.ts index c4d443698746..91a66646b6b1 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/mix.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/mix.spec.ts @@ -16,10 +16,10 @@ Same as mix(e1,e2,T2(e3)). import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32, TypeVec } from '../../../../../util/conversion.js'; -import { allInputSources, run } from '../../expression.js'; +import { TypeAbstractFloat, TypeF16, TypeF32, TypeVec } from '../../../../../util/conversion.js'; +import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; -import { builtin } from './builtin.js'; +import { abstractBuiltin, builtin } from './builtin.js'; import { d } from './mix.cache.js'; export const g = makeTestGroup(GPUTest); @@ -28,27 +28,69 @@ g.test('abstract_float_matching') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') .desc(`abstract_float test with matching third param`) .params(u => - u.combine('inputSource', allInputSources).combine('vectorize', [undefined, 2, 3, 4] as const) + u + .combine('inputSource', onlyConstInputSource) + .combine('vectorize', [undefined, 2, 3, 4] as const) ) - .unimplemented(); + .fn(async t => { + const cases = await d.get('abstract_const'); + await run( + t, + abstractBuiltin('mix'), + [TypeAbstractFloat, TypeAbstractFloat, TypeAbstractFloat], + TypeAbstractFloat, + t.params, + cases + ); + }); g.test('abstract_float_nonmatching_vec2') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') .desc(`abstract_float tests with two vec2 params and scalar third param`) - .params(u => u.combine('inputSource', allInputSources)) - .unimplemented(); + .params(u => u.combine('inputSource', onlyConstInputSource)) + .fn(async t => { + const cases = await d.get('abstract_vec2_scalar_const'); + await run( + t, + abstractBuiltin('mix'), + [TypeVec(2, TypeAbstractFloat), TypeVec(2, TypeAbstractFloat), TypeAbstractFloat], + TypeVec(2, TypeAbstractFloat), + t.params, + cases + ); + }); g.test('abstract_float_nonmatching_vec3') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') .desc(`abstract_float tests with two vec3 params and scalar third param`) - .params(u => u.combine('inputSource', allInputSources)) - .unimplemented(); + .params(u => u.combine('inputSource', onlyConstInputSource)) + .fn(async t => { + const cases = await d.get('abstract_vec3_scalar_const'); + await run( + t, + abstractBuiltin('mix'), + [TypeVec(3, TypeAbstractFloat), TypeVec(3, TypeAbstractFloat), TypeAbstractFloat], + TypeVec(3, TypeAbstractFloat), + t.params, + cases + ); + }); g.test('abstract_float_nonmatching_vec4') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') .desc(`abstract_float tests with two vec4 params and scalar third param`) - .params(u => u.combine('inputSource', allInputSources)) - .unimplemented(); + .params(u => u.combine('inputSource', onlyConstInputSource)) + .fn(async t => { + const cases = await d.get('abstract_vec4_scalar_const'); + await run( + t, + abstractBuiltin('mix'), + [TypeVec(4, TypeAbstractFloat), TypeVec(4, TypeAbstractFloat), TypeAbstractFloat], + TypeVec(4, TypeAbstractFloat), + t.params, + cases + ); + }); g.test('f32_matching') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/util/floating_point.ts b/src/webgpu/util/floating_point.ts index 5880a7593775..d8e5f3b43413 100644 --- a/src/webgpu/util/floating_point.ts +++ b/src/webgpu/util/floating_point.ts @@ -5107,14 +5107,8 @@ class FPAbstractTraits extends FPTraits { public readonly log2Interval = this.unimplementedScalarToInterval.bind(this, 'log2Interval'); public readonly maxInterval = this.maxIntervalImpl.bind(this); public readonly minInterval = this.minIntervalImpl.bind(this); - public readonly mixImpreciseInterval = this.unimplementedScalarTripleToInterval.bind( - this, - 'mixImpreciseInterval' - ); - public readonly mixPreciseInterval = this.unimplementedScalarTripleToInterval.bind( - this, - 'mixPreciseInterval' - ); + public readonly mixImpreciseInterval = this.mixImpreciseIntervalImpl.bind(this); + public readonly mixPreciseInterval = this.mixPreciseIntervalImpl.bind(this); public readonly mixIntervals = [this.mixImpreciseInterval, this.mixPreciseInterval]; public readonly modfInterval = this.modfIntervalImpl.bind(this); public readonly multiplicationInterval = this.multiplicationIntervalImpl.bind(this);